From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/pybind/mgr/.gitignore | 1 + src/pybind/mgr/CMakeLists.txt | 14 + src/pybind/mgr/alerts/__init__.py | 1 + src/pybind/mgr/alerts/module.py | 259 + src/pybind/mgr/ansible/.gitignore | 1 + src/pybind/mgr/ansible/CMakeLists.txt | 7 + src/pybind/mgr/ansible/__init__.py | 9 + src/pybind/mgr/ansible/ansible_runner_svc.py | 326 + src/pybind/mgr/ansible/module.py | 729 + src/pybind/mgr/ansible/output_wizards.py | 158 + src/pybind/mgr/ansible/requirements.txt | 2 + src/pybind/mgr/ansible/run-tox.sh | 43 + src/pybind/mgr/ansible/tests/__init__.py | 0 .../mgr/ansible/tests/pb_execution_events.data | 183 + .../mgr/ansible/tests/test_client_playbooks.py | 287 + .../mgr/ansible/tests/test_output_wizards.py | 207 + src/pybind/mgr/ansible/tox.ini | 18 + src/pybind/mgr/balancer/__init__.py | 1 + src/pybind/mgr/balancer/module.py | 1324 ++ src/pybind/mgr/crash/__init__.py | 1 + src/pybind/mgr/crash/module.py | 369 + src/pybind/mgr/dashboard/.coveragerc | 7 + src/pybind/mgr/dashboard/.editorconfig | 29 + src/pybind/mgr/dashboard/.gitignore | 16 + src/pybind/mgr/dashboard/.pylintrc | 535 + src/pybind/mgr/dashboard/CMakeLists.txt | 133 + src/pybind/mgr/dashboard/HACKING.rst | 1784 +++ src/pybind/mgr/dashboard/README.rst | 37 + src/pybind/mgr/dashboard/__init__.py | 54 + src/pybind/mgr/dashboard/awsauth.py | 183 + src/pybind/mgr/dashboard/cherrypy_backports.py | 203 + src/pybind/mgr/dashboard/ci/check_grafana_uids.py | 155 + src/pybind/mgr/dashboard/constraints.txt | 9 + src/pybind/mgr/dashboard/controllers/__init__.py | 957 ++ src/pybind/mgr/dashboard/controllers/auth.py | 96 + src/pybind/mgr/dashboard/controllers/cephfs.py | 294 + .../dashboard/controllers/cluster_configuration.py | 106 + src/pybind/mgr/dashboard/controllers/docs.py | 427 + .../dashboard/controllers/erasure_code_profile.py | 66 + src/pybind/mgr/dashboard/controllers/grafana.py | 50 + src/pybind/mgr/dashboard/controllers/health.py | 189 + src/pybind/mgr/dashboard/controllers/home.py | 133 + src/pybind/mgr/dashboard/controllers/host.py | 12 + src/pybind/mgr/dashboard/controllers/iscsi.py | 1049 ++ src/pybind/mgr/dashboard/controllers/logging.py | 10 + src/pybind/mgr/dashboard/controllers/logs.py | 51 + .../mgr/dashboard/controllers/mgr_modules.py | 172 + src/pybind/mgr/dashboard/controllers/monitor.py | 40 + src/pybind/mgr/dashboard/controllers/nfsganesha.py | 315 + src/pybind/mgr/dashboard/controllers/osd.py | 242 + .../mgr/dashboard/controllers/perf_counters.py | 85 + src/pybind/mgr/dashboard/controllers/pool.py | 234 + src/pybind/mgr/dashboard/controllers/prometheus.py | 83 + src/pybind/mgr/dashboard/controllers/rbd.py | 526 + .../mgr/dashboard/controllers/rbd_mirroring.py | 460 + src/pybind/mgr/dashboard/controllers/rgw.py | 385 + src/pybind/mgr/dashboard/controllers/role.py | 110 + src/pybind/mgr/dashboard/controllers/saml2.py | 113 + src/pybind/mgr/dashboard/controllers/settings.py | 68 + src/pybind/mgr/dashboard/controllers/summary.py | 87 + src/pybind/mgr/dashboard/controllers/task.py | 15 + src/pybind/mgr/dashboard/controllers/user.py | 91 + src/pybind/mgr/dashboard/exceptions.py | 107 + src/pybind/mgr/dashboard/frontend/.babelrc | 3 + src/pybind/mgr/dashboard/frontend/.editorconfig | 13 + src/pybind/mgr/dashboard/frontend/.gitignore | 49 + src/pybind/mgr/dashboard/frontend/.prettierignore | 1 + src/pybind/mgr/dashboard/frontend/.prettierrc | 5 + src/pybind/mgr/dashboard/frontend/angular.json | 233 + .../frontend/dist/en-US/2.22b12bf9358f95829e55.js | 1 + .../frontend/dist/en-US/3rdpartylicenses.txt | 1462 ++ .../frontend/dist/en-US/6.f054f1f260c137d64363.js | 1 + .../frontend/dist/en-US/7.76846491986b0ea6c0bd.js | 1 + .../frontend/dist/en-US/8.7550b99d388b9ca165da.js | 1 + .../frontend/dist/en-US/9.b19f6391d5c667b85d12.js | 1 + ..._RGB_120411_fa_228x228.1ed169ccc35367a2dab2.png | Bin 0 -> 12949 bytes .../dist/en-US/assets/1280px-Mimic_Octopus2.jpg | Bin 0 -> 452518 bytes .../dist/en-US/assets/1280px-Nautilus_Octopus.jpg | Bin 0 -> 86126 bytes .../Ceph_Logo_Stacked_RGB_120411_fa_228x228.png | Bin 0 -> 12949 bytes .../Ceph_Logo_Stacked_RGB_120411_fa_348x348.png | Bin 0 -> 18960 bytes ...ph_Logo_Stacked_RGB_White_120411_fa_256x256.png | Bin 0 -> 8330 bytes .../Ceph_Logo_Standard_RGB_White_120411_fa.png | Bin 0 -> 4801 bytes .../frontend/dist/en-US/assets/loading.gif | Bin 0 -> 35386 bytes .../frontend/dist/en-US/assets/logo-mini.png | Bin 0 -> 1811 bytes .../dist/en-US/assets/notification-icons.png | Bin 0 -> 3397 bytes .../frontend/dist/en-US/assets/prometheus_logo.svg | 50 + .../dist/en-US/common.8a53d98b04768bd15706.js | 1 + .../mgr/dashboard/frontend/dist/en-US/favicon.ico | Bin 0 -> 1150 bytes .../forkawesome-webfont.35e77a38ca9d85c4e897.eot | Bin 0 -> 188946 bytes .../forkawesome-webfont.3a9e014c2469ffa65a0e.woff2 | Bin 0 -> 91624 bytes .../forkawesome-webfont.44bbdbbfb5a10ba2d1ce.woff | Bin 0 -> 115148 bytes .../forkawesome-webfont.78dcc9c4999659b8026a.svg | 2849 ++++ .../forkawesome-webfont.fc46f3dae03b2b2e1cee.ttf | Bin 0 -> 188756 bytes ...ns-halflings-regular.448c34a56d699c29117a.woff2 | Bin 0 -> 18028 bytes ...cons-halflings-regular.89889688147bd7575d63.svg | 288 + ...cons-halflings-regular.e18bbf611f2a2e43afc0.ttf | Bin 0 -> 45404 bytes ...cons-halflings-regular.f4769f9bdb7466be6508.eot | Bin 0 -> 20127 bytes ...ons-halflings-regular.fa2772327f55d8198301.woff | Bin 0 -> 23424 bytes .../mgr/dashboard/frontend/dist/en-US/index.html | 28 + .../dist/en-US/main.a8acf27ca1415ab0d94b.js | 1 + .../dist/en-US/polyfills.f31db31652a3fd9f4bca.js | 1 + .../en-US/prometheus_logo.074db273ef932a67d91b.svg | 50 + .../dist/en-US/runtime.ff444394af058f159c51.js | 1 + .../dist/en-US/scripts.fc88ef4a23399c760d0b.js | 1 + .../dist/en-US/styles.f5317b15474518dffebc.css | 27 + .../frontend/dist/en-US/swagger-ui-bundle.js | 134 + .../dashboard/frontend/dist/en-US/swagger-ui.css | 4 + .../frontend/e2e/block/images.e2e-spec.ts | 34 + .../mgr/dashboard/frontend/e2e/block/images.po.ts | 7 + .../dashboard/frontend/e2e/block/iscsi.e2e-spec.ts | 24 + .../mgr/dashboard/frontend/e2e/block/iscsi.po.ts | 7 + .../frontend/e2e/block/mirroring.e2e-spec.ts | 34 + .../dashboard/frontend/e2e/block/mirroring.po.ts | 7 + .../frontend/e2e/cluster/configuration.e2e-spec.ts | 24 + .../frontend/e2e/cluster/configuration.po.ts | 7 + .../frontend/e2e/cluster/crush-map.e2e-spec.ts | 24 + .../dashboard/frontend/e2e/cluster/crush-map.po.ts | 7 + .../frontend/e2e/cluster/hosts.e2e-spec.ts | 36 + .../mgr/dashboard/frontend/e2e/cluster/hosts.po.ts | 7 + .../frontend/e2e/cluster/logs.e2e-spec.ts | 36 + .../mgr/dashboard/frontend/e2e/cluster/logs.po.ts | 9 + .../frontend/e2e/cluster/mgr-modules.e2e-spec.ts | 24 + .../frontend/e2e/cluster/mgr-modules.po.ts | 7 + .../frontend/e2e/cluster/monitors.e2e-spec.ts | 24 + .../dashboard/frontend/e2e/cluster/monitors.po.ts | 7 + .../frontend/e2e/cluster/osds.e2e-spec.ts | 36 + .../mgr/dashboard/frontend/e2e/cluster/osds.po.ts | 7 + .../e2e/filesystems/filesystems.e2e-spec.ts | 24 + .../frontend/e2e/filesystems/filesystems.po.ts | 7 + src/pybind/mgr/dashboard/frontend/e2e/helper.po.ts | 48 + .../mgr/dashboard/frontend/e2e/nfs/nfs.e2e-spec.ts | 24 + .../mgr/dashboard/frontend/e2e/nfs/nfs.po.ts | 7 + .../dashboard/frontend/e2e/pools/pools.e2e-spec.ts | 36 + .../mgr/dashboard/frontend/e2e/pools/pools.po.ts | 7 + .../mgr/dashboard/frontend/e2e/tsconfig.e2e.json | 15 + .../mgr/dashboard/frontend/environment.build.js | 74 + .../mgr/dashboard/frontend/html-linter.config.json | 12 + src/pybind/mgr/dashboard/frontend/i18n.config.json | 12 + .../mgr/dashboard/frontend/package-lock.json | 15346 +++++++++++++++++++ src/pybind/mgr/dashboard/frontend/package.json | 139 + .../mgr/dashboard/frontend/protractor.conf.js | 58 + .../mgr/dashboard/frontend/proxy.conf.json.sample | 12 + .../frontend/src/app/app-routing.module.ts | 268 + .../dashboard/frontend/src/app/app.component.html | 8 + .../dashboard/frontend/src/app/app.component.scss | 31 + .../frontend/src/app/app.component.spec.ts | 29 + .../dashboard/frontend/src/app/app.component.ts | 34 + .../mgr/dashboard/frontend/src/app/app.module.ts | 77 + .../frontend/src/app/ceph/block/block.module.ts | 172 + .../iscsi-setting/iscsi-setting.component.html | 58 + .../iscsi-setting/iscsi-setting.component.scss | 0 .../iscsi-setting/iscsi-setting.component.spec.ts | 37 + .../block/iscsi-setting/iscsi-setting.component.ts | 31 + .../block/iscsi-tabs/iscsi-tabs.component.html | 12 + .../block/iscsi-tabs/iscsi-tabs.component.scss | 0 .../block/iscsi-tabs/iscsi-tabs.component.spec.ts | 28 + .../ceph/block/iscsi-tabs/iscsi-tabs.component.ts | 22 + .../iscsi-target-details.component.html | 35 + .../iscsi-target-details.component.scss | 3 + .../iscsi-target-details.component.spec.ts | 206 + .../iscsi-target-details.component.ts | 333 + .../iscsi-target-discovery-modal.component.html | 147 + .../iscsi-target-discovery-modal.component.scss | 0 .../iscsi-target-discovery-modal.component.spec.ts | 138 + .../iscsi-target-discovery-modal.component.ts | 123 + .../iscsi-target-form.component.html | 721 + .../iscsi-target-form.component.scss | 3 + .../iscsi-target-form.component.spec.ts | 538 + .../iscsi-target-form.component.ts | 813 + ...scsi-target-image-settings-modal.component.html | 102 + ...scsi-target-image-settings-modal.component.scss | 0 ...i-target-image-settings-modal.component.spec.ts | 98 + .../iscsi-target-image-settings-modal.component.ts | 82 + .../iscsi-target-iqn-settings-modal.component.html | 40 + .../iscsi-target-iqn-settings-modal.component.scss | 0 ...csi-target-iqn-settings-modal.component.spec.ts | 71 + .../iscsi-target-iqn-settings-modal.component.ts | 55 + .../iscsi-target-list.component.html | 48 + .../iscsi-target-list.component.scss | 9 + .../iscsi-target-list.component.spec.ts | 431 + .../iscsi-target-list.component.ts | 231 + .../src/app/ceph/block/iscsi/iscsi.component.html | 55 + .../src/app/ceph/block/iscsi/iscsi.component.scss | 0 .../app/ceph/block/iscsi/iscsi.component.spec.ts | 79 + .../src/app/ceph/block/iscsi/iscsi.component.ts | 114 + .../daemon-list/daemon-list.component.html | 12 + .../daemon-list/daemon-list.component.scss | 0 .../daemon-list/daemon-list.component.spec.ts | 38 + .../mirroring/daemon-list/daemon-list.component.ts | 63 + .../mirroring/image-list/image-list.component.html | 47 + .../mirroring/image-list/image-list.component.scss | 0 .../image-list/image-list.component.spec.ts | 38 + .../mirroring/image-list/image-list.component.ts | 97 + .../mirroring/mirror-health-color.pipe.spec.ts | 25 + .../block/mirroring/mirror-health-color.pipe.ts | 17 + .../app/ceph/block/mirroring/mirroring.module.ts | 51 + .../mirroring/overview/overview.component.html | 25 + .../mirroring/overview/overview.component.scss | 0 .../mirroring/overview/overview.component.spec.ts | 51 + .../block/mirroring/overview/overview.component.ts | 32 + .../pool-edit-mode-modal.component.html | 50 + .../pool-edit-mode-modal.component.scss | 0 .../pool-edit-mode-modal.component.spec.ts | 83 + .../pool-edit-mode-modal.component.ts | 109 + .../pool-edit-mode-response.model.ts | 3 + .../pool-edit-peer-modal.component.html | 115 + .../pool-edit-peer-modal.component.scss | 0 .../pool-edit-peer-modal.component.spec.ts | 152 + .../pool-edit-peer-modal.component.ts | 134 + .../pool-edit-peer-response.model.ts | 7 + .../mirroring/pool-list/pool-list.component.html | 21 + .../mirroring/pool-list/pool-list.component.scss | 0 .../pool-list/pool-list.component.spec.ts | 42 + .../mirroring/pool-list/pool-list.component.ts | 171 + .../rbd-configuration-form.component.html | 77 + .../rbd-configuration-form.component.scss | 4 + .../rbd-configuration-form.component.spec.ts | 305 + .../rbd-configuration-form.component.ts | 152 + .../rbd-configuration-list.component.html | 31 + .../rbd-configuration-list.component.scss | 0 .../rbd-configuration-list.component.spec.ts | 102 + .../rbd-configuration-list.component.ts | 67 + .../block/rbd-details/rbd-details.component.html | 144 + .../block/rbd-details/rbd-details.component.scss | 0 .../rbd-details/rbd-details.component.spec.ts | 31 + .../block/rbd-details/rbd-details.component.ts | 27 + .../ceph/block/rbd-form/rbd-feature.interface.ts | 9 + .../block/rbd-form/rbd-form-clone-request.model.ts | 12 + .../block/rbd-form/rbd-form-copy-request.model.ts | 13 + .../rbd-form/rbd-form-create-request.model.ts | 5 + .../block/rbd-form/rbd-form-edit-request.model.ts | 8 + .../app/ceph/block/rbd-form/rbd-form-mode.enum.ts | 5 + .../ceph/block/rbd-form/rbd-form-response.model.ts | 7 + .../ceph/block/rbd-form/rbd-form.component.html | 317 + .../ceph/block/rbd-form/rbd-form.component.scss | 0 .../ceph/block/rbd-form/rbd-form.component.spec.ts | 343 + .../app/ceph/block/rbd-form/rbd-form.component.ts | 678 + .../src/app/ceph/block/rbd-form/rbd-form.model.ts | 16 + .../app/ceph/block/rbd-form/rbd-parent.model.ts | 5 + .../block/rbd-images/rbd-images.component.html | 21 + .../block/rbd-images/rbd-images.component.scss | 0 .../block/rbd-images/rbd-images.component.spec.ts | 52 + .../ceph/block/rbd-images/rbd-images.component.ts | 19 + .../ceph/block/rbd-list/rbd-list.component.html | 43 + .../ceph/block/rbd-list/rbd-list.component.scss | 0 .../ceph/block/rbd-list/rbd-list.component.spec.ts | 367 + .../app/ceph/block/rbd-list/rbd-list.component.ts | 353 + .../src/app/ceph/block/rbd-list/rbd-model.ts | 14 + .../rbd-snapshot-form.component.html | 53 + .../rbd-snapshot-form.component.scss | 0 .../rbd-snapshot-form.component.spec.ts | 64 + .../rbd-snapshot-form.component.ts | 136 + .../rbd-snapshot-actions.model.ts | 89 + .../rbd-snapshot-list.component.html | 27 + .../rbd-snapshot-list.component.scss | 0 .../rbd-snapshot-list.component.spec.ts | 425 + .../rbd-snapshot-list.component.ts | 286 + .../block/rbd-snapshot-list/rbd-snapshot.model.ts | 9 + .../rbd-trash-list/rbd-trash-list.component.html | 51 + .../rbd-trash-list/rbd-trash-list.component.scss | 0 .../rbd-trash-list.component.spec.ts | 163 + .../rbd-trash-list/rbd-trash-list.component.ts | 212 + .../rbd-trash-move-modal.component.html | 49 + .../rbd-trash-move-modal.component.scss | 5 + .../rbd-trash-move-modal.component.spec.ts | 100 + .../rbd-trash-move-modal.component.ts | 88 + .../rbd-trash-purge-modal.component.html | 52 + .../rbd-trash-purge-modal.component.scss | 0 .../rbd-trash-purge-modal.component.spec.ts | 102 + .../rbd-trash-purge-modal.component.ts | 72 + .../rbd-trash-restore-modal.component.html | 49 + .../rbd-trash-restore-modal.component.scss | 0 .../rbd-trash-restore-modal.component.spec.ts | 75 + .../rbd-trash-restore-modal.component.ts | 61 + .../dashboard/frontend/src/app/ceph/ceph.module.ts | 23 + .../cephfs-chart/cephfs-chart.component.html | 12 + .../cephfs-chart/cephfs-chart.component.scss | 8 + .../cephfs-chart/cephfs-chart.component.spec.ts | 76 + .../cephfs/cephfs-chart/cephfs-chart.component.ts | 198 + .../cephfs-clients/cephfs-clients.component.html | 6 + .../cephfs-clients/cephfs-clients.component.scss | 0 .../cephfs-clients.component.spec.ts | 35 + .../cephfs-clients/cephfs-clients.component.ts | 45 + .../cephfs-detail/cephfs-detail.component.html | 65 + .../cephfs-detail/cephfs-detail.component.scss | 3 + .../cephfs-detail/cephfs-detail.component.spec.ts | 52 + .../cephfs-detail/cephfs-detail.component.ts | 143 + .../cephfs/cephfs-list/cephfs-list.component.html | 12 + .../cephfs/cephfs-list/cephfs-list.component.scss | 0 .../cephfs-list/cephfs-list.component.spec.ts | 35 + .../cephfs/cephfs-list/cephfs-list.component.ts | 56 + .../frontend/src/app/ceph/cephfs/cephfs.module.ts | 31 + .../src/app/ceph/cluster/cluster.module.ts | 98 + .../configuration-details.component.html | 108 + .../configuration-details.component.scss | 0 .../configuration-details.component.spec.ts | 29 + .../configuration-details.component.ts | 36 + .../configuration-form-create-request.model.ts | 4 + .../configuration-form.component.html | 168 + .../configuration-form.component.scss | 12 + .../configuration-form.component.spec.ts | 107 + .../configuration-form.component.ts | 173 + .../configuration/configuration.component.html | 39 + .../configuration/configuration.component.scss | 7 + .../configuration/configuration.component.spec.ts | 38 + .../configuration/configuration.component.ts | 157 + .../ceph/cluster/crushmap/crushmap.component.html | 29 + .../ceph/cluster/crushmap/crushmap.component.scss | 21 + .../cluster/crushmap/crushmap.component.spec.ts | 151 + .../ceph/cluster/crushmap/crushmap.component.ts | 80 + .../hosts/host-details/host-details.component.html | 9 + .../hosts/host-details/host-details.component.scss | 0 .../host-details/host-details.component.spec.ts | 38 + .../hosts/host-details/host-details.component.ts | 27 + .../app/ceph/cluster/hosts/hosts.component.html | 35 + .../app/ceph/cluster/hosts/hosts.component.scss | 0 .../app/ceph/cluster/hosts/hosts.component.spec.ts | 84 + .../src/app/ceph/cluster/hosts/hosts.component.ts | 98 + .../src/app/ceph/cluster/logs/logs.component.html | 107 + .../src/app/ceph/cluster/logs/logs.component.scss | 143 + .../app/ceph/cluster/logs/logs.component.spec.ts | 138 + .../src/app/ceph/cluster/logs/logs.component.ts | 115 + .../mgr-module-details.component.html | 6 + .../mgr-module-details.component.scss | 0 .../mgr-module-details.component.spec.ts | 31 + .../mgr-module-details.component.ts | 27 + .../mgr-module-form/mgr-module-form.component.html | 123 + .../mgr-module-form/mgr-module-form.component.scss | 0 .../mgr-module-form.component.spec.ts | 93 + .../mgr-module-form/mgr-module-form.component.ts | 146 + .../mgr-module-list/mgr-module-list.component.html | 18 + .../mgr-module-list/mgr-module-list.component.scss | 0 .../mgr-module-list.component.spec.ts | 176 + .../mgr-module-list/mgr-module-list.component.ts | 192 + .../ceph/cluster/mgr-modules/mgr-modules.module.ts | 23 + .../ceph/cluster/monitor/monitor.component.html | 60 + .../ceph/cluster/monitor/monitor.component.scss | 0 .../ceph/cluster/monitor/monitor.component.spec.ts | 86 + .../app/ceph/cluster/monitor/monitor.component.ts | 77 + .../osd/osd-details/osd-details.component.html | 52 + .../osd/osd-details/osd-details.component.scss | 0 .../osd/osd-details/osd-details.component.spec.ts | 77 + .../osd/osd-details/osd-details.component.ts | 47 + .../osd-flags-modal/osd-flags-modal.component.html | 45 + .../osd-flags-modal/osd-flags-modal.component.scss | 5 + .../osd-flags-modal.component.spec.ts | 100 + .../osd-flags-modal/osd-flags-modal.component.ts | 162 + .../cluster/osd/osd-list/osd-list.component.html | 95 + .../cluster/osd/osd-list/osd-list.component.scss | 3 + .../osd/osd-list/osd-list.component.spec.ts | 292 + .../cluster/osd/osd-list/osd-list.component.ts | 351 + .../osd-performance-histogram.component.html | 9 + .../osd-performance-histogram.component.scss | 0 .../osd-performance-histogram.component.spec.ts | 23 + .../osd-performance-histogram.component.ts | 60 + .../osd-pg-scrub-modal.component.html | 50 + .../osd-pg-scrub-modal.component.scss | 0 .../osd-pg-scrub-modal.component.spec.ts | 65 + .../osd-pg-scrub-modal.component.ts | 70 + .../osd-pg-scrub-modal.options.ts | 39 + .../osd-recv-speed-modal.component.html | 98 + .../osd-recv-speed-modal.component.scss | 0 .../osd-recv-speed-modal.component.spec.ts | 318 + .../osd-recv-speed-modal.component.ts | 238 + .../osd-reweight-modal.component.html | 38 + .../osd-reweight-modal.component.scss | 0 .../osd-reweight-modal.component.spec.ts | 52 + .../osd-reweight-modal.component.ts | 45 + .../osd-scrub-modal/osd-scrub-modal.component.html | 29 + .../osd-scrub-modal/osd-scrub-modal.component.scss | 0 .../osd-scrub-modal.component.spec.ts | 49 + .../osd-scrub-modal/osd-scrub-modal.component.ts | 54 + .../active-alert-list.component.html | 32 + .../active-alert-list.component.scss | 0 .../active-alert-list.component.spec.ts | 132 + .../active-alert-list.component.ts | 97 + .../monitoring-list/monitoring-list.component.html | 35 + .../monitoring-list/monitoring-list.component.scss | 0 .../monitoring-list.component.spec.ts | 46 + .../monitoring-list/monitoring-list.component.ts | 70 + .../rules-list/rules-list.component.html | 9 + .../rules-list/rules-list.component.scss | 0 .../rules-list/rules-list.component.spec.ts | 29 + .../prometheus/rules-list/rules-list.component.ts | 44 + .../silence-form/silence-form.component.html | 219 + .../silence-form/silence-form.component.scss | 3 + .../silence-form/silence-form.component.spec.ts | 606 + .../silence-form/silence-form.component.ts | 333 + .../silence-list/silence-list.component.html | 27 + .../silence-list/silence-list.component.scss | 0 .../silence-list/silence-list.component.spec.ts | 319 + .../silence-list/silence-list.component.ts | 201 + .../silence-matcher-modal.component.html | 98 + .../silence-matcher-modal.component.scss | 0 .../silence-matcher-modal.component.spec.ts | 163 + .../silence-matcher-modal.component.ts | 79 + .../src/app/ceph/dashboard/dashboard.module.ts | 44 + .../dashboard/dashboard/dashboard.component.html | 13 + .../dashboard/dashboard/dashboard.component.scss | 3 + .../dashboard/dashboard.component.spec.ts | 25 + .../dashboard/dashboard/dashboard.component.ts | 14 + .../dashboard/health-pie/health-pie-color.enum.ts | 7 + .../dashboard/health-pie/health-pie.component.html | 15 + .../dashboard/health-pie/health-pie.component.scss | 22 + .../health-pie/health-pie.component.spec.ts | 74 + .../dashboard/health-pie/health-pie.component.ts | 187 + .../ceph/dashboard/health/health.component.html | 267 + .../ceph/dashboard/health/health.component.scss | 89 + .../ceph/dashboard/health/health.component.spec.ts | 338 + .../app/ceph/dashboard/health/health.component.ts | 225 + .../dashboard/info-card/info-card-popover.scss | 42 + .../dashboard/info-card/info-card.component.html | 14 + .../dashboard/info-card/info-card.component.scss | 135 + .../info-card/info-card.component.spec.ts | 65 + .../dashboard/info-card/info-card.component.ts | 17 + .../dashboard/info-group/info-group.component.html | 4 + .../dashboard/info-group/info-group.component.scss | 7 + .../info-group/info-group.component.spec.ts | 31 + .../dashboard/info-group/info-group.component.ts | 11 + .../app/ceph/dashboard/mds-summary.pipe.spec.ts | 72 + .../src/app/ceph/dashboard/mds-summary.pipe.ts | 83 + .../app/ceph/dashboard/mgr-summary.pipe.spec.ts | 53 + .../src/app/ceph/dashboard/mgr-summary.pipe.ts | 51 + .../app/ceph/dashboard/mon-summary.pipe.spec.ts | 40 + .../src/app/ceph/dashboard/mon-summary.pipe.ts | 22 + .../app/ceph/dashboard/osd-summary.pipe.spec.ts | 127 + .../src/app/ceph/dashboard/osd-summary.pipe.ts | 62 + .../app/ceph/nfs/nfs-501/nfs-501.component.html | 5 + .../app/ceph/nfs/nfs-501/nfs-501.component.scss | 0 .../app/ceph/nfs/nfs-501/nfs-501.component.spec.ts | 28 + .../src/app/ceph/nfs/nfs-501/nfs-501.component.ts | 50 + .../nfs/nfs-details/nfs-details.component.html | 19 + .../nfs/nfs-details/nfs-details.component.scss | 0 .../nfs/nfs-details/nfs-details.component.spec.ts | 114 + .../ceph/nfs/nfs-details/nfs-details.component.ts | 73 + .../nfs-form-client/nfs-form-client.component.html | 104 + .../nfs-form-client/nfs-form-client.component.scss | 0 .../nfs-form-client.component.spec.ts | 72 + .../nfs-form-client/nfs-form-client.component.ts | 88 + .../app/ceph/nfs/nfs-form/nfs-form.component.html | 530 + .../app/ceph/nfs/nfs-form/nfs-form.component.scss | 3 + .../ceph/nfs/nfs-form/nfs-form.component.spec.ts | 229 + .../app/ceph/nfs/nfs-form/nfs-form.component.ts | 597 + .../app/ceph/nfs/nfs-list/nfs-list.component.html | 28 + .../app/ceph/nfs/nfs-list/nfs-list.component.scss | 0 .../ceph/nfs/nfs-list/nfs-list.component.spec.ts | 325 + .../app/ceph/nfs/nfs-list/nfs-list.component.ts | 221 + .../frontend/src/app/ceph/nfs/nfs.module.ts | 34 + .../performance-counter.module.ts | 14 + .../performance-counter.component.html | 4 + .../performance-counter.component.scss | 0 .../performance-counter.component.spec.ts | 29 + .../performance-counter.component.ts | 25 + .../table-performance-counter.component.html | 13 + .../table-performance-counter.component.scss | 0 .../table-performance-counter.component.spec.ts | 63 + .../table-performance-counter.component.ts | 74 + .../erasure-code-profile-form.component.html | 330 + .../erasure-code-profile-form.component.scss | 0 .../erasure-code-profile-form.component.spec.ts | 325 + .../erasure-code-profile-form.component.ts | 259 + .../pool/pool-details/pool-details.component.html | 34 + .../pool/pool-details/pool-details.component.scss | 0 .../pool-details/pool-details.component.spec.ts | 102 + .../pool/pool-details/pool-details.component.ts | 77 + .../src/app/ceph/pool/pool-form/pool-form-data.ts | 46 + .../ceph/pool/pool-form/pool-form.component.html | 459 + .../ceph/pool/pool-form/pool-form.component.scss | 3 + .../pool/pool-form/pool-form.component.spec.ts | 1140 ++ .../app/ceph/pool/pool-form/pool-form.component.ts | 674 + .../ceph/pool/pool-list/pool-list.component.html | 42 + .../ceph/pool/pool-list/pool-list.component.scss | 17 + .../pool/pool-list/pool-list.component.spec.ts | 489 + .../app/ceph/pool/pool-list/pool-list.component.ts | 300 + .../frontend/src/app/ceph/pool/pool-stat.ts | 16 + .../frontend/src/app/ceph/pool/pool.module.ts | 61 + .../dashboard/frontend/src/app/ceph/pool/pool.ts | 73 + .../app/ceph/rgw/models/rgw-user-capabilities.ts | 15 + .../src/app/ceph/rgw/models/rgw-user-capability.ts | 4 + .../src/app/ceph/rgw/models/rgw-user-s3-key.ts | 6 + .../src/app/ceph/rgw/models/rgw-user-subuser.ts | 6 + .../src/app/ceph/rgw/models/rgw-user-swift-key.ts | 4 + .../app/ceph/rgw/rgw-501/rgw-501.component.html | 5 + .../app/ceph/rgw/rgw-501/rgw-501.component.scss | 0 .../app/ceph/rgw/rgw-501/rgw-501.component.spec.ts | 28 + .../src/app/ceph/rgw/rgw-501/rgw-501.component.ts | 47 + .../rgw-bucket-details.component.html | 101 + .../rgw-bucket-details.component.scss | 7 + .../rgw-bucket-details.component.spec.ts | 30 + .../rgw-bucket-details.component.ts | 23 + .../rgw-bucket-form/rgw-bucket-form.component.html | 108 + .../rgw-bucket-form/rgw-bucket-form.component.scss | 0 .../rgw-bucket-form.component.spec.ts | 131 + .../rgw-bucket-form/rgw-bucket-form.component.ts | 160 + .../rgw-bucket-list/rgw-bucket-list.component.html | 39 + .../rgw-bucket-list/rgw-bucket-list.component.scss | 0 .../rgw-bucket-list.component.spec.ts | 291 + .../rgw-bucket-list/rgw-bucket-list.component.ts | 189 + .../rgw-daemon-details.component.html | 22 + .../rgw-daemon-details.component.scss | 0 .../rgw-daemon-details.component.spec.ts | 31 + .../rgw-daemon-details.component.ts | 45 + .../rgw-daemon-list/rgw-daemon-list.component.html | 22 + .../rgw-daemon-list/rgw-daemon-list.component.scss | 0 .../rgw-daemon-list.component.spec.ts | 38 + .../rgw-daemon-list/rgw-daemon-list.component.ts | 65 + .../rgw-user-capability-modal.component.html | 84 + .../rgw-user-capability-modal.component.scss | 0 .../rgw-user-capability-modal.component.spec.ts | 30 + .../rgw-user-capability-modal.component.ts | 94 + .../rgw-user-details.component.html | 155 + .../rgw-user-details.component.scss | 0 .../rgw-user-details.component.spec.ts | 85 + .../rgw-user-details/rgw-user-details.component.ts | 122 + .../rgw/rgw-user-form/rgw-user-form.component.html | 623 + .../rgw/rgw-user-form/rgw-user-form.component.scss | 6 + .../rgw-user-form/rgw-user-form.component.spec.ts | 339 + .../rgw/rgw-user-form/rgw-user-form.component.ts | 713 + .../rgw/rgw-user-list/rgw-user-list.component.html | 18 + .../rgw/rgw-user-list/rgw-user-list.component.scss | 0 .../rgw-user-list/rgw-user-list.component.spec.ts | 196 + .../rgw/rgw-user-list/rgw-user-list.component.ts | 152 + .../rgw-user-s3-key-modal.component.html | 144 + .../rgw-user-s3-key-modal.component.scss | 0 .../rgw-user-s3-key-modal.component.spec.ts | 30 + .../rgw-user-s3-key-modal.component.ts | 86 + .../rgw-user-subuser-modal.component.html | 146 + .../rgw-user-subuser-modal.component.scss | 0 .../rgw-user-subuser-modal.component.spec.ts | 71 + .../rgw-user-subuser-modal.component.ts | 132 + .../rgw-user-swift-key-modal.component.html | 61 + .../rgw-user-swift-key-modal.component.scss | 0 .../rgw-user-swift-key-modal.component.spec.ts | 31 + .../rgw-user-swift-key-modal.component.ts | 35 + .../frontend/src/app/ceph/rgw/rgw.module.ts | 134 + .../src/app/ceph/shared/ceph-shared.module.ts | 7 + .../src/app/ceph/shared/pg-category.model.ts | 71 + .../app/ceph/shared/pg-category.service.spec.ts | 55 + .../src/app/ceph/shared/pg-category.service.ts | 63 + .../frontend/src/app/core/auth/auth.module.ts | 86 + .../src/app/core/auth/login/login.component.html | 69 + .../src/app/core/auth/login/login.component.scss | 31 + .../app/core/auth/login/login.component.spec.ts | 32 + .../src/app/core/auth/login/login.component.ts | 68 + .../auth/role-details/role-details.component.html | 13 + .../auth/role-details/role-details.component.scss | 12 + .../role-details/role-details.component.spec.ts | 77 + .../auth/role-details/role-details.component.ts | 83 + .../app/core/auth/role-form/role-form-mode.enum.ts | 3 + .../core/auth/role-form/role-form.component.html | 125 + .../core/auth/role-form/role-form.component.scss | 4 + .../auth/role-form/role-form.component.spec.ts | 222 + .../app/core/auth/role-form/role-form.component.ts | 314 + .../src/app/core/auth/role-form/role-form.model.ts | 5 + .../core/auth/role-list/role-list.component.html | 19 + .../core/auth/role-list/role-list.component.scss | 0 .../auth/role-list/role-list.component.spec.ts | 203 + .../app/core/auth/role-list/role-list.component.ts | 138 + .../sso/sso-not-found/sso-not-found.component.html | 15 + .../sso/sso-not-found/sso-not-found.component.scss | 11 + .../sso-not-found/sso-not-found.component.spec.ts | 30 + .../sso/sso-not-found/sso-not-found.component.ts | 14 + .../app/core/auth/user-form/user-form-mode.enum.ts | 3 + .../core/auth/user-form/user-form-role.model.ts | 14 + .../core/auth/user-form/user-form.component.html | 163 + .../core/auth/user-form/user-form.component.scss | 0 .../auth/user-form/user-form.component.spec.ts | 231 + .../app/core/auth/user-form/user-form.component.ts | 234 + .../src/app/core/auth/user-form/user-form.model.ts | 7 + .../core/auth/user-list/user-list.component.html | 22 + .../core/auth/user-list/user-list.component.scss | 0 .../auth/user-list/user-list.component.spec.ts | 202 + .../app/core/auth/user-list/user-list.component.ts | 145 + .../core/auth/user-tabs/user-tabs.component.html | 12 + .../core/auth/user-tabs/user-tabs.component.scss | 0 .../auth/user-tabs/user-tabs.component.spec.ts | 29 + .../app/core/auth/user-tabs/user-tabs.component.ts | 22 + .../dashboard/frontend/src/app/core/core.module.ts | 13 + .../app/core/forbidden/forbidden.component.html | 10 + .../app/core/forbidden/forbidden.component.scss | 13 + .../app/core/forbidden/forbidden.component.spec.ts | 23 + .../src/app/core/forbidden/forbidden.component.ts | 10 + .../app/core/navigation/about/about.component.html | 60 + .../app/core/navigation/about/about.component.scss | 36 + .../core/navigation/about/about.component.spec.ts | 55 + .../app/core/navigation/about/about.component.ts | 74 + .../administration/administration.component.html | 21 + .../administration/administration.component.scss | 0 .../administration.component.spec.ts | 25 + .../administration/administration.component.ts | 19 + .../breadcrumbs/breadcrumbs.component.html | 11 + .../breadcrumbs/breadcrumbs.component.scss | 18 + .../breadcrumbs/breadcrumbs.component.spec.ts | 131 + .../breadcrumbs/breadcrumbs.component.ts | 126 + .../dashboard-help/dashboard-help.component.html | 36 + .../dashboard-help/dashboard-help.component.scss | 0 .../dashboard-help.component.spec.ts | 27 + .../dashboard-help/dashboard-help.component.ts | 48 + .../navigation/identity/identity.component.html | 31 + .../navigation/identity/identity.component.scss | 0 .../navigation/identity/identity.component.spec.ts | 27 + .../core/navigation/identity/identity.component.ts | 23 + .../src/app/core/navigation/navigation.module.ts | 47 + .../navigation/navigation.component.html | 241 + .../navigation/navigation.component.scss | 210 + .../navigation/navigation.component.spec.ts | 47 + .../navigation/navigation/navigation.component.ts | 64 + .../notifications/notifications.component.html | 57 + .../notifications/notifications.component.scss | 1 + .../notifications/notifications.component.spec.ts | 89 + .../notifications/notifications.component.ts | 58 + .../task-manager/task-manager.component.html | 85 + .../task-manager/task-manager.component.scss | 1 + .../task-manager/task-manager.component.spec.ts | 86 + .../task-manager/task-manager.component.ts | 55 + .../app/core/not-found/not-found.component.html | 14 + .../app/core/not-found/not-found.component.scss | 11 + .../app/core/not-found/not-found.component.spec.ts | 23 + .../src/app/core/not-found/not-found.component.ts | 10 + .../frontend/src/app/shared/api/api.module.ts | 7 + .../src/app/shared/api/auth.service.spec.ts | 54 + .../frontend/src/app/shared/api/auth.service.ts | 43 + .../src/app/shared/api/cephfs.service.spec.ts | 52 + .../frontend/src/app/shared/api/cephfs.service.ts | 29 + .../app/shared/api/configuration.service.spec.ts | 80 + .../src/app/shared/api/configuration.service.ts | 36 + .../api/erasure-code-profile.service.spec.ts | 67 + .../app/shared/api/erasure-code-profile.service.ts | 107 + .../src/app/shared/api/health.service.spec.ts | 40 + .../frontend/src/app/shared/api/health.service.ts | 19 + .../src/app/shared/api/host.service.spec.ts | 38 + .../frontend/src/app/shared/api/host.service.ts | 20 + .../src/app/shared/api/iscsi.service.spec.ts | 97 + .../frontend/src/app/shared/api/iscsi.service.ts | 61 + .../src/app/shared/api/logging.service.spec.ts | 39 + .../frontend/src/app/shared/api/logging.service.ts | 20 + .../src/app/shared/api/logs.service.spec.ts | 34 + .../frontend/src/app/shared/api/logs.service.ts | 19 + .../src/app/shared/api/mgr-module.service.spec.ts | 66 + .../src/app/shared/api/mgr-module.service.ts | 67 + .../src/app/shared/api/monitor.service.spec.ts | 34 + .../frontend/src/app/shared/api/monitor.service.ts | 15 + .../src/app/shared/api/nfs.service.spec.ts | 90 + .../frontend/src/app/shared/api/nfs.service.ts | 113 + .../src/app/shared/api/osd.service.spec.ts | 114 + .../frontend/src/app/shared/api/osd.service.ts | 116 + .../shared/api/performance-counter.service.spec.ts | 45 + .../app/shared/api/performance-counter.service.ts | 30 + .../src/app/shared/api/pool.service.spec.ts | 123 + .../frontend/src/app/shared/api/pool.service.ts | 75 + .../src/app/shared/api/prometheus.service.spec.ts | 238 + .../src/app/shared/api/prometheus.service.ts | 92 + .../app/shared/api/rbd-mirroring.service.spec.ts | 130 + .../src/app/shared/api/rbd-mirroring.service.ts | 84 + .../frontend/src/app/shared/api/rbd.model.ts | 29 + .../src/app/shared/api/rbd.service.spec.ts | 137 + .../frontend/src/app/shared/api/rbd.service.ts | 150 + .../src/app/shared/api/rgw-bucket.service.spec.ts | 75 + .../src/app/shared/api/rgw-bucket.service.ts | 75 + .../src/app/shared/api/rgw-daemon.service.spec.ts | 40 + .../src/app/shared/api/rgw-daemon.service.ts | 23 + .../src/app/shared/api/rgw-user.service.spec.ts | 156 + .../src/app/shared/api/rgw-user.service.ts | 159 + .../src/app/shared/api/role.service.spec.ts | 68 + .../frontend/src/app/shared/api/role.service.ts | 46 + .../src/app/shared/api/scope.service.spec.ts | 34 + .../frontend/src/app/shared/api/scope.service.ts | 15 + .../src/app/shared/api/settings.service.spec.ts | 128 + .../src/app/shared/api/settings.service.ts | 50 + .../src/app/shared/api/user.service.spec.ts | 73 + .../frontend/src/app/shared/api/user.service.ts | 32 + .../back-button/back-button.component.html | 6 + .../back-button/back-button.component.scss | 0 .../back-button/back-button.component.spec.ts | 26 + .../back-button/back-button.component.ts | 16 + .../src/app/shared/components/components.module.ts | 92 + .../config-option/config-option.component.html | 72 + .../config-option/config-option.component.scss | 30 + .../config-option/config-option.component.spec.ts | 295 + .../config-option/config-option.component.ts | 118 + .../config-option/config-option.model.ts | 12 + .../config-option/config-option.types.spec.ts | 272 + .../config-option/config-option.types.ts | 144 + .../confirmation-modal.component.html | 26 + .../confirmation-modal.component.scss | 0 .../confirmation-modal.component.spec.ts | 37 + .../confirmation-modal.component.ts | 43 + .../critical-confirmation-modal.component.html | 59 + .../critical-confirmation-modal.component.scss | 9 + .../critical-confirmation-modal.component.spec.ts | 250 + .../critical-confirmation-modal.component.ts | 58 + .../error-panel/error-panel.component.html | 28 + .../error-panel/error-panel.component.scss | 7 + .../error-panel/error-panel.component.spec.ts | 26 + .../error-panel/error-panel.component.ts | 22 + .../components/grafana/grafana.component.html | 53 + .../components/grafana/grafana.component.scss | 44 + .../components/grafana/grafana.component.spec.ts | 83 + .../shared/components/grafana/grafana.component.ts | 221 + .../shared/components/helper/helper.component.html | 12 + .../shared/components/helper/helper.component.scss | 7 + .../components/helper/helper.component.spec.ts | 26 + .../shared/components/helper/helper.component.ts | 13 + .../info-panel/info-panel.component.html | 18 + .../info-panel/info-panel.component.scss | 7 + .../info-panel/info-panel.component.spec.ts | 27 + .../components/info-panel/info-panel.component.ts | 19 + .../language-selector.component.html | 26 + .../language-selector.component.scss | 0 .../language-selector.component.spec.ts | 90 + .../language-selector.component.ts | 59 + .../language-selector/supported-languages.enum.ts | 47 + .../loading-panel/loading-panel.component.html | 7 + .../loading-panel/loading-panel.component.scss | 0 .../loading-panel/loading-panel.component.spec.ts | 26 + .../loading-panel/loading-panel.component.ts | 8 + .../shared/components/modal/modal.component.html | 13 + .../shared/components/modal/modal.component.scss | 17 + .../components/modal/modal.component.spec.ts | 42 + .../app/shared/components/modal/modal.component.ts | 28 + .../refresh-selector.component.html | 18 + .../refresh-selector.component.scss | 26 + .../refresh-selector.component.spec.ts | 28 + .../refresh-selector/refresh-selector.component.ts | 32 + .../select-badges/select-badges.component.html | 22 + .../select-badges/select-badges.component.scss | 8 + .../select-badges/select-badges.component.spec.ts | 61 + .../select-badges/select-badges.component.ts | 36 + .../components/select/select-messages.model.ts | 29 + .../components/select/select-option.model.ts | 13 + .../shared/components/select/select.component.html | 79 + .../shared/components/select/select.component.scss | 19 + .../components/select/select.component.spec.ts | 278 + .../shared/components/select/select.component.ts | 150 + .../components/sparkline/sparkline.component.html | 13 + .../components/sparkline/sparkline.component.scss | 5 + .../sparkline/sparkline.component.spec.ts | 53 + .../components/sparkline/sparkline.component.ts | 123 + .../submit-button/submit-button.component.html | 9 + .../submit-button/submit-button.component.scss | 0 .../submit-button/submit-button.component.spec.ts | 27 + .../submit-button/submit-button.component.ts | 86 + .../components/usage-bar/usage-bar.component.html | 26 + .../components/usage-bar/usage-bar.component.scss | 0 .../usage-bar/usage-bar.component.spec.ts | 27 + .../components/usage-bar/usage-bar.component.ts | 27 + .../view-cache/view-cache.component.html | 15 + .../view-cache/view-cache.component.scss | 0 .../view-cache/view-cache.component.spec.ts | 34 + .../components/view-cache/view-cache.component.ts | 20 + .../warning-panel/warning-panel.component.html | 18 + .../warning-panel/warning-panel.component.scss | 9 + .../warning-panel/warning-panel.component.spec.ts | 26 + .../warning-panel/warning-panel.component.ts | 15 + .../src/app/shared/constants/app.constants.ts | 198 + .../src/app/shared/datatable/datatable.module.ts | 28 + .../table-actions/table-actions.component.html | 39 + .../table-actions/table-actions.component.scss | 4 + .../table-actions/table-actions.component.spec.ts | 334 + .../table-actions/table-actions.component.ts | 148 + .../table-key-value/table-key-value.component.html | 12 + .../table-key-value/table-key-value.component.scss | 0 .../table-key-value.component.spec.ts | 317 + .../table-key-value/table-key-value.component.ts | 224 + .../shared/datatable/table/table.component.html | 191 + .../shared/datatable/table/table.component.scss | 282 + .../shared/datatable/table/table.component.spec.ts | 431 + .../app/shared/datatable/table/table.component.ts | 582 + .../src/app/shared/decorators/cd-encode.spec.ts | 41 + .../src/app/shared/decorators/cd-encode.ts | 79 + .../shared/directives/autofocus.directive.spec.ts | 61 + .../app/shared/directives/autofocus.directive.ts | 17 + .../copy2clipboard-button.directive.spec.ts | 8 + .../directives/copy2clipboard-button.directive.ts | 48 + .../dimless-binary-per-second.directive.spec.ts | 12 + .../dimless-binary-per-second.directive.ts | 132 + .../directives/dimless-binary.directive.spec.ts | 12 + .../shared/directives/dimless-binary.directive.ts | 122 + .../src/app/shared/directives/directives.module.ts | 41 + .../form-input-disable.directive.spec.ts | 75 + .../directives/form-input-disable.directive.ts | 30 + .../shared/directives/form-scope.directive.spec.ts | 8 + .../app/shared/directives/form-scope.directive.ts | 8 + .../app/shared/directives/iops.directive.spec.ts | 8 + .../src/app/shared/directives/iops.directive.ts | 31 + .../directives/milliseconds.directive.spec.ts | 8 + .../shared/directives/milliseconds.directive.ts | 31 + .../directives/password-button.directive.spec.ts | 8 + .../shared/directives/password-button.directive.ts | 46 + .../app/shared/directives/trim.directive.spec.ts | 50 + .../src/app/shared/directives/trim.directive.ts | 21 + .../src/app/shared/enum/cell-template.enum.ts | 18 + .../src/app/shared/enum/components.enum.ts | 9 + .../frontend/src/app/shared/enum/icons.enum.ts | 72 + .../src/app/shared/enum/notification-type.enum.ts | 5 + .../src/app/shared/enum/unix_errno.enum.ts | 4 + .../src/app/shared/enum/view-cache-status.enum.ts | 6 + .../src/app/shared/forms/cd-form-builder.spec.ts | 32 + .../src/app/shared/forms/cd-form-builder.ts | 20 + .../src/app/shared/forms/cd-form-group.spec.ts | 184 + .../frontend/src/app/shared/forms/cd-form-group.ts | 75 + .../src/app/shared/forms/cd-validators.spec.ts | 478 + .../frontend/src/app/shared/forms/cd-validators.ts | 284 + .../src/app/shared/models/alertmanager-silence.ts | 23 + .../frontend/src/app/shared/models/breadcrumbs.ts | 59 + .../src/app/shared/models/cd-notification.spec.ts | 95 + .../src/app/shared/models/cd-notification.ts | 40 + .../src/app/shared/models/cd-table-action.ts | 46 + .../src/app/shared/models/cd-table-column.ts | 10 + .../shared/models/cd-table-fetch-data-context.ts | 17 + .../src/app/shared/models/cd-table-selection.ts | 28 + .../src/app/shared/models/cd-user-config.ts | 9 + .../src/app/shared/models/chart-tooltip.ts | 115 + .../src/app/shared/models/configuration.ts | 43 + .../frontend/src/app/shared/models/credentials.ts | 4 + .../frontend/src/app/shared/models/crush-rule.ts | 10 + .../frontend/src/app/shared/models/crush-step.ts | 7 + .../src/app/shared/models/erasure-code-profile.ts | 15 + .../src/app/shared/models/executing-task.ts | 6 + .../src/app/shared/models/finished-task.ts | 14 + .../src/app/shared/models/login-response.ts | 4 + .../src/app/shared/models/permission.spec.ts | 62 + .../frontend/src/app/shared/models/permissions.ts | 50 + .../src/app/shared/models/pool-form-info.ts | 14 + .../src/app/shared/models/prometheus-alerts.ts | 85 + .../src/app/shared/models/task-exception.ts | 9 + .../frontend/src/app/shared/models/task.ts | 10 + .../src/app/shared/pipes/boolean-text.pipe.spec.ts | 47 + .../src/app/shared/pipes/boolean-text.pipe.ts | 18 + .../src/app/shared/pipes/cd-date.pipe.spec.ts | 24 + .../frontend/src/app/shared/pipes/cd-date.pipe.ts | 20 + .../shared/pipes/ceph-release-name.pipe.spec.ts | 28 + .../src/app/shared/pipes/ceph-release-name.pipe.ts | 24 + .../shared/pipes/ceph-short-version.pipe.spec.ts | 21 + .../app/shared/pipes/ceph-short-version.pipe.ts | 18 + .../shared/pipes/dimless-binary-per-second.pipe.ts | 23 + .../app/shared/pipes/dimless-binary.pipe.spec.ts | 56 + .../src/app/shared/pipes/dimless-binary.pipe.ts | 23 + .../src/app/shared/pipes/dimless.pipe.spec.ts | 56 + .../frontend/src/app/shared/pipes/dimless.pipe.ts | 13 + .../src/app/shared/pipes/duration.pipe.spec.ts | 24 + .../frontend/src/app/shared/pipes/duration.pipe.ts | 47 + .../src/app/shared/pipes/empty.pipe.spec.ts | 19 + .../frontend/src/app/shared/pipes/empty.pipe.ts | 12 + .../src/app/shared/pipes/encode-uri.pipe.spec.ts | 13 + .../src/app/shared/pipes/encode-uri.pipe.ts | 10 + .../src/app/shared/pipes/filter.pipe.spec.ts | 54 + .../frontend/src/app/shared/pipes/filter.pipe.ts | 25 + .../src/app/shared/pipes/health-color.pipe.spec.ts | 25 + .../src/app/shared/pipes/health-color.pipe.ts | 18 + .../src/app/shared/pipes/iops.pipe.spec.ts | 8 + .../frontend/src/app/shared/pipes/iops.pipe.ts | 10 + .../app/shared/pipes/iscsi-backstore.pipe.spec.ts | 17 + .../src/app/shared/pipes/iscsi-backstore.pipe.ts | 17 + .../src/app/shared/pipes/list.pipe.spec.ts | 13 + .../frontend/src/app/shared/pipes/list.pipe.ts | 10 + .../src/app/shared/pipes/log-priority.pipe.spec.ts | 32 + .../src/app/shared/pipes/log-priority.pipe.ts | 18 + .../frontend/src/app/shared/pipes/map.pipe.spec.ts | 25 + .../frontend/src/app/shared/pipes/map.pipe.ts | 15 + .../src/app/shared/pipes/milliseconds.pipe.spec.ts | 8 + .../src/app/shared/pipes/milliseconds.pipe.ts | 10 + .../app/shared/pipes/not-available.pipe.spec.ts | 32 + .../src/app/shared/pipes/not-available.pipe.ts | 16 + .../src/app/shared/pipes/ordinal.pipe.spec.ts | 8 + .../frontend/src/app/shared/pipes/ordinal.pipe.ts | 25 + .../frontend/src/app/shared/pipes/pipes.module.ts | 106 + .../pipes/rbd-configuration-source.pipe.spec.ts | 22 + .../shared/pipes/rbd-configuration-source.pipe.ts | 15 + .../app/shared/pipes/relative-date.pipe.spec.ts | 30 + .../src/app/shared/pipes/relative-date.pipe.ts | 17 + .../src/app/shared/pipes/round.pipe.spec.ts | 13 + .../frontend/src/app/shared/pipes/round.pipe.ts | 12 + .../src/app/shared/pipes/upper-first.pipe.spec.ts | 17 + .../src/app/shared/pipes/upper-first.pipe.ts | 12 + .../services/api-interceptor.service.spec.ts | 217 + .../app/shared/services/api-interceptor.service.ts | 109 + .../app/shared/services/auth-guard.service.spec.ts | 54 + .../src/app/shared/services/auth-guard.service.ts | 29 + .../shared/services/auth-storage.service.spec.ts | 35 + .../app/shared/services/auth-storage.service.ts | 33 + .../services/feature-toggles-guard.service.spec.ts | 72 + .../services/feature-toggles-guard.service.ts | 29 + .../services/feature-toggles.service.spec.ts | 54 + .../app/shared/services/feature-toggles.service.ts | 28 + .../app/shared/services/formatter.service.spec.ts | 90 + .../src/app/shared/services/formatter.service.ts | 79 + .../shared/services/js-error-handler.service.ts | 16 + .../app/shared/services/language.service.spec.ts | 34 + .../src/app/shared/services/language.service.ts | 24 + .../services/module-status-guard.service.spec.ts | 82 + .../shared/services/module-status-guard.service.ts | 68 + .../shared/services/notification.service.spec.ts | 262 + .../app/shared/services/notification.service.ts | 207 + .../services/prometheus-alert-formatter.spec.ts | 98 + .../shared/services/prometheus-alert-formatter.ts | 73 + .../services/prometheus-alert.service.spec.ts | 190 + .../shared/services/prometheus-alert.service.ts | 91 + .../prometheus-notification.service.spec.ts | 232 + .../services/prometheus-notification.service.ts | 53 + .../prometheus-silence-matcher.service.spec.ts | 133 + .../services/prometheus-silence-matcher.service.ts | 82 + .../services/rbd-configuration.service.spec.ts | 45 + .../shared/services/rbd-configuration.service.ts | 146 + .../services/refresh-interval.service.spec.ts | 45 + .../shared/services/refresh-interval.service.ts | 42 + .../app/shared/services/summary.service.spec.ts | 117 + .../src/app/shared/services/summary.service.ts | 85 + .../app/shared/services/task-list.service.spec.ts | 136 + .../src/app/shared/services/task-list.service.ts | 106 + .../shared/services/task-manager.service.spec.ts | 74 + .../app/shared/services/task-manager.service.ts | 62 + .../shared/services/task-message.service.spec.ts | 274 + .../app/shared/services/task-message.service.ts | 396 + .../shared/services/task-wrapper.service.spec.ts | 98 + .../app/shared/services/task-wrapper.service.ts | 65 + .../app/shared/services/time-diff.service.spec.ts | 66 + .../src/app/shared/services/time-diff.service.ts | 51 + .../shared/services/url-builder.service.spec.ts | 37 + .../src/app/shared/services/url-builder.service.ts | 50 + .../frontend/src/app/shared/shared.module.ts | 26 + .../mgr/dashboard/frontend/src/assets/.gitkeep | 0 .../frontend/src/assets/1280px-Mimic_Octopus2.jpg | Bin 0 -> 452518 bytes .../src/assets/1280px-Nautilus_Octopus.jpg | Bin 0 -> 86126 bytes .../Ceph_Logo_Stacked_RGB_120411_fa_228x228.png | Bin 0 -> 12949 bytes .../Ceph_Logo_Stacked_RGB_120411_fa_348x348.png | Bin 0 -> 18960 bytes ...ph_Logo_Stacked_RGB_White_120411_fa_256x256.png | Bin 0 -> 8330 bytes .../Ceph_Logo_Standard_RGB_White_120411_fa.png | Bin 0 -> 4801 bytes .../mgr/dashboard/frontend/src/assets/loading.gif | Bin 0 -> 35386 bytes .../dashboard/frontend/src/assets/logo-mini.png | Bin 0 -> 1811 bytes .../frontend/src/assets/notification-icons.png | Bin 0 -> 3397 bytes .../frontend/src/assets/prometheus_logo.svg | 50 + .../mgr/dashboard/frontend/src/defaults.scss | 188 + .../frontend/src/environments/environment.tpl.ts | 10 + src/pybind/mgr/dashboard/frontend/src/favicon.ico | Bin 0 -> 1150 bytes src/pybind/mgr/dashboard/frontend/src/index.html | 28 + .../mgr/dashboard/frontend/src/jestGlobalMocks.ts | 19 + .../dashboard/frontend/src/locale/messages.cs.xlf | 4365 ++++++ .../frontend/src/locale/messages.de-DE.xlf | 4365 ++++++ .../frontend/src/locale/messages.es-ES.xlf | 4371 ++++++ .../frontend/src/locale/messages.fr-FR.xlf | 4367 ++++++ .../frontend/src/locale/messages.id-ID.xlf | 4363 ++++++ .../frontend/src/locale/messages.it-IT.xlf | 4367 ++++++ .../frontend/src/locale/messages.ja-JP.xlf | 4368 ++++++ .../frontend/src/locale/messages.ko-KR.xlf | 4340 ++++++ .../frontend/src/locale/messages.pl-PL.xlf | 4360 ++++++ .../frontend/src/locale/messages.pt-BR.xlf | 4366 ++++++ .../frontend/src/locale/messages.zh-CN.xlf | 4365 ++++++ .../frontend/src/locale/messages.zh-TW.xlf | 4371 ++++++ src/pybind/mgr/dashboard/frontend/src/main.ts | 13 + src/pybind/mgr/dashboard/frontend/src/polyfills.ts | 67 + src/pybind/mgr/dashboard/frontend/src/setupJest.ts | 4 + src/pybind/mgr/dashboard/frontend/src/styles.scss | 392 + .../frontend/src/styles/chart-tooltip.scss | 64 + .../mgr/dashboard/frontend/src/styles/popover.scss | 46 + .../frontend/src/testing/activated-route-stub.ts | 23 + .../frontend/src/testing/unit-test-helper.ts | 344 + .../mgr/dashboard/frontend/src/tsconfig.app.json | 13 + .../mgr/dashboard/frontend/src/tsconfig.spec.json | 22 + src/pybind/mgr/dashboard/frontend/src/typings.d.ts | 5 + .../frontend/src/unit-test-configuration.ts.sample | 1 + .../dashboard/frontend/src/vendor.overrides.scss | 3 + .../dashboard/frontend/src/vendor.variables.scss | 1 + src/pybind/mgr/dashboard/frontend/tsconfig.json | 16 + src/pybind/mgr/dashboard/frontend/tslint.json | 90 + src/pybind/mgr/dashboard/grafana.py | 134 + src/pybind/mgr/dashboard/module.py | 517 + src/pybind/mgr/dashboard/plugins/__init__.py | 74 + src/pybind/mgr/dashboard/plugins/debug.py | 91 + .../mgr/dashboard/plugins/feature_toggles.py | 140 + src/pybind/mgr/dashboard/plugins/interfaces.py | 82 + src/pybind/mgr/dashboard/plugins/lru_cache.py | 47 + src/pybind/mgr/dashboard/plugins/pluggy.py | 111 + src/pybind/mgr/dashboard/plugins/plugin.py | 33 + src/pybind/mgr/dashboard/plugins/ttl_cache.py | 55 + src/pybind/mgr/dashboard/requirements-py27.txt | 3 + src/pybind/mgr/dashboard/requirements-py3.txt | 3 + src/pybind/mgr/dashboard/requirements.txt | 36 + src/pybind/mgr/dashboard/rest_client.py | 531 + .../mgr/dashboard/run-backend-api-request.sh | 23 + src/pybind/mgr/dashboard/run-backend-api-tests.sh | 166 + .../mgr/dashboard/run-backend-rook-api-request.sh | 40 + src/pybind/mgr/dashboard/run-frontend-e2e-tests.sh | 85 + src/pybind/mgr/dashboard/run-frontend-unittests.sh | 56 + src/pybind/mgr/dashboard/run-tox.sh | 51 + src/pybind/mgr/dashboard/security.py | 61 + src/pybind/mgr/dashboard/services/__init__.py | 2 + .../mgr/dashboard/services/access_control.py | 670 + src/pybind/mgr/dashboard/services/auth.py | 207 + src/pybind/mgr/dashboard/services/ceph_service.py | 254 + src/pybind/mgr/dashboard/services/cephfs.py | 77 + src/pybind/mgr/dashboard/services/cephx.py | 29 + src/pybind/mgr/dashboard/services/exception.py | 122 + src/pybind/mgr/dashboard/services/ganesha.py | 998 ++ src/pybind/mgr/dashboard/services/iscsi_cli.py | 50 + src/pybind/mgr/dashboard/services/iscsi_client.py | 257 + src/pybind/mgr/dashboard/services/iscsi_config.py | 135 + src/pybind/mgr/dashboard/services/orchestrator.py | 38 + src/pybind/mgr/dashboard/services/rbd.py | 177 + src/pybind/mgr/dashboard/services/rgw_client.py | 437 + src/pybind/mgr/dashboard/services/sso.py | 268 + src/pybind/mgr/dashboard/services/tcmu_service.py | 96 + src/pybind/mgr/dashboard/settings.py | 201 + src/pybind/mgr/dashboard/tests/__init__.py | 262 + src/pybind/mgr/dashboard/tests/helper.py | 56 + .../mgr/dashboard/tests/test_access_control.py | 695 + .../mgr/dashboard/tests/test_api_auditing.py | 94 + src/pybind/mgr/dashboard/tests/test_auth.py | 20 + .../mgr/dashboard/tests/test_ceph_service.py | 67 + src/pybind/mgr/dashboard/tests/test_cephfs.py | 48 + src/pybind/mgr/dashboard/tests/test_controllers.py | 192 + src/pybind/mgr/dashboard/tests/test_docs.py | 71 + .../dashboard/tests/test_erasure_code_profile.py | 36 + src/pybind/mgr/dashboard/tests/test_exceptions.py | 157 + .../mgr/dashboard/tests/test_feature_toggles.py | 61 + src/pybind/mgr/dashboard/tests/test_ganesha.py | 642 + src/pybind/mgr/dashboard/tests/test_grafana.py | 116 + src/pybind/mgr/dashboard/tests/test_home.py | 68 + src/pybind/mgr/dashboard/tests/test_iscsi.py | 998 ++ .../mgr/dashboard/tests/test_notification.py | 138 + src/pybind/mgr/dashboard/tests/test_osd.py | 240 + .../mgr/dashboard/tests/test_plugin_debug.py | 38 + src/pybind/mgr/dashboard/tests/test_pool.py | 117 + src/pybind/mgr/dashboard/tests/test_prometheus.py | 128 + .../mgr/dashboard/tests/test_rbd_mirroring.py | 95 + src/pybind/mgr/dashboard/tests/test_rbd_service.py | 37 + src/pybind/mgr/dashboard/tests/test_rest_client.py | 94 + src/pybind/mgr/dashboard/tests/test_rest_tasks.py | 86 + src/pybind/mgr/dashboard/tests/test_rgw.py | 129 + src/pybind/mgr/dashboard/tests/test_rgw_client.py | 112 + src/pybind/mgr/dashboard/tests/test_settings.py | 191 + src/pybind/mgr/dashboard/tests/test_sso.py | 157 + src/pybind/mgr/dashboard/tests/test_task.py | 433 + src/pybind/mgr/dashboard/tests/test_tools.py | 188 + src/pybind/mgr/dashboard/tools.py | 932 ++ src/pybind/mgr/dashboard/tox.ini | 30 + src/pybind/mgr/deepsea/__init__.py | 1 + src/pybind/mgr/deepsea/module.py | 527 + src/pybind/mgr/devicehealth/__init__.py | 2 + src/pybind/mgr/devicehealth/module.py | 651 + src/pybind/mgr/diskprediction_cloud/__init__.py | 1 + .../mgr/diskprediction_cloud/agent/__init__.py | 38 + .../diskprediction_cloud/agent/metrics/__init__.py | 61 + .../agent/metrics/ceph_cluster.py | 145 + .../agent/metrics/ceph_mon_osd.py | 222 + .../agent/metrics/ceph_pool.py | 57 + .../diskprediction_cloud/agent/metrics/db_relay.py | 703 + .../agent/metrics/sai_agent.py | 70 + .../agent/metrics/sai_cluster.py | 35 + .../diskprediction_cloud/agent/metrics/sai_disk.py | 175 + .../agent/metrics/sai_disk_smart.py | 182 + .../diskprediction_cloud/agent/metrics/sai_host.py | 105 + .../mgr/diskprediction_cloud/agent/predictor.py | 48 + .../mgr/diskprediction_cloud/common/__init__.py | 61 + .../mgr/diskprediction_cloud/common/client_pb2.py | 1775 +++ .../diskprediction_cloud/common/client_pb2_grpc.py | 395 + .../mgr/diskprediction_cloud/common/clusterdata.py | 464 + .../mgr/diskprediction_cloud/common/cypher.py | 71 + .../mgr/diskprediction_cloud/common/grpcclient.py | 242 + .../mgr/diskprediction_cloud/common/server.crt | 17 + src/pybind/mgr/diskprediction_cloud/module.py | 454 + .../mgr/diskprediction_cloud/requirements.txt | 12 + src/pybind/mgr/diskprediction_cloud/task.py | 181 + src/pybind/mgr/diskprediction_local/__init__.py | 1 + .../mgr/diskprediction_local/models/config.json | 77 + .../mgr/diskprediction_local/models/svm_1.pkl | Bin 0 -> 281292 bytes .../mgr/diskprediction_local/models/svm_10.pkl | Bin 0 -> 217792 bytes .../mgr/diskprediction_local/models/svm_104.pkl | Bin 0 -> 492492 bytes .../mgr/diskprediction_local/models/svm_105.pkl | Bin 0 -> 217192 bytes .../mgr/diskprediction_local/models/svm_109.pkl | Bin 0 -> 256392 bytes .../mgr/diskprediction_local/models/svm_112.pkl | Bin 0 -> 499492 bytes .../mgr/diskprediction_local/models/svm_114.pkl | Bin 0 -> 276492 bytes .../mgr/diskprediction_local/models/svm_115.pkl | Bin 0 -> 509592 bytes .../mgr/diskprediction_local/models/svm_118.pkl | Bin 0 -> 315192 bytes .../mgr/diskprediction_local/models/svm_119.pkl | Bin 0 -> 485992 bytes .../mgr/diskprediction_local/models/svm_12.pkl | Bin 0 -> 275692 bytes .../mgr/diskprediction_local/models/svm_120.pkl | Bin 0 -> 307592 bytes .../mgr/diskprediction_local/models/svm_123.pkl | Bin 0 -> 246792 bytes .../mgr/diskprediction_local/models/svm_124.pkl | Bin 0 -> 310292 bytes .../mgr/diskprediction_local/models/svm_125.pkl | Bin 0 -> 452492 bytes .../mgr/diskprediction_local/models/svm_128.pkl | Bin 0 -> 550492 bytes .../mgr/diskprediction_local/models/svm_131.pkl | Bin 0 -> 493192 bytes .../mgr/diskprediction_local/models/svm_134.pkl | Bin 0 -> 266692 bytes .../mgr/diskprediction_local/models/svm_138.pkl | Bin 0 -> 488292 bytes .../mgr/diskprediction_local/models/svm_14.pkl | Bin 0 -> 244892 bytes .../mgr/diskprediction_local/models/svm_141.pkl | Bin 0 -> 422368 bytes .../mgr/diskprediction_local/models/svm_145.pkl | Bin 0 -> 359512 bytes .../mgr/diskprediction_local/models/svm_151.pkl | Bin 0 -> 305944 bytes .../mgr/diskprediction_local/models/svm_16.pkl | Bin 0 -> 308192 bytes .../mgr/diskprediction_local/models/svm_161.pkl | Bin 0 -> 305188 bytes .../mgr/diskprediction_local/models/svm_168.pkl | Bin 0 -> 301516 bytes .../mgr/diskprediction_local/models/svm_169.pkl | Bin 0 -> 363400 bytes .../mgr/diskprediction_local/models/svm_174.pkl | Bin 0 -> 323764 bytes .../mgr/diskprediction_local/models/svm_18.pkl | Bin 0 -> 312692 bytes .../mgr/diskprediction_local/models/svm_182.pkl | Bin 0 -> 354652 bytes .../mgr/diskprediction_local/models/svm_185.pkl | Bin 0 -> 317176 bytes .../mgr/diskprediction_local/models/svm_186.pkl | Bin 0 -> 276352 bytes .../mgr/diskprediction_local/models/svm_195.pkl | Bin 0 -> 489544 bytes .../mgr/diskprediction_local/models/svm_201.pkl | Bin 0 -> 307888 bytes .../mgr/diskprediction_local/models/svm_204.pkl | Bin 0 -> 567088 bytes .../mgr/diskprediction_local/models/svm_206.pkl | Bin 0 -> 474856 bytes .../mgr/diskprediction_local/models/svm_208.pkl | Bin 0 -> 283588 bytes .../mgr/diskprediction_local/models/svm_210.pkl | Bin 0 -> 617200 bytes .../mgr/diskprediction_local/models/svm_212.pkl | Bin 0 -> 345148 bytes .../mgr/diskprediction_local/models/svm_213.pkl | Bin 0 -> 357568 bytes .../mgr/diskprediction_local/models/svm_219.pkl | Bin 0 -> 342232 bytes .../mgr/diskprediction_local/models/svm_221.pkl | Bin 0 -> 365128 bytes .../mgr/diskprediction_local/models/svm_222.pkl | Bin 0 -> 314800 bytes .../mgr/diskprediction_local/models/svm_223.pkl | Bin 0 -> 342124 bytes .../mgr/diskprediction_local/models/svm_225.pkl | Bin 0 -> 329812 bytes .../mgr/diskprediction_local/models/svm_227.pkl | Bin 0 -> 296440 bytes .../mgr/diskprediction_local/models/svm_229.pkl | Bin 0 -> 572380 bytes .../mgr/diskprediction_local/models/svm_230.pkl | Bin 0 -> 251188 bytes .../mgr/diskprediction_local/models/svm_234.pkl | Bin 0 -> 277972 bytes .../mgr/diskprediction_local/models/svm_235.pkl | Bin 0 -> 243736 bytes .../mgr/diskprediction_local/models/svm_236.pkl | Bin 0 -> 377872 bytes .../mgr/diskprediction_local/models/svm_239.pkl | Bin 0 -> 571732 bytes .../mgr/diskprediction_local/models/svm_243.pkl | Bin 0 -> 534148 bytes .../mgr/diskprediction_local/models/svm_27.pkl | Bin 0 -> 504592 bytes .../mgr/diskprediction_local/models/svm_3.pkl | Bin 0 -> 557192 bytes .../mgr/diskprediction_local/models/svm_33.pkl | Bin 0 -> 547392 bytes .../mgr/diskprediction_local/models/svm_36.pkl | Bin 0 -> 516692 bytes .../mgr/diskprediction_local/models/svm_44.pkl | Bin 0 -> 546592 bytes .../mgr/diskprediction_local/models/svm_50.pkl | Bin 0 -> 448292 bytes .../mgr/diskprediction_local/models/svm_57.pkl | Bin 0 -> 328292 bytes .../mgr/diskprediction_local/models/svm_59.pkl | Bin 0 -> 494292 bytes .../mgr/diskprediction_local/models/svm_6.pkl | Bin 0 -> 314092 bytes .../mgr/diskprediction_local/models/svm_61.pkl | Bin 0 -> 499492 bytes .../mgr/diskprediction_local/models/svm_62.pkl | Bin 0 -> 483492 bytes .../mgr/diskprediction_local/models/svm_67.pkl | Bin 0 -> 492592 bytes .../mgr/diskprediction_local/models/svm_69.pkl | Bin 0 -> 288292 bytes .../mgr/diskprediction_local/models/svm_71.pkl | Bin 0 -> 228792 bytes .../mgr/diskprediction_local/models/svm_72.pkl | Bin 0 -> 489492 bytes .../mgr/diskprediction_local/models/svm_78.pkl | Bin 0 -> 491392 bytes .../mgr/diskprediction_local/models/svm_79.pkl | Bin 0 -> 284992 bytes .../mgr/diskprediction_local/models/svm_82.pkl | Bin 0 -> 255292 bytes .../mgr/diskprediction_local/models/svm_85.pkl | Bin 0 -> 522092 bytes .../mgr/diskprediction_local/models/svm_88.pkl | Bin 0 -> 502392 bytes .../mgr/diskprediction_local/models/svm_93.pkl | Bin 0 -> 302592 bytes .../mgr/diskprediction_local/models/svm_97.pkl | Bin 0 -> 272392 bytes src/pybind/mgr/diskprediction_local/module.py | 266 + src/pybind/mgr/diskprediction_local/predictor.py | 265 + src/pybind/mgr/hello/__init__.py | 1 + src/pybind/mgr/hello/module.py | 82 + src/pybind/mgr/influx/__init__.py | 1 + src/pybind/mgr/influx/module.py | 489 + src/pybind/mgr/insights/CMakeLists.txt | 7 + src/pybind/mgr/insights/__init__.py | 9 + src/pybind/mgr/insights/health.py | 191 + src/pybind/mgr/insights/module.py | 322 + src/pybind/mgr/insights/run-tox.sh | 43 + src/pybind/mgr/insights/tests/__init__.py | 0 src/pybind/mgr/insights/tests/test_health.py | 273 + src/pybind/mgr/insights/tox.ini | 17 + src/pybind/mgr/iostat/__init__.py | 1 + src/pybind/mgr/iostat/module.py | 73 + src/pybind/mgr/k8sevents/README.md | 81 + src/pybind/mgr/k8sevents/__init__.py | 1 + src/pybind/mgr/k8sevents/module.py | 1460 ++ src/pybind/mgr/k8sevents/rbac_sample.yaml | 45 + src/pybind/mgr/localpool/__init__.py | 1 + src/pybind/mgr/localpool/module.py | 136 + src/pybind/mgr/mgr_module.py | 1504 ++ src/pybind/mgr/mgr_util.py | 300 + src/pybind/mgr/orchestrator.py | 1085 ++ src/pybind/mgr/orchestrator_cli/.gitignore | 1 + src/pybind/mgr/orchestrator_cli/CMakeLists.txt | 7 + src/pybind/mgr/orchestrator_cli/README.md | 16 + src/pybind/mgr/orchestrator_cli/__init__.py | 10 + src/pybind/mgr/orchestrator_cli/module.py | 437 + src/pybind/mgr/orchestrator_cli/requirements.txt | 2 + src/pybind/mgr/orchestrator_cli/run-tox.sh | 46 + .../mgr/orchestrator_cli/test_orchestrator.py | 48 + src/pybind/mgr/orchestrator_cli/tox.ini | 18 + src/pybind/mgr/osd_perf_query/__init__.py | 1 + src/pybind/mgr/osd_perf_query/module.py | 194 + src/pybind/mgr/pg_autoscaler/__init__.py | 1 + src/pybind/mgr/pg_autoscaler/module.py | 507 + src/pybind/mgr/progress/__init__.py | 2 + src/pybind/mgr/progress/module.py | 693 + src/pybind/mgr/prometheus/__init__.py | 2 + src/pybind/mgr/prometheus/module.py | 1324 ++ src/pybind/mgr/rbd_support/__init__.py | 1 + src/pybind/mgr/rbd_support/module.py | 1427 ++ src/pybind/mgr/restful/__init__.py | 1 + src/pybind/mgr/restful/api/__init__.py | 39 + src/pybind/mgr/restful/api/config.py | 86 + src/pybind/mgr/restful/api/crush.py | 26 + src/pybind/mgr/restful/api/doc.py | 15 + src/pybind/mgr/restful/api/mon.py | 40 + src/pybind/mgr/restful/api/osd.py | 135 + src/pybind/mgr/restful/api/perf.py | 27 + src/pybind/mgr/restful/api/pool.py | 140 + src/pybind/mgr/restful/api/request.py | 93 + src/pybind/mgr/restful/api/server.py | 35 + src/pybind/mgr/restful/common.py | 156 + src/pybind/mgr/restful/context.py | 2 + src/pybind/mgr/restful/decorators.py | 79 + src/pybind/mgr/restful/hooks.py | 11 + src/pybind/mgr/restful/module.py | 610 + src/pybind/mgr/rook/__init__.py | 2 + src/pybind/mgr/rook/module.py | 469 + src/pybind/mgr/rook/rook_cluster.py | 442 + src/pybind/mgr/selftest/__init__.py | 3 + src/pybind/mgr/selftest/module.py | 489 + src/pybind/mgr/ssh/.gitignore | 1 + src/pybind/mgr/ssh/README.md | 93 + src/pybind/mgr/ssh/Vagrantfile | 39 + src/pybind/mgr/ssh/__init__.py | 1 + src/pybind/mgr/ssh/ceph.repo | 23 + src/pybind/mgr/ssh/module.py | 740 + src/pybind/mgr/ssh/remotes.py | 81 + src/pybind/mgr/status/__init__.py | 1 + src/pybind/mgr/status/module.py | 261 + src/pybind/mgr/telegraf/__init__.py | 1 + src/pybind/mgr/telegraf/basesocket.py | 45 + src/pybind/mgr/telegraf/module.py | 301 + src/pybind/mgr/telegraf/protocol.py | 44 + src/pybind/mgr/telegraf/utils.py | 20 + src/pybind/mgr/telemetry/__init__.py | 1 + src/pybind/mgr/telemetry/module.py | 854 ++ src/pybind/mgr/test_orchestrator/__init__.py | 1 + src/pybind/mgr/test_orchestrator/module.py | 259 + src/pybind/mgr/volumes/__init__.py | 2 + src/pybind/mgr/volumes/fs/__init__.py | 0 src/pybind/mgr/volumes/fs/async_cloner.py | 345 + src/pybind/mgr/volumes/fs/async_job.py | 279 + src/pybind/mgr/volumes/fs/exception.py | 63 + src/pybind/mgr/volumes/fs/fs_util.py | 161 + src/pybind/mgr/volumes/fs/operations/__init__.py | 0 src/pybind/mgr/volumes/fs/operations/access.py | 142 + .../mgr/volumes/fs/operations/clone_index.py | 98 + src/pybind/mgr/volumes/fs/operations/group.py | 186 + src/pybind/mgr/volumes/fs/operations/index.py | 23 + src/pybind/mgr/volumes/fs/operations/lock.py | 42 + .../mgr/volumes/fs/operations/rankevicter.py | 114 + src/pybind/mgr/volumes/fs/operations/resolver.py | 26 + .../mgr/volumes/fs/operations/snapshot_util.py | 30 + src/pybind/mgr/volumes/fs/operations/subvolume.py | 74 + src/pybind/mgr/volumes/fs/operations/template.py | 173 + src/pybind/mgr/volumes/fs/operations/trash.py | 145 + .../mgr/volumes/fs/operations/versions/__init__.py | 109 + .../fs/operations/versions/auth_metadata.py | 208 + .../fs/operations/versions/metadata_manager.py | 144 + .../mgr/volumes/fs/operations/versions/op_sm.py | 114 + .../fs/operations/versions/subvolume_attrs.py | 61 + .../fs/operations/versions/subvolume_base.py | 331 + .../volumes/fs/operations/versions/subvolume_v1.py | 780 + .../volumes/fs/operations/versions/subvolume_v2.py | 370 + src/pybind/mgr/volumes/fs/operations/volume.py | 348 + src/pybind/mgr/volumes/fs/purge_queue.py | 109 + src/pybind/mgr/volumes/fs/vol_spec.py | 37 + src/pybind/mgr/volumes/fs/volume.py | 660 + src/pybind/mgr/volumes/module.py | 576 + src/pybind/mgr/zabbix/__init__.py | 1 + src/pybind/mgr/zabbix/module.py | 380 + src/pybind/mgr/zabbix/zabbix_template.xml | 2569 ++++ 1257 files changed, 193080 insertions(+) create mode 100644 src/pybind/mgr/.gitignore create mode 100644 src/pybind/mgr/CMakeLists.txt create mode 100644 src/pybind/mgr/alerts/__init__.py create mode 100644 src/pybind/mgr/alerts/module.py create mode 100644 src/pybind/mgr/ansible/.gitignore create mode 100644 src/pybind/mgr/ansible/CMakeLists.txt create mode 100644 src/pybind/mgr/ansible/__init__.py create mode 100644 src/pybind/mgr/ansible/ansible_runner_svc.py create mode 100644 src/pybind/mgr/ansible/module.py create mode 100644 src/pybind/mgr/ansible/output_wizards.py create mode 100644 src/pybind/mgr/ansible/requirements.txt create mode 100644 src/pybind/mgr/ansible/run-tox.sh create mode 100644 src/pybind/mgr/ansible/tests/__init__.py create mode 100644 src/pybind/mgr/ansible/tests/pb_execution_events.data create mode 100644 src/pybind/mgr/ansible/tests/test_client_playbooks.py create mode 100644 src/pybind/mgr/ansible/tests/test_output_wizards.py create mode 100644 src/pybind/mgr/ansible/tox.ini create mode 100644 src/pybind/mgr/balancer/__init__.py create mode 100644 src/pybind/mgr/balancer/module.py create mode 100644 src/pybind/mgr/crash/__init__.py create mode 100644 src/pybind/mgr/crash/module.py create mode 100644 src/pybind/mgr/dashboard/.coveragerc create mode 100644 src/pybind/mgr/dashboard/.editorconfig create mode 100644 src/pybind/mgr/dashboard/.gitignore create mode 100644 src/pybind/mgr/dashboard/.pylintrc create mode 100644 src/pybind/mgr/dashboard/CMakeLists.txt create mode 100644 src/pybind/mgr/dashboard/HACKING.rst create mode 100644 src/pybind/mgr/dashboard/README.rst create mode 100644 src/pybind/mgr/dashboard/__init__.py create mode 100644 src/pybind/mgr/dashboard/awsauth.py create mode 100644 src/pybind/mgr/dashboard/cherrypy_backports.py create mode 100644 src/pybind/mgr/dashboard/ci/check_grafana_uids.py create mode 100644 src/pybind/mgr/dashboard/constraints.txt create mode 100644 src/pybind/mgr/dashboard/controllers/__init__.py create mode 100644 src/pybind/mgr/dashboard/controllers/auth.py create mode 100644 src/pybind/mgr/dashboard/controllers/cephfs.py create mode 100644 src/pybind/mgr/dashboard/controllers/cluster_configuration.py create mode 100644 src/pybind/mgr/dashboard/controllers/docs.py create mode 100644 src/pybind/mgr/dashboard/controllers/erasure_code_profile.py create mode 100644 src/pybind/mgr/dashboard/controllers/grafana.py create mode 100644 src/pybind/mgr/dashboard/controllers/health.py create mode 100644 src/pybind/mgr/dashboard/controllers/home.py create mode 100644 src/pybind/mgr/dashboard/controllers/host.py create mode 100644 src/pybind/mgr/dashboard/controllers/iscsi.py create mode 100644 src/pybind/mgr/dashboard/controllers/logging.py create mode 100644 src/pybind/mgr/dashboard/controllers/logs.py create mode 100644 src/pybind/mgr/dashboard/controllers/mgr_modules.py create mode 100644 src/pybind/mgr/dashboard/controllers/monitor.py create mode 100644 src/pybind/mgr/dashboard/controllers/nfsganesha.py create mode 100644 src/pybind/mgr/dashboard/controllers/osd.py create mode 100644 src/pybind/mgr/dashboard/controllers/perf_counters.py create mode 100644 src/pybind/mgr/dashboard/controllers/pool.py create mode 100644 src/pybind/mgr/dashboard/controllers/prometheus.py create mode 100644 src/pybind/mgr/dashboard/controllers/rbd.py create mode 100644 src/pybind/mgr/dashboard/controllers/rbd_mirroring.py create mode 100644 src/pybind/mgr/dashboard/controllers/rgw.py create mode 100644 src/pybind/mgr/dashboard/controllers/role.py create mode 100644 src/pybind/mgr/dashboard/controllers/saml2.py create mode 100644 src/pybind/mgr/dashboard/controllers/settings.py create mode 100644 src/pybind/mgr/dashboard/controllers/summary.py create mode 100644 src/pybind/mgr/dashboard/controllers/task.py create mode 100644 src/pybind/mgr/dashboard/controllers/user.py create mode 100644 src/pybind/mgr/dashboard/exceptions.py create mode 100644 src/pybind/mgr/dashboard/frontend/.babelrc create mode 100644 src/pybind/mgr/dashboard/frontend/.editorconfig create mode 100644 src/pybind/mgr/dashboard/frontend/.gitignore create mode 100644 src/pybind/mgr/dashboard/frontend/.prettierignore create mode 100644 src/pybind/mgr/dashboard/frontend/.prettierrc create mode 100644 src/pybind/mgr/dashboard/frontend/angular.json create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/2.22b12bf9358f95829e55.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/6.f054f1f260c137d64363.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/7.76846491986b0ea6c0bd.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/8.7550b99d388b9ca165da.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/9.b19f6391d5c667b85d12.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo_Stacked_RGB_120411_fa_228x228.1ed169ccc35367a2dab2.png create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Mimic_Octopus2.jpg create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Nautilus_Octopus.jpg create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_228x228.png create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_348x348.png create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_White_120411_fa_256x256.png create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Standard_RGB_White_120411_fa.png create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gif create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.png create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/notification-icons.png create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/common.8a53d98b04768bd15706.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.ico create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.35e77a38ca9d85c4e897.eot create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.3a9e014c2469ffa65a0e.woff2 create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.44bbdbbfb5a10ba2d1ce.woff create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.78dcc9c4999659b8026a.svg create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.fc46f3dae03b2b2e1cee.ttf create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.448c34a56d699c29117a.woff2 create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.89889688147bd7575d63.svg create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.f4769f9bdb7466be6508.eot create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.fa2772327f55d8198301.woff create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/index.html create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/main.a8acf27ca1415ab0d94b.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.f31db31652a3fd9f4bca.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.074db273ef932a67d91b.svg create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.ff444394af058f159c51.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/scripts.fc88ef4a23399c760d0b.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f5317b15474518dffebc.css create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/swagger-ui-bundle.js create mode 100644 src/pybind/mgr/dashboard/frontend/dist/en-US/swagger-ui.css create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/block/images.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/block/images.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/block/iscsi.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/block/iscsi.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/block/mirroring.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/block/mirroring.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/configuration.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/configuration.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/crush-map.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/crush-map.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/hosts.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/hosts.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/logs.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/logs.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/mgr-modules.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/mgr-modules.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/monitors.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/monitors.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/osds.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/cluster/osds.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/filesystems/filesystems.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/filesystems/filesystems.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/helper.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/nfs/nfs.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/nfs/nfs.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/pools/pools.e2e-spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/pools/pools.po.ts create mode 100644 src/pybind/mgr/dashboard/frontend/e2e/tsconfig.e2e.json create mode 100755 src/pybind/mgr/dashboard/frontend/environment.build.js create mode 100644 src/pybind/mgr/dashboard/frontend/html-linter.config.json create mode 100644 src/pybind/mgr/dashboard/frontend/i18n.config.json create mode 100644 src/pybind/mgr/dashboard/frontend/package-lock.json create mode 100644 src/pybind/mgr/dashboard/frontend/package.json create mode 100644 src/pybind/mgr/dashboard/frontend/protractor.conf.js create mode 100644 src/pybind/mgr/dashboard/frontend/proxy.conf.json.sample create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/app.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/app.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/app.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/app.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/app.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-setting/iscsi-setting.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-tabs/iscsi-tabs.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi/iscsi.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/daemon-list/daemon-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/image-list/image-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirror-health-color.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-response.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-response.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-form/rbd-configuration-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-configuration-list/rbd-configuration-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-feature.interface.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-clone-request.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-copy-request.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-create-request.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-edit-request.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-mode.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form-response.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-parent.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-images/rbd-images.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-images/rbd-images.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-images/rbd-images.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-images/rbd-images.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-actions.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/ceph.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-chart/cephfs-chart.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-detail/cephfs-detail.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.scss create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.spec.ts create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form-create-request.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-form/configuration-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-details/mgr-module-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-form/mgr-module-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-module-list/mgr-module-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/mgr-modules/mgr-modules.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-performance-histogram/osd-performance-histogram.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-performance-histogram/osd-performance-histogram.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-performance-histogram/osd-performance-histogram.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-performance-histogram/osd-performance-histogram.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.options.ts create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.scss create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts create mode 100755 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/monitoring-list/monitoring-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie-color.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health-pie/health-pie.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-summary.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-summary.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-summary.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-501/nfs-501.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-details/nfs-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form-client/nfs-form-client.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-form/nfs-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/table-performance-counter/table-performance-counter.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form-data.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-stat.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capabilities.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-capability.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-s3-key.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-subuser.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/models/rgw-user-swift-key.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-501/rgw-501.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/ceph-shared.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/shared/pg-category.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/auth.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-details/role-details.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form-mode.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/sso/sso-not-found/sso-not-found.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/sso/sso-not-found/sso-not-found.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/sso/sso-not-found/sso-not-found.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/sso/sso-not-found/sso-not-found.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-mode.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form-role.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-tabs/user-tabs.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/core.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/forbidden/forbidden.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/forbidden/forbidden.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/forbidden/forbidden.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/forbidden/forbidden.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/administration/administration.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/identity/identity.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/not-found/not-found.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/not-found/not-found.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/not-found/not-found.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/core/not-found/not-found.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/api.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/auth.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/cephfs.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/configuration.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/health.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/host.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/iscsi.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/logging.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/logs.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/mgr-module.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/monitor.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/nfs.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/performance-counter.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/pool.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd-mirroring.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-daemon.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/role.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/scope.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/settings.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/api/user.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/back-button/back-button.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.types.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/error-panel/error-panel.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/error-panel/error-panel.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/error-panel/error-panel.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/error-panel/error-panel.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/helper/helper.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/info-panel/info-panel.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/info-panel/info-panel.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/info-panel/info-panel.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/info-panel/info-panel.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/language-selector.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/language-selector/supported-languages.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/loading-panel/loading-panel.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select-badges/select-badges.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-messages.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select-option.model.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/select/select.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/sparkline/sparkline.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/submit-button/submit-button.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/view-cache/view-cache.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/view-cache/view-cache.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/view-cache/view-cache.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/view-cache/view-cache.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/warning-panel/warning-panel.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/warning-panel/warning-panel.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/warning-panel/warning-panel.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/warning-panel/warning-panel.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/constants/app.constants.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/datatable.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-key-value/table-key-value.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/decorators/cd-encode.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/autofocus.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/copy2clipboard-button.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/copy2clipboard-button.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/directives.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-input-disable.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/form-scope.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/iops.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/milliseconds.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/password-button.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/directives/trim.directive.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/components.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/notification-type.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/unix_errno.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/enum/view-cache-status.enum.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-builder.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-form-group.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/forms/cd-validators.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/alertmanager-silence.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/breadcrumbs.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-notification.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-action.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-column.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-fetch-data-context.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-table-selection.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/cd-user-config.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/chart-tooltip.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/configuration.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/credentials.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-rule.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/crush-step.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/erasure-code-profile.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/executing-task.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/finished-task.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/login-response.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/permission.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/permissions.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/pool-form-info.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/prometheus-alerts.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/task-exception.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/models/task.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/boolean-text.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/cd-date.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-release-name.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ceph-short-version.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary-per-second.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless-binary.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/encode-uri.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/filter.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/health-color.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iops.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/iscsi-backstore.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/list.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/list.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/log-priority.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/map.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/milliseconds.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/not-available.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/ordinal.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/rbd-configuration-source.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/relative-date.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/round.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/upper-first.pipe.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/api-interceptor.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-guard.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/auth-storage.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles-guard.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/js-error-handler.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/language.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/notification.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert-formatter.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-notification.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/rbd-configuration.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/refresh-interval.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/summary.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-list.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-manager.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-message.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/task-wrapper.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/time-diff.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/url-builder.service.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/shared.module.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/.gitkeep create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/1280px-Mimic_Octopus2.jpg create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/1280px-Nautilus_Octopus.jpg create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo_Stacked_RGB_120411_fa_228x228.png create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo_Stacked_RGB_120411_fa_348x348.png create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo_Stacked_RGB_White_120411_fa_256x256.png create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/Ceph_Logo_Standard_RGB_White_120411_fa.png create mode 100755 src/pybind/mgr/dashboard/frontend/src/assets/loading.gif create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/logo-mini.png create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/notification-icons.png create mode 100644 src/pybind/mgr/dashboard/frontend/src/assets/prometheus_logo.svg create mode 100644 src/pybind/mgr/dashboard/frontend/src/defaults.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/environments/environment.tpl.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/favicon.ico create mode 100644 src/pybind/mgr/dashboard/frontend/src/index.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf create mode 100644 src/pybind/mgr/dashboard/frontend/src/main.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/polyfills.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/setupJest.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/styles.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/styles/chart-tooltip.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/styles/popover.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json create mode 100644 src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json create mode 100644 src/pybind/mgr/dashboard/frontend/src/typings.d.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/unit-test-configuration.ts.sample create mode 100644 src/pybind/mgr/dashboard/frontend/src/vendor.overrides.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/vendor.variables.scss create mode 100644 src/pybind/mgr/dashboard/frontend/tsconfig.json create mode 100644 src/pybind/mgr/dashboard/frontend/tslint.json create mode 100644 src/pybind/mgr/dashboard/grafana.py create mode 100644 src/pybind/mgr/dashboard/module.py create mode 100644 src/pybind/mgr/dashboard/plugins/__init__.py create mode 100644 src/pybind/mgr/dashboard/plugins/debug.py create mode 100644 src/pybind/mgr/dashboard/plugins/feature_toggles.py create mode 100644 src/pybind/mgr/dashboard/plugins/interfaces.py create mode 100644 src/pybind/mgr/dashboard/plugins/lru_cache.py create mode 100644 src/pybind/mgr/dashboard/plugins/pluggy.py create mode 100644 src/pybind/mgr/dashboard/plugins/plugin.py create mode 100644 src/pybind/mgr/dashboard/plugins/ttl_cache.py create mode 100644 src/pybind/mgr/dashboard/requirements-py27.txt create mode 100644 src/pybind/mgr/dashboard/requirements-py3.txt create mode 100644 src/pybind/mgr/dashboard/requirements.txt create mode 100644 src/pybind/mgr/dashboard/rest_client.py create mode 100755 src/pybind/mgr/dashboard/run-backend-api-request.sh create mode 100755 src/pybind/mgr/dashboard/run-backend-api-tests.sh create mode 100755 src/pybind/mgr/dashboard/run-backend-rook-api-request.sh create mode 100755 src/pybind/mgr/dashboard/run-frontend-e2e-tests.sh create mode 100755 src/pybind/mgr/dashboard/run-frontend-unittests.sh create mode 100755 src/pybind/mgr/dashboard/run-tox.sh create mode 100644 src/pybind/mgr/dashboard/security.py create mode 100644 src/pybind/mgr/dashboard/services/__init__.py create mode 100644 src/pybind/mgr/dashboard/services/access_control.py create mode 100644 src/pybind/mgr/dashboard/services/auth.py create mode 100644 src/pybind/mgr/dashboard/services/ceph_service.py create mode 100644 src/pybind/mgr/dashboard/services/cephfs.py create mode 100644 src/pybind/mgr/dashboard/services/cephx.py create mode 100644 src/pybind/mgr/dashboard/services/exception.py create mode 100644 src/pybind/mgr/dashboard/services/ganesha.py create mode 100644 src/pybind/mgr/dashboard/services/iscsi_cli.py create mode 100644 src/pybind/mgr/dashboard/services/iscsi_client.py create mode 100644 src/pybind/mgr/dashboard/services/iscsi_config.py create mode 100644 src/pybind/mgr/dashboard/services/orchestrator.py create mode 100644 src/pybind/mgr/dashboard/services/rbd.py create mode 100644 src/pybind/mgr/dashboard/services/rgw_client.py create mode 100644 src/pybind/mgr/dashboard/services/sso.py create mode 100644 src/pybind/mgr/dashboard/services/tcmu_service.py create mode 100644 src/pybind/mgr/dashboard/settings.py create mode 100644 src/pybind/mgr/dashboard/tests/__init__.py create mode 100644 src/pybind/mgr/dashboard/tests/helper.py create mode 100644 src/pybind/mgr/dashboard/tests/test_access_control.py create mode 100644 src/pybind/mgr/dashboard/tests/test_api_auditing.py create mode 100644 src/pybind/mgr/dashboard/tests/test_auth.py create mode 100644 src/pybind/mgr/dashboard/tests/test_ceph_service.py create mode 100644 src/pybind/mgr/dashboard/tests/test_cephfs.py create mode 100644 src/pybind/mgr/dashboard/tests/test_controllers.py create mode 100644 src/pybind/mgr/dashboard/tests/test_docs.py create mode 100644 src/pybind/mgr/dashboard/tests/test_erasure_code_profile.py create mode 100644 src/pybind/mgr/dashboard/tests/test_exceptions.py create mode 100644 src/pybind/mgr/dashboard/tests/test_feature_toggles.py create mode 100644 src/pybind/mgr/dashboard/tests/test_ganesha.py create mode 100644 src/pybind/mgr/dashboard/tests/test_grafana.py create mode 100644 src/pybind/mgr/dashboard/tests/test_home.py create mode 100644 src/pybind/mgr/dashboard/tests/test_iscsi.py create mode 100644 src/pybind/mgr/dashboard/tests/test_notification.py create mode 100644 src/pybind/mgr/dashboard/tests/test_osd.py create mode 100644 src/pybind/mgr/dashboard/tests/test_plugin_debug.py create mode 100644 src/pybind/mgr/dashboard/tests/test_pool.py create mode 100644 src/pybind/mgr/dashboard/tests/test_prometheus.py create mode 100644 src/pybind/mgr/dashboard/tests/test_rbd_mirroring.py create mode 100644 src/pybind/mgr/dashboard/tests/test_rbd_service.py create mode 100644 src/pybind/mgr/dashboard/tests/test_rest_client.py create mode 100644 src/pybind/mgr/dashboard/tests/test_rest_tasks.py create mode 100644 src/pybind/mgr/dashboard/tests/test_rgw.py create mode 100644 src/pybind/mgr/dashboard/tests/test_rgw_client.py create mode 100644 src/pybind/mgr/dashboard/tests/test_settings.py create mode 100644 src/pybind/mgr/dashboard/tests/test_sso.py create mode 100644 src/pybind/mgr/dashboard/tests/test_task.py create mode 100644 src/pybind/mgr/dashboard/tests/test_tools.py create mode 100644 src/pybind/mgr/dashboard/tools.py create mode 100644 src/pybind/mgr/dashboard/tox.ini create mode 100644 src/pybind/mgr/deepsea/__init__.py create mode 100644 src/pybind/mgr/deepsea/module.py create mode 100644 src/pybind/mgr/devicehealth/__init__.py create mode 100644 src/pybind/mgr/devicehealth/module.py create mode 100644 src/pybind/mgr/diskprediction_cloud/__init__.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/__init__.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/__init__.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_mon_osd.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_pool.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/db_relay.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_agent.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_cluster.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk_smart.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_host.py create mode 100644 src/pybind/mgr/diskprediction_cloud/agent/predictor.py create mode 100644 src/pybind/mgr/diskprediction_cloud/common/__init__.py create mode 100644 src/pybind/mgr/diskprediction_cloud/common/client_pb2.py create mode 100644 src/pybind/mgr/diskprediction_cloud/common/client_pb2_grpc.py create mode 100644 src/pybind/mgr/diskprediction_cloud/common/clusterdata.py create mode 100644 src/pybind/mgr/diskprediction_cloud/common/cypher.py create mode 100644 src/pybind/mgr/diskprediction_cloud/common/grpcclient.py create mode 100644 src/pybind/mgr/diskprediction_cloud/common/server.crt create mode 100644 src/pybind/mgr/diskprediction_cloud/module.py create mode 100644 src/pybind/mgr/diskprediction_cloud/requirements.txt create mode 100644 src/pybind/mgr/diskprediction_cloud/task.py create mode 100644 src/pybind/mgr/diskprediction_local/__init__.py create mode 100644 src/pybind/mgr/diskprediction_local/models/config.json create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_1.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_10.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_104.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_105.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_109.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_112.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_114.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_115.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_118.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_119.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_12.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_120.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_123.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_124.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_125.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_128.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_131.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_134.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_138.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_14.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_141.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_145.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_151.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_16.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_161.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_168.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_169.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_174.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_18.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_182.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_185.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_186.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_195.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_201.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_204.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_206.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_208.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_210.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_212.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_213.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_219.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_221.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_222.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_223.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_225.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_227.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_229.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_230.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_234.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_235.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_236.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_239.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_243.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_27.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_3.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_33.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_36.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_44.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_50.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_57.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_59.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_6.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_61.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_62.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_67.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_69.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_71.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_72.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_78.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_79.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_82.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_85.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_88.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_93.pkl create mode 100644 src/pybind/mgr/diskprediction_local/models/svm_97.pkl create mode 100644 src/pybind/mgr/diskprediction_local/module.py create mode 100644 src/pybind/mgr/diskprediction_local/predictor.py create mode 100644 src/pybind/mgr/hello/__init__.py create mode 100644 src/pybind/mgr/hello/module.py create mode 100644 src/pybind/mgr/influx/__init__.py create mode 100644 src/pybind/mgr/influx/module.py create mode 100644 src/pybind/mgr/insights/CMakeLists.txt create mode 100644 src/pybind/mgr/insights/__init__.py create mode 100644 src/pybind/mgr/insights/health.py create mode 100644 src/pybind/mgr/insights/module.py create mode 100644 src/pybind/mgr/insights/run-tox.sh create mode 100644 src/pybind/mgr/insights/tests/__init__.py create mode 100644 src/pybind/mgr/insights/tests/test_health.py create mode 100644 src/pybind/mgr/insights/tox.ini create mode 100644 src/pybind/mgr/iostat/__init__.py create mode 100644 src/pybind/mgr/iostat/module.py create mode 100644 src/pybind/mgr/k8sevents/README.md create mode 100644 src/pybind/mgr/k8sevents/__init__.py create mode 100644 src/pybind/mgr/k8sevents/module.py create mode 100644 src/pybind/mgr/k8sevents/rbac_sample.yaml create mode 100644 src/pybind/mgr/localpool/__init__.py create mode 100644 src/pybind/mgr/localpool/module.py create mode 100644 src/pybind/mgr/mgr_module.py create mode 100644 src/pybind/mgr/mgr_util.py create mode 100644 src/pybind/mgr/orchestrator.py create mode 100644 src/pybind/mgr/orchestrator_cli/.gitignore create mode 100644 src/pybind/mgr/orchestrator_cli/CMakeLists.txt create mode 100644 src/pybind/mgr/orchestrator_cli/README.md create mode 100644 src/pybind/mgr/orchestrator_cli/__init__.py create mode 100644 src/pybind/mgr/orchestrator_cli/module.py create mode 100644 src/pybind/mgr/orchestrator_cli/requirements.txt create mode 100644 src/pybind/mgr/orchestrator_cli/run-tox.sh create mode 100644 src/pybind/mgr/orchestrator_cli/test_orchestrator.py create mode 100644 src/pybind/mgr/orchestrator_cli/tox.ini create mode 100644 src/pybind/mgr/osd_perf_query/__init__.py create mode 100644 src/pybind/mgr/osd_perf_query/module.py create mode 100644 src/pybind/mgr/pg_autoscaler/__init__.py create mode 100644 src/pybind/mgr/pg_autoscaler/module.py create mode 100644 src/pybind/mgr/progress/__init__.py create mode 100644 src/pybind/mgr/progress/module.py create mode 100644 src/pybind/mgr/prometheus/__init__.py create mode 100644 src/pybind/mgr/prometheus/module.py create mode 100644 src/pybind/mgr/rbd_support/__init__.py create mode 100644 src/pybind/mgr/rbd_support/module.py create mode 100644 src/pybind/mgr/restful/__init__.py create mode 100644 src/pybind/mgr/restful/api/__init__.py create mode 100644 src/pybind/mgr/restful/api/config.py create mode 100644 src/pybind/mgr/restful/api/crush.py create mode 100644 src/pybind/mgr/restful/api/doc.py create mode 100644 src/pybind/mgr/restful/api/mon.py create mode 100644 src/pybind/mgr/restful/api/osd.py create mode 100644 src/pybind/mgr/restful/api/perf.py create mode 100644 src/pybind/mgr/restful/api/pool.py create mode 100644 src/pybind/mgr/restful/api/request.py create mode 100644 src/pybind/mgr/restful/api/server.py create mode 100644 src/pybind/mgr/restful/common.py create mode 100644 src/pybind/mgr/restful/context.py create mode 100644 src/pybind/mgr/restful/decorators.py create mode 100644 src/pybind/mgr/restful/hooks.py create mode 100644 src/pybind/mgr/restful/module.py create mode 100644 src/pybind/mgr/rook/__init__.py create mode 100644 src/pybind/mgr/rook/module.py create mode 100644 src/pybind/mgr/rook/rook_cluster.py create mode 100644 src/pybind/mgr/selftest/__init__.py create mode 100644 src/pybind/mgr/selftest/module.py create mode 100644 src/pybind/mgr/ssh/.gitignore create mode 100644 src/pybind/mgr/ssh/README.md create mode 100644 src/pybind/mgr/ssh/Vagrantfile create mode 100644 src/pybind/mgr/ssh/__init__.py create mode 100644 src/pybind/mgr/ssh/ceph.repo create mode 100644 src/pybind/mgr/ssh/module.py create mode 100644 src/pybind/mgr/ssh/remotes.py create mode 100644 src/pybind/mgr/status/__init__.py create mode 100644 src/pybind/mgr/status/module.py create mode 100644 src/pybind/mgr/telegraf/__init__.py create mode 100644 src/pybind/mgr/telegraf/basesocket.py create mode 100644 src/pybind/mgr/telegraf/module.py create mode 100644 src/pybind/mgr/telegraf/protocol.py create mode 100644 src/pybind/mgr/telegraf/utils.py create mode 100644 src/pybind/mgr/telemetry/__init__.py create mode 100644 src/pybind/mgr/telemetry/module.py create mode 100644 src/pybind/mgr/test_orchestrator/__init__.py create mode 100644 src/pybind/mgr/test_orchestrator/module.py create mode 100644 src/pybind/mgr/volumes/__init__.py create mode 100644 src/pybind/mgr/volumes/fs/__init__.py create mode 100644 src/pybind/mgr/volumes/fs/async_cloner.py create mode 100644 src/pybind/mgr/volumes/fs/async_job.py create mode 100644 src/pybind/mgr/volumes/fs/exception.py create mode 100644 src/pybind/mgr/volumes/fs/fs_util.py create mode 100644 src/pybind/mgr/volumes/fs/operations/__init__.py create mode 100644 src/pybind/mgr/volumes/fs/operations/access.py create mode 100644 src/pybind/mgr/volumes/fs/operations/clone_index.py create mode 100644 src/pybind/mgr/volumes/fs/operations/group.py create mode 100644 src/pybind/mgr/volumes/fs/operations/index.py create mode 100644 src/pybind/mgr/volumes/fs/operations/lock.py create mode 100644 src/pybind/mgr/volumes/fs/operations/rankevicter.py create mode 100644 src/pybind/mgr/volumes/fs/operations/resolver.py create mode 100644 src/pybind/mgr/volumes/fs/operations/snapshot_util.py create mode 100644 src/pybind/mgr/volumes/fs/operations/subvolume.py create mode 100644 src/pybind/mgr/volumes/fs/operations/template.py create mode 100644 src/pybind/mgr/volumes/fs/operations/trash.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/__init__.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/auth_metadata.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/op_sm.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/subvolume_attrs.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py create mode 100644 src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py create mode 100644 src/pybind/mgr/volumes/fs/operations/volume.py create mode 100644 src/pybind/mgr/volumes/fs/purge_queue.py create mode 100644 src/pybind/mgr/volumes/fs/vol_spec.py create mode 100644 src/pybind/mgr/volumes/fs/volume.py create mode 100644 src/pybind/mgr/volumes/module.py create mode 100644 src/pybind/mgr/zabbix/__init__.py create mode 100644 src/pybind/mgr/zabbix/module.py create mode 100644 src/pybind/mgr/zabbix/zabbix_template.xml (limited to 'src/pybind/mgr') diff --git a/src/pybind/mgr/.gitignore b/src/pybind/mgr/.gitignore new file mode 100644 index 00000000..fcdcddd5 --- /dev/null +++ b/src/pybind/mgr/.gitignore @@ -0,0 +1 @@ +proxy.conf.json diff --git a/src/pybind/mgr/CMakeLists.txt b/src/pybind/mgr/CMakeLists.txt new file mode 100644 index 00000000..2b5f4a7d --- /dev/null +++ b/src/pybind/mgr/CMakeLists.txt @@ -0,0 +1,14 @@ +add_subdirectory(dashboard) +add_subdirectory(insights) +add_subdirectory(ansible) +add_subdirectory(orchestrator_cli) + +# Location needs to match default setting for mgr_module_path, currently: +# OPTION(mgr_module_path, OPT_STR, CEPH_PKGLIBDIR "/mgr") +install(DIRECTORY + ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION ${CEPH_INSTALL_DATADIR} + REGEX "CMakeLists.txt" EXCLUDE + REGEX "\\.gitignore" EXCLUDE + REGEX "hello/.*" EXCLUDE + REGEX "osd_perf_query/.*" EXCLUDE) diff --git a/src/pybind/mgr/alerts/__init__.py b/src/pybind/mgr/alerts/__init__.py new file mode 100644 index 00000000..e4c185ca --- /dev/null +++ b/src/pybind/mgr/alerts/__init__.py @@ -0,0 +1 @@ +from .module import Alerts diff --git a/src/pybind/mgr/alerts/module.py b/src/pybind/mgr/alerts/module.py new file mode 100644 index 00000000..d6cec4b6 --- /dev/null +++ b/src/pybind/mgr/alerts/module.py @@ -0,0 +1,259 @@ + +""" +A simple cluster health alerting module. +""" + +from mgr_module import MgrModule, HandleCommandResult +from threading import Event +import errno +import json +import smtplib + +class Alerts(MgrModule): + COMMANDS = [ + { + "cmd": "alerts send", + "desc": "(re)send alerts immediately", + "perm": "r" + }, + ] + + MODULE_OPTIONS = [ + { + 'name': 'interval', + 'type': 'secs', + 'default': 60, + 'desc': 'How frequently to reexamine health status', + 'runtime': True, + }, + # smtp + { + 'name': 'smtp_host', + 'default': '', + 'desc': 'SMTP server', + 'runtime': True, + }, + { + 'name': 'smtp_destination', + 'default': '', + 'desc': 'Email address to send alerts to', + 'runtime': True, + }, + { + 'name': 'smtp_port', + 'type': 'int', + 'default': 465, + 'desc': 'SMTP port', + 'runtime': True, + }, + { + 'name': 'smtp_ssl', + 'type': 'bool', + 'default': True, + 'desc': 'Use SSL to connect to SMTP server', + 'runtime': True, + }, + { + 'name': 'smtp_user', + 'default': '', + 'desc': 'User to authenticate as', + 'runtime': True, + }, + { + 'name': 'smtp_password', + 'default': '', + 'desc': 'Password to authenticate with', + 'runtime': True, + }, + { + 'name': 'smtp_sender', + 'default': '', + 'desc': 'SMTP envelope sender', + 'runtime': True, + }, + { + 'name': 'smtp_from_name', + 'default': 'Ceph', + 'desc': 'Email From: name', + 'runtime': True, + }, + ] + + # These are "native" Ceph options that this module cares about. + NATIVE_OPTIONS = [ + ] + + def __init__(self, *args, **kwargs): + super(Alerts, self).__init__(*args, **kwargs) + + # set up some members to enable the serve() method and shutdown() + self.run = True + self.event = Event() + + # ensure config options members are initialized; see config_notify() + self.config_notify() + + self.log.info("Init") + + + def config_notify(self): + """ + This method is called whenever one of our config options is changed. + """ + # This is some boilerplate that stores MODULE_OPTIONS in a class + # member, so that, for instance, the 'emphatic' option is always + # available as 'self.emphatic'. + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' mgr option %s = %s', + opt['name'], getattr(self, opt['name'])) + # Do the same for the native options. + for opt in self.NATIVE_OPTIONS: + setattr(self, + opt, + self.get_ceph_option(opt)) + self.log.debug(' native option %s = %s', opt, getattr(self, opt)) + + def handle_command(self, inbuf, cmd): + ret = 0 + out = '' + err = '' + if cmd['prefix'] == 'alerts send': + status = json.loads(self.get('health')['json']) + self._send_alert(status, {}) + return HandleCommandResult( + retval=ret, # exit code + stdout=out, # stdout + stderr=err) + + def _diff(self, last, new): + d = {} + for code, alert in new.get('checks', {}).items(): + self.log.debug('new code %s alert %s' % (code, alert)) + if code not in last.get('checks', {}): + if 'new' not in d: + d['new'] = {} + d['new'][code] = alert + elif alert['summary'].get('count', 0) > \ + last['checks'][code]['summary'].get('count', 0): + if 'updated' not in d: + d['updated'] = {} + d['updated'][code] = alert + for code, alert in last.get('checks', {}).items(): + self.log.debug('old code %s alert %s' % (code, alert)) + if code not in new.get('checks', {}): + if 'cleared' not in d: + d['cleared'] = {} + d['cleared'][code] = alert + return d + + def _send_alert(self, status, diff): + checks = {} + if self.smtp_host: + r = self._send_alert_smtp(status, diff) + if r: + for code, alert in r.items(): + checks[code] = alert + else: + self.log.warn('Alert is not sent because smtp_host is not configured') + self.set_health_checks(checks) + + def serve(self): + """ + This method is called by the mgr when the module starts and can be + used for any background activity. + """ + self.log.info("Starting") + last_status = {} + while self.run: + # Do some useful background work here. + new_status = json.loads(self.get('health')['json']) + if new_status != last_status: + self.log.debug('last_status %s' % last_status) + self.log.debug('new_status %s' % new_status) + diff = self._diff(last_status, + new_status) + self.log.debug('diff %s' % diff) + if diff: + self._send_alert(new_status, diff) + last_status = new_status + + self.log.debug('Sleeping for %d seconds', self.interval) + ret = self.event.wait(self.interval) + self.event.clear() + + def shutdown(self): + """ + This method is called by the mgr when the module needs to shut + down (i.e., when the serve() function needs to exit). + """ + self.log.info('Stopping') + self.run = False + self.event.set() + + # SMTP + def _smtp_format_alert(self, code, alert): + r = '[{sev}] {code}: {summary}\n'.format( + code=code, + sev=alert['severity'].split('_')[1], + summary=alert['summary']['message']) + for detail in alert['detail']: + r += ' {message}\n'.format( + message=detail['message']) + return r + + def _send_alert_smtp(self, status, diff): + # message + self.log.debug('_send_alert_smtp') + message = ('From: {from_name} <{sender}>\n' + 'Subject: {status}\n' + 'To: {target}\n' + '\n' + '{status}\n'.format( + sender=self.smtp_sender, + from_name=self.smtp_from_name, + status=status['status'], + target=self.smtp_destination)) + + if 'new' in diff: + message += ('\n--- New ---\n') + for code, alert in diff['new'].items(): + message += self._smtp_format_alert(code, alert) + if 'updated' in diff: + message += ('\n--- Updated ---\n') + for code, alert in diff['updated'].items(): + message += self._smtp_format_alert(code, alert) + if 'cleared' in diff: + message += ('\n--- Cleared ---\n') + for code, alert in diff['cleared'].items(): + message += self._smtp_format_alert(code, alert) + + message += ('\n\n=== Full health status ===\n') + for code, alert in status['checks'].items(): + message += self._smtp_format_alert(code, alert) + + self.log.debug('message: %s' % message) + + # send + try: + if self.smtp_ssl: + server = smtplib.SMTP_SSL(self.smtp_host, self.smtp_port) + else: + server = smtplib.SMTP(self.smtp_host, self.smtp_port) + if self.smtp_password: + server.login(self.smtp_user, self.smtp_password) + server.sendmail(self.smtp_sender, self.smtp_destination, message) + server.quit() + except Exception as e: + return { + 'ALERTS_SMTP_ERROR': { + 'severity': 'warning', + 'summary': 'unable to send alert email', + 'count': 1, + 'detail': [ str(e) ] + } + } + self.log.debug('Sent email to %s' % self.smtp_destination) + return None diff --git a/src/pybind/mgr/ansible/.gitignore b/src/pybind/mgr/ansible/.gitignore new file mode 100644 index 00000000..43a2d269 --- /dev/null +++ b/src/pybind/mgr/ansible/.gitignore @@ -0,0 +1 @@ +wheelhouse* diff --git a/src/pybind/mgr/ansible/CMakeLists.txt b/src/pybind/mgr/ansible/CMakeLists.txt new file mode 100644 index 00000000..c706aa8c --- /dev/null +++ b/src/pybind/mgr/ansible/CMakeLists.txt @@ -0,0 +1,7 @@ +set(MGR_ANSIBLE_VIRTUALENV ${CEPH_BUILD_VIRTUALENV}/mgr-ansible-virtualenv) + +add_custom_target(mgr-ansible-test-venv + COMMAND ${CMAKE_SOURCE_DIR}/src/tools/setup-virtualenv.sh --python=${MGR_PYTHON_EXECUTABLE} ${MGR_ANSIBLE_VIRTUALENV} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/ansible + COMMENT "ansible tests virtualenv is being created") +add_dependencies(tests mgr-ansible-test-venv) diff --git a/src/pybind/mgr/ansible/__init__.py b/src/pybind/mgr/ansible/__init__.py new file mode 100644 index 00000000..ea61a12f --- /dev/null +++ b/src/pybind/mgr/ansible/__init__.py @@ -0,0 +1,9 @@ +from __future__ import absolute_import +import os + +if 'UNITTEST' not in os.environ: + from .module import Module +else: + import sys + import mock + sys.modules['ceph_module'] = mock.Mock() diff --git a/src/pybind/mgr/ansible/ansible_runner_svc.py b/src/pybind/mgr/ansible/ansible_runner_svc.py new file mode 100644 index 00000000..636e20b0 --- /dev/null +++ b/src/pybind/mgr/ansible/ansible_runner_svc.py @@ -0,0 +1,326 @@ +""" +Client module to interact with the Ansible Runner Service +""" +import requests +import json +import re +from functools import wraps + +# Ansible Runner service API endpoints +API_URL = "api" +LOGIN_URL = "api/v1/login" +PLAYBOOK_EXEC_URL = "api/v1/playbooks" +PLAYBOOK_EVENTS = "api/v1/jobs/%s/events" +EVENT_DATA_URL = "api/v1/jobs/%s/events/%s" + +class AnsibleRunnerServiceError(Exception): + pass + +def handle_requests_exceptions(func): + """Decorator to manage errors raised by requests library + """ + @wraps(func) + def inner(*args, **kwargs): + try: + return func(*args, **kwargs) + except requests.exceptions.RequestException as ex: + raise AnsibleRunnerServiceError(str(ex)) + return inner + +class ExecutionStatusCode(object): + """Execution status of playbooks ( 'msg' field in playbook status request) + """ + + SUCCESS = 0 # Playbook has been executed succesfully" msg = successful + ERROR = 1 # Playbook has finished with error msg = failed + ON_GOING = 2 # Playbook is being executed msg = running + NOT_LAUNCHED = 3 # Not initialized + +class PlayBookExecution(object): + """Object to provide all the results of a Playbook execution + """ + + def __init__(self, rest_client, playbook, logger, result_pattern="", + the_params=None, + querystr_dict=None): + + self.rest_client = rest_client + + # Identifier of the playbook execution + self.play_uuid = "-" + + # Pattern used to extract the result from the events + self.result_task_pattern = result_pattern + + # Playbook name + self.playbook = playbook + + # Parameters used in the playbook + self.params = the_params + + # Query string used in the "launch" request + self.querystr_dict = querystr_dict + + # Logger + self.log = logger + + def launch(self): + """ Launch the playbook execution + """ + + response = None + endpoint = "%s/%s" % (PLAYBOOK_EXEC_URL, self.playbook) + + try: + response = self.rest_client.http_post(endpoint, + self.params, + self.querystr_dict) + except AnsibleRunnerServiceError: + self.log.exception("Error launching playbook <%s>", self.playbook) + raise + + # Here we have a server response, but an error trying + # to launch the playbook is also posible (ex. 404, playbook not found) + # Error already logged by rest_client, but an error should be raised + # to the orchestrator (via completion object) + if response.ok: + self.play_uuid = json.loads(response.text)["data"]["play_uuid"] + self.log.info("Playbook execution launched succesfuly") + else: + raise AnsibleRunnerServiceError(response.reason) + + def get_status(self): + """ Return the status of the execution + + In the msg field of the respons we can find: + "msg": "successful" + "msg": "running" + "msg": "failed" + """ + + status_value = ExecutionStatusCode.NOT_LAUNCHED + response = None + + if self.play_uuid == '-': # Initialized + status_value = ExecutionStatusCode.NOT_LAUNCHED + elif self.play_uuid == '': # Error launching playbook + status_value = ExecutionStatusCode.ERROR + else: + endpoint = "%s/%s" % (PLAYBOOK_EXEC_URL, self.play_uuid) + + try: + response = self.rest_client.http_get(endpoint) + except AnsibleRunnerServiceError: + self.log.exception("Error getting playbook <%s> status", + self.playbook) + + if response: + the_status = json.loads(response.text)["msg"] + if the_status == 'successful': + status_value = ExecutionStatusCode.SUCCESS + elif the_status == 'failed': + status_value = ExecutionStatusCode.ERROR + else: + status_value = ExecutionStatusCode.ON_GOING + else: + status_value = ExecutionStatusCode.ERROR + + self.log.info("Requested playbook execution status is: %s", status_value) + return status_value + + def get_result(self, event_filter=""): + """Get the data of the events filtered by a task pattern and + a event filter + + @returns: the events that matches with the patterns provided + """ + response = None + if not self.play_uuid: + return {} + + try: + response = self.rest_client.http_get(PLAYBOOK_EVENTS % self.play_uuid) + except AnsibleRunnerServiceError: + self.log.exception("Error getting playbook <%s> result", self.playbook) + + if not response: + result_events = {} + else: + events = json.loads(response.text)["data"]["events"] + + if self.result_task_pattern: + result_events = {event:data for event,data in events.items() + if "task" in data and + re.match(self.result_task_pattern, data["task"])} + else: + result_events = events + + if event_filter: + result_events = {event:data for event,data in result_events.items() + if re.match(event_filter, data['event'])} + + self.log.info("Requested playbook result is: %s", json.dumps(result_events)) + return result_events + +class Client(object): + """An utility object that allows to connect with the Ansible runner service + and execute easily playbooks + """ + + def __init__(self, server_url, user, password, verify_server, logger): + """Provide an https client to make easy interact with the Ansible + Runner Service" + + :param servers_url: The base URL >server>: of the Ansible Runner Service + :param user: Username of the authorized user + :param password: Password of the authorized user + :param verify_server: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param logger: Log file + """ + self.server_url = server_url + self.user = user + self.password = password + self.log = logger + self.auth = (self.user, self.password) + if not verify_server: + self.verify_server = True + elif verify_server.lower().strip() == 'false': + self.verify_server = False + else: + self.verify_server = verify_server + + # Once authenticated this token will be used in all the requests + self.token = "" + + self.server_url = "https://{0}".format(self.server_url) + + # Log in the server and get a token + self.login() + + @handle_requests_exceptions + def login(self): + """ Login with user credentials to obtain a valid token + """ + + the_url = "%s/%s" % (self.server_url, LOGIN_URL) + response = requests.get(the_url, + auth = self.auth, + verify = self.verify_server) + + if response.status_code != requests.codes.ok: + self.log.error("login error <<%s>> (%s):%s", + the_url, response.status_code, response.text) + else: + self.log.info("login succesful <<%s>> (%s):%s", + the_url, response.status_code, response.text) + + if response: + self.token = json.loads(response.text)["data"]["token"] + self.log.info("Connection with Ansible Runner Service is operative") + + @handle_requests_exceptions + def is_operative(self): + """Indicates if the connection with the Ansible runner Server is ok + """ + + # No Token... this means we haven't used yet the service. + if not self.token: + return False + + # Check the service + response = self.http_get(API_URL) + + if response: + return response.status_code == requests.codes.ok + else: + return False + + @handle_requests_exceptions + def http_get(self, endpoint): + """Execute an http get request + + :param endpoint: Ansible Runner service RESTful API endpoint + + :returns: A requests object + """ + + the_url = "%s/%s" % (self.server_url, endpoint) + response = requests.get(the_url, + verify = self.verify_server, + headers = {"Authorization": self.token}) + + if response.status_code != requests.codes.ok: + self.log.error("http GET %s <--> (%s - %s)\n%s", + the_url, response.status_code, response.reason, + response.text) + else: + self.log.info("http GET %s <--> (%s - %s)", + the_url, response.status_code, response.text) + + return response + + @handle_requests_exceptions + def http_post(self, endpoint, payload, params_dict): + """Execute an http post request + + :param endpoint: Ansible Runner service RESTful API endpoint + :param payload: Dictionary with the data used in the post request + :param params_dict: A dict used to build a query string + + :returns: A requests object + """ + + the_url = "%s/%s" % (self.server_url, endpoint) + response = requests.post(the_url, + verify = self.verify_server, + headers = {"Authorization": self.token, + "Content-type": "application/json"}, + json = payload, + params = params_dict) + + if response.status_code != requests.codes.ok: + self.log.error("http POST %s [%s] <--> (%s - %s:%s)\n", + the_url, payload, response.status_code, + response.reason, response.text) + else: + self.log.info("http POST %s <--> (%s - %s)", + the_url, response.status_code, response.text) + + return response + + @handle_requests_exceptions + def http_delete(self, endpoint): + """Execute an http delete request + + :param endpoint: Ansible Runner service RESTful API endpoint + + :returns: A requests object + """ + + the_url = "%s/%s" % (self.server_url, endpoint) + response = requests.delete(the_url, + verify = self.verify_server, + headers = {"Authorization": self.token}) + + if response.status_code != requests.codes.ok: + self.log.error("http DELETE %s <--> (%s - %s)\n%s", + the_url, response.status_code, response.reason, + response.text) + else: + self.log.info("http DELETE %s <--> (%s - %s)", + the_url, response.status_code, response.text) + + return response + + def http_put(self, endpoint, payload): + """Execute an http put request + + :param endpoint: Ansible Runner service RESTful API endpoint + :param payload: Dictionary with the data used in the put request + + :returns: A requests object + """ + # TODO + raise NotImplementedError("TODO") diff --git a/src/pybind/mgr/ansible/module.py b/src/pybind/mgr/ansible/module.py new file mode 100644 index 00000000..81e1c40a --- /dev/null +++ b/src/pybind/mgr/ansible/module.py @@ -0,0 +1,729 @@ +""" +ceph-mgr Ansible orchestrator module + +The external Orchestrator is the Ansible runner service (RESTful https service) +""" + +# pylint: disable=abstract-method, no-member, bad-continuation + +import json +import requests + +from mgr_module import MgrModule +import orchestrator + +from .ansible_runner_svc import Client, PlayBookExecution, ExecutionStatusCode,\ + AnsibleRunnerServiceError + +from .output_wizards import ProcessInventory, ProcessPlaybookResult, \ + ProcessHostsList + +# Time to clean the completions list +WAIT_PERIOD = 10 + +# List of playbooks names used + +# Name of the playbook used in the "get_inventory" method. +# This playbook is expected to provide a list of storage devices in the host +# where the playbook is executed. +GET_STORAGE_DEVICES_CATALOG_PLAYBOOK = "storage-inventory.yml" + +# Used in the create_osd method +ADD_OSD_PLAYBOOK = "add-osd.yml" + +# Used in the remove_osds method +REMOVE_OSD_PLAYBOOK = "shrink-osd.yml" + +# Default name for the inventory group for hosts managed by the Orchestrator +ORCHESTRATOR_GROUP = "orchestrator" + +# URLs for Ansible Runner Operations +# Add or remove host in one group +URL_ADD_RM_HOSTS = "api/v1/hosts/{host_name}/groups/{inventory_group}" + +# Retrieve the groups where the host is included in. +URL_GET_HOST_GROUPS = "api/v1/hosts/{host_name}" +# Manage groups +URL_MANAGE_GROUP = "api/v1/groups/{group_name}" +# URLs for Ansible Runner Operations +URL_GET_HOSTS = "api/v1/hosts" + + +class AnsibleReadOperation(orchestrator.ReadCompletion): + """ A read operation means to obtain information from the cluster. + """ + def __init__(self, client, logger): + """ + :param client : Ansible Runner Service Client + :param logger : The object used to log messages + """ + super(AnsibleReadOperation, self).__init__() + + # Private attributes + self._is_complete = False + self._is_errored = False + self._result = [] + self._status = ExecutionStatusCode.NOT_LAUNCHED + + # Object used to process operation result in different ways + self.output_wizard = None + + # Error description in operation + self.error = "" + + # Ansible Runner Service client + self.ar_client = client + + # Logger + self.log = logger + + # OutputWizard object used to process the result + self.output_wizard = None + + @property + def is_complete(self): + return self._is_complete + + @property + def is_errored(self): + return self._is_errored + + @property + def result(self): + return self._result + + @property + def status(self): + """Retrieve the current status of the operation and update state + attributes + """ + raise NotImplementedError() + +class ARSOperation(AnsibleReadOperation): + """Execute an Ansible Runner Service Operation + """ + + def __init__(self, client, logger, url, get_operation=True, payload=None): + """ + :param client : Ansible Runner Service Client + :param logger : The object used to log messages + :param url : The Ansible Runner Service URL that provides + the operation + :param get_operation : True if operation is provided using an http GET + :param payload : http request payload + """ + super(ARSOperation, self).__init__(client, logger) + + self.url = url + self.get_operation = get_operation + self.payload = payload + + def __str__(self): + return "Ansible Runner Service: {operation} {url}".format( + operation="GET" if self.get_operation else "POST", + url=self.url) + + @property + def status(self): + """ Execute the Ansible Runner Service operation and update the status + and result of the underlying Completion object. + """ + + # Execute the right kind of http request + if self.get_operation: + response = self.ar_client.http_get(self.url) + else: + response = self.ar_client.http_post(self.url, self.payload) + + # If no connection errors, the operation is complete + self._is_complete = True + + # Depending of the response, status and result is updated + if not response: + self._is_errored = True + self._status = ExecutionStatusCode.ERROR + self._result = "Ansible Runner Service not Available" + else: + self._is_errored = (response.status_code != requests.codes.ok) + + if not self._is_errored: + self._status = ExecutionStatusCode.SUCCESS + if self.output_wizard: + self._result = self.output_wizard.process(self.url, + response.text) + else: + self._result = response.text + else: + self._status = ExecutionStatusCode.ERROR + self._result = response.reason + + return self._status + + +class PlaybookOperation(AnsibleReadOperation): + """Execute a playbook using the Ansible Runner Service + """ + + def __init__(self, client, playbook, logger, result_pattern, + params, + querystr_dict={}): + """ + :param client : Ansible Runner Service Client + :param playbook : The playbook to execute + :param logger : The object used to log messages + :param result_pattern: The "pattern" to discover what execution events + have the information deemed as result + :param params : http request payload for the playbook execution + :param querystr_dict : http request querystring for the playbook + execution (DO NOT MODIFY HERE) + + """ + super(PlaybookOperation, self).__init__(client, logger) + + # Private attributes + self.playbook = playbook + + # An aditional filter of result events based in the event + self.event_filter = "" + + # Playbook execution object + self.pb_execution = PlayBookExecution(client, + playbook, + logger, + result_pattern, + params, + querystr_dict) + + def __str__(self): + return "Playbook {playbook_name}".format(playbook_name=self.playbook) + + @property + def status(self): + """Check the status of the playbook execution and update the status + and result of the underlying Completion object. + """ + + if self._status in [ExecutionStatusCode.ON_GOING, + ExecutionStatusCode.NOT_LAUNCHED]: + self._status = self.pb_execution.get_status() + + self._is_complete = (self._status == ExecutionStatusCode.SUCCESS) or \ + (self._status == ExecutionStatusCode.ERROR) + + self._is_errored = (self._status == ExecutionStatusCode.ERROR) + + if self._is_complete: + self.update_result() + + return self._status + + def execute_playbook(self): + """Launch the execution of the playbook with the parameters configured + """ + try: + self.pb_execution.launch() + except AnsibleRunnerServiceError: + self._status = ExecutionStatusCode.ERROR + raise + + def update_result(self): + """Output of the read operation + + The result of the playbook execution can be customized through the + function provided as 'process_output' attribute + + :return string: Result of the operation formatted if it is possible + """ + + processed_result = [] + + if self._is_complete: + raw_result = self.pb_execution.get_result(self.event_filter) + + if self.output_wizard: + processed_result = self.output_wizard.process(self.pb_execution.play_uuid, + raw_result) + else: + processed_result = raw_result + + self._result = processed_result + + +class AnsibleChangeOperation(orchestrator.WriteCompletion): + """Operations that changes the "cluster" state + + Modifications/Changes (writes) are a two-phase thing, firstly execute + the playbook that is going to change elements in the Ceph Cluster. + When the playbook finishes execution (independently of the result), + the modification/change operation has finished. + """ + def __init__(self): + super(AnsibleChangeOperation, self).__init__() + + self._status = ExecutionStatusCode.NOT_LAUNCHED + self._result = None + + # Object used to process operation result in different ways + self.output_wizard = None + + @property + def status(self): + """Return the status code of the operation + """ + raise NotImplementedError() + + @property + def is_persistent(self): + """ + Has the operation updated the orchestrator's configuration + persistently? Typically this would indicate that an update + had been written to a manifest, but that the update + had not necessarily been pushed out to the cluster. + + :return Boolean: True if the execution of the Ansible Playbook or the + operation over the Ansible Runner Service has finished + """ + + return self._status in [ExecutionStatusCode.SUCCESS, + ExecutionStatusCode.ERROR] + + @property + def is_effective(self): + """Has the operation taken effect on the cluster? + For example, if we were adding a service, has it come up and appeared + in Ceph's cluster maps? + + In the case of Ansible, this will be True if the playbooks has been + executed succesfully. + + :return Boolean: if the playbook/ARS operation has been executed + succesfully + """ + + return self._status == ExecutionStatusCode.SUCCESS + + @property + def is_errored(self): + return self._status == ExecutionStatusCode.ERROR + + @property + def result(self): + return self._result + +class HttpOperation(object): + """A class to ease the management of http operations + """ + + def __init__(self, url, http_operation, payload="", query_string="{}"): + self.url = url + self.http_operation = http_operation + self.payload = payload + self.query_string = query_string + self.response = None + +class ARSChangeOperation(AnsibleChangeOperation): + """Execute one or more Ansible Runner Service Operations that implies + a change in the cluster + """ + def __init__(self, client, logger, operations): + """ + :param client : Ansible Runner Service Client + :param logger : The object used to log messages + :param operations : A list of http_operation objects + :param payload : dict with http request payload + """ + super(ARSChangeOperation, self).__init__() + + assert operations, "At least one operation is needed" + self.ar_client = client + self.log = logger + self.operations = operations + + def __str__(self): + # Use the last operation as the main + return "Ansible Runner Service: {operation} {url}".format( + operation=self.operations[-1].http_operation, + url=self.operations[-1].url) + + @property + def status(self): + """Execute the Ansible Runner Service operations and update the status + and result of the underlying Completion object. + """ + + for my_request in self.operations: + # Execute the right kind of http request + try: + if my_request.http_operation == "post": + response = self.ar_client.http_post(my_request.url, + my_request.payload, + my_request.query_string) + elif my_request.http_operation == "delete": + response = self.ar_client.http_delete(my_request.url) + elif my_request.http_operation == "get": + response = self.ar_client.http_get(my_request.url) + + # Any problem executing the secuence of operations will + # produce an errored completion object. + if response.status_code != requests.codes.ok: + self._status = ExecutionStatusCode.ERROR + self._result = response.text + return self._status + + # Any kind of error communicating with ARS or preventing + # to have a right http response + except AnsibleRunnerServiceError as ex: + self._status = ExecutionStatusCode.ERROR + self._result = str(ex) + return self._status + + # If this point is reached, all the operations has been succesfuly + # executed, and the final result is updated + self._status = ExecutionStatusCode.SUCCESS + if self.output_wizard: + self._result = self.output_wizard.process("", response.text) + else: + self._result = response.text + + return self._status + +class Module(MgrModule, orchestrator.Orchestrator): + """An Orchestrator that uses to perform operations + """ + + MODULE_OPTIONS = [ + {'name': 'server_url'}, + {'name': 'username'}, + {'name': 'password'}, + {'name': 'verify_server'} # Check server identity (Boolean/path to CA bundle) + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + + self.run = False + + self.all_completions = [] + + self.ar_client = None + + def available(self): + """ Check if Ansible Runner service is working + """ + # TODO + return (True, "Everything ready") + + def wait(self, completions): + """Given a list of Completion instances, progress any which are + incomplete. + + :param completions: list of Completion instances + :Returns : True if everything is done. + """ + + # Check progress and update status in each operation + # Access completion.status property do the trick + for operation in completions: + self.log.info("<%s> status:%s", operation, operation.status) + + completions = filter(lambda x: not x.is_complete, completions) + + ops_pending = len(completions) + self.log.info("Operations pending: %s", ops_pending) + + return ops_pending == 0 + + def serve(self): + """ Mandatory for standby modules + """ + self.log.info("Starting Ansible Orchestrator module ...") + + # Verify config options (Just that settings are available) + self.verify_config() + + # Ansible runner service client + try: + self.ar_client = Client(server_url=self.get_module_option('server_url', ''), + user=self.get_module_option('username', ''), + password=self.get_module_option('password', ''), + verify_server=self.get_module_option('verify_server', True), + logger=self.log) + except AnsibleRunnerServiceError: + self.log.exception("Ansible Runner Service not available. " + "Check external server status/TLS identity or " + "connection options. If configuration options changed" + " try to disable/enable the module.") + self.shutdown() + return + + self.run = True + + def shutdown(self): + + self.log.info('Stopping Ansible orchestrator module') + self.run = False + + def get_inventory(self, node_filter=None, refresh=False): + """ + + :param : node_filter instance + :param : refresh any cached state + :Return : A AnsibleReadOperation instance (Completion Object) + """ + + # Create a new read completion object for execute the playbook + playbook_operation = PlaybookOperation(client=self.ar_client, + playbook=GET_STORAGE_DEVICES_CATALOG_PLAYBOOK, + logger=self.log, + result_pattern="list storage inventory", + params={}) + + + # Assign the process_output function + playbook_operation.output_wizard = ProcessInventory(self.ar_client, + self.log) + playbook_operation.event_filter = "runner_on_ok" + + # Execute the playbook to obtain data + self._launch_operation(playbook_operation) + + return playbook_operation + + def create_osds(self, drive_group, all_hosts): + """Create one or more OSDs within a single Drive Group. + If no host provided the operation affects all the host in the OSDS role + + + :param drive_group: (orchestrator.DriveGroupSpec), + Drive group with the specification of drives to use + :param all_hosts : (List[str]), + List of hosts where the OSD's must be created + """ + + # Transform drive group specification to Ansible playbook parameters + host, osd_spec = dg_2_ansible(drive_group) + + # Create a new read completion object for execute the playbook + playbook_operation = PlaybookOperation(client=self.ar_client, + playbook=ADD_OSD_PLAYBOOK, + logger=self.log, + result_pattern="", + params=osd_spec, + querystr_dict={"limit": host}) + + # Filter to get the result + playbook_operation.output_wizard = ProcessPlaybookResult(self.ar_client, + self.log) + playbook_operation.event_filter = "playbook_on_stats" + + # Execute the playbook + self._launch_operation(playbook_operation) + + return playbook_operation + + def remove_osds(self, osd_ids): + """Remove osd's. + + :param osd_ids: List of osd's to be removed (List[int]) + """ + + extravars = {'osd_to_kill': ",".join([str(osd_id) for osd_id in osd_ids]), + 'ireallymeanit':'yes'} + + # Create a new read completion object for execute the playbook + playbook_operation = PlaybookOperation(client=self.ar_client, + playbook=REMOVE_OSD_PLAYBOOK, + logger=self.log, + result_pattern="", + params=extravars) + + # Filter to get the result + playbook_operation.output_wizard = ProcessPlaybookResult(self.ar_client, + self.log) + playbook_operation.event_filter = "playbook_on_stats" + + # Execute the playbook + self._launch_operation(playbook_operation) + + return playbook_operation + + def get_hosts(self): + """Provides a list Inventory nodes + """ + + host_ls_op = ARSOperation(self.ar_client, self.log, URL_GET_HOSTS) + + host_ls_op.output_wizard = ProcessHostsList(self.ar_client, + self.log) + + return host_ls_op + + def add_host(self, host): + """ + Add a host to the Ansible Runner Service inventory in the "orchestrator" + group + + :param host: hostname + :returns : orchestrator.WriteCompletion + """ + + url_group = URL_MANAGE_GROUP.format(group_name=ORCHESTRATOR_GROUP) + + try: + # Create the orchestrator default group if not exist. + # If exists we ignore the error response + dummy_response = self.ar_client.http_post(url_group, "", {}) + + # Here, the default group exists so... + # Prepare the operation for adding the new host + add_url = URL_ADD_RM_HOSTS.format(host_name=host, + inventory_group=ORCHESTRATOR_GROUP) + + operations = [HttpOperation(add_url, "post")] + + except AnsibleRunnerServiceError as ex: + # Problems with the external orchestrator. + # Prepare the operation to return the error in a Completion object. + self.log.exception("Error checking group: %s", ex) + operations = [HttpOperation(url_group, "post")] + + return ARSChangeOperation(self.ar_client, self.log, operations) + + def remove_host(self, host): + """ + Remove a host from all the groups in the Ansible Runner Service + inventory. + + :param host: hostname + :returns : orchestrator.WriteCompletion + """ + + operations = [] + host_groups = [] + + try: + # Get the list of groups where the host is included + groups_url = URL_GET_HOST_GROUPS.format(host_name=host) + response = self.ar_client.http_get(groups_url) + + if response.status_code == requests.codes.ok: + host_groups = json.loads(response.text)["data"]["groups"] + + except AnsibleRunnerServiceError: + self.log.exception("Error retrieving host groups") + + if not host_groups: + # Error retrieving the groups, prepare the completion object to + # execute the problematic operation just to provide the error + # to the caller + operations = [HttpOperation(groups_url, "get")] + else: + # Build the operations list + operations = list(map(lambda x: + HttpOperation(URL_ADD_RM_HOSTS.format( + host_name=host, + inventory_group=x), + "delete"), + host_groups)) + + return ARSChangeOperation(self.ar_client, self.log, operations) + + def _launch_operation(self, ansible_operation): + """Launch the operation and add the operation to the completion objects + ongoing + + :ansible_operation: A read/write ansible operation (completion object) + """ + + # Execute the playbook + ansible_operation.execute_playbook() + + # Add the operation to the list of things ongoing + self.all_completions.append(ansible_operation) + + def verify_config(self): + """ Verify configuration options for the Ansible orchestrator module + """ + client_msg = "" + + if not self.get_module_option('server_url', ''): + msg = "No Ansible Runner Service base URL :." \ + "Try 'ceph config set mgr mgr/{0}/server_url " \ + ":'".format(self.module_name) + self.log.error(msg) + client_msg += msg + + if not self.get_module_option('username', ''): + msg = "No Ansible Runner Service user. " \ + "Try 'ceph config set mgr mgr/{0}/username " \ + "'".format(self.module_name) + self.log.error(msg) + client_msg += msg + + if not self.get_module_option('password', ''): + msg = "No Ansible Runner Service User password. " \ + "Try 'ceph config set mgr mgr/{0}/password " \ + "'".format(self.module_name) + self.log.error(msg) + client_msg += msg + + if not self.get_module_option('verify_server', ''): + msg = "TLS server identity verification is enabled by default." \ + "Use 'ceph config set mgr mgr/{0}/verify_server False' " \ + "to disable it. Use 'ceph config set mgr mgr/{0}/verify_server " \ + "' to point the CA bundle path used for " \ + "verification".format(self.module_name) + self.log.error(msg) + client_msg += msg + + if client_msg: + # Raise error + # TODO: Use OrchestratorValidationError + raise Exception(client_msg) + + + +# Auxiliary functions +#============================================================================== +def dg_2_ansible(drive_group): + """ Transform a drive group especification into: + + a host : limit the playbook execution to this host + a osd_spec : dict of parameters to pass to the Ansible playbook used + to create the osds + + :param drive_group: (type: DriveGroupSpec) + + TODO: Possible this function will be removed/or modified heavily when + the ansible playbook to create osd's use ceph volume batch with + drive group parameter + """ + + # Limit the execution of the playbook to certain hosts + # TODO: Now only accepted "*" (all the hosts) or a host_name in the + # drive_group.host_pattern + # This attribute is intended to be used with "fnmatch" patterns, so when + # this become effective it will be needed to use the "get_inventory" method + # in order to have a list of hosts to be filtered with the "host_pattern" + if drive_group.host_pattern in ["*"]: + host = None # No limit in the playbook + else: + # For the moment, we assume that we only have 1 host + host = drive_group.host_pattern + + # Compose the OSD configuration + + + osd = {} + osd["data"] = drive_group.data_devices.paths[0] + # Other parameters will be extracted in the same way + #osd["dmcrypt"] = drive_group.encryption + + # lvm_volumes parameters + # (by the moment is what is accepted in the current playbook) + osd_spec = {"lvm_volumes":[osd]} + + #Global scope variables also can be included in the osd_spec + #osd_spec["osd_objectstore"] = drive_group.objectstore + + return host, osd_spec diff --git a/src/pybind/mgr/ansible/output_wizards.py b/src/pybind/mgr/ansible/output_wizards.py new file mode 100644 index 00000000..d924bf04 --- /dev/null +++ b/src/pybind/mgr/ansible/output_wizards.py @@ -0,0 +1,158 @@ +""" +ceph-mgr Output Wizards module + +Output wizards are used to process results in different ways in +completion objects +""" + +# pylint: disable=bad-continuation + +import json + + +from orchestrator import InventoryDevice, InventoryNode + +from .ansible_runner_svc import EVENT_DATA_URL + +class OutputWizard(object): + """Base class for help to process output in completion objects + """ + def __init__(self, ar_client, logger): + """Make easy to work in output wizards using this attributes: + + :param ars_client: Ansible Runner Service client + :param logger: log object + """ + self.ar_client = ar_client + self.log = logger + + def process(self, operation_id, raw_result): + """Make the magic here + + :param operation_id: Allows to identify the Ansible Runner Service + operation whose result we wnat to process + :param raw_result: input for processing + """ + raise NotImplementedError + +class ProcessInventory(OutputWizard): + """ Adapt the output of the playbook used in 'get_inventory' + to the Orchestrator expected output (list of InventoryNode) + """ + + def process(self, operation_id, raw_result): + """ + :param operation_id: Playbook uuid + :param raw_result: events dict with the results + + Example: + inventory_events = + {'37-100564f1-9fed-48c2-bd62-4ae8636dfcdb': {'host': '192.168.121.254', + 'task': 'list storage inventory', + 'event': 'runner_on_ok'}, + '36-2016b900-e38f-7dcd-a2e7-00000000000e': {'host': '192.168.121.252' + 'task': 'list storage inventory', + 'event': 'runner_on_ok'}} + + :return : list of InventoryNode + """ + # Just making more readable the method + inventory_events = raw_result + + #Obtain the needed data for each result event + inventory_nodes = [] + + # Loop over the result events and request the event data + for event_key, dummy_data in inventory_events.items(): + + event_response = self.ar_client.http_get(EVENT_DATA_URL % + (operation_id, event_key)) + + # self.pb_execution.play_uuid + + # Process the data for each event + if event_response: + event_data = json.loads(event_response.text)["data"]["event_data"] + + host = event_data["host"] + + devices = json.loads(event_data["res"]["stdout"]) + devs = [] + for storage_device in devices: + dev = InventoryDevice.from_ceph_volume_inventory(storage_device) + devs.append(dev) + + inventory_nodes.append(InventoryNode(host, devs)) + + + return inventory_nodes + +class ProcessPlaybookResult(OutputWizard): + """ Provides the result of a playbook execution as plain text + """ + def process(self, operation_id, raw_result): + """ + :param operation_id: Playbook uuid + :param raw_result: events dict with the results + + :return : String with the playbook execution event list + """ + # Just making more readable the method + inventory_events = raw_result + + result = "" + + # Loop over the result events and request the data + for event_key, dummy_data in inventory_events.items(): + event_response = self.ar_client.http_get(EVENT_DATA_URL % + (operation_id, event_key)) + + result += event_response.text + + return result + + +class ProcessHostsList(OutputWizard): + """ Format the output of host ls call + """ + def process(self, operation_id, raw_result): + """ Format the output of host ls call + + :param operation_id: Not used in this output wizard + :param raw_result: In this case is like the following json: + { + "status": "OK", + "msg": "", + "data": { + "hosts": [ + "host_a", + "host_b", + ... + "host_x", + ] + } + } + + :return: list of InventoryNodes + """ + # Just making more readable the method + host_ls_json = raw_result + + inventory_nodes = [] + + try: + json_resp = json.loads(host_ls_json) + + for host in json_resp["data"]["hosts"]: + inventory_nodes.append(InventoryNode(host, [])) + + except ValueError: + self.log.exception("Malformed json response") + except KeyError: + self.log.exception("Unexpected content in Ansible Runner Service" + " response") + except TypeError: + self.log.exception("Hosts data must be iterable in Ansible Runner " + "Service response") + + return inventory_nodes diff --git a/src/pybind/mgr/ansible/requirements.txt b/src/pybind/mgr/ansible/requirements.txt new file mode 100644 index 00000000..e75b578d --- /dev/null +++ b/src/pybind/mgr/ansible/requirements.txt @@ -0,0 +1,2 @@ +tox==2.9.1 +importlib_metadata==2.1.0 diff --git a/src/pybind/mgr/ansible/run-tox.sh b/src/pybind/mgr/ansible/run-tox.sh new file mode 100644 index 00000000..fd6da244 --- /dev/null +++ b/src/pybind/mgr/ansible/run-tox.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +function dump_envvars { + echo "WITH_PYTHON2: ->$WITH_PYTHON2<-" + echo "WITH_PYTHON3: ->$WITH_PYTHON3<-" + echo "TOX_PATH: ->$TOX_PATH<-" + echo "ENV_LIST: ->$ENV_LIST<-" +} + +# run from ./ or from ../ +: ${MGR_ANSIBLE_VIRTUALENV:=$CEPH_BUILD_DIR/mgr-ansible-virtualenv} +: ${WITH_PYTHON2:=ON} +: ${WITH_PYTHON3:=3} +: ${CEPH_BUILD_DIR:=$PWD/.tox} +test -d ansible && cd ansible + +if [ -e tox.ini ]; then + TOX_PATH=$(readlink -f tox.ini) +else + TOX_PATH=$(readlink -f $(dirname $0)/tox.ini) +fi + +# tox.ini will take care of this. +unset PYTHONPATH +export CEPH_BUILD_DIR=$CEPH_BUILD_DIR + +source ${MGR_ANSIBLE_VIRTUALENV}/bin/activate + +if [ "$WITH_PYTHON2" = "ON" ]; then + ENV_LIST+="py27," +fi +# WITH_PYTHON3 might be set to "ON" or to the python3 RPM version number +# prevailing on the system - e.g. "3", "36" +if [[ "$WITH_PYTHON3" =~ (^3|^ON) ]]; then + ENV_LIST+="py3," +fi +# use bash string manipulation to strip off any trailing comma +ENV_LIST=${ENV_LIST%,} + +tox -c "${TOX_PATH}" -e "${ENV_LIST}" "$@" +TOX_STATUS="$?" +test "$TOX_STATUS" -ne "0" && dump_envvars +exit $TOX_STATUS diff --git a/src/pybind/mgr/ansible/tests/__init__.py b/src/pybind/mgr/ansible/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/pybind/mgr/ansible/tests/pb_execution_events.data b/src/pybind/mgr/ansible/tests/pb_execution_events.data new file mode 100644 index 00000000..248134a3 --- /dev/null +++ b/src/pybind/mgr/ansible/tests/pb_execution_events.data @@ -0,0 +1,183 @@ +{ + "status": "OK", + "msg": "", + "data": { + "events": { + "2-6edf768f-2923-44e1-b884-f0227b811cfc": { + "event": "playbook_on_start" + }, + "3-2016b900-e38f-7dcd-a2e7-000000000008": { + "event": "playbook_on_play_start" + }, + "4-2016b900-e38f-7dcd-a2e7-000000000012": { + "event": "playbook_on_task_start", + "task": "Gathering Facts" + }, + "5-19ae1e5e-aa2d-479e-845a-ef0253cc1f99": { + "event": "runner_on_ok", + "host": "192.168.121.245", + "task": "Gathering Facts" + }, + "6-aad3acc4-06a3-4c97-82ff-31e9e484b1f5": { + "event": "runner_on_ok", + "host": "192.168.121.61", + "task": "Gathering Facts" + }, + "7-55298017-3e7d-4734-b316-bbe13ce1da5e": { + "event": "runner_on_ok", + "host": "192.168.121.254", + "task": "Gathering Facts" + }, + "8-2016b900-e38f-7dcd-a2e7-00000000000a": { + "event": "playbook_on_task_start", + "task": "setup" + }, + "9-2085ccb6-e337-4b9f-bc38-1d8bbf9b973f": { + "event": "runner_on_ok", + "host": "192.168.121.254", + "task": "setup" + }, + "10-e14cdbbc-4883-436c-a41c-a8194ec69075": { + "event": "runner_on_ok", + "host": "192.168.121.245", + "task": "setup" + }, + "11-6d815a26-df53-4240-b8b6-2484e88e4f48": { + "event": "runner_on_ok", + "host": "192.168.121.61", + "task": "setup" + }, + "12-2016b900-e38f-7dcd-a2e7-00000000000b": { + "event": "playbook_on_task_start", + "task": "Get a list of block devices (excludes loop and child devices)" + }, + "13-799b0119-ccab-4eca-b30b-a37b0bafa02c": { + "event": "runner_on_ok", + "host": "192.168.121.245", + "task": "Get a list of block devices (excludes loop and child devices)" + }, + "14-6beb6958-4bfd-4a9c-bd2c-d20d00248605": { + "event": "runner_on_ok", + "host": "192.168.121.61", + "task": "Get a list of block devices (excludes loop and child devices)" + }, + "15-3ca99cc8-98ea-4967-8f2d-115426d00b6a": { + "event": "runner_on_ok", + "host": "192.168.121.254", + "task": "Get a list of block devices (excludes loop and child devices)" + }, + "16-2016b900-e38f-7dcd-a2e7-00000000000c": { + "event": "playbook_on_task_start", + "task": "check if disk {{ item }} is free" + }, + "17-8c88141a-08d1-411f-a855-9f7702a49c4e": { + "event": "runner_item_on_failed", + "host": "192.168.121.245", + "task": "check if disk vda is free" + }, + "18-4457db98-6f18-4f63-bfaa-584db5eea05b": { + "event": "runner_on_failed", + "host": "192.168.121.245", + "task": "check if disk {{ item }} is free" + }, + "19-ac3c72cd-1fbb-495a-be69-53fa6029f356": { + "event": "runner_item_on_failed", + "host": "192.168.121.61", + "task": "check if disk vda is free" + }, + "20-d161cb70-ba2e-4571-b029-c6428a566fef": { + "event": "runner_on_failed", + "host": "192.168.121.61", + "task": "check if disk {{ item }} is free" + }, + "21-65f1ce5c-2d86-4cc3-8e10-cff6bf6cbd82": { + "event": "runner_item_on_failed", + "host": "192.168.121.254", + "task": "check if disk sda is free" + }, + "22-7f86dcd4-4ef7-4f5a-9db3-c3780b67cc4b": { + "event": "runner_item_on_failed", + "host": "192.168.121.254", + "task": "check if disk sdb is free" + }, + "23-837bf4f6-a912-46a8-b94b-55aa66a935c4": { + "event": "runner_item_on_ok", + "host": "192.168.121.254", + "task": "check if disk sdc is free" + }, + "24-adf6238d-723f-4783-9226-8475419d466e": { + "event": "runner_item_on_failed", + "host": "192.168.121.254", + "task": "check if disk vda is free" + }, + "25-554661d8-bc34-4885-a589-4960d6b8a487": { + "event": "runner_on_failed", + "host": "192.168.121.254", + "task": "check if disk {{ item }} is free" + }, + "26-2016b900-e38f-7dcd-a2e7-00000000000d": { + "event": "playbook_on_task_start", + "task": "Update hosts freedisk list" + }, + "27-52df484c-30a0-4e3b-9057-02ca345c5790": { + "event": "runner_item_on_skipped", + "host": "192.168.121.254", + "task": "Update hosts freedisk list" + }, + "28-083616ad-3c1f-4fb8-a06c-5d64e670e362": { + "event": "runner_item_on_skipped", + "host": "192.168.121.254", + "task": "Update hosts freedisk list" + }, + "29-bffc68d3-5448-491f-8780-07858285f5cd": { + "event": "runner_item_on_skipped", + "host": "192.168.121.245", + "task": "Update hosts freedisk list" + }, + "30-cca2dfd9-16e9-4fcb-8bf7-c4da7dab5668": { + "event": "runner_on_skipped", + "host": "192.168.121.245", + "task": "Update hosts freedisk list" + }, + "31-158a98ac-7e8d-4ebb-8c53-4467351a2d3a": { + "event": "runner_item_on_ok", + "host": "192.168.121.254", + "task": "Update hosts freedisk list" + }, + "32-06a7e809-8d82-41df-b01d-45d94e519cb7": { + "event": "runner_item_on_skipped", + "host": "192.168.121.254", + "task": "Update hosts freedisk list" + }, + "33-d5cdbb58-728a-4be5-abf1-4a051146e727": { + "event": "runner_item_on_skipped", + "host": "192.168.121.61", + "task": "Update hosts freedisk list" + }, + "34-9b3c570b-22d8-4539-8c94-d0c1cbed8633": { + "event": "runner_on_ok", + "host": "192.168.121.254", + "task": "Update hosts freedisk list" + }, + "35-93336830-03cd-43ff-be87-a7e063ca7547": { + "event": "runner_on_skipped", + "host": "192.168.121.61", + "task": "Update hosts freedisk list" + }, + "36-2016b900-e38f-7dcd-a2e7-00000000000e": { + "event": "playbook_on_task_start", + "task": "RESULTS" + }, + "37-100564f1-9fed-48c2-bd62-4ae8636dfcdb": { + "event": "runner_on_ok", + "host": "192.168.121.254", + "task": "RESULTS" + }, + "38-20a64160-30a1-481f-a3ee-36e491bc7869": { + "event": "playbook_on_stats" + } + }, + "total_events": 37 + } +} + diff --git a/src/pybind/mgr/ansible/tests/test_client_playbooks.py b/src/pybind/mgr/ansible/tests/test_client_playbooks.py new file mode 100644 index 00000000..98dfd3dd --- /dev/null +++ b/src/pybind/mgr/ansible/tests/test_client_playbooks.py @@ -0,0 +1,287 @@ +import logging +import unittest +import mock +import json + +import requests_mock + +from requests.exceptions import ConnectionError + +from ..ansible_runner_svc import Client, PlayBookExecution, ExecutionStatusCode, \ + LOGIN_URL, API_URL, PLAYBOOK_EXEC_URL, \ + PLAYBOOK_EVENTS, AnsibleRunnerServiceError + + +SERVER_URL = "ars:5001" +USER = "admin" +PASSWORD = "admin" +CERTIFICATE = "" + +# Playbook attributes +PB_NAME = "test_playbook" +PB_UUID = "1733c3ac" + +# Playbook execution data file +PB_EVENTS_FILE = "./tests/pb_execution_events.data" + +# create console handler and set level to info +logger = logging.getLogger() +handler = logging.StreamHandler() +handler.setLevel(logging.INFO) +formatter = logging.Formatter("%(levelname)s - %(message)s") +handler.setFormatter(formatter) +logger.addHandler(handler) + + +def mock_login(mock_server): + + the_login_url = "https://%s/%s" % (SERVER_URL,LOGIN_URL) + + mock_server.register_uri("GET", + the_login_url, + json={"status": "OK", + "msg": "Token returned", + "data": {"token": "dummy_token"}}, + status_code=200) + + the_api_url = "https://%s/%s" % (SERVER_URL,API_URL) + mock_server.register_uri("GET", + the_api_url, + text="api", + status_code=200) + +def mock_get_pb(mock_server, playbook_name, return_code): + + mock_login(mock_server) + + ars_client = Client(SERVER_URL, USER, PASSWORD, + CERTIFICATE, logger) + + the_pb_url = "https://%s/%s/%s" % (SERVER_URL, PLAYBOOK_EXEC_URL, playbook_name) + + if return_code == 404: + mock_server.register_uri("POST", + the_pb_url, + json={ "status": "NOTFOUND", + "msg": "playbook file not found", + "data": {}}, + status_code=return_code) + elif return_code == 202: + mock_server.register_uri("POST", + the_pb_url, + json={ "status": "STARTED", + "msg": "starting", + "data": { "play_uuid": "1733c3ac" }}, + status_code=return_code) + + return PlayBookExecution(ars_client, playbook_name, logger, + result_pattern = "RESULTS") + +class ARSclientTest(unittest.TestCase): + + def test_server_not_reachable(self): + + with self.assertRaises(AnsibleRunnerServiceError): + ars_client = Client(SERVER_URL, USER, PASSWORD, + CERTIFICATE, logger) + + def test_server_wrong_USER(self): + + with requests_mock.Mocker() as mock_server: + the_login_url = "https://%s/%s" % (SERVER_URL,LOGIN_URL) + mock_server.get(the_login_url, + json={"status": "NOAUTH", + "msg": "Access denied invalid login: unknown USER", + "data": {}}, + status_code=401) + + + ars_client = Client(SERVER_URL, USER, PASSWORD, + CERTIFICATE, logger) + + self.assertFalse(ars_client.is_operative(), + "Operative attribute expected to be False") + + def test_server_connection_ok(self): + + with requests_mock.Mocker() as mock_server: + + mock_login(mock_server) + + ars_client = Client(SERVER_URL, USER, PASSWORD, + CERTIFICATE, logger) + + self.assertTrue(ars_client.is_operative(), + "Operative attribute expected to be True") + + def test_server_http_delete(self): + + with requests_mock.Mocker() as mock_server: + + mock_login(mock_server) + + ars_client = Client(SERVER_URL, USER, PASSWORD, + CERTIFICATE, logger) + + url = "https://%s/test" % (SERVER_URL) + mock_server.register_uri("DELETE", + url, + json={ "status": "OK", + "msg": "", + "data": {}}, + status_code=201) + + response = ars_client.http_delete("test") + self.assertTrue(response.status_code == 201) + +class PlayBookExecutionTests(unittest.TestCase): + + + def test_playbook_execution_ok(self): + """Check playbook id is set when the playbook is launched + """ + with requests_mock.Mocker() as mock_server: + + test_pb = mock_get_pb(mock_server, PB_NAME, 202) + + test_pb.launch() + + self.assertEqual(test_pb.play_uuid, PB_UUID, + "Found Unexpected playbook uuid") + + + + def test_playbook_execution_error(self): + """Check playbook id is not set when the playbook is not present + """ + + with requests_mock.Mocker() as mock_server: + + test_pb = mock_get_pb(mock_server, "unknown_playbook", 404) + + with self.assertRaises(AnsibleRunnerServiceError): + test_pb.launch() + + #self.assertEqual(test_pb.play_uuid, "", + # "Playbook uuid not empty") + + def test_playbook_not_launched(self): + """Check right status code when Playbook execution has not been launched + """ + + with requests_mock.Mocker() as mock_server: + + test_pb = mock_get_pb(mock_server, PB_NAME, 202) + + # Check playbook not launched + self.assertEqual(test_pb.get_status(), + ExecutionStatusCode.NOT_LAUNCHED, + "Wrong status code for playbook not launched") + + def test_playbook_launched(self): + """Check right status code when Playbook execution has been launched + """ + + with requests_mock.Mocker() as mock_server: + + test_pb = mock_get_pb(mock_server, PB_NAME, 202) + + test_pb.launch() + + the_status_url = "https://%s/%s/%s" % (SERVER_URL, + PLAYBOOK_EXEC_URL, + PB_UUID) + mock_server.register_uri("GET", + the_status_url, + json={"status": "OK", + "msg": "running", + "data": {"task": "Step 2", + "last_task_num": 6} + }, + status_code=200) + + self.assertEqual(test_pb.get_status(), + ExecutionStatusCode.ON_GOING, + "Wrong status code for a running playbook") + + self.assertEqual(test_pb.play_uuid, PB_UUID, + "Unexpected playbook uuid") + + def test_playbook_finish_ok(self): + """Check right status code when Playbook execution is succesful + """ + with requests_mock.Mocker() as mock_server: + + test_pb = mock_get_pb(mock_server, PB_NAME, 202) + + test_pb.launch() + + the_status_url = "https://%s/%s/%s" % (SERVER_URL, + PLAYBOOK_EXEC_URL, + PB_UUID) + mock_server.register_uri("GET", + the_status_url, + json={"status": "OK", + "msg": "successful", + "data": {} + }, + status_code=200) + + self.assertEqual(test_pb.get_status(), + ExecutionStatusCode.SUCCESS, + "Wrong status code for a playbook executed succesfully") + + def test_playbook_finish_error(self): + """Check right status code when Playbook execution has failed + """ + with requests_mock.Mocker() as mock_server: + + test_pb = mock_get_pb(mock_server, PB_NAME, 202) + + test_pb.launch() + + the_status_url = "https://%s/%s/%s" % (SERVER_URL, + PLAYBOOK_EXEC_URL, + PB_UUID) + mock_server.register_uri("GET", + the_status_url, + json={"status": "OK", + "msg": "failed", + "data": {} + }, + status_code=200) + + self.assertEqual(test_pb.get_status(), + ExecutionStatusCode.ERROR, + "Wrong status code for a playbook with error") + + def test_playbook_get_result(self): + """ Find the right result event in a set of different events + """ + with requests_mock.Mocker() as mock_server: + + test_pb = mock_get_pb(mock_server, PB_NAME, 202) + + test_pb.launch() + + the_events_url = "https://%s/%s" % (SERVER_URL, + PLAYBOOK_EVENTS % PB_UUID) + + # Get the events stored in a file + pb_events = {} + with open(PB_EVENTS_FILE) as events_file: + pb_events = json.loads(events_file.read()) + + mock_server.register_uri("GET", + the_events_url, + json=pb_events, + status_code=200) + + result = test_pb.get_result("runner_on_ok") + + self.assertEqual(len(result.keys()), 1, + "Unique result event not found") + + self.assertIn("37-100564f1-9fed-48c2-bd62-4ae8636dfcdb", + result.keys(), + "Predefined result event not found") diff --git a/src/pybind/mgr/ansible/tests/test_output_wizards.py b/src/pybind/mgr/ansible/tests/test_output_wizards.py new file mode 100644 index 00000000..2a3a9017 --- /dev/null +++ b/src/pybind/mgr/ansible/tests/test_output_wizards.py @@ -0,0 +1,207 @@ +""" Test output wizards +""" +import unittest +import mock + +from ..ansible_runner_svc import EVENT_DATA_URL +from ..output_wizards import ProcessHostsList, ProcessPlaybookResult, \ + ProcessInventory + +class OutputWizardProcessHostsList(unittest.TestCase): + """Test ProcessHostsList Output Wizard + """ + RESULT_OK = """ + { + "status": "OK", + "msg": "", + "data": { + "hosts": [ + "host_a", + "host_b", + "host_c" + ] + } + } + """ + ar_client = mock.Mock() + logger = mock.Mock() + test_wizard = ProcessHostsList(ar_client, logger) + + def test_process(self): + """Test a normal call""" + + nodes_list = self.test_wizard.process("", self.RESULT_OK) + self.assertEqual([node.name for node in nodes_list], + ["host_a", "host_b", "host_c"]) + + def test_errors(self): + """Test different kind of errors processing result""" + + # Malformed json + host_list = self.test_wizard.process("", """{"msg": """"") + self.assertEqual(host_list, []) + + # key error + host_list = self.test_wizard.process("", """{"msg": ""}""") + self.assertEqual(host_list, []) + + # Hosts not in iterable + host_list = self.test_wizard.process("", """{"data":{"hosts": 123} }""") + self.assertEqual(host_list, []) + +class OutputWizardProcessPlaybookResult(unittest.TestCase): + """Test ProcessPlaybookResult Output Wizard + """ + # Input to process + INVENTORY_EVENTS = {1:"first event", 2:"second event"} + EVENT_INFORMATION = "event information\n" + + # Mocked response + mocked_response = mock.Mock() + mocked_response.text = EVENT_INFORMATION + + # The Ansible Runner Service client + ar_client = mock.Mock() + ar_client.http_get = mock.MagicMock(return_value=mocked_response) + + logger = mock.Mock() + + test_wizard = ProcessPlaybookResult(ar_client, logger) + + def test_process(self): + """Test a normal call + """ + + operation_id = 24 + result = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS) + + # Check http request are correct and compose expected result + expected_result = "" + for key, dummy_data in self.INVENTORY_EVENTS.items(): + http_request = EVENT_DATA_URL % (operation_id, key) + self.ar_client.http_get.assert_any_call(http_request) + expected_result += self.EVENT_INFORMATION + + #Check result + self.assertEqual(result, expected_result) + +class OutputWizardProcessInventory(unittest.TestCase): + """Test ProcessInventory Output Wizard + """ + # Input to process + INVENTORY_EVENTS = {'event_uuid_1': {'host': '192.168.121.144', + 'task': 'list storage inventory', + 'event': 'runner_on_ok'}} + EVENT_DATA = r""" + { + "status": "OK", + "msg": "", + "data": { + "uuid": "5e96d509-174d-4f5f-bd94-e278c3a5b85b", + "counter": 11, + "stdout": "changed: [192.168.121.144]", + "start_line": 17, + "end_line": 18, + "runner_ident": "6e98b2ba-3ce1-11e9-be81-2016b900e38f", + "created": "2019-03-02T11:50:56.582112", + "pid": 482, + "event_data": { + "play_pattern": "osds", + "play": "query each host for storage device inventory", + "task": "list storage inventory", + "task_args": "_ansible_version=2.6.5, _ansible_selinux_special_fs=['fuse', 'nfs', 'vboxsf', 'ramfs', '9p'], _ansible_no_log=False, _ansible_module_name=ceph_volume, _ansible_debug=False, _ansible_verbosity=0, _ansible_keep_remote_files=False, _ansible_syslog_facility=LOG_USER, _ansible_socket=None, action=inventory, _ansible_diff=False, _ansible_remote_tmp=~/.ansible/tmp, _ansible_shell_executable=/bin/sh, _ansible_check_mode=False, _ansible_tmpdir=None", + "remote_addr": "192.168.121.144", + "res": { + "_ansible_parsed": true, + "stderr_lines": [], + "changed": true, + "end": "2019-03-02 11:50:56.554937", + "_ansible_no_log": false, + "stdout": "[{\"available\": true, \"rejected_reasons\": [], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 0, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdc\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [], \"path\": \"/dev/sdc\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sda\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-dcf8a88c-5546-42d2-afa4-b36f7fb23b66\", \"osd_id\": \"3\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"fVqujC-9dgh-cN9W-1XD4-zVx1-1UdA-fUS3ha\", \"osd_fsid\": \"8b7cbeba-5e86-44ff-a5f3-2e7df77753fe\"}], \"path\": \"/dev/sda\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdb\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-8c92e986-bd97-4b3d-ba77-2cb88e15d80f\", \"osd_id\": \"1\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"mgzO7O-vUfu-H3mf-4R3K-2f97-ZMRH-SngBFP\", \"osd_fsid\": \"6d067688-3e1b-45f9-ad03-8abd19e9f117\"}], \"path\": \"/dev/sdb\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"mq-deadline\", \"rotational\": \"1\", \"vendor\": \"0x1af4\", \"human_readable_size\": \"41.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {\"vda1\": {\"start\": \"2048\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2048\", \"size\": \"1024.00 KB\"}, \"vda3\": {\"start\": \"2101248\", \"holders\": [\"dm-0\", \"dm-1\"], \"sectorsize\": 512, \"sectors\": \"81784832\", \"size\": \"39.00 GB\"}, \"vda2\": {\"start\": \"4096\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2097152\", \"size\": \"1024.00 MB\"}}, \"rev\": \"\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/vda\", \"support_discard\": \"\", \"model\": \"\", \"ro\": \"0\", \"nr_requests\": \"256\", \"size\": 44023414784.0}, \"lvs\": [{\"comment\": \"not used by ceph\", \"name\": \"LogVol00\"}, {\"comment\": \"not used by ceph\", \"name\": \"LogVol01\"}], \"path\": \"/dev/vda\"}]", + "cmd": [ + "ceph-volume", + "inventory", + "--format=json" + ], + "rc": 0, + "start": "2019-03-02 11:50:55.150121", + "stderr": "", + "delta": "0:00:01.404816", + "invocation": { + "module_args": { + "wal_vg": null, + "wal": null, + "dmcrypt": false, + "block_db_size": "-1", + "journal": null, + "objectstore": "bluestore", + "db": null, + "batch_devices": [], + "db_vg": null, + "journal_vg": null, + "cluster": "ceph", + "osds_per_device": 1, + "containerized": "False", + "crush_device_class": null, + "report": false, + "data_vg": null, + "data": null, + "action": "inventory", + "journal_size": "5120" + } + }, + "stdout_lines": [ + "[{\"available\": true, \"rejected_reasons\": [], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 0, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdc\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [], \"path\": \"/dev/sdc\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sda\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-dcf8a88c-5546-42d2-afa4-b36f7fb23b66\", \"osd_id\": \"3\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"fVqujC-9dgh-cN9W-1XD4-zVx1-1UdA-fUS3ha\", \"osd_fsid\": \"8b7cbeba-5e86-44ff-a5f3-2e7df77753fe\"}], \"path\": \"/dev/sda\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdb\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-8c92e986-bd97-4b3d-ba77-2cb88e15d80f\", \"osd_id\": \"1\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"mgzO7O-vUfu-H3mf-4R3K-2f97-ZMRH-SngBFP\", \"osd_fsid\": \"6d067688-3e1b-45f9-ad03-8abd19e9f117\"}], \"path\": \"/dev/sdb\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"mq-deadline\", \"rotational\": \"1\", \"vendor\": \"0x1af4\", \"human_readable_size\": \"41.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {\"vda1\": {\"start\": \"2048\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2048\", \"size\": \"1024.00 KB\"}, \"vda3\": {\"start\": \"2101248\", \"holders\": [\"dm-0\", \"dm-1\"], \"sectorsize\": 512, \"sectors\": \"81784832\", \"size\": \"39.00 GB\"}, \"vda2\": {\"start\": \"4096\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2097152\", \"size\": \"1024.00 MB\"}}, \"rev\": \"\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/vda\", \"support_discard\": \"\", \"model\": \"\", \"ro\": \"0\", \"nr_requests\": \"256\", \"size\": 44023414784.0}, \"lvs\": [{\"comment\": \"not used by ceph\", \"name\": \"LogVol00\"}, {\"comment\": \"not used by ceph\", \"name\": \"LogVol01\"}], \"path\": \"/dev/vda\"}]" + ] + }, + "pid": 482, + "play_uuid": "2016b900-e38f-0e09-19be-00000000000c", + "task_uuid": "2016b900-e38f-0e09-19be-000000000012", + "event_loop": null, + "playbook_uuid": "e80e66f2-4a78-4a96-aaf6-fbe473f11312", + "playbook": "storage-inventory.yml", + "task_action": "ceph_volume", + "host": "192.168.121.144", + "task_path": "/usr/share/ansible-runner-service/project/storage-inventory.yml:29" + }, + "event": "runner_on_ok" + } + } + """ + + # Mocked response + mocked_response = mock.Mock() + mocked_response.text = EVENT_DATA + + # The Ansible Runner Service client + ar_client = mock.Mock() + ar_client.http_get = mock.MagicMock(return_value=mocked_response) + + logger = mock.Mock() + + test_wizard = ProcessInventory(ar_client, logger) + + def test_process(self): + """Test a normal call + """ + operation_id = 12 + nodes_list = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS) + + for key, dummy_data in self.INVENTORY_EVENTS.items(): + http_request = EVENT_DATA_URL % (operation_id, key) + self.ar_client.http_get.assert_any_call(http_request) + + + # Only one host + self.assertTrue(len(nodes_list), 1) + + # Host retrieved OK + self.assertEqual(nodes_list[0].name, "192.168.121.144") + + # Devices + self.assertTrue(len(nodes_list[0].devices), 4) + + expected_device_ids = ["/dev/sdc", "/dev/sda", "/dev/sdb", "/dev/vda"] + device_ids = [dev.id for dev in nodes_list[0].devices] + + self.assertEqual(expected_device_ids, device_ids) diff --git a/src/pybind/mgr/ansible/tox.ini b/src/pybind/mgr/ansible/tox.ini new file mode 100644 index 00000000..ae9888a6 --- /dev/null +++ b/src/pybind/mgr/ansible/tox.ini @@ -0,0 +1,18 @@ +[tox] +envlist = py27,py3 +skipsdist = true +toxworkdir = {env:CEPH_BUILD_DIR}/ansible +minversion = 2.8.1 + +[testenv] +deps = + pytest + mock + requests-mock +setenv= + UNITTEST = true + py27: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.2 + py3: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.3 + +commands= + {envbindir}/py.test tests/ diff --git a/src/pybind/mgr/balancer/__init__.py b/src/pybind/mgr/balancer/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/balancer/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/balancer/module.py b/src/pybind/mgr/balancer/module.py new file mode 100644 index 00000000..acca915d --- /dev/null +++ b/src/pybind/mgr/balancer/module.py @@ -0,0 +1,1324 @@ +""" +Balance PG distribution across OSDs. +""" + +import copy +import errno +import json +import math +import random +import six +import time +from mgr_module import MgrModule, CommandResult +from threading import Event +from mgr_module import CRUSHMap +import datetime + +TIME_FORMAT = '%Y-%m-%d_%H:%M:%S' + +class MappingState: + def __init__(self, osdmap, raw_pg_stats, raw_pool_stats, desc=''): + self.desc = desc + self.osdmap = osdmap + self.osdmap_dump = self.osdmap.dump() + self.crush = osdmap.get_crush() + self.crush_dump = self.crush.dump() + self.raw_pg_stats = raw_pg_stats + self.raw_pool_stats = raw_pool_stats + self.pg_stat = { + i['pgid']: i['stat_sum'] for i in raw_pg_stats.get('pg_stats', []) + } + osd_poolids = [p['pool'] for p in self.osdmap_dump.get('pools', [])] + pg_poolids = [p['poolid'] for p in raw_pool_stats.get('pool_stats', [])] + self.poolids = set(osd_poolids) & set(pg_poolids) + self.pg_up = {} + self.pg_up_by_poolid = {} + for poolid in self.poolids: + self.pg_up_by_poolid[poolid] = osdmap.map_pool_pgs_up(poolid) + for a,b in six.iteritems(self.pg_up_by_poolid[poolid]): + self.pg_up[a] = b + + def calc_misplaced_from(self, other_ms): + num = len(other_ms.pg_up) + misplaced = 0 + for pgid, before in six.iteritems(other_ms.pg_up): + if before != self.pg_up.get(pgid, []): + misplaced += 1 + if num > 0: + return float(misplaced) / float(num) + return 0.0 + +class Plan: + def __init__(self, name, ms, pools): + self.mode = 'unknown' + self.name = name + self.initial = ms + self.pools = pools + + self.osd_weights = {} + self.compat_ws = {} + self.inc = ms.osdmap.new_incremental() + + def final_state(self): + self.inc.set_osd_reweights(self.osd_weights) + self.inc.set_crush_compat_weight_set_weights(self.compat_ws) + return MappingState(self.initial.osdmap.apply_incremental(self.inc), + self.initial.raw_pg_stats, + self.initial.raw_pool_stats, + 'plan %s final' % self.name) + + def dump(self): + return json.dumps(self.inc.dump(), indent=4) + + def show(self): + ls = [] + ls.append('# starting osdmap epoch %d' % self.initial.osdmap.get_epoch()) + ls.append('# starting crush version %d' % + self.initial.osdmap.get_crush_version()) + ls.append('# mode %s' % self.mode) + if len(self.compat_ws) and \ + not CRUSHMap.have_default_choose_args(self.initial.crush_dump): + ls.append('ceph osd crush weight-set create-compat') + for osd, weight in six.iteritems(self.compat_ws): + ls.append('ceph osd crush weight-set reweight-compat %s %f' % + (osd, weight)) + for osd, weight in six.iteritems(self.osd_weights): + ls.append('ceph osd reweight osd.%d %f' % (osd, weight)) + incdump = self.inc.dump() + for pgid in incdump.get('old_pg_upmap_items', []): + ls.append('ceph osd rm-pg-upmap-items %s' % pgid) + for item in incdump.get('new_pg_upmap_items', []): + osdlist = [] + for m in item['mappings']: + osdlist += [m['from'], m['to']] + ls.append('ceph osd pg-upmap-items %s %s' % + (item['pgid'], ' '.join([str(a) for a in osdlist]))) + return '\n'.join(ls) + + +class Eval: + def __init__(self, ms): + self.ms = ms + self.root_ids = {} # root name -> id + self.pool_name = {} # pool id -> pool name + self.pool_id = {} # pool name -> id + self.pool_roots = {} # pool name -> root name + self.root_pools = {} # root name -> pools + self.target_by_root = {} # root name -> target weight map + self.count_by_pool = {} + self.count_by_root = {} + self.actual_by_pool = {} # pool -> by_* -> actual weight map + self.actual_by_root = {} # pool -> by_* -> actual weight map + self.total_by_pool = {} # pool -> by_* -> total + self.total_by_root = {} # root -> by_* -> total + self.stats_by_pool = {} # pool -> by_* -> stddev or avg -> value + self.stats_by_root = {} # root -> by_* -> stddev or avg -> value + + self.score_by_pool = {} + self.score_by_root = {} + + self.score = 0.0 + + def show(self, verbose=False): + if verbose: + r = self.ms.desc + '\n' + r += 'target_by_root %s\n' % self.target_by_root + r += 'actual_by_pool %s\n' % self.actual_by_pool + r += 'actual_by_root %s\n' % self.actual_by_root + r += 'count_by_pool %s\n' % self.count_by_pool + r += 'count_by_root %s\n' % self.count_by_root + r += 'total_by_pool %s\n' % self.total_by_pool + r += 'total_by_root %s\n' % self.total_by_root + r += 'stats_by_root %s\n' % self.stats_by_root + r += 'score_by_pool %s\n' % self.score_by_pool + r += 'score_by_root %s\n' % self.score_by_root + else: + r = self.ms.desc + ' ' + r += 'score %f (lower is better)\n' % self.score + return r + + def calc_stats(self, count, target, total): + num = max(len(target), 1) + r = {} + for t in ('pgs', 'objects', 'bytes'): + if total[t] == 0: + r[t] = { + 'avg': 0, + 'stddev': 0, + 'sum_weight': 0, + 'score': 0, + } + continue + + avg = float(total[t]) / float(num) + dev = 0.0 + + # score is a measure of how uneven the data distribution is. + # score lies between [0, 1), 0 means perfect distribution. + score = 0.0 + sum_weight = 0.0 + + for k, v in six.iteritems(count[t]): + # adjust/normalize by weight + if target[k]: + adjusted = float(v) / target[k] / float(num) + else: + adjusted = 0.0 + + # Overweighted devices and their weights are factors to calculate reweight_urgency. + # One 10% underfilled device with 5 2% overfilled devices, is arguably a better + # situation than one 10% overfilled with 5 2% underfilled devices + if adjusted > avg: + ''' + F(x) = 2*phi(x) - 1, where phi(x) = cdf of standard normal distribution + x = (adjusted - avg)/avg. + Since, we're considering only over-weighted devices, x >= 0, and so phi(x) lies in [0.5, 1). + To bring range of F(x) in range [0, 1), we need to make the above modification. + + In general, we need to use a function F(x), where x = (adjusted - avg)/avg + 1. which is bounded between 0 and 1, so that ultimately reweight_urgency will also be bounded. + 2. A larger value of x, should imply more urgency to reweight. + 3. Also, the difference between F(x) when x is large, should be minimal. + 4. The value of F(x) should get close to 1 (highest urgency to reweight) with steeply. + + Could have used F(x) = (1 - e^(-x)). But that had slower convergence to 1, compared to the one currently in use. + + cdf of standard normal distribution: https://stackoverflow.com/a/29273201 + ''' + score += target[k] * (math.erf(((adjusted - avg)/avg) / math.sqrt(2.0))) + sum_weight += target[k] + dev += (avg - adjusted) * (avg - adjusted) + stddev = math.sqrt(dev / float(max(num - 1, 1))) + score = score / max(sum_weight, 1) + r[t] = { + 'avg': avg, + 'stddev': stddev, + 'sum_weight': sum_weight, + 'score': score, + } + return r + +class Module(MgrModule): + MODULE_OPTIONS = [ + { + 'name': 'active', + 'type': 'bool', + 'default': False, + 'desc': 'automatically balance PGs across cluster', + 'runtime': True, + }, + { + 'name': 'begin_time', + 'type': 'str', + 'default': '0000', + 'desc': 'beginning time of day to automatically balance', + 'long_desc': 'This is a time of day in the format HHMM.', + 'runtime': True, + }, + { + 'name': 'end_time', + 'type': 'str', + 'default': '2400', + 'desc': 'ending time of day to automatically balance', + 'long_desc': 'This is a time of day in the format HHMM.', + 'runtime': True, + }, + { + 'name': 'begin_weekday', + 'type': 'uint', + 'default': 0, + 'min': 0, + 'max': 7, + 'desc': 'Restrict automatic balancing to this day of the week or later', + 'long_desc': '0 or 7 = Sunday, 1 = Monday, etc.', + 'runtime': True, + }, + { + 'name': 'end_weekday', + 'type': 'uint', + 'default': 7, + 'min': 0, + 'max': 7, + 'desc': 'Restrict automatic balancing to days of the week earlier than this', + 'long_desc': '0 or 7 = Sunday, 1 = Monday, etc.', + 'runtime': True, + }, + { + 'name': 'crush_compat_max_iterations', + 'type': 'uint', + 'default': 25, + 'min': 1, + 'max': 250, + 'desc': 'maximum number of iterations to attempt optimization', + 'runtime': True, + }, + { + 'name': 'crush_compat_metrics', + 'type': 'str', + 'default': 'pgs,objects,bytes', + 'desc': 'metrics with which to calculate OSD utilization', + 'long_desc': 'Value is a list of one or more of "pgs", "objects", or "bytes", and indicates which metrics to use to balance utilization.', + 'runtime': True, + }, + { + 'name': 'crush_compat_step', + 'type': 'float', + 'default': .5, + 'min': .001, + 'max': .999, + 'desc': 'aggressiveness of optimization', + 'long_desc': '.99 is very aggressive, .01 is less aggressive', + 'runtime': True, + }, + { + 'name': 'min_score', + 'type': 'float', + 'default': 0, + 'desc': 'minimum score, below which no optimization is attempted', + 'runtime': True, + }, + { + 'name': 'mode', + 'desc': 'Balancer mode', + 'default': 'none', + 'enum_allowed': ['none', 'crush-compat', 'upmap'], + 'runtime': True, + }, + { + 'name': 'sleep_interval', + 'type': 'secs', + 'default': 60, + 'desc': 'how frequently to wake up and attempt optimization', + 'runtime': True, + }, + { + 'name': 'upmap_max_iterations', + 'type': 'uint', + 'default': 10, + 'desc': 'maximum upmap optimization iterations', + 'runtime': True, + }, + { + 'name': 'upmap_max_deviation', + 'type': 'int', + 'default': 5, + 'min': 1, + 'desc': 'deviation below which no optimization is attempted', + 'long_desc': 'If the number of PGs are within this count then no optimization is attempted', + 'runtime': True, + }, + { + 'name': 'pool_ids', + 'type': 'str', + 'default': '', + 'desc': 'pools which the automatic balancing will be limited to', + 'runtime': True, + }, + ] + + COMMANDS = [ + { + "cmd": "balancer status", + "desc": "Show balancer status", + "perm": "r", + }, + { + "cmd": "balancer mode name=mode,type=CephChoices,strings=none|crush-compat|upmap", + "desc": "Set balancer mode", + "perm": "rw", + }, + { + "cmd": "balancer on", + "desc": "Enable automatic balancing", + "perm": "rw", + }, + { + "cmd": "balancer off", + "desc": "Disable automatic balancing", + "perm": "rw", + }, + { + "cmd": "balancer pool ls", + "desc": "List automatic balancing pools. " + "Note that empty list means all existing pools will be automatic balancing targets, " + "which is the default behaviour of balancer.", + "perm": "r", + }, + { + "cmd": "balancer pool add name=pools,type=CephString,n=N", + "desc": "Enable automatic balancing for specific pools", + "perm": "rw", + }, + { + "cmd": "balancer pool rm name=pools,type=CephString,n=N", + "desc": "Disable automatic balancing for specific pools", + "perm": "rw", + }, + { + "cmd": "balancer eval name=option,type=CephString,req=false", + "desc": "Evaluate data distribution for the current cluster or specific pool or specific plan", + "perm": "r", + }, + { + "cmd": "balancer eval-verbose name=option,type=CephString,req=false", + "desc": "Evaluate data distribution for the current cluster or specific pool or specific plan (verbosely)", + "perm": "r", + }, + { + "cmd": "balancer optimize name=plan,type=CephString name=pools,type=CephString,n=N,req=false", + "desc": "Run optimizer to create a new plan", + "perm": "rw", + }, + { + "cmd": "balancer show name=plan,type=CephString", + "desc": "Show details of an optimization plan", + "perm": "r", + }, + { + "cmd": "balancer rm name=plan,type=CephString", + "desc": "Discard an optimization plan", + "perm": "rw", + }, + { + "cmd": "balancer reset", + "desc": "Discard all optimization plans", + "perm": "rw", + }, + { + "cmd": "balancer dump name=plan,type=CephString", + "desc": "Show an optimization plan", + "perm": "r", + }, + { + "cmd": "balancer ls", + "desc": "List all plans", + "perm": "r", + }, + { + "cmd": "balancer execute name=plan,type=CephString", + "desc": "Execute an optimization plan", + "perm": "rw", + }, + ] + active = False + run = True + plans = {} + mode = '' + optimizing = False + last_optimize_started = '' + last_optimize_duration = '' + optimize_result = '' + success_string = 'Optimization plan created successfully' + in_progress_string = 'in progress' + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.event = Event() + + def handle_command(self, inbuf, command): + self.log.warn("Handling command: '%s'" % str(command)) + if command['prefix'] == 'balancer status': + s = { + 'plans': list(self.plans.keys()), + 'active': self.active, + 'last_optimize_started': self.last_optimize_started, + 'last_optimize_duration': self.last_optimize_duration, + 'optimize_result': self.optimize_result, + 'mode': self.get_module_option('mode'), + } + return (0, json.dumps(s, indent=4), '') + elif command['prefix'] == 'balancer mode': + if command['mode'] == 'upmap': + min_compat_client = self.get_osdmap().dump().get('require_min_compat_client', '') + if min_compat_client < 'luminous': # works well because version is alphabetized.. + warn = 'min_compat_client "%s" ' \ + '< "luminous", which is required for pg-upmap. ' \ + 'Try "ceph osd set-require-min-compat-client luminous" ' \ + 'before enabling this mode' % min_compat_client + return (-errno.EPERM, '', warn) + elif command['mode'] == 'crush-compat': + ms = MappingState(self.get_osdmap(), + self.get("pg_stats"), + self.get("pool_stats"), + 'initialize compat weight-set') + self.get_compat_weight_set_weights(ms) # ignore error + self.set_module_option('mode', command['mode']) + return (0, '', '') + elif command['prefix'] == 'balancer on': + if not self.active: + self.set_module_option('active', 'true') + self.active = True + self.event.set() + return (0, '', '') + elif command['prefix'] == 'balancer off': + if self.active: + self.set_module_option('active', 'false') + self.active = False + self.event.set() + return (0, '', '') + elif command['prefix'] == 'balancer pool ls': + pool_ids = self.get_module_option('pool_ids') + if pool_ids == '': + return (0, '', '') + pool_ids = pool_ids.split(',') + pool_ids = [int(p) for p in pool_ids] + pool_name_by_id = dict((p['pool'], p['pool_name']) for p in self.get_osdmap().dump().get('pools', [])) + should_prune = False + final_ids = [] + final_names = [] + for p in pool_ids: + if p in pool_name_by_id: + final_ids.append(p) + final_names.append(pool_name_by_id[p]) + else: + should_prune = True + if should_prune: # some pools were gone, prune + self.set_module_option('pool_ids', ','.join(final_ids)) + return (0, json.dumps(final_names, indent=4), '') + elif command['prefix'] == 'balancer pool add': + raw_names = command['pools'] + pool_id_by_name = dict((p['pool_name'], p['pool']) for p in self.get_osdmap().dump().get('pools', [])) + invalid_names = [p for p in raw_names if p not in pool_id_by_name] + if invalid_names: + return (-errno.EINVAL, '', 'pool(s) %s not found' % invalid_names) + to_add = [str(pool_id_by_name[p]) for p in raw_names if p in pool_id_by_name] + existing = self.get_module_option('pool_ids') + final = to_add + if existing != '': + existing = existing.split(',') + final = set(to_add) | set(existing) + self.set_module_option('pool_ids', ','.join(final)) + return (0, '', '') + elif command['prefix'] == 'balancer pool rm': + raw_names = command['pools'] + existing = self.get_module_option('pool_ids') + if existing == '': # for idempotence + return (0, '', '') + existing = existing.split(',') + osdmap = self.get_osdmap() + pool_ids = [str(p['pool']) for p in osdmap.dump().get('pools', [])] + pool_id_by_name = dict((p['pool_name'], p['pool']) for p in osdmap.dump().get('pools', [])) + final = [p for p in existing if p in pool_ids] + to_delete = [str(pool_id_by_name[p]) for p in raw_names if p in pool_id_by_name] + final = set(final) - set(to_delete) + self.set_module_option('pool_ids', ','.join(final)) + return (0, '', '') + elif command['prefix'] == 'balancer eval' or command['prefix'] == 'balancer eval-verbose': + verbose = command['prefix'] == 'balancer eval-verbose' + pools = [] + if 'option' in command: + plan = self.plans.get(command['option']) + if not plan: + # not a plan, does it look like a pool? + osdmap = self.get_osdmap() + valid_pool_names = [p['pool_name'] for p in osdmap.dump().get('pools', [])] + option = command['option'] + if option not in valid_pool_names: + return (-errno.EINVAL, '', 'option "%s" not a plan or a pool' % option) + pools.append(option) + ms = MappingState(osdmap, self.get("pg_stats"), self.get("pool_stats"), 'pool "%s"' % option) + else: + pools = plan.pools + ms = plan.final_state() + else: + ms = MappingState(self.get_osdmap(), + self.get("pg_stats"), + self.get("pool_stats"), + 'current cluster') + return (0, self.evaluate(ms, pools, verbose=verbose), '') + elif command['prefix'] == 'balancer optimize': + # The GIL can be release by the active balancer, so disallow when active + if self.active: + return (-errno.EINVAL, '', 'Balancer enabled, disable to optimize manually') + if self.optimizing: + return (-errno.EINVAL, '', 'Balancer finishing up....try again') + pools = [] + if 'pools' in command: + pools = command['pools'] + osdmap = self.get_osdmap() + valid_pool_names = [p['pool_name'] for p in osdmap.dump().get('pools', [])] + invalid_pool_names = [] + for p in pools: + if p not in valid_pool_names: + invalid_pool_names.append(p) + if len(invalid_pool_names): + return (-errno.EINVAL, '', 'pools %s not found' % invalid_pool_names) + plan = self.plan_create(command['plan'], osdmap, pools) + self.last_optimize_started = time.asctime(time.localtime()) + self.optimize_result = self.in_progress_string + start = time.time() + r, detail = self.optimize(plan) + end = time.time() + self.last_optimize_duration = str(datetime.timedelta(seconds=(end - start))) + if r == 0: + # Add plan if an optimization was created + self.optimize_result = self.success_string + self.plans[command['plan']] = plan + else: + self.optimize_result = detail + return (r, '', detail) + elif command['prefix'] == 'balancer rm': + self.plan_rm(command['plan']) + return (0, '', '') + elif command['prefix'] == 'balancer reset': + self.plans = {} + return (0, '', '') + elif command['prefix'] == 'balancer ls': + return (0, json.dumps([p for p in self.plans], indent=4), '') + elif command['prefix'] == 'balancer dump': + plan = self.plans.get(command['plan']) + if not plan: + return (-errno.ENOENT, '', 'plan %s not found' % command['plan']) + return (0, plan.dump(), '') + elif command['prefix'] == 'balancer show': + plan = self.plans.get(command['plan']) + if not plan: + return (-errno.ENOENT, '', 'plan %s not found' % command['plan']) + return (0, plan.show(), '') + elif command['prefix'] == 'balancer execute': + # The GIL can be release by the active balancer, so disallow when active + if self.active: + return (-errno.EINVAL, '', 'Balancer enabled, disable to execute a plan') + if self.optimizing: + return (-errno.EINVAL, '', 'Balancer finishing up....try again') + plan = self.plans.get(command['plan']) + if not plan: + return (-errno.ENOENT, '', 'plan %s not found' % command['plan']) + r, detail = self.execute(plan) + self.plan_rm(command['plan']) + return (r, '', detail) + else: + return (-errno.EINVAL, '', + "Command not found '{0}'".format(command['prefix'])) + + def shutdown(self): + self.log.info('Stopping') + self.run = False + self.event.set() + + def time_permit(self): + local_time = time.localtime() + time_of_day = time.strftime('%H%M', local_time) + weekday = (local_time.tm_wday + 1) % 7 # be compatible with C + permit = False + + begin_time = self.get_module_option('begin_time') + end_time = self.get_module_option('end_time') + if begin_time <= end_time: + permit = begin_time <= time_of_day < end_time + else: + permit = time_of_day >= begin_time or time_of_day < end_time + if not permit: + self.log.debug("should run between %s - %s, now %s, skipping", + begin_time, end_time, time_of_day) + return False + + begin_weekday = self.get_module_option('begin_weekday') + end_weekday = self.get_module_option('end_weekday') + if begin_weekday <= end_weekday: + permit = begin_weekday <= weekday < end_weekday + else: + permit = weekday >= begin_weekday or weekday < end_weekday + if not permit: + self.log.debug("should run between weekday %d - %d, now %d, skipping", + begin_weekday, end_weekday, weekday) + return False + + return True + + def serve(self): + self.log.info('Starting') + while self.run: + self.active = self.get_module_option('active') + sleep_interval = self.get_module_option('sleep_interval') + self.log.debug('Waking up [%s, now %s]', + "active" if self.active else "inactive", + time.strftime(TIME_FORMAT, time.localtime())) + if self.active and self.time_permit(): + self.log.debug('Running') + name = 'auto_%s' % time.strftime(TIME_FORMAT, time.gmtime()) + osdmap = self.get_osdmap() + allow = self.get_module_option('pool_ids') + final = [] + if allow != '': + allow = allow.split(',') + valid = [str(p['pool']) for p in osdmap.dump().get('pools', [])] + final = set(allow) & set(valid) + if set(allow) - set(valid): # some pools were gone, prune + self.set_module_option('pool_ids', ','.join(final)) + pool_name_by_id = dict((p['pool'], p['pool_name']) for p in osdmap.dump().get('pools', [])) + final = [int(p) for p in final] + final = [pool_name_by_id[p] for p in final if p in pool_name_by_id] + plan = self.plan_create(name, osdmap, final) + self.optimizing = True + self.last_optimize_started = time.asctime(time.localtime()) + self.optimize_result = self.in_progress_string + start = time.time() + r, detail = self.optimize(plan) + end = time.time() + self.last_optimize_duration = str(datetime.timedelta(seconds=(end - start))) + if r == 0: + self.optimize_result = self.success_string + self.execute(plan) + else: + self.optimize_result = detail + self.optimizing = False + self.log.debug('Sleeping for %d', sleep_interval) + self.event.wait(sleep_interval) + self.event.clear() + + def plan_create(self, name, osdmap, pools): + plan = Plan(name, + MappingState(osdmap, + self.get("pg_stats"), + self.get("pool_stats"), + 'plan %s initial' % name), + pools) + return plan + + def plan_rm(self, name): + if name in self.plans: + del self.plans[name] + + def calc_eval(self, ms, pools): + pe = Eval(ms) + pool_rule = {} + pool_info = {} + for p in ms.osdmap_dump.get('pools',[]): + if len(pools) and p['pool_name'] not in pools: + continue + # skip dead or not-yet-ready pools too + if p['pool'] not in ms.poolids: + continue + pe.pool_name[p['pool']] = p['pool_name'] + pe.pool_id[p['pool_name']] = p['pool'] + pool_rule[p['pool_name']] = p['crush_rule'] + pe.pool_roots[p['pool_name']] = [] + pool_info[p['pool_name']] = p + if len(pool_info) == 0: + return pe + self.log.debug('pool_name %s' % pe.pool_name) + self.log.debug('pool_id %s' % pe.pool_id) + self.log.debug('pools %s' % pools) + self.log.debug('pool_rule %s' % pool_rule) + + osd_weight = { a['osd']: a['weight'] + for a in ms.osdmap_dump.get('osds',[]) if a['weight'] > 0 } + + # get expected distributions by root + actual_by_root = {} + rootids = ms.crush.find_takes() + roots = [] + for rootid in rootids: + ls = ms.osdmap.get_pools_by_take(rootid) + want = [] + # find out roots associating with pools we are passed in + for candidate in ls: + if candidate in pe.pool_name: + want.append(candidate) + if len(want) == 0: + continue + root = ms.crush.get_item_name(rootid) + pe.root_pools[root] = [] + for poolid in want: + pe.pool_roots[pe.pool_name[poolid]].append(root) + pe.root_pools[root].append(pe.pool_name[poolid]) + pe.root_ids[root] = rootid + roots.append(root) + weight_map = ms.crush.get_take_weight_osd_map(rootid) + adjusted_map = { + osd: cw * osd_weight[osd] + for osd,cw in six.iteritems(weight_map) if osd in osd_weight and cw > 0 + } + sum_w = sum(adjusted_map.values()) + assert len(adjusted_map) == 0 or sum_w > 0 + pe.target_by_root[root] = { osd: w / sum_w + for osd,w in six.iteritems(adjusted_map) } + actual_by_root[root] = { + 'pgs': {}, + 'objects': {}, + 'bytes': {}, + } + for osd in pe.target_by_root[root]: + actual_by_root[root]['pgs'][osd] = 0 + actual_by_root[root]['objects'][osd] = 0 + actual_by_root[root]['bytes'][osd] = 0 + pe.total_by_root[root] = { + 'pgs': 0, + 'objects': 0, + 'bytes': 0, + } + self.log.debug('pool_roots %s' % pe.pool_roots) + self.log.debug('root_pools %s' % pe.root_pools) + self.log.debug('target_by_root %s' % pe.target_by_root) + + # pool and root actual + for pool, pi in six.iteritems(pool_info): + poolid = pi['pool'] + pm = ms.pg_up_by_poolid[poolid] + pgs = 0 + objects = 0 + bytes = 0 + pgs_by_osd = {} + objects_by_osd = {} + bytes_by_osd = {} + for pgid, up in six.iteritems(pm): + for osd in [int(osd) for osd in up]: + if osd == CRUSHMap.ITEM_NONE: + continue + if osd not in pgs_by_osd: + pgs_by_osd[osd] = 0 + objects_by_osd[osd] = 0 + bytes_by_osd[osd] = 0 + pgs_by_osd[osd] += 1 + objects_by_osd[osd] += ms.pg_stat[pgid]['num_objects'] + bytes_by_osd[osd] += ms.pg_stat[pgid]['num_bytes'] + # pick a root to associate this pg instance with. + # note that this is imprecise if the roots have + # overlapping children. + # FIXME: divide bytes by k for EC pools. + for root in pe.pool_roots[pool]: + if osd in pe.target_by_root[root]: + actual_by_root[root]['pgs'][osd] += 1 + actual_by_root[root]['objects'][osd] += ms.pg_stat[pgid]['num_objects'] + actual_by_root[root]['bytes'][osd] += ms.pg_stat[pgid]['num_bytes'] + pgs += 1 + objects += ms.pg_stat[pgid]['num_objects'] + bytes += ms.pg_stat[pgid]['num_bytes'] + pe.total_by_root[root]['pgs'] += 1 + pe.total_by_root[root]['objects'] += ms.pg_stat[pgid]['num_objects'] + pe.total_by_root[root]['bytes'] += ms.pg_stat[pgid]['num_bytes'] + break + pe.count_by_pool[pool] = { + 'pgs': { + k: v + for k, v in six.iteritems(pgs_by_osd) + }, + 'objects': { + k: v + for k, v in six.iteritems(objects_by_osd) + }, + 'bytes': { + k: v + for k, v in six.iteritems(bytes_by_osd) + }, + } + pe.actual_by_pool[pool] = { + 'pgs': { + k: float(v) / float(max(pgs, 1)) + for k, v in six.iteritems(pgs_by_osd) + }, + 'objects': { + k: float(v) / float(max(objects, 1)) + for k, v in six.iteritems(objects_by_osd) + }, + 'bytes': { + k: float(v) / float(max(bytes, 1)) + for k, v in six.iteritems(bytes_by_osd) + }, + } + pe.total_by_pool[pool] = { + 'pgs': pgs, + 'objects': objects, + 'bytes': bytes, + } + for root in pe.total_by_root: + pe.count_by_root[root] = { + 'pgs': { + k: float(v) + for k, v in six.iteritems(actual_by_root[root]['pgs']) + }, + 'objects': { + k: float(v) + for k, v in six.iteritems(actual_by_root[root]['objects']) + }, + 'bytes': { + k: float(v) + for k, v in six.iteritems(actual_by_root[root]['bytes']) + }, + } + pe.actual_by_root[root] = { + 'pgs': { + k: float(v) / float(max(pe.total_by_root[root]['pgs'], 1)) + for k, v in six.iteritems(actual_by_root[root]['pgs']) + }, + 'objects': { + k: float(v) / float(max(pe.total_by_root[root]['objects'], 1)) + for k, v in six.iteritems(actual_by_root[root]['objects']) + }, + 'bytes': { + k: float(v) / float(max(pe.total_by_root[root]['bytes'], 1)) + for k, v in six.iteritems(actual_by_root[root]['bytes']) + }, + } + self.log.debug('actual_by_pool %s' % pe.actual_by_pool) + self.log.debug('actual_by_root %s' % pe.actual_by_root) + + # average and stddev and score + pe.stats_by_root = { + a: pe.calc_stats( + b, + pe.target_by_root[a], + pe.total_by_root[a] + ) for a, b in six.iteritems(pe.count_by_root) + } + self.log.debug('stats_by_root %s' % pe.stats_by_root) + + # the scores are already normalized + pe.score_by_root = { + r: { + 'pgs': pe.stats_by_root[r]['pgs']['score'], + 'objects': pe.stats_by_root[r]['objects']['score'], + 'bytes': pe.stats_by_root[r]['bytes']['score'], + } for r in pe.total_by_root.keys() + } + self.log.debug('score_by_root %s' % pe.score_by_root) + + # get the list of score metrics, comma separated + metrics = self.get_module_option('crush_compat_metrics').split(',') + + # total score is just average of normalized stddevs + pe.score = 0.0 + for r, vs in six.iteritems(pe.score_by_root): + for k, v in six.iteritems(vs): + if k in metrics: + pe.score += v + pe.score /= len(metrics) * len(roots) + return pe + + def evaluate(self, ms, pools, verbose=False): + pe = self.calc_eval(ms, pools) + return pe.show(verbose=verbose) + + def optimize(self, plan): + self.log.info('Optimize plan %s' % plan.name) + plan.mode = self.get_module_option('mode') + max_misplaced = float(self.get_ceph_option('target_max_misplaced_ratio')) + self.log.info('Mode %s, max misplaced %f' % + (plan.mode, max_misplaced)) + + info = self.get('pg_status') + unknown = info.get('unknown_pgs_ratio', 0.0) + degraded = info.get('degraded_ratio', 0.0) + inactive = info.get('inactive_pgs_ratio', 0.0) + misplaced = info.get('misplaced_ratio', 0.0) + self.log.debug('unknown %f degraded %f inactive %f misplaced %g', + unknown, degraded, inactive, misplaced) + if unknown > 0.0: + detail = 'Some PGs (%f) are unknown; try again later' % unknown + self.log.info(detail) + return -errno.EAGAIN, detail + elif degraded > 0.0: + detail = 'Some objects (%f) are degraded; try again later' % degraded + self.log.info(detail) + return -errno.EAGAIN, detail + elif inactive > 0.0: + detail = 'Some PGs (%f) are inactive; try again later' % inactive + self.log.info(detail) + return -errno.EAGAIN, detail + elif misplaced >= max_misplaced: + detail = 'Too many objects (%f > %f) are misplaced; ' \ + 'try again later' % (misplaced, max_misplaced) + self.log.info(detail) + return -errno.EAGAIN, detail + else: + if plan.mode == 'upmap': + return self.do_upmap(plan) + elif plan.mode == 'crush-compat': + return self.do_crush_compat(plan) + elif plan.mode == 'none': + detail = 'Please do "ceph balancer mode" to choose a valid mode first' + self.log.info('Idle') + return -errno.ENOEXEC, detail + else: + detail = 'Unrecognized mode %s' % plan.mode + self.log.info(detail) + return -errno.EINVAL, detail + ## + + def do_upmap(self, plan): + self.log.info('do_upmap') + max_iterations = self.get_module_option('upmap_max_iterations') + max_deviation = self.get_module_option('upmap_max_deviation') + + ms = plan.initial + if len(plan.pools): + pools = plan.pools + else: # all + pools = [str(i['pool_name']) for i in ms.osdmap_dump.get('pools',[])] + if len(pools) == 0: + detail = 'No pools available' + self.log.info(detail) + return -errno.ENOENT, detail + # shuffle pool list so they all get equal (in)attention + random.shuffle(pools) + self.log.info('pools %s' % pools) + + adjusted_pools = [] + inc = plan.inc + total_did = 0 + left = max_iterations + osdmap_dump = self.get_osdmap().dump() + pools_with_pg_merge = [p['pool_name'] for p in osdmap_dump.get('pools', []) + if p['pg_num'] > p['pg_num_target']] + crush_rule_by_pool_name = dict((p['pool_name'], p['crush_rule']) for p in osdmap_dump.get('pools', [])) + for pool in pools: + if pool not in crush_rule_by_pool_name: + self.log.info('pool %s does not exist' % pool) + continue + if pool in pools_with_pg_merge: + self.log.info('pool %s has pending PG(s) for merging, skipping for now' % pool) + continue + adjusted_pools.append(pool) + # shuffle so all pools get equal (in)attention + random.shuffle(adjusted_pools) + for pool in adjusted_pools: + did = ms.osdmap.calc_pg_upmaps(inc, max_deviation, left, [pool]) + total_did += did + left -= did + if left <= 0: + break + self.log.info('prepared %d/%d changes' % (total_did, max_iterations)) + if total_did == 0: + return -errno.EALREADY, 'Unable to find further optimization, ' \ + 'or pool(s) pg_num is decreasing, ' \ + 'or distribution is already perfect' + return 0, '' + + def do_crush_compat(self, plan): + self.log.info('do_crush_compat') + max_iterations = self.get_module_option('crush_compat_max_iterations') + if max_iterations < 1: + return -errno.EINVAL, '"crush_compat_max_iterations" must be >= 1' + step = self.get_module_option('crush_compat_step') + if step <= 0 or step >= 1.0: + return -errno.EINVAL, '"crush_compat_step" must be in (0, 1)' + max_misplaced = float(self.get_ceph_option('target_max_misplaced_ratio')) + min_pg_per_osd = 2 + + ms = plan.initial + osdmap = ms.osdmap + crush = osdmap.get_crush() + pe = self.calc_eval(ms, plan.pools) + min_score_to_optimize = self.get_module_option('min_score') + if pe.score <= min_score_to_optimize: + if pe.score == 0: + detail = 'Distribution is already perfect' + else: + detail = 'score %f <= min_score %f, will not optimize' \ + % (pe.score, min_score_to_optimize) + self.log.info(detail) + return -errno.EALREADY, detail + + # get current osd reweights + orig_osd_weight = { a['osd']: a['weight'] + for a in ms.osdmap_dump.get('osds',[]) } + reweighted_osds = [ a for a,b in six.iteritems(orig_osd_weight) + if b < 1.0 and b > 0.0 ] + + # get current compat weight-set weights + orig_ws = self.get_compat_weight_set_weights(ms) + if not orig_ws: + return -errno.EAGAIN, 'compat weight-set not available' + orig_ws = { a: b for a, b in six.iteritems(orig_ws) if a >= 0 } + + # Make sure roots don't overlap their devices. If so, we + # can't proceed. + roots = list(pe.target_by_root.keys()) + self.log.debug('roots %s', roots) + visited = {} + overlap = {} + root_ids = {} + for root, wm in six.iteritems(pe.target_by_root): + for osd in wm: + if osd in visited: + if osd not in overlap: + overlap[osd] = [ visited[osd] ] + overlap[osd].append(root) + visited[osd] = root + if len(overlap) > 0: + detail = 'Some osds belong to multiple subtrees: %s' % \ + overlap + self.log.error(detail) + return -errno.EOPNOTSUPP, detail + + # rebalance by pgs, objects, or bytes + metrics = self.get_module_option('crush_compat_metrics').split(',') + key = metrics[0] # balancing using the first score metric + if key not in ['pgs', 'bytes', 'objects']: + self.log.warn("Invalid crush_compat balancing key %s. Using 'pgs'." % key) + key = 'pgs' + + # go + best_ws = copy.deepcopy(orig_ws) + best_ow = copy.deepcopy(orig_osd_weight) + best_pe = pe + left = max_iterations + bad_steps = 0 + next_ws = copy.deepcopy(best_ws) + next_ow = copy.deepcopy(best_ow) + while left > 0: + # adjust + self.log.debug('best_ws %s' % best_ws) + random.shuffle(roots) + for root in roots: + pools = best_pe.root_pools[root] + osds = len(best_pe.target_by_root[root]) + min_pgs = osds * min_pg_per_osd + if best_pe.total_by_root[root][key] < min_pgs: + self.log.info('Skipping root %s (pools %s), total pgs %d ' + '< minimum %d (%d per osd)', + root, pools, + best_pe.total_by_root[root][key], + min_pgs, min_pg_per_osd) + continue + self.log.info('Balancing root %s (pools %s) by %s' % + (root, pools, key)) + target = best_pe.target_by_root[root] + actual = best_pe.actual_by_root[root][key] + queue = sorted(actual.keys(), + key=lambda osd: -abs(target[osd] - actual[osd])) + for osd in queue: + if orig_osd_weight[osd] == 0: + self.log.debug('skipping out osd.%d', osd) + else: + deviation = target[osd] - actual[osd] + if deviation == 0: + break + self.log.debug('osd.%d deviation %f', osd, deviation) + weight = best_ws[osd] + ow = orig_osd_weight[osd] + if actual[osd] > 0: + calc_weight = target[osd] / actual[osd] * weight * ow + else: + # for newly created osds, reset calc_weight at target value + # this way weight-set will end up absorbing *step* of its + # target (final) value at the very beginning and slowly catch up later. + # note that if this turns out causing too many misplaced + # pgs, then we'll reduce step and retry + calc_weight = target[osd] + new_weight = weight * (1.0 - step) + calc_weight * step + self.log.debug('Reweight osd.%d %f -> %f', osd, weight, + new_weight) + next_ws[osd] = new_weight + if ow < 1.0: + new_ow = min(1.0, max(step + (1.0 - step) * ow, + ow + .005)) + self.log.debug('Reweight osd.%d reweight %f -> %f', + osd, ow, new_ow) + next_ow[osd] = new_ow + + # normalize weights under this root + root_weight = crush.get_item_weight(pe.root_ids[root]) + root_sum = sum(b for a,b in six.iteritems(next_ws) + if a in target.keys()) + if root_sum > 0 and root_weight > 0: + factor = root_sum / root_weight + self.log.debug('normalizing root %s %d, weight %f, ' + 'ws sum %f, factor %f', + root, pe.root_ids[root], root_weight, + root_sum, factor) + for osd in actual.keys(): + next_ws[osd] = next_ws[osd] / factor + + # recalc + plan.compat_ws = copy.deepcopy(next_ws) + next_ms = plan.final_state() + next_pe = self.calc_eval(next_ms, plan.pools) + next_misplaced = next_ms.calc_misplaced_from(ms) + self.log.debug('Step result score %f -> %f, misplacing %f', + best_pe.score, next_pe.score, next_misplaced) + + if next_misplaced > max_misplaced: + if best_pe.score < pe.score: + self.log.debug('Step misplaced %f > max %f, stopping', + next_misplaced, max_misplaced) + break + step /= 2.0 + next_ws = copy.deepcopy(best_ws) + next_ow = copy.deepcopy(best_ow) + self.log.debug('Step misplaced %f > max %f, reducing step to %f', + next_misplaced, max_misplaced, step) + else: + if next_pe.score > best_pe.score * 1.0001: + bad_steps += 1 + if bad_steps < 5 and random.randint(0, 100) < 70: + self.log.debug('Score got worse, taking another step') + else: + step /= 2.0 + next_ws = copy.deepcopy(best_ws) + next_ow = copy.deepcopy(best_ow) + self.log.debug('Score got worse, trying smaller step %f', + step) + else: + bad_steps = 0 + best_pe = next_pe + best_ws = copy.deepcopy(next_ws) + best_ow = copy.deepcopy(next_ow) + if best_pe.score == 0: + break + left -= 1 + + # allow a small regression if we are phasing out osd weights + fudge = 0 + if best_ow != orig_osd_weight: + fudge = .001 + + if best_pe.score < pe.score + fudge: + self.log.info('Success, score %f -> %f', pe.score, best_pe.score) + plan.compat_ws = best_ws + for osd, w in six.iteritems(best_ow): + if w != orig_osd_weight[osd]: + self.log.debug('osd.%d reweight %f', osd, w) + plan.osd_weights[osd] = w + return 0, '' + else: + self.log.info('Failed to find further optimization, score %f', + pe.score) + plan.compat_ws = {} + return -errno.EDOM, 'Unable to find further optimization, ' \ + 'change balancer mode and retry might help' + + def get_compat_weight_set_weights(self, ms): + if not CRUSHMap.have_default_choose_args(ms.crush_dump): + # enable compat weight-set first + self.log.debug('ceph osd crush weight-set create-compat') + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd crush weight-set create-compat', + 'format': 'json', + }), '') + r, outb, outs = result.wait() + if r != 0: + self.log.error('Error creating compat weight-set') + return + + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd crush dump', + 'format': 'json', + }), '') + r, outb, outs = result.wait() + if r != 0: + self.log.error('Error dumping crush map') + return + try: + crushmap = json.loads(outb) + except: + raise RuntimeError('unable to parse crush map') + else: + crushmap = ms.crush_dump + + raw = CRUSHMap.get_default_choose_args(crushmap) + weight_set = {} + for b in raw: + bucket = None + for t in crushmap['buckets']: + if t['id'] == b['bucket_id']: + bucket = t + break + if not bucket: + raise RuntimeError('could not find bucket %s' % b['bucket_id']) + self.log.debug('bucket items %s' % bucket['items']) + self.log.debug('weight set %s' % b['weight_set'][0]) + if len(bucket['items']) != len(b['weight_set'][0]): + raise RuntimeError('weight-set size does not match bucket items') + for pos in range(len(bucket['items'])): + weight_set[bucket['items'][pos]['id']] = b['weight_set'][0][pos] + + self.log.debug('weight_set weights %s' % weight_set) + return weight_set + + def do_crush(self): + self.log.info('do_crush (not yet implemented)') + + def do_osd_weight(self): + self.log.info('do_osd_weight (not yet implemented)') + + def execute(self, plan): + self.log.info('Executing plan %s' % plan.name) + + commands = [] + + # compat weight-set + if len(plan.compat_ws) and \ + not CRUSHMap.have_default_choose_args(plan.initial.crush_dump): + self.log.debug('ceph osd crush weight-set create-compat') + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd crush weight-set create-compat', + 'format': 'json', + }), '') + r, outb, outs = result.wait() + if r != 0: + self.log.error('Error creating compat weight-set') + return r, outs + + for osd, weight in six.iteritems(plan.compat_ws): + self.log.info('ceph osd crush weight-set reweight-compat osd.%d %f', + osd, weight) + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd crush weight-set reweight-compat', + 'format': 'json', + 'item': 'osd.%d' % osd, + 'weight': [weight], + }), '') + commands.append(result) + + # new_weight + reweightn = {} + for osd, weight in six.iteritems(plan.osd_weights): + reweightn[str(osd)] = str(int(weight * float(0x10000))) + if len(reweightn): + self.log.info('ceph osd reweightn %s', reweightn) + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd reweightn', + 'format': 'json', + 'weights': json.dumps(reweightn), + }), '') + commands.append(result) + + # upmap + incdump = plan.inc.dump() + for pgid in incdump.get('old_pg_upmap_items', []): + self.log.info('ceph osd rm-pg-upmap-items %s', pgid) + result = CommandResult('foo') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd rm-pg-upmap-items', + 'format': 'json', + 'pgid': pgid, + }), 'foo') + commands.append(result) + + for item in incdump.get('new_pg_upmap_items', []): + self.log.info('ceph osd pg-upmap-items %s mappings %s', item['pgid'], + item['mappings']) + osdlist = [] + for m in item['mappings']: + osdlist += [m['from'], m['to']] + result = CommandResult('foo') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd pg-upmap-items', + 'format': 'json', + 'pgid': item['pgid'], + 'id': osdlist, + }), 'foo') + commands.append(result) + + # wait for commands + self.log.debug('commands %s' % commands) + for result in commands: + r, outb, outs = result.wait() + if r != 0: + self.log.error('execute error: r = %d, detail = %s' % (r, outs)) + return r, outs + self.log.debug('done') + return 0, '' + + def gather_telemetry(self): + return { + 'active': self.active, + 'mode': self.mode, + } diff --git a/src/pybind/mgr/crash/__init__.py b/src/pybind/mgr/crash/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/crash/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/crash/module.py b/src/pybind/mgr/crash/module.py new file mode 100644 index 00000000..b9cf4929 --- /dev/null +++ b/src/pybind/mgr/crash/module.py @@ -0,0 +1,369 @@ +from mgr_module import MgrModule +import datetime +import errno +import json +from collections import defaultdict +from prettytable import PrettyTable +from threading import Event, Lock + + +DATEFMT = '%Y-%m-%d %H:%M:%S.%f' + +MAX_WAIT = 600 +MIN_WAIT = 60 + +class Module(MgrModule): + MODULE_OPTIONS = [ + { + 'name': 'warn_recent_interval', + 'type': 'secs', + 'default': 60*60*24*14, + 'desc': 'time interval in which to warn about recent crashes', + 'runtime': True, + }, + { + 'name': 'retain_interval', + 'type': 'secs', + 'default': 60*60*24 * 365, + 'desc': 'how long to retain crashes before pruning them', + 'runtime': True, + }, + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.crashes = None + self.crashes_lock = Lock() + self.run = True + self.event = Event() + + def shutdown(self): + self.run = False + self.event.set() + + def serve(self): + self.config_notify() + while self.run: + with self.crashes_lock: + self._refresh_health_checks() + self._prune(self.retain_interval) + wait = min(MAX_WAIT, max(self.warn_recent_interval / 100, MIN_WAIT)) + self.event.wait(wait) + self.event.clear() + + def config_notify(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' mgr option %s = %s', + opt['name'], getattr(self, opt['name'])) + + def _load_crashes(self): + raw = self.get_store_prefix('crash/') + self.crashes = {k[6:]: json.loads(m) for (k, m) in raw.items()} + + def _refresh_health_checks(self): + if not self.crashes: + self._load_crashes() + cutoff = datetime.datetime.utcnow() - datetime.timedelta( + seconds=self.warn_recent_interval) + recent = { + crashid: crash for crashid, crash in self.crashes.items() + if self.time_from_string(crash['timestamp']) > cutoff and 'archived' not in crash + } + num = len(recent) + health_checks = {} + if recent: + detail = [ + '%s crashed on host %s at %s' % ( + crash.get('entity_name', 'unidentified daemon'), + crash.get('utsname_hostname', '(unknown)'), + crash.get('timestamp', 'unknown time')) + for (_, crash) in recent.items()] + if num > 30: + detail = detail[0:30] + detail.append('and %d more' % (num - 30)) + self.log.debug('detail %s' % detail) + health_checks['RECENT_CRASH'] = { + 'severity': 'warning', + 'summary': '%d daemons have recently crashed' % (num), + 'detail': detail, + } + self.set_health_checks(health_checks) + + def handle_command(self, inbuf, command): + with self.crashes_lock: + if not self.crashes: + self._load_crashes() + for cmd in self.COMMANDS: + if cmd['cmd'].startswith(command['prefix']): + handler = cmd['handler'] + break + if handler is None: + return errno.EINVAL, '', 'unknown command %s' % command['prefix'] + + return handler(self, command, inbuf) + + def time_from_string(self, timestr): + # drop the 'Z' timezone indication, it's always UTC + timestr = timestr.rstrip('Z') + return datetime.datetime.strptime(timestr, DATEFMT) + + def validate_crash_metadata(self, inbuf): + # raise any exceptions to caller + metadata = json.loads(inbuf) + for f in ['crash_id', 'timestamp']: + if f not in metadata: + raise AttributeError("missing '%s' field" % f) + time = self.time_from_string(metadata['timestamp']) + return metadata + + def timestamp_filter(self, f): + """ + Filter crash reports by timestamp. + + :param f: f(time) return true to keep crash report + :returns: crash reports for which f(time) returns true + """ + def inner(pair): + _, crash = pair + time = self.time_from_string(crash["timestamp"]) + return f(time) + return filter(inner, self.crashes.items()) + + # command handlers + + def do_info(self, cmd, inbuf): + crashid = cmd['id'] + crash = self.crashes.get(crashid) + if not crash: + return errno.EINVAL, '', 'crash info: %s not found' % crashid + val = json.dumps(crash, indent=4) + return 0, val, '' + + def do_post(self, cmd, inbuf): + try: + metadata = self.validate_crash_metadata(inbuf) + except Exception as e: + return errno.EINVAL, '', 'malformed crash metadata: %s' % e + crashid = metadata['crash_id'] + + if crashid not in self.crashes: + self.crashes[crashid] = metadata + key = 'crash/%s' % crashid + self.set_store(key, json.dumps(metadata)) + self._refresh_health_checks() + return 0, '', '' + + def ls(self): + if not self.crashes: + self._load_crashes() + return self.do_ls({'prefix': 'crash ls'}, '') + + def do_ls(self, cmd, inbuf): + if cmd['prefix'] == 'crash ls': + t = self.crashes.values() + else: + t = [crash for crashid, crash in self.crashes.items() + if 'archived' not in crash] + r = sorted(t, key=lambda i: i.get('crash_id')) + if cmd.get('format') == 'json' or cmd.get('format') == 'json-pretty': + return 0, json.dumps(r, indent=4), '' + else: + table = PrettyTable(['ID', 'ENTITY', 'NEW'], + border=False) + table.left_padding_width = 0 + table.right_padding_width = 1 + table.align['ID'] = 'l' + table.align['ENTITY'] = 'l' + for c in r: + table.add_row([c.get('crash_id'), + c.get('entity_name','unknown'), + '' if 'archived' in c else '*']) + return 0, table.get_string(), '' + + def do_rm(self, cmd, inbuf): + crashid = cmd['id'] + if crashid in self.crashes: + del self.crashes[crashid] + key = 'crash/%s' % crashid + self.set_store(key, None) # removes key + self._refresh_health_checks() + return 0, '', '' + + def do_prune(self, cmd, inbuf): + keep = cmd['keep'] + try: + keep = int(keep) + except ValueError: + return errno.EINVAL, '', 'keep argument must be integer' + + self._prune(keep * 60*60*24) + return 0, '', '' + + def _prune(self, seconds): + now = datetime.datetime.utcnow() + cutoff = now - datetime.timedelta(seconds=seconds) + removed_any = False + # make a copy of the list, since we'll modify self.crashes below + to_prune = list(self.timestamp_filter(lambda ts: ts <= cutoff)) + for crashid, crash in to_prune: + del self.crashes[crashid] + key = 'crash/%s' % crashid + self.set_store(key, None) + removed_any = True + if removed_any: + self._refresh_health_checks() + + def do_archive(self, cmd, inbuf): + crashid = cmd['id'] + crash = self.crashes.get(crashid) + if not crash: + return errno.EINVAL, '', 'crash info: %s not found' % crashid + if not crash.get('archived'): + crash['archived'] = str(datetime.datetime.utcnow()) + self.crashes[crashid] = crash + key = 'crash/%s' % crashid + self.set_store(key, json.dumps(crash)) + self._refresh_health_checks() + return 0, '', '' + + def do_archive_all(self, cmd, inbuf): + for crashid, crash in self.crashes.items(): + if not crash.get('archived'): + crash['archived'] = str(datetime.datetime.utcnow()) + self.crashes[crashid] = crash + key = 'crash/%s' % crashid + self.set_store(key, json.dumps(crash)) + self._refresh_health_checks() + return 0, '', '' + + def do_stat(self, cmd, inbuf): + # age in days for reporting, ordered smallest first + bins = [1, 3, 7] + retlines = list() + + def binstr(bindict): + binlines = list() + count = len(bindict['idlist']) + if count: + binlines.append( + '%d older than %s days old:' % (count, bindict['age']) + ) + for crashid in bindict['idlist']: + binlines.append(crashid) + return '\n'.join(binlines) + + total = 0 + now = datetime.datetime.utcnow() + for i, age in enumerate(bins): + agelimit = now - datetime.timedelta(days=age) + bins[i] = { + 'age': age, + 'agelimit': agelimit, + 'idlist': list() + } + + for crashid, crash in self.crashes.items(): + total += 1 + stamp = self.time_from_string(crash['timestamp']) + for i, bindict in enumerate(bins): + if stamp <= bindict['agelimit']: + bindict['idlist'].append(crashid) + # don't count this one again + continue + + retlines.append('%d crashes recorded' % total) + + for bindict in bins: + retlines.append(binstr(bindict)) + return 0, '\n'.join(retlines), '' + + def do_json_report(self, cmd, inbuf): + """ + Return a machine readable summary of recent crashes. + """ + try: + hours = int(cmd['hours']) + except ValueError: + return errno.EINVAL, '', ' argument must be integer' + + report = defaultdict(lambda: 0) + for crashid, crash in self.crashes.items(): + pname = crash.get("process_name", "unknown") + if not pname: + pname = "unknown" + report[pname] += 1 + + return 0, '', json.dumps(report) + + def self_test(self): + # test time conversion + timestr = '2018-06-22 20:35:38.058818Z' + dt = self.time_from_string(timestr) + if dt != datetime.datetime(2018, 6, 22, 20, 35, 38, 58818): + raise RuntimeError('time_from_string() failed') + + COMMANDS = [ + { + 'cmd': 'crash info name=id,type=CephString', + 'desc': 'show crash dump metadata', + 'perm': 'r', + 'handler': do_info, + }, + { + 'cmd': 'crash ls', + 'desc': 'Show new and archived crash dumps', + 'perm': 'r', + 'handler': do_ls, + }, + { + 'cmd': 'crash ls-new', + 'desc': 'Show new crash dumps', + 'perm': 'r', + 'handler': do_ls, + }, + { + 'cmd': 'crash post', + 'desc': 'Add a crash dump (use -i )', + 'perm': 'rw', + 'handler': do_post, + }, + { + 'cmd': 'crash prune name=keep,type=CephString', + 'desc': 'Remove crashes older than days', + 'perm': 'rw', + 'handler': do_prune, + }, + { + 'cmd': 'crash rm name=id,type=CephString', + 'desc': 'Remove a saved crash ', + 'perm': 'rw', + 'handler': do_rm, + }, + { + 'cmd': 'crash stat', + 'desc': 'Summarize recorded crashes', + 'perm': 'r', + 'handler': do_stat, + }, + { + 'cmd': 'crash json_report name=hours,type=CephString', + 'desc': 'Crashes in the last hours', + 'perm': 'r', + 'handler': do_json_report, + }, + { + 'cmd': 'crash archive name=id,type=CephString', + 'desc': 'Acknowledge a crash and silence health warning(s)', + 'perm': 'w', + 'handler': do_archive, + }, + { + 'cmd': 'crash archive-all', + 'desc': 'Acknowledge all new crashes and silence health warning(s)', + 'perm': 'w', + 'handler': do_archive_all, + }, + ] diff --git a/src/pybind/mgr/dashboard/.coveragerc b/src/pybind/mgr/dashboard/.coveragerc new file mode 100644 index 00000000..29a63192 --- /dev/null +++ b/src/pybind/mgr/dashboard/.coveragerc @@ -0,0 +1,7 @@ +[run] +omit = tests/* + */python*/* + ceph_module_mock.py + __init__.py + */mgr_module.py + diff --git a/src/pybind/mgr/dashboard/.editorconfig b/src/pybind/mgr/dashboard/.editorconfig new file mode 100644 index 00000000..a831e3da --- /dev/null +++ b/src/pybind/mgr/dashboard/.editorconfig @@ -0,0 +1,29 @@ +# EditorConfig helps developers define and maintain consistent coding styles +# between different editors and IDEs.: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Set default charset +[*.{js,py}] +charset = utf-8 + +# 4 space indentation for Python files +[*.py] +indent_style = space +indent_size = 4 + +# Indentation override for all JS under frontend directory +[frontend/**.js] +indent_style = space +indent_size = 2 + +# Indentation override for all HTML under frontend directory +[frontend/**.html] +indent_style = space +indent_size = 2 diff --git a/src/pybind/mgr/dashboard/.gitignore b/src/pybind/mgr/dashboard/.gitignore new file mode 100644 index 00000000..0e6f6149 --- /dev/null +++ b/src/pybind/mgr/dashboard/.gitignore @@ -0,0 +1,16 @@ +.coverage* +htmlcov +.tox +coverage.xml +junit*xml +.cache +ceph.conf +wheelhouse* + +# IDE +.vscode +*.egg +.env + +# virtualenv +venv diff --git a/src/pybind/mgr/dashboard/.pylintrc b/src/pybind/mgr/dashboard/.pylintrc new file mode 100644 index 00000000..d5a9d1f7 --- /dev/null +++ b/src/pybind/mgr/dashboard/.pylintrc @@ -0,0 +1,535 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist=rados,rbd,math,cephfs + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. +jobs=1 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=import-star-module-level, + raw-checker-failed, + bad-inline-option, + locally-disabled, + locally-enabled, + suppressed-message, + useless-suppression, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + missing-docstring, + invalid-name, + no-self-use, + too-few-public-methods, + no-member, + too-many-arguments, + too-many-locals, + too-many-statements, + useless-object-inheritance + + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio).You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=optparse.Values,sys.exit + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins + + +[BASIC] + +# Naming style matching correct argument names +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style +#argument-rgx= + +# Naming style matching correct attribute names +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style +#class-attribute-rgx= + +# Naming style matching correct class names +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming-style +#class-rgx= + +# Naming style matching correct constant names +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# Naming style matching correct inline iteration names +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style +#inlinevar-rgx= + +# Naming style matching correct method names +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style +#method-rgx= + +# Naming style matching correct module names +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style +#variable-rgx= + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules=cherrypy,distutils + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub, + TERMIOS, + Bastion, + rexec + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in a if statement +max-bool-expr=5 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of statements in function / method body +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff --git a/src/pybind/mgr/dashboard/CMakeLists.txt b/src/pybind/mgr/dashboard/CMakeLists.txt new file mode 100644 index 00000000..b6c78618 --- /dev/null +++ b/src/pybind/mgr/dashboard/CMakeLists.txt @@ -0,0 +1,133 @@ +set(MGR_DASHBOARD_VIRTUALENV ${CEPH_BUILD_VIRTUALENV}/mgr-dashboard-virtualenv) + +add_custom_target(mgr-dashboard-test-venv + COMMAND + ${CMAKE_SOURCE_DIR}/src/tools/setup-virtualenv.sh --python=${MGR_PYTHON_EXECUTABLE} ${MGR_DASHBOARD_VIRTUALENV} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard + COMMENT "dashboard tests virtualenv is being created") +add_dependencies(tests mgr-dashboard-test-venv) + +include(CMakeParseArguments) +function(add_npm_command) + set(options NODEENV) + set(single_kw OUTPUT COMMENT WORKING_DIRECTORY) + set(multi_kw COMMAND DEPENDS) + cmake_parse_arguments(NC "${options}" "${single_kw}" "${multi_kw}" ${ARGN}) + string(REPLACE ";" " " command "${NC_COMMAND}") + if(NC_NODEENV) + string(REGEX REPLACE "^(.*(npm|npx) .*)$" ". ${mgr-dashboard-nodeenv-dir}/bin/activate && \\1 && deactivate" command ${command}) + endif() + string(REPLACE " " ";" command "${command}") + add_custom_command( + OUTPUT "${NC_OUTPUT}" + COMMAND ${command} + DEPENDS ${NC_DEPENDS} + WORKING_DIRECTORY "${NC_WORKING_DIRECTORY}" + COMMENT ${NC_COMMENT}) +endfunction(add_npm_command) + +if(WITH_MGR_DASHBOARD_FRONTEND AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm|ARM") + +if(WITH_SYSTEM_NPM) + set(mgr-dashboard-nodeenv-dir ) + set(nodeenv "") + add_custom_target(mgr-dashboard-frontend-deps + DEPENDS frontend/node_modules + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend + ) +else() + set(mgr-dashboard-nodeenv-dir ${CMAKE_CURRENT_BINARY_DIR}/node-env) + set(nodeenv NODEENV) + + add_custom_command( + OUTPUT "${mgr-dashboard-nodeenv-dir}/bin/npm" + COMMAND ${CMAKE_SOURCE_DIR}/src/tools/setup-virtualenv.sh --python=${MGR_PYTHON_EXECUTABLE} ${mgr-dashboard-nodeenv-dir} + COMMAND ${mgr-dashboard-nodeenv-dir}/bin/pip install nodeenv + COMMAND ${mgr-dashboard-nodeenv-dir}/bin/nodeenv -p --node=10.13.0 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "dashboard nodeenv is being installed" + ) + add_custom_target(mgr-dashboard-nodeenv + DEPENDS ${mgr-dashboard-nodeenv-dir}/bin/npm + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + add_custom_target(mgr-dashboard-frontend-deps + DEPENDS frontend/node_modules mgr-dashboard-nodeenv + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend + ) +endif() + +add_npm_command( + OUTPUT "${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend/node_modules" + COMMAND npm ci + DEPENDS frontend/package.json + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend + COMMENT "dashboard frontend dependencies are being installed" + ${nodeenv} +) + +# Glob some frontend files. With CMake 3.6, this can be simplified +# to *.ts *.html. Just add: +# list(FILTER frontend_src INCLUDE REGEX "frontend/src") +file( + GLOB_RECURSE frontend_src + frontend/src/*.ts + frontend/src/*.html + frontend/src/*/*.ts + frontend/src/*/*.html + frontend/src/*/*/*.ts + frontend/src/*/*/*.html + frontend/src/*/*/*/*.ts + frontend/src/*/*/*/*.html + frontend/src/*/*/*/*/*.ts + frontend/src/*/*/*/*/*.html + frontend/src/*/*/*/*/*/*.ts + frontend/src/*/*/*/*/*/*.html) + +# these files are generated during build +list(REMOVE_ITEM frontend_src + ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend/src/environments/environment.prod.ts + ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend/src/environments/environment.ts) + +execute_process( + COMMAND bash -c "jq -r .config.locale ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend/package.json" + OUTPUT_VARIABLE default_lang + OUTPUT_STRIP_TRAILING_WHITESPACE) + +if(DASHBOARD_FRONTEND_LANGS) + string(STRIP "${DASHBOARD_FRONTEND_LANGS}" DASHBOARD_FRONTEND_LANGS) + if(DASHBOARD_FRONTEND_LANGS STREQUAL "ALL") + set(build_target ":*") + else() + string(FIND "${DASHBOARD_FRONTEND_LANGS}" "${default_lang}" default_idx) + if (default_idx EQUAL -1) + # default language must be always built + string(CONCAT DASHBOARD_FRONTEND_LANGS "${DASHBOARD_FRONTEND_LANGS}" ",${default_lang}") + endif() + set(build_target ":\{${DASHBOARD_FRONTEND_LANGS}\}") + endif() +else(DASHBOARD_FRONTEND_LANGS) + set(build_target ":${default_lang}") +endif(DASHBOARD_FRONTEND_LANGS) + +if(NOT CMAKE_BUILD_TYPE STREQUAL Debug) + set(npm_args "-- --prod --progress=false") +else() + set(npm_args "-- --progress=false") +endif() + +add_npm_command( + OUTPUT "${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend/dist" + COMMAND npx npm-run-all --print-label --parallel --max-parallel 2 "\"build${build_target} -- ${npm_args}\"" + DEPENDS ${frontend_src} frontend/node_modules + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend + COMMENT "dashboard frontend is being created" + ${nodeenv} +) +add_custom_target(mgr-dashboard-frontend-build + ALL + DEPENDS frontend/dist mgr-dashboard-frontend-deps + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/dashboard/frontend) + +add_dependencies(tests mgr-dashboard-frontend-build) +endif(WITH_MGR_DASHBOARD_FRONTEND AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64|arm|ARM") diff --git a/src/pybind/mgr/dashboard/HACKING.rst b/src/pybind/mgr/dashboard/HACKING.rst new file mode 100644 index 00000000..5a790aaa --- /dev/null +++ b/src/pybind/mgr/dashboard/HACKING.rst @@ -0,0 +1,1784 @@ +Ceph Dashboard Developer Documentation +====================================== + +.. contents:: Table of Contents + +Frontend Development +-------------------- + +Before you can start the dashboard from within a development environment, you +will need to generate the frontend code and either use a compiled and running +Ceph cluster (e.g. started by ``vstart.sh``) or the standalone development web +server. + +The build process is based on `Node.js `_ and requires the +`Node Package Manager `_ ``npm`` to be installed. + +Prerequisites +~~~~~~~~~~~~~ + + * Node 8.9.0 or higher + * NPM 5.7.0 or higher + +nodeenv: + During Ceph's build we create a virtualenv with ``node`` and ``npm`` + installed, which can be used as an alternative to installing node/npm in your + system. + + If you want to use the node installed in the virtualenv you just need to + activate the virtualenv before you run any npm commands. To activate it run + ``. build/src/pybind/mgr/dashboard/node-env/bin/activate``. + + Once you finish, you can simply run ``deactivate`` and exit the virtualenv. + +Angular CLI: + If you do not have the `Angular CLI `_ + installed globally, then you need to execute ``ng`` commands with an + additional ``npm run`` before it. + +Package installation +~~~~~~~~~~~~~~~~~~~~ + +Run ``npm install`` in directory ``src/pybind/mgr/dashboard/frontend`` to +install the required packages locally. + +Setting up a Development Server +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create the ``proxy.conf.json`` file based on ``proxy.conf.json.sample``. + +Run ``npm start`` for a dev server. +Navigate to ``http://localhost:4200/``. The app will automatically +reload if you change any of the source files. + +Code Scaffolding +~~~~~~~~~~~~~~~~ + +Run ``ng generate component component-name`` to generate a new +component. You can also use +``ng generate directive|pipe|service|class|guard|interface|enum|module``. + +Build the Project +~~~~~~~~~~~~~~~~~ + +Run ``npm run build`` to build the project. The build artifacts will be +stored in the ``dist/`` directory. Use the ``-prod`` flag for a +production build. Navigate to ``https://localhost:8443``. + +Build the Code Documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run ``npm run doc-build`` to generate code docs in the ``documentation/`` +directory. To make them accesible locally for a web browser, run +``npm run doc-serve`` and they will become available at ``http://localhost:8444``. +With ``npm run compodoc -- `` you may +`fully configure it https://compodoc.app/guides/usage.html`_. + +Code linting and formatting +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We use the following tools to lint and format the code in all our TS, SCSS and +HTML files: + +- `codelyzer `_ +- `html-linter `_ +- `Prettier `_ +- `TSLint `_ + +We added 2 npm scripts to help run these tools: + +- ``npm run lint``, will check frontend files against all linters +- ``npm run fix``, will try to fix all the detected linting errors + +Writing Unit Tests +~~~~~~~~~~~~~~~~~~ + +To write unit tests most efficient we have a small collection of tools, +we use within test suites. + +Those tools can be found under +``src/pybind/mgr/dashboard/frontend/src/testing/``, especially take +a look at ``unit-test-helper.ts``. + +There you will be able to find: + +``configureTestBed`` that replaces the initial ``TestBed`` +methods. It takes the same arguments as ``TestBed.configureTestingModule``. +Using it will run your tests a lot faster in development, as it doesn't +recreate everything from scratch on every test. To use the default behaviour +pass ``true`` as the second argument. + +``PermissionHelper`` to help determine if +the correct actions are shown based on the current permissions and selection +in a list. + +``FormHelper`` which makes testing a form a lot easier +with a few simple methods. It allows you to set a control or multiple +controls, expect if a control is valid or has an error or just do both with +one method. Additional you can expect a template element or multiple elements +to be visible in the rendered template. + +Running Unit Tests +~~~~~~~~~~~~~~~~~~ + +Create ``unit-test-configuration.ts`` file based on +``unit-test-configuration.ts.sample`` in directory +``src/pybind/mgr/dashboard/frontend/src``. + +Run ``npm run test`` to execute the unit tests via `Jest +`_. + +If you get errors on all tests, it could be because `Jest +`_ or something else was updated. +There are a few ways how you can try to resolve this: + +- Remove all modules with ``rm -rf dist node_modules`` and run ``npm install`` + again in order to reinstall them +- Clear the cache of jest by running ``npx jest --clearCache`` + +Running End-to-End Tests +~~~~~~~~~~~~~~~~~~~~~~~~ + +We use `Protractor `__ to run our frontend e2e +tests. + +Our ``run-frontend-e2e-tests.sh`` script will check if Chrome or Docker is +installed and run the tests if either is found. + +Start all frontend e2e tests by running:: + + $ ./run-frontend-e2e-tests.sh + +Device: + You can force the script to use a specific device with the ``-d`` flag:: + + $ ./run-frontend-e2e-tests.sh -d + +Remote: + If you want to run the tests outside the ceph environment, you will need to + manually define the dashboard url using ``-r``:: + + $ ./run-frontend-e2e-tests.sh -r + +Note: + When using docker, as your device, you might need to run the script with sudo + permissions. + +Writing End-to-End Tests +~~~~~~~~~~~~~~~~~~~~~~~~ + +When writing e2e tests you don't want to recompile every time from scratch to +try out if your test has succeeded. As usual you have your development server +open (``npm start``) which already has compiled all files. To attach +`Protractor `__ to this process, instead of +spinning up it's own server, you can use ``npm run e2e -- --dev-server-target`` +or just ``npm run e2e:dev`` which is equivalent. + +Further Help +~~~~~~~~~~~~ + +To get more help on the Angular CLI use ``ng help`` or go check out the +`Angular CLI +README `__. + +Example of a Generator +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + # Create module 'Core' + src/app> ng generate module core -m=app --routing + + # Create module 'Auth' under module 'Core' + src/app/core> ng generate module auth -m=core --routing + or, alternatively: + src/app> ng generate module core/auth -m=core --routing + + # Create component 'Login' under module 'Auth' + src/app/core/auth> ng generate component login -m=core/auth + or, alternatively: + src/app> ng generate component core/auth/login -m=core/auth + +Frontend Typescript Code Style Guide Recommendations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Group the imports based on its source and separate them with a blank +line. + +The source groups can be either from Angular, external or internal. + +Example: + +.. code:: javascript + + import { Component } from '@angular/core'; + import { Router } from '@angular/router'; + + import { ToastrManager } from 'ngx-toastr'; + + import { Credentials } from '../../../shared/models/credentials.model'; + import { HostService } from './services/host.service'; + +Frontend components +~~~~~~~~~~~~~~~~~~~ + +There are several components that can be reused on different pages. +This components are declared on the components module: +`src/pybind/mgr/dashboard/frontend/src/app/shared/components`. + +Helper +...... + +This component should be used to provide additional information to the user. + +Example: + +.. code:: html + + + Some helper html text + + +Terminology and wording +~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of using the Ceph component names, the approach +suggested is to use the logical/generic names (Block over RBD, Filesystem over +CephFS, Object over RGW). Nevertheless, as Ceph-Dashboard cannot completely hide +the Ceph internals, some Ceph-specific names might remain visible. + +Regarding the wording for action labels and other textual elements (form titles, +buttons, etc.), the chosen approach is to follow `these guidelines +`_. +As a rule of thumb, 'Create' and 'Delete' are the proper wording for most forms, +instead of 'Add' and 'Remove', unless some already created item is either added +or removed to/from a set of items (e.g.: 'Add permission' to a user vs. 'Create +(new) permission'). + +In order to enforce the use of this wording, a service ``ActionLabelsI18n`` has +been created, which provides translated labels for use in UI elements. + +Frontend branding +~~~~~~~~~~~~~~~~~ + +Every vendor can customize the 'Ceph dashboard' to his needs. No matter if +logo, HTML-Template or TypeScript, every file inside the frontend folder can be +replaced. + +To replace files, open ``./frontend/angular.json`` and scroll to the section +``fileReplacements`` inside the production configuration. Here you can add the +files you wish to brand. We recommend to place the branded version of a file in +the same directory as the original one and to add a ``.brand`` to the file +name, right in front of the file extension. A ``fileReplacement`` could for +example look like this: + +.. code:: javascript + + { + "replace": "src/app/core/auth/login/login.component.html", + "with": "src/app/core/auth/login/login.component.brand.html" + } + +To serve or build the branded user interface run: + + $ npm run start -- --prod + +or + + $ npm run build -- --prod + +Unfortunately it's currently not possible to use multiple configurations when +serving or building the UI at the same time. That means a configuration just +for the branding ``fileReplacements`` is not an option, because you want to use +the production configuration anyway +(https://github.com/angular/angular-cli/issues/10612). +Furthermore it's also not possible to use glob expressions for +``fileReplacements``. As long as the feature hasn't been implemented, you have +to add the file replacements manually to the angular.json file +(https://github.com/angular/angular-cli/issues/12354). + +Nevertheless you should stick to the suggested naming scheme because it makes +it easier for you to use glob expressions once it's supported in the future. + +To change the variable defaults you can overwrite them in the file +``./frontend/src/vendor.variables.scss``. Just reassign the variable you want +to change, for example ``$color-primary: teal;`` +To overwrite or extend the default CSS, you can add your own styles in +``./frontend/src/vendor.overrides.scss``. + +I18N +---- + +How to extract messages from source code? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To extract the I18N messages from the templates and the TypeScript files just +run the following command in ``src/pybind/mgr/dashboard/frontend``:: + + $ npm run i18n:extract + +This will extract all marked messages from the HTML templates first and then +add all marked strings from the TypeScript files to the translation template. +Since the extraction from TypeScript files is still not supported by Angular +itself, we are using the +`ngx-translator `_ extractor to +parse the TypeScript files. + +When the command ran successfully, it should have created or updated the file +``src/locale/messages.xlf``. + +The file isn't tracked by git, you can just use it to start with the +translation offline or add/update the resource files on transifex. + +Supported languages +~~~~~~~~~~~~~~~~~~~ + +All our supported languages should be registered in both exports in +``supported-languages.enum.ts`` and have a corresponding test in +``language-selector.component.spec.ts``. + +The ``SupportedLanguages`` enum will provide the list for the default language selection. + +The ``languageBootstrapMapping`` variable will provide the +`language support `_ +for ngx-bootstrap components like the +`date picker `_. + +Translating process +~~~~~~~~~~~~~~~~~~~ + +To facilitate the translation process of the dashboard we are using a web tool +called `transifex `_. + +If you wish to help translating to any language just go to our `transifex +project page `_, join the +project and you can start translating immediately. + +All translations will then be reviewed and later pushed upstream. + +Updating translated messages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Any time there are new messages translated and reviewed in a specific language +we should update the translation file upstream. + +To do that, check the settings in the i18n config file +``src/pybind/mgr/dashboard/frontend/i18n.config.json``:: and make sure that the +organization is *ceph*, the project is *ceph-dashboard* and the resource is +the one you want to pull from and push to e.g. *Master:master*. To find a list +of avaiable resources visit ``https://www.transifex.com/ceph/ceph-dashboard/content/``:: + +After you checked the config go to the directory ``src/pybind/mgr/dashboard/frontend``:: and run + + $ npm run i18n + +This command will extract all marked messages from the HTML templates and +TypeScript files. Once the source file has been created it will push it to +transifex and pull the latest translations. It will also fill all the +untranslated strings with the source string. +The tool will ask you for an api token, unless you added it by running: + + $ npm run i18n:token + +To create a transifex api token visit ``https://www.transifex.com/user/settings/api/``:: + +After the command ran successfully, build the UI and check if everything is +working as expected. You also might want to run the frontend tests. + +Suggestions +~~~~~~~~~~~ + +Strings need to start and end in the same line as the element: + +.. code-block:: xml + + + + Foo + + + + Foo + + + + + Foo bar baz. + Foo bar baz. + + + + Foo bar baz. + Foo bar baz. + +Isolated interpolations should not be translated: + +.. code-block:: xml + + + {{ foo }} + + + {{ foo }} + +Interpolations used in a sentence should be kept in the translation: + +.. code-block:: xml + + + There are {{ x }} OSDs. + +Remove elements that are outside the context of the translation: + +.. code-block:: xml + + + + + + + +Keep elements that affect the sentence: + +.. code-block:: xml + + + Profile foo will be removed. + +Backend Development +------------------- + +The Python backend code of this module requires a number of Python modules to be +installed. They are listed in file ``requirements.txt``. Using `pip +`_ you may install all required dependencies +by issuing ``pip install -r requirements.txt`` in directory +``src/pybind/mgr/dashboard``. + +If you're using the `ceph-dev-docker development environment +`_, simply run +``./install_deps.sh`` from the toplevel directory to install them. + +Unit Testing +~~~~~~~~~~~~ + +In dashboard we have two different kinds of backend tests: + +1. Unit tests based on ``tox`` +2. API tests based on Teuthology. + +Unit tests based on tox +~~~~~~~~~~~~~~~~~~~~~~~~ + +We included a ``tox`` configuration file that will run the unit tests under +Python 2 or 3, as well as linting tools to guarantee the uniformity of code. + +You need to install ``tox`` and ``coverage`` before running it. To install the +packages in your system, either install it via your operating system's package +management tools, e.g. by running ``dnf install python-tox python-coverage`` on +Fedora Linux. + +Alternatively, you can use Python's native package installation method:: + + $ pip install tox + $ pip install coverage + +To run the tests, run ``run-tox.sh`` in the dashboard directory (where +``tox.ini`` is located):: + + ## Run Python 2+3 tests+lint commands: + $ ./run-tox.sh + + ## Run Python 3 tests+lint commands: + $ WITH_PYTHON2=OFF ./run-tox.sh + + ## Run Python 3 arbitrary command (e.g. 1 single test): + $ WITH_PYTHON2=OFF ./run-tox.sh pytest tests/test_rgw_client.py::RgwClientTest::test_ssl_verify + +You can also run tox instead of ``run-tox.sh``:: + + ## Run Python 3 tests command: + $ CEPH_BUILD_DIR=.tox tox -e py3-cov + + ## Run Python 3 arbitrary command (e.g. 1 single test): + $ CEPH_BUILD_DIR=.tox tox -e py3-run pytest tests/test_rgw_client.py::RgwClientTest::test_ssl_verify + +We also collect coverage information from the backend code when you run tests. You can check the +coverage information provided by the tox output, or by running the following +command after tox has finished successfully:: + + $ coverage html + +This command will create a directory ``htmlcov`` with an HTML representation of +the code coverage of the backend. + +API tests based on Teuthology +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +How to run existing API tests: + To run the API tests against a real Ceph cluster, we leverage the Teuthology + framework. This has the advantage of catching bugs originated from changes in + the internal Ceph code. + + Our ``run-backend-api-tests.sh`` script will start a ``vstart`` Ceph cluster + before running the Teuthology tests, and then it stops the cluster after the + tests are run. Of course this implies that you have built/compiled Ceph + previously. + + Start all dashboard tests by running:: + + $ ./run-backend-api-tests.sh + + Or, start one or multiple specific tests by specifying the test name:: + + $ ./run-backend-api-tests.sh tasks.mgr.dashboard.test_pool.PoolTest + + Or, ``source`` the script and run the tests manually:: + + $ source run-backend-api-tests.sh + $ run_teuthology_tests [tests]... + $ cleanup_teuthology + +How to write your own tests: + There are two possible ways to write your own API tests: + + The first is by extending one of the existing test classes in the + ``qa/tasks/mgr/dashboard`` directory. + + The second way is by adding your own API test module if you're creating a new + controller for example. To do so you'll just need to add the file containing + your new test class to the ``qa/tasks/mgr/dashboard`` directory and implement + all your tests here. + + .. note:: Don't forget to add the path of the newly created module to + ``modules`` section in ``qa/suites/rados/mgr/tasks/dashboard.yaml``. + + Short example: Let's assume you created a new controller called + ``my_new_controller.py`` and the related test module + ``test_my_new_controller.py``. You'll need to add + ``tasks.mgr.dashboard.test_my_new_controller`` to the ``modules`` section in + the ``dashboard.yaml`` file. + + Also, if you're removing test modules please keep in mind to remove the + related section. Otherwise the Teuthology test run will fail. + + Please run your API tests on your dev environment (as explained above) + before submitting a pull request. Also make sure that a full QA run in + Teuthology/sepia lab (based on your changes) has completed successfully + before it gets merged. You don't need to schedule the QA run yourself, just + add the 'needs-qa' label to your pull request as soon as you think it's ready + for merging (e.g. make check was successful, the pull request is approved and + all comments have been addressed). One of the developers who has access to + Teuthology/the sepia lab will take care of it and report the result back to + you. + + +How to add a new controller? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A controller is a Python class that extends from the ``BaseController`` class +and is decorated with either the ``@Controller``, ``@ApiController`` or +``@UiApiController`` decorators. The Python class must be stored inside a Python +file located under the ``controllers`` directory. The Dashboard module will +automatically load your new controller upon start. + +``@ApiController`` and ``@UiApiController`` are both specializations of the +``@Controller`` decorator. + +The ``@ApiController`` should be used for controllers that provide an API-like +REST interface and the ``@UiApiController`` should be used for endpoints consumed +by the UI but that are not part of the 'public' API. For any other kinds of +controllers the ``@Controller`` decorator should be used. + +A controller has a URL prefix path associated that is specified in the +controller decorator, and all endpoints exposed by the controller will share +the same URL prefix path. + +A controller's endpoint is exposed by implementing a method on the controller +class decorated with the ``@Endpoint`` decorator. + +For example create a file ``ping.py`` under ``controllers`` directory with the +following code: + +.. code-block:: python + + from ..tools import Controller, ApiController, UiApiController, BaseController, Endpoint + + @Controller('/ping') + class Ping(BaseController): + @Endpoint() + def hello(self): + return {'msg': "Hello"} + + @ApiController('/ping') + class ApiPing(BaseController): + @Endpoint() + def hello(self): + return {'msg': "Hello"} + + @UiApiController('/ping') + class UiApiPing(BaseController): + @Endpoint() + def hello(self): + return {'msg': "Hello"} + +The ``hello`` endpoint of the ``Ping`` controller can be reached by the +following URL: https://mgr_hostname:8443/ping/hello using HTTP GET requests. +As you can see the controller URL path ``/ping`` is concatenated to the +method name ``hello`` to generate the endpoint's URL. + +In the case of the ``ApiPing`` controller, the ``hello`` endpoint can be +reached by the following URL: https://mgr_hostname:8443/api/ping/hello using a +HTTP GET request. +The API controller URL path ``/ping`` is prefixed by the ``/api`` path and then +concatenated to the method name ``hello`` to generate the endpoint's URL. +Internally, the ``@ApiController`` is actually calling the ``@Controller`` +decorator by passing an additional decorator parameter called ``base_url``:: + + @ApiController('/ping') <=> @Controller('/ping', base_url="/api") + +``UiApiPing`` works in a similar way than the ``ApiPing``, but the URL will be +prefixed by ``/ui-api``: https://mgr_hostname:8443/ui-api/ping/hello. ``UiApiPing`` is +also a ``@Controller`` extension:: + + @UiApiController('/ping') <=> @Controller('/ping', base_url="/ui-api") + +The ``@Endpoint`` decorator also supports many parameters to customize the +endpoint: + +* ``method="GET"``: the HTTP method allowed to access this endpoint. +* ``path="/"``: the URL path of the endpoint, excluding the + controller URL path prefix. +* ``path_params=[]``: list of method parameter names that correspond to URL + path parameters. Can only be used when ``method in ['POST', 'PUT']``. +* ``query_params=[]``: list of method parameter names that correspond to URL + query parameters. +* ``json_response=True``: indicates if the endpoint response should be + serialized in JSON format. +* ``proxy=False``: indicates if the endpoint should be used as a proxy. + +An endpoint method may have parameters declared. Depending on the HTTP method +defined for the endpoint the method parameters might be considered either +path parameters, query parameters, or body parameters. + +For ``GET`` and ``DELETE`` methods, the method's non-optional parameters are +considered path parameters by default. Optional parameters are considered +query parameters. By specifying the ``query_parameters`` in the endpoint +decorator it is possible to make a non-optional parameter to be a query +parameter. + +For ``POST`` and ``PUT`` methods, all method parameters are considered +body parameters by default. To override this default, one can use the +``path_params`` and ``query_params`` to specify which method parameters are +path and query parameters respectivelly. +Body parameters are decoded from the request body, either from a form format, or +from a dictionary in JSON format. + +Let's use an example to better understand the possible ways to customize an +endpoint: + +.. code-block:: python + + from ..tools import Controller, BaseController, Endpoint + + @Controller('/ping') + class Ping(BaseController): + + # URL: /ping/{key}?opt1=...&opt2=... + @Endpoint(path="/", query_params=['opt1']) + def index(self, key, opt1, opt2=None): + # ... + + # URL: /ping/{key}?opt1=...&opt2=... + @Endpoint(query_params=['opt1']) + def __call__(self, key, opt1, opt2=None): + # ... + + # URL: /ping/post/{key1}/{key2} + @Endpoint('POST', path_params=['key1', 'key2']) + def post(self, key1, key2, data1, data2=None): + # ... + + +In the above example we see how the ``path`` option can be used to override the +generated endpoint URL in order to not use the method's name in the URL. In the +``index`` method we set the ``path`` to ``"/"`` to generate an endpoint that is +accessible by the root URL of the controller. + +An alternative approach to generate an endpoint that is accessible through just +the controller's path URL is by using the ``__call__`` method, as we show in +the above example. + +From the third method you can see that the path parameters are collected from +the URL by parsing the list of values separated by slashes ``/`` that come +after the URL path ``/ping`` for ``index`` method case, and ``/ping/post`` for +the ``post`` method case. + +Defining path parameters in endpoints's URLs using python methods's parameters +is very easy but it is still a bit strict with respect to the position of these +parameters in the URL structure. +Sometimes we may want to explicitly define a URL scheme that +contains path parameters mixed with static parts of the URL. +Our controller infrastructure also supports the declaration of URL paths with +explicit path parameters at both the controller level and method level. + +Consider the following example: + +.. code-block:: python + + from ..tools import Controller, BaseController, Endpoint + + @Controller('/ping/{node}/stats') + class Ping(BaseController): + + # URL: /ping/{node}/stats/{date}/latency?unit=... + @Endpoint(path="/{date}/latency") + def latency(self, node, date, unit="ms"): + # ... + +In this example we explicitly declare a path parameter ``{node}`` in the +controller URL path, and a path parameter ``{date}`` in the ``latency`` +method. The endpoint for the ``latency`` method is then accessible through +the URL: https://mgr_hostname:8443/ping/{node}/stats/{date}/latency . + +For a full set of examples on how to use the ``@Endpoint`` +decorator please check the unit test file: ``tests/test_controllers.py``. +There you will find many examples of how to customize endpoint methods. + + +Implementing Proxy Controller +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes you might need to relay some requests from the Dashboard frontend +directly to an external service. +For that purpose we provide a decorator called ``@Proxy``. +(As a concrete example, check the ``controllers/rgw.py`` file where we +implemented an RGW Admin Ops proxy.) + + +The ``@Proxy`` decorator is a wrapper of the ``@Endpoint`` decorator that +already customizes the endpoint for working as a proxy. +A proxy endpoint works by capturing the URL path that follows the controller +URL prefix path, and does not do any decoding of the request body. + +Example: + +.. code-block:: python + + from ..tools import Controller, BaseController, Proxy + + @Controller('/foo/proxy') + class FooServiceProxy(BaseController): + + @Proxy() + def proxy(self, path, **params): + # if requested URL is "/foo/proxy/access/service?opt=1" + # then path is "access/service" and params is {'opt': '1'} + # ... + + +How does the RESTController work? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We also provide a simple mechanism to create REST based controllers using the +``RESTController`` class. Any class which inherits from ``RESTController`` will, +by default, return JSON. + +The ``RESTController`` is basically an additional abstraction layer which eases +and unifies the work with collections. A collection is just an array of objects +with a specific type. ``RESTController`` enables some default mappings of +request types and given parameters to specific method names. This may sound +complicated at first, but it's fairly easy. Lets have look at the following +example: + +.. code-block:: python + + import cherrypy + from ..tools import ApiController, RESTController + + @ApiController('ping') + class Ping(RESTController): + def list(self): + return {"msg": "Hello"} + + def get(self, id): + return self.objects[id] + +In this case, the ``list`` method is automatically used for all requests to +``api/ping`` where no additional argument is given and where the request type +is ``GET``. If the request is given an additional argument, the ID in our +case, it won't map to ``list`` anymore but to ``get`` and return the element +with the given ID (assuming that ``self.objects`` has been filled before). The +same applies to other request types: + ++--------------+------------+----------------+-------------+ +| Request type | Arguments | Method | Status Code | ++==============+============+================+=============+ +| GET | No | list | 200 | ++--------------+------------+----------------+-------------+ +| PUT | No | bulk_set | 200 | ++--------------+------------+----------------+-------------+ +| POST | No | create | 201 | ++--------------+------------+----------------+-------------+ +| DELETE | No | bulk_delete | 204 | ++--------------+------------+----------------+-------------+ +| GET | Yes | get | 200 | ++--------------+------------+----------------+-------------+ +| PUT | Yes | set | 200 | ++--------------+------------+----------------+-------------+ +| DELETE | Yes | delete | 204 | ++--------------+------------+----------------+-------------+ + +How to use a custom API endpoint in a RESTController? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you don't have any access restriction you can use ``@Endpoint``. If you +have set a permission scope to restrict access to your endpoints, +``@Endpoint`` will fail, as it doesn't know which permission property should be +used. To use a custom endpoint inside a restricted ``RESTController`` use +``@RESTController.Collection`` instead. You can also choose +``@RESTController.Resource`` if you have set a ``RESOURCE_ID`` in your +``RESTController`` class. + +.. code-block:: python + + import cherrypy + from ..tools import ApiController, RESTController + + @ApiController('ping', Scope.Ping) + class Ping(RESTController): + RESOURCE_ID = 'ping' + + @RESTController.Resource('GET') + def some_get_endpoint(self): + return {"msg": "Hello"} + + @RESTController.Collection('POST') + def some_post_endpoint(self, **data): + return {"msg": data} + +Both decorators also support four parameters to customize the +endpoint: + +* ``method="GET"``: the HTTP method allowed to access this endpoint. +* ``path="/"``: the URL path of the endpoint, excluding the + controller URL path prefix. +* ``status=200``: set the HTTP status response code +* ``query_params=[]``: list of method parameter names that correspond to URL + query parameters. + +How to restrict access to a controller? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All controllers require authentication by default. +If you require that the controller can be accessed without authentication, +then you can add the parameter ``secure=False`` to the controller decorator. + +Example: + +.. code-block:: python + + import cherrypy + from . import ApiController, RESTController + + + @ApiController('ping', secure=False) + class Ping(RESTController): + def list(self): + return {"msg": "Hello"} + + +How to access the manager module instance from a controller? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We provide the manager module instance as a global variable that can be +imported in any module. We also provide a logger instance in the same way. + +Example: + +.. code-block:: python + + import cherrypy + from .. import logger, mgr + from ..tools import ApiController, RESTController + + + @ApiController('servers') + class Servers(RESTController): + def list(self): + logger.debug('Listing available servers') + return {'servers': mgr.list_servers()} + + +How to write a unit test for a controller? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We provide a test helper class called ``ControllerTestCase`` to easily create +unit tests for your controller. + +If we want to write a unit test for the above ``Ping`` controller, create a +``test_ping.py`` file under the ``tests`` directory with the following code: + +.. code-block:: python + + from .helper import ControllerTestCase + from .controllers.ping import Ping + + + class PingTest(ControllerTestCase): + @classmethod + def setup_test(cls): + Ping._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([Ping]) + + def test_ping(self): + self._get("/api/ping") + self.assertStatus(200) + self.assertJsonBody({'msg': 'Hello'}) + +The ``ControllerTestCase`` class starts by initializing a CherryPy webserver. +Then it will call the ``setup_test()`` class method where we can explicitly +load the controllers that we want to test. In the above example we are only +loading the ``Ping`` controller. We can also disable authentication of a +controller at this stage, as depicted in the example. + + +How to listen for manager notifications in a controller? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The manager notifies the modules of several types of cluster events, such +as cluster logging event, etc... + +Each module has a "global" handler function called ``notify`` that the manager +calls to notify the module. But this handler function must not block or spend +too much time processing the event notification. +For this reason we provide a notification queue that controllers can register +themselves with to receive cluster notifications. + +The example below represents a controller that implements a very simple live +log viewer page: + +.. code-block:: python + + from __future__ import absolute_import + + import collections + + import cherrypy + + from ..tools import ApiController, BaseController, NotificationQueue + + + @ApiController('livelog') + class LiveLog(BaseController): + log_buffer = collections.deque(maxlen=1000) + + def __init__(self): + super(LiveLog, self).__init__() + NotificationQueue.register(self.log, 'clog') + + def log(self, log_struct): + self.log_buffer.appendleft(log_struct) + + @cherrypy.expose + def default(self): + ret = '' + for l in self.log_buffer: + ret += "{}
".format(l) + ret += "" + return ret + +As you can see above, the ``NotificationQueue`` class provides a register +method that receives the function as its first argument, and receives the +"notification type" as the second argument. +You can omit the second argument of the ``register`` method, and in that case +you are registering to listen all notifications of any type. + +Here is an list of notification types (these might change in the future) that +can be used: + +* ``clog``: cluster log notifications +* ``command``: notification when a command issued by ``MgrModule.send_command`` + completes +* ``perf_schema_update``: perf counters schema update +* ``mon_map``: monitor map update +* ``fs_map``: cephfs map update +* ``osd_map``: OSD map update +* ``service_map``: services (RGW, RBD-Mirror, etc.) map update +* ``mon_status``: monitor status regular update +* ``health``: health status regular update +* ``pg_summary``: regular update of PG status information + + +How to write a unit test when a controller accesses a Ceph module? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider the following example that implements a controller that retrieves the +list of RBD images of the ``rbd`` pool: + +.. code-block:: python + + import rbd + from .. import mgr + from ..tools import ApiController, RESTController + + + @ApiController('rbdimages') + class RbdImages(RESTController): + def __init__(self): + self.ioctx = mgr.rados.open_ioctx('rbd') + self.rbd = rbd.RBD() + + def list(self): + return [{'name': n} for n in self.rbd.list(self.ioctx)] + +In the example above, we want to mock the return value of the ``rbd.list`` +function, so that we can test the JSON response of the controller. + +The unit test code will look like the following: + +.. code-block:: python + + import mock + from .helper import ControllerTestCase + + + class RbdImagesTest(ControllerTestCase): + @mock.patch('rbd.RBD.list') + def test_list(self, rbd_list_mock): + rbd_list_mock.return_value = ['img1', 'img2'] + self._get('/api/rbdimages') + self.assertJsonBody([{'name': 'img1'}, {'name': 'img2'}]) + + + +How to add a new configuration setting? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you need to store some configuration setting for a new feature, we already +provide an easy mechanism for you to specify/use the new config setting. + +For instance, if you want to add a new configuration setting to hold the +email address of the dashboard admin, just add a setting name as a class +attribute to the ``Options`` class in the ``settings.py`` file:: + + # ... + class Options(object): + # ... + + ADMIN_EMAIL_ADDRESS = ('admin@admin.com', str) + +The value of the class attribute is a pair composed by the default value for that +setting, and the python type of the value. + +By declaring the ``ADMIN_EMAIL_ADDRESS`` class attribute, when you restart the +dashboard module, you will automatically gain two additional CLI commands to +get and set that setting:: + + $ ceph dashboard get-admin-email-address + $ ceph dashboard set-admin-email-address + +To access, or modify the config setting value from your Python code, either +inside a controller or anywhere else, you just need to import the ``Settings`` +class and access it like this: + +.. code-block:: python + + from settings import Settings + + # ... + tmp_var = Settings.ADMIN_EMAIL_ADDRESS + + # .... + Settings.ADMIN_EMAIL_ADDRESS = 'myemail@admin.com' + +The settings management implementation will make sure that if you change a +setting value from the Python code you will see that change when accessing +that setting from the CLI and vice-versa. + + +How to run a controller read-write operation asynchronously? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some controllers might need to execute operations that alter the state of the +Ceph cluster. These operations might take some time to execute and to maintain +a good user experience in the Web UI, we need to run those operations +asynchronously and return immediately to frontend some information that the +operations are running in the background. + +To help in the development of the above scenario we added the support for +asynchronous tasks. To trigger the execution of an asynchronous task we must +use the following class method of the ``TaskManager`` class:: + + from ..tools import TaskManager + # ... + TaskManager.run(name, metadata, func, args, kwargs) + +* ``name`` is a string that can be used to group tasks. For instance + for RBD image creation tasks we could specify ``"rbd/create"`` as the + name, or similarly ``"rbd/remove"`` for RBD image removal tasks. + +* ``metadata`` is a dictionary where we can store key-value pairs that + characterize the task. For instance, when creating a task for creating + RBD images we can specify the metadata argument as + ``{'pool_name': "rbd", image_name': "test-img"}``. + +* ``func`` is the python function that implements the operation code, which + will be executed asynchronously. + +* ``args`` and ``kwargs`` are the positional and named arguments that will be + passed to ``func`` when the task manager starts its execution. + +The ``TaskManager.run`` method triggers the asynchronous execution of function +``func`` and returns a ``Task`` object. +The ``Task`` provides the public method ``Task.wait(timeout)``, which can be +used to wait for the task to complete up to a timeout defined in seconds and +provided as an argument. If no argument is provided the ``wait`` method +blocks until the task is finished. + +The ``Task.wait`` is very useful for tasks that usually are fast to execute but +that sometimes may take a long time to run. +The return value of the ``Task.wait`` method is a pair ``(state, value)`` +where ``state`` is a string with following possible values: + +* ``VALUE_DONE = "done"`` +* ``VALUE_EXECUTING = "executing"`` + +The ``value`` will store the result of the execution of function ``func`` if +``state == VALUE_DONE``. If ``state == VALUE_EXECUTING`` then +``value == None``. + +The pair ``(name, metadata)`` should unequivocally identify the task being +run, which means that if you try to trigger a new task that matches the same +``(name, metadata)`` pair of the currently running task, then the new task +is not created and you get the task object of the current running task. + +For instance, consider the following example: + +.. code-block:: python + + task1 = TaskManager.run("dummy/task", {'attr': 2}, func) + task2 = TaskManager.run("dummy/task", {'attr': 2}, func) + +If the second call to ``TaskManager.run`` executes while the first task is +still executing then it will return the same task object: +``assert task1 == task2``. + + +How to get the list of executing and finished asynchronous tasks? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The list of executing and finished tasks is included in the ``Summary`` +controller, which is already polled every 5 seconds by the dashboard frontend. +But we also provide a dedicated controller to get the same list of executing +and finished tasks. + +The ``Task`` controller exposes the ``/api/task`` endpoint that returns the +list of executing and finished tasks. This endpoint accepts the ``name`` +parameter that accepts a glob expression as its value. +For instance, an HTTP GET request of the URL ``/api/task?name=rbd/*`` +will return all executing and finished tasks which name starts with ``rbd/``. + +To prevent the finished tasks list from growing unbounded, we will always +maintain the 10 most recent finished tasks, and the remaining older finished +tasks will be removed when reaching a TTL of 1 minute. The TTL is calculated +using the timestamp when the task finished its execution. After a minute, when +the finished task information is retrieved, either by the summary controller or +by the task controller, it is automatically deleted from the list and it will +not be included in further task queries. + +Each executing task is represented by the following dictionary:: + + { + 'name': "name", # str + 'metadata': { }, # dict + 'begin_time': "2018-03-14T15:31:38.423605Z", # str (ISO 8601 format) + 'progress': 0 # int (percentage) + } + +Each finished task is represented by the following dictionary:: + + { + 'name': "name", # str + 'metadata': { }, # dict + 'begin_time': "2018-03-14T15:31:38.423605Z", # str (ISO 8601 format) + 'end_time': "2018-03-14T15:31:39.423605Z", # str (ISO 8601 format) + 'duration': 0.0, # float + 'progress': 0 # int (percentage) + 'success': True, # bool + 'ret_value': None, # object, populated only if 'success' == True + 'exception': None, # str, populated only if 'success' == False + } + + +How to use asynchronous APIs with asynchronous tasks? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``TaskManager.run`` method as described in a previous section, is well +suited for calling blocking functions, as it runs the function inside a newly +created thread. But sometimes we want to call some function of an API that is +already asynchronous by nature. + +For these cases we want to avoid creating a new thread for just running a +non-blocking function, and want to leverage the asynchronous nature of the +function. The ``TaskManager.run`` is already prepared to be used with +non-blocking functions by passing an object of the type ``TaskExecutor`` as an +additional parameter called ``executor``. The full method signature of +``TaskManager.run``:: + + TaskManager.run(name, metadata, func, args=None, kwargs=None, executor=None) + + +The ``TaskExecutor`` class is responsible for code that executes a given task +function, and defines three methods that can be overridden by +subclasses:: + + def init(self, task) + def start(self) + def finish(self, ret_value, exception) + +The ``init`` method is called before the running the task function, and +receives the task object (of class ``Task``). + +The ``start`` method runs the task function. The default implementation is to +run the task function in the current thread context. + +The ``finish`` method should be called when the task function finishes with +either the ``ret_value`` populated with the result of the execution, or with +an exception object in the case that execution raised an exception. + +To leverage the asynchronous nature of a non-blocking function, the developer +should implement a custom executor by creating a subclass of the +``TaskExecutor`` class, and provide an instance of the custom executor class +as the ``executor`` parameter of the ``TaskManager.run``. + +To better understand the expressive power of executors, we write a full example +of use a custom executor to execute the ``MgrModule.send_command`` asynchronous +function: + +.. code-block:: python + + import json + from mgr_module import CommandResult + from .. import mgr + from ..tools import ApiController, RESTController, NotificationQueue, \ + TaskManager, TaskExecutor + + + class SendCommandExecutor(TaskExecutor): + def __init__(self): + super(SendCommandExecutor, self).__init__() + self.tag = None + self.result = None + + def init(self, task): + super(SendCommandExecutor, self).init(task) + + # we need to listen for 'command' events to know when the command + # finishes + NotificationQueue.register(self._handler, 'command') + + # store the CommandResult object to retrieve the results + self.result = self.task.fn_args[0] + if len(self.task.fn_args) > 4: + # the user specified a tag for the command, so let's use it + self.tag = self.task.fn_args[4] + else: + # let's generate a unique tag for the command + self.tag = 'send_command_{}'.format(id(self)) + self.task.fn_args.append(self.tag) + + def _handler(self, data): + if data == self.tag: + # the command has finished, notifying the task with the result + self.finish(self.result.wait(), None) + # deregister listener to avoid memory leaks + NotificationQueue.deregister(self._handler, 'command') + + + @ApiController('test') + class Test(RESTController): + + def _run_task(self, osd_id): + task = TaskManager.run("test/task", {}, mgr.send_command, + [CommandResult(''), 'osd', osd_id, + json.dumps({'prefix': 'perf histogram dump'})], + executor=SendCommandExecutor()) + return task.wait(1.0) + + def get(self, osd_id): + status, value = self._run_task(osd_id) + return {'status': status, 'value': value} + + +The above ``SendCommandExecutor`` executor class can be used for any call to +``MgrModule.send_command``. This means that we should need just one custom +executor class implementation for each non-blocking API that we use in our +controllers. + +The default executor, used when no executor object is passed to +``TaskManager.run``, is the ``ThreadedExecutor``. You can check its +implementation in the ``tools.py`` file. + + +How to update the execution progress of an asynchronous task? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The asynchronous tasks infrastructure provides support for updating the +execution progress of an executing task. +The progress can be updated from within the code the task is executing, which +usually is the place where we have the progress information available. + +To update the progress from within the task code, the ``TaskManager`` class +provides a method to retrieve the current task object:: + + TaskManager.current_task() + +The above method is only available when using the default executor +``ThreadedExecutor`` for executing the task. +The ``current_task()`` method returns the current ``Task`` object. The +``Task`` object provides two public methods to update the execution progress +value: the ``set_progress(percentage)``, and the ``inc_progress(delta)`` +methods. + +The ``set_progress`` method receives as argument an integer value representing +the absolute percentage that we want to set to the task. + +The ``inc_progress`` method receives as argument an integer value representing +the delta we want to increment to the current execution progress percentage. + +Take the following example of a controller that triggers a new task and +updates its progress: + +.. code-block:: python + + from __future__ import absolute_import + import random + import time + import cherrypy + from ..tools import TaskManager, ApiController, BaseController + + + @ApiController('dummy_task') + class DummyTask(BaseController): + def _dummy(self): + top = random.randrange(100) + for i in range(top): + TaskManager.current_task().set_progress(i*100/top) + # or TaskManager.current_task().inc_progress(100/top) + time.sleep(1) + return "finished" + + @cherrypy.expose + @cherrypy.tools.json_out() + def default(self): + task = TaskManager.run("dummy/task", {}, self._dummy) + return task.wait(5) # wait for five seconds + + +How to deal with asynchronous tasks in the front-end? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All executing and most recently finished asynchronous tasks are displayed on +"Background-Tasks" and if finished on "Recent-Notifications" in the menu bar. +For each task a operation name for three states (running, success and failure), +a function that tells who is involved and error descriptions, if any, have to +be provided. This can be achieved by appending +``TaskManagerMessageService.messages``. This has to be done to achieve +consistency among all tasks and states. + +Operation Object + Ensures consistency among all tasks. It consists of three verbs for each + different state f.e. + ``{running: 'Creating', failure: 'create', success: 'Created'}``. + +#. Put running operations in present participle f.e. ``'Updating'``. +#. Failed messages always start with ``'Failed to '`` and should be continued + with the operation in present tense f.e. ``'update'``. +#. Put successful operations in past tense f.e. ``'Updated'``. + +Involves Function + Ensures consistency among all messages of a task, it resembles who's + involved by the operation. It's a function that returns a string which + takes the metadata from the task to return f.e. + ``"RBD 'somePool/someImage'"``. + +Both combined create the following messages: + +* Failure => ``"Failed to create RBD 'somePool/someImage'"`` +* Running => ``"Creating RBD 'somePool/someImage'"`` +* Success => ``"Created RBD 'somePool/someImage'"`` + +For automatic task handling use ``TaskWrapperService.wrapTaskAroundCall``. + +If for some reason ``wrapTaskAroundCall`` is not working for you, +you have to subscribe to your asynchronous task manually through +``TaskManagerService.subscribe``, and provide it with a callback, +in case of a success to notify the user. A notification can +be triggered with ``NotificationService.notifyTask``. It will use +``TaskManagerMessageService.messages`` to display a message based on the state +of a task. + +Notifications of API errors are handled by ``ApiInterceptorService``. + +Usage example: + +.. code-block:: javascript + + export class TaskManagerMessageService { + // ... + messages = { + // Messages for task 'rbd/create' + 'rbd/create': new TaskManagerMessage( + // Message prefixes + ['create', 'Creating', 'Created'], + // Message suffix + (metadata) => `RBD '${metadata.pool_name}/${metadata.image_name}'`, + (metadata) => ({ + // Error code and description + '17': `Name is already used by RBD '${metadata.pool_name}/${ + metadata.image_name}'.` + }) + ), + // ... + }; + // ... + } + + export class RBDFormComponent { + // ... + createAction() { + const request = this.createRequest(); + // Subscribes to 'call' with submitted 'task' and handles notifications + return this.taskWrapper.wrapTaskAroundCall({ + task: new FinishedTask('rbd/create', { + pool_name: request.pool_name, + image_name: request.name + }), + call: this.rbdService.create(request) + }); + } + // ... + } + + +REST API documentation +~~~~~~~~~~~~~~~~~~~~~~ +There is an automatically generated Swagger UI page for documentation of the REST +API endpoints.However, by default it is not very detailed. There are two +decorators that can be used to add more information: + +* ``@EndpointDoc()`` for documentation of endpoints. It has four optional arguments + (explained below): ``description``, ``group``, ``parameters`` and``responses``. +* ``@ControllerDoc()`` for documentation of controller or group associated with + the endpoints. It only takes the two first arguments: ``description`` and``group``. + + +``description``: A a string with a short (1-2 sentences) description of the object. + + +``group``: By default, an endpoint is grouped together with other endpoints +within the same controller class. ``group`` is a string that can be used to +assign an endpoint or all endpoints in a class to another controller or a +conceived group name. + + +``parameters``: A dict used to describe path, query or request body parameters. +By default, all parameters for an endpoint are listed on the Swagger UI page, +including information of whether the parameter is optional/required and default +values. However, there will be no description of the parameter and the parameter +type will only be displayed in some cases. +When adding information, each parameters should be described as in the example +below. Note that the parameter type should be expressed as a built-in python +type and not as a string. Allowed values are ``str``, ``int``, ``bool``, ``float``. + +.. code-block:: python + + @EndpointDoc(parameters={'my_string': (str, 'Description of my_string')}) + +For body parameters, more complex cases are possible. If the parameter is a +dictionary, the type should be replaced with a ``dict`` containing its nested +parameters. When describing nested parameters, the same format as other +parameters is used. However, all nested parameters are set as required by default. +If the nested parameter is optional this must be specified as for ``item2`` in +the example below. If a nested parameters is set to optional, it is also +possible to specify the default value (this will not be provided automatically +for nested parameters). + +.. code-block:: python + + @EndpointDoc(parameters={ + 'my_dictionary': ({ + 'item1': (str, 'Description of item1'), + 'item2': (str, 'Description of item2', True), # item2 is optional + 'item3': (str, 'Description of item3', True, 'foo'), # item3 is optional with 'foo' as default value + }, 'Description of my_dictionary')}) + +If the parameter is a ``list`` of primitive types, the type should be +surrounded with square brackets. + +.. code-block:: python + + @EndpointDoc(parameters={'my_list': ([int], 'Description of my_list')}) + +If the parameter is a ``list`` with nested parameters, the nested parameters +should be placed in a dictionary and surrounded with square brackets. + +.. code-block:: python + + @EndpointDoc(parameters={ + 'my_list': ([{ + 'list_item': (str, 'Description of list_item'), + 'list_item2': (str, 'Description of list_item2') + }], 'Description of my_list')}) + + +``responses``: A dict used for describing responses. Rules for describing +responses are the same as for request body parameters, with one difference: +responses also needs to be assigned to the related response code as in the +example below: + +.. code-block:: python + + @EndpointDoc(responses={ + '400':{'my_response': (str, 'Description of my_response')} + + +Error Handling in Python +~~~~~~~~~~~~~~~~~~~~~~~~ + +Good error handling is a key requirement in creating a good user experience +and providing a good API. + +Dashboard code should not duplicate C++ code. Thus, if error handling in C++ +is sufficient to provide good feedback, a new wrapper to catch these errors +is not necessary. On the other hand, input validation is the best place to +catch errors and generate the best error messages. If required, generate +errors as soon as possible. + +The backend provides few standard ways of returning errors. + +First, there is a generic Internal Server Error:: + + Status Code: 500 + { + "version": , + "detail": "The server encountered an unexpected condition which prevented it from fulfilling the request.", + } + + +For errors generated by the backend, we provide a standard error +format:: + + Status Code: 400 + { + "detail": str(e), # E.g. "[errno -42] " + "component": "rbd", # this can be null to represent a global error code + "code": "3", # Or a error name, e.g. "code": "some_error_key" + } + + +In case, the API Endpoints uses @ViewCache to temporarily cache results, +the error looks like so:: + + Status Code 400 + { + "detail": str(e), # E.g. "[errno -42] " + "component": "rbd", # this can be null to represent a global error code + "code": "3", # Or a error name, e.g. "code": "some_error_key" + 'status': 3, # Indicating the @ViewCache error status + } + +In case, the API Endpoints uses a task the error looks like so:: + + Status Code 400 + { + "detail": str(e), # E.g. "[errno -42] " + "component": "rbd", # this can be null to represent a global error code + "code": "3", # Or a error name, e.g. "code": "some_error_key" + "task": { # Information about the task itself + "name": "taskname", + "metadata": {...} + } + } + + +Our WebUI should show errors generated by the API to the user. Especially +field-related errors in wizards and dialogs or show non-intrusive notifications. + +Handling exceptions in Python should be an exception. In general, we +should have few exception handlers in our project. Per default, propagate +errors to the API, as it will take care of all exceptions anyway. In general, +log the exception by adding ``logger.exception()`` with a description to the +handler. + +We need to distinguish between user errors from internal errors and +programming errors. Using different exception types will ease the +task for the API layer and for the user interface: + +Standard Python errors, like ``SystemError``, ``ValueError`` or ``KeyError`` +will end up as internal server errors in the API. + +In general, do not ``return`` error responses in the REST API. They will be +returned by the error handler. Instead, raise the appropriate exception. + +Plug-ins +~~~~~~~~ + +New functionality can be provided by means of a plug-in architecture. Among the +benefits this approach brings in, loosely coupled development is one of the most +notable. As the Ceph Dashboard grows in feature richness, its code-base becomes +more and more complex. The hook-based nature of a plug-in architecture allows to +extend functionality in a controlled manner, and isolate the scope of the +changes. + +Ceph Dashboard relies on `Pluggy `_ to provide +for plug-ing support. On top of pluggy, an interface-based approach has been +implemented, with some safety checks (method override and abstract method +checks). + +In order to create a new plugin, the following steps are required: + +#. Add a new file under ``src/pybind/mgr/dashboard/plugins``. +#. Import the ``PLUGIN_MANAGER`` instance and the ``Interfaces``. +#. Create a class extending the desired interfaces. The plug-in library will + check if all the methods of the interfaces have been properly overridden. +#. Register the plugin in the ``PLUGIN_MANAGER`` instance. +#. Import the plug-in from within the Ceph Dashboard ``module.py`` (currently no + dynamic loading is implemented). + +The available Mixins (helpers) are: + +- ``CanMgr``: provides the plug-in with access to the ``mgr`` instance under ``self.mgr``. +- ``CanLog``: provides the plug-in with access to the Ceph Dashboard logger under ``self.log``. + +The available Interfaces are: + +- ``Initializable``: requires overriding ``init()`` hook. This method is run at + the very beginning of the dashboard module, right after all imports have been + performed. +- ``Setupable``: requires overriding ``setup()`` hook. This method is run in the + Ceph Dashboard ``serve()`` method, right after CherryPy has been configured, + but before it is started. It's a placeholder for the plug-in initialization + logic. +- ``HasOptions``: requires overriding ``get_options()`` hook by returning a list + of ``Options()``. The options returned here are added to the + ``MODULE_OPTIONS``. +- ``HasCommands``: requires overriding ``register_commands()`` hook by defining + the commands the plug-in can handle and decorating them with ``@CLICommand``. + The commands can be optionally returned, so that they can be invoked + externally (which makes unit testing easier). +- ``HasControllers``: requires overriding ``get_controllers()`` hook by defining + and returning the controllers as usual. +- ``FilterRequest.BeforeHandler``: requires overriding + ``filter_request_before_handler()`` hook. This method receives a + ``cherrypy.request`` object for processing. A usual implementation of this + method will allow some requests to pass or will raise a ``cherrypy.HTTPError` + based on the ``request`` metadata and other conditions. + +New interfaces and hooks should be added as soon as they are required to +implement new functionality. The above list only comprises the hooks needed for +the existing plugins. + +A sample plugin implementation would look like this: + +.. code-block:: python + + # src/pybind/mgr/dashboard/plugins/mute.py + + from . import PLUGIN_MANAGER as PM + from . import interfaces as I + + from mgr_module import CLICommand, Option + import cherrypy + + @PM.add_plugin + class Mute(I.CanMgr, I.CanLog, I.Setupable, I.HasOptions, + I.HasCommands, I.FilterRequest.BeforeHandler, + I.HasControllers): + @PM.add_hook + def get_options(self): + return [Option('mute', default=False, type='bool')] + + @PM.add_hook + def setup(self): + self.mute = self.mgr.get_module_option('mute') + + @PM.add_hook + def register_commands(self): + @CLICommand("dashboard mute") + def _(mgr): + self.mute = True + self.mgr.set_module_option('mute', True) + return 0 + + @PM.add_hook + def filter_request_before_handler(self, request): + if self.mute: + raise cherrypy.HTTPError(500, "I'm muted :-x") + + @PM.add_hook + def get_controllers(self): + from ..controllers import ApiController, RESTController + + @ApiController('/mute') + class MuteController(RESTController): + def get(_): + return self.mute + + return [MuteController] + + +Additionally, a helper for creating plugins ``SimplePlugin`` is provided. It +facilitates the basic tasks (Options, Commands, and common Mixins). The previous +plugin could be rewritten like this: + +.. code-block:: python + + from . import PLUGIN_MANAGER as PM + from . import interfaces as I + from .plugin import SimplePlugin as SP + + import cherrypy + + @PM.add_plugin + class Mute(SP, I.Setupable, I.FilterRequest.BeforeHandler, I.HasControllers): + OPTIONS = [ + SP.Option('mute', default=False, type='bool') + ] + + def shut_up(self): + self.set_option('mute', True) + self.mute = True + return 0 + + COMMANDS = [ + SP.Command("dashboard mute", handler=shut_up) + ] + + @PM.add_hook + def setup(self): + self.mute = self.get_option('mute') + + @PM.add_hook + def filter_request_before_handler(self, request): + if self.mute: + raise cherrypy.HTTPError(500, "I'm muted :-x") + + @PM.add_hook + def get_controllers(self): + from ..controllers import ApiController, RESTController + + @ApiController('/mute') + class MuteController(RESTController): + def get(_): + return self.mute + + return [MuteController] + + diff --git a/src/pybind/mgr/dashboard/README.rst b/src/pybind/mgr/dashboard/README.rst new file mode 100644 index 00000000..0756845e --- /dev/null +++ b/src/pybind/mgr/dashboard/README.rst @@ -0,0 +1,37 @@ +Ceph Dashboard +============== + +Overview +-------- + +The Ceph Dashboard is a built-in web-based Ceph management and monitoring +application to administer various aspects and objects of the cluster. It is +implemented as a Ceph Manager module. + +Enabling and Starting the Dashboard +----------------------------------- + +If you want to start the dashboard from within a development environment, you +need to have built Ceph (see the toplevel ``README.md`` file and the `developer +documentation `_ for details on how to +accomplish this. + +Finally, you need to build the dashboard frontend code. See the file +``HACKING.rst`` in this directory for instructions on setting up the necessary +development environment. + +If you use the ``vstart.sh`` script to start up your development cluster, it +will configure and enable the dashboard automatically. The URL and login +credentials are displayed when the script finishes. + +Please see the `Ceph Dashboard documentation +`_ for details on how to enable +and configure the dashboard manually and how to configure other settings, e.g. +access to the Ceph object gateway. + +Working on the Dashboard Code +----------------------------- + +If you're interested in helping with the development of the dashboard, please +see the file ``HACKING.rst`` for details on how to set up a development +environment and other development-related topics. diff --git a/src/pybind/mgr/dashboard/__init__.py b/src/pybind/mgr/dashboard/__init__.py new file mode 100644 index 00000000..798ed37e --- /dev/null +++ b/src/pybind/mgr/dashboard/__init__.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# pylint: disable=wrong-import-position,global-statement,protected-access +""" +ceph dashboard module +""" +from __future__ import absolute_import + +import os + + +if 'UNITTEST' not in os.environ: + class _LoggerProxy(object): + def __init__(self): + self._logger = None + + def __getattr__(self, item): + if self._logger is None: + raise AttributeError("logger not initialized") + return getattr(self._logger, item) + + class _ModuleProxy(object): + def __init__(self): + self._mgr = None + + def init(self, module_inst): + global logger + self._mgr = module_inst + logger._logger = self._mgr._logger + + def __getattr__(self, item): + if self._mgr is None: + raise AttributeError("global manager module instance not initialized") + return getattr(self._mgr, item) + + mgr = _ModuleProxy() + logger = _LoggerProxy() + + from .module import Module, StandbyModule +else: + import logging + logging.basicConfig(level=logging.DEBUG) + logger = logging.getLogger(__name__) + logging.root.handlers[0].setLevel(logging.DEBUG) + os.environ['PATH'] = '{}:{}'.format(os.path.abspath('../../../../build/bin'), + os.environ['PATH']) + + # Mock ceph module otherwise every module that is involved in a testcase and imports it will + # raise an ImportError + import sys + import mock + sys.modules['ceph_module'] = mock.Mock() + + mgr = mock.Mock() + mgr.get_frontend_path.side_effect = lambda: os.path.abspath("./frontend/dist") diff --git a/src/pybind/mgr/dashboard/awsauth.py b/src/pybind/mgr/dashboard/awsauth.py new file mode 100644 index 00000000..fdf87de6 --- /dev/null +++ b/src/pybind/mgr/dashboard/awsauth.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +# pylint: disable-all +# +# Copyright (c) 2012-2013 Paul Tax All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. Neither the name of Infrae nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import hmac + +from hashlib import sha1 as sha + +py3k = False +try: + from urlparse import urlparse, unquote + from base64 import encodestring +except ImportError: + py3k = True + from urllib.parse import urlparse, unquote + from base64 import encodebytes as encodestring + +from email.utils import formatdate + +from requests.auth import AuthBase + + +class S3Auth(AuthBase): + + """Attaches AWS Authentication to the given Request object.""" + + service_base_url = 's3.amazonaws.com' + # List of Query String Arguments of Interest + special_params = [ + 'acl', 'location', 'logging', 'partNumber', 'policy', 'requestPayment', + 'torrent', 'versioning', 'versionId', 'versions', 'website', 'uploads', + 'uploadId', 'response-content-type', 'response-content-language', + 'response-expires', 'response-cache-control', 'delete', 'lifecycle', + 'response-content-disposition', 'response-content-encoding', 'tagging', + 'notification', 'cors' + ] + + def __init__(self, access_key, secret_key, service_url=None): + if service_url: + self.service_base_url = service_url + self.access_key = str(access_key) + self.secret_key = str(secret_key) + + def __call__(self, r): + # Create date header if it is not created yet. + if 'date' not in r.headers and 'x-amz-date' not in r.headers: + r.headers['date'] = formatdate( + timeval=None, + localtime=False, + usegmt=True) + signature = self.get_signature(r) + if py3k: + signature = signature.decode('utf-8') + r.headers['Authorization'] = 'AWS %s:%s' % (self.access_key, signature) + return r + + def get_signature(self, r): + canonical_string = self.get_canonical_string( + r.url, r.headers, r.method) + if py3k: + key = self.secret_key.encode('utf-8') + msg = canonical_string.encode('utf-8') + else: + key = self.secret_key + msg = canonical_string + h = hmac.new(key, msg, digestmod=sha) + return encodestring(h.digest()).strip() + + def get_canonical_string(self, url, headers, method): + parsedurl = urlparse(url) + objectkey = parsedurl.path[1:] + query_args = sorted(parsedurl.query.split('&')) + + bucket = parsedurl.netloc[:-len(self.service_base_url)] + if len(bucket) > 1: + # remove last dot + bucket = bucket[:-1] + + interesting_headers = { + 'content-md5': '', + 'content-type': '', + 'date': ''} + for key in headers: + lk = key.lower() + try: + if isinstance(lk, bytes): + lk = lk.decode('utf-8') + except UnicodeDecodeError: + pass + if headers[key] and (lk in interesting_headers.keys() + or lk.startswith('x-amz-')): + interesting_headers[lk] = headers[key].strip() + + # If x-amz-date is used it supersedes the date header. + if not py3k: + if 'x-amz-date' in interesting_headers: + interesting_headers['date'] = '' + else: + if 'x-amz-date' in interesting_headers: + interesting_headers['date'] = '' + + buf = '%s\n' % method + for key in sorted(interesting_headers.keys()): + val = interesting_headers[key] + if key.startswith('x-amz-'): + buf += '%s:%s\n' % (key, val) + else: + buf += '%s\n' % val + + # append the bucket if it exists + if bucket != '': + buf += '/%s' % bucket + + # add the objectkey. even if it doesn't exist, add the slash + buf += '/%s' % objectkey + + params_found = False + + # handle special query string arguments + for q in query_args: + k = q.split('=')[0] + if k in self.special_params: + buf += '&' if params_found else '?' + params_found = True + + try: + k, v = q.split('=', 1) + + except ValueError: + buf += q + + else: + # Riak CS multipart upload ids look like this, `TFDSheOgTxC2Tsh1qVK73A==`, + # is should be escaped to be included as part of a query string. + # + # A requests mp upload part request may look like + # resp = requests.put( + # 'https://url_here', + # params={ + # 'partNumber': 1, + # 'uploadId': 'TFDSheOgTxC2Tsh1qVK73A==' + # }, + # data='some data', + # auth=S3Auth('access_key', 'secret_key') + # ) + # + # Requests automatically escapes the values in the `params` dict, so now + # our uploadId is `TFDSheOgTxC2Tsh1qVK73A%3D%3D`, + # if we sign the request with the encoded value the signature will + # not be valid, we'll get 403 Access Denied. + # So we unquote, this is no-op if the value isn't encoded. + buf += '{key}={value}'.format(key=k, value=unquote(v)) + + return buf diff --git a/src/pybind/mgr/dashboard/cherrypy_backports.py b/src/pybind/mgr/dashboard/cherrypy_backports.py new file mode 100644 index 00000000..524e3d58 --- /dev/null +++ b/src/pybind/mgr/dashboard/cherrypy_backports.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +""" +Copyright © 2004-2019, CherryPy Team (team@cherrypy.org) + +All rights reserved. + +* * * + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of CherryPy nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +from distutils.version import StrictVersion + +# The SSL code in CherryPy 3.5.0 is buggy. It was fixed long ago, +# but 3.5.0 is still shipping in major linux distributions +# (Fedora 27, Ubuntu Xenial), so we must monkey patch it to get SSL working. + + +def patch_http_connection_init(v): + # It was fixed in 3.7.0. Exact lower bound version is probably earlier, + # but 3.5.0 is what this monkey patch is tested on. + if StrictVersion("3.5.0") <= v < StrictVersion("3.7.0"): + from cherrypy.wsgiserver.wsgiserver2 import \ + HTTPConnection, CP_fileobject + + def fixed_init(hc_self, server, sock, makefile=CP_fileobject): + hc_self.server = server + hc_self.socket = sock + hc_self.rfile = makefile(sock, "rb", hc_self.rbufsize) + hc_self.wfile = makefile(sock, "wb", hc_self.wbufsize) + hc_self.requests_seen = 0 + + HTTPConnection.__init__ = fixed_init + + +# When the CherryPy server in 3.2.2 (and later) starts it attempts to verify +# that the ports its listening on are in fact bound. When using the any address +# "::" it tries both ipv4 and ipv6, and in some environments (e.g. kubernetes) +# ipv6 isn't yet configured / supported and CherryPy throws an uncaught +# exception. +def skip_wait_for_occupied_port(v): + # the issue was fixed in 3.2.3. it's present in 3.2.2 (current version on + # centos:7) and back to at least 3.0.0. + if StrictVersion("3.1.2") <= v < StrictVersion("3.2.3"): + # https://github.com/cherrypy/cherrypy/issues/1100 + from cherrypy.process import servers + servers.wait_for_occupied_port = lambda host, port: None + + +# cherrypy.wsgiserver was extracted wsgiserver into cheroot in cherrypy v9.0.0 +def patch_builtin_ssl_wrap(v, new_wrap): + if v < StrictVersion("9.0.0"): + from cherrypy.wsgiserver.ssl_builtin import BuiltinSSLAdapter as builtin_ssl + else: + from cheroot.ssl.builtin import BuiltinSSLAdapter as builtin_ssl + builtin_ssl.wrap = new_wrap(builtin_ssl.wrap) + + +def accept_exceptions_from_builtin_ssl(v): + # the fix was included by cheroot v5.2.0, which was included by cherrypy + # 10.2.0. + if v < StrictVersion("10.2.0"): + # see https://github.com/cherrypy/cheroot/pull/4 + import ssl + + def accept_ssl_errors(func): + def wrapper(self, sock): + try: + return func(self, sock) + except ssl.SSLError as e: + if e.errno == ssl.SSL_ERROR_SSL: + # Check if it's one of the known errors + # Errors that are caught by PyOpenSSL, but thrown by + # built-in ssl + _block_errors = ('unknown protocol', 'unknown ca', 'unknown_ca', + 'unknown error', + 'https proxy request', 'inappropriate fallback', + 'wrong version number', + 'no shared cipher', 'certificate unknown', + 'ccs received early', + 'certificate verify failed', # client cert w/o trusted CA + 'version too low', # caused by SSL3 connections + 'unsupported protocol', # caused by TLS1 connections + 'sslv3 alert bad certificate') + for error_text in _block_errors: + if error_text in e.args[1].lower(): + # Accepted error, let's pass + return None, {} + raise + return wrapper + patch_builtin_ssl_wrap(v, accept_ssl_errors) + + +def accept_socket_error_0(v): + # see https://github.com/cherrypy/cherrypy/issues/1618 + try: + import cheroot + cheroot_version = cheroot.__version__ + except ImportError: + pass + + if v < StrictVersion("9.0.0") or cheroot_version < StrictVersion("6.5.5"): + import six + if six.PY3: + generic_socket_error = OSError + else: + import socket + generic_socket_error = socket.error + + def accept_socket_error_0(func): + def wrapper(self, sock): + try: + return func(self, sock) + except generic_socket_error as e: + """It is unclear why exactly this happens. + + It's reproducible only with openssl>1.0 and stdlib ``ssl`` wrapper. + In CherryPy it's triggered by Checker plugin, which connects + to the app listening to the socket port in TLS mode via plain + HTTP during startup (from the same process). + + Ref: https://github.com/cherrypy/cherrypy/issues/1618 + """ + import ssl + is_error0 = e.args == (0, 'Error') + IS_ABOVE_OPENSSL10 = ssl.OPENSSL_VERSION_INFO >= (1, 1) + del ssl + if is_error0 and IS_ABOVE_OPENSSL10: + return None, {} + raise + return wrapper + patch_builtin_ssl_wrap(v, accept_socket_error_0) + + +def patch_request_unique_id(v): + """ + Older versions of cherrypy don't include request.unique_id field (a lazily + calculated UUID4). + + Monkey-patching is preferred over alternatives as inheritance, as it'd break + type checks (cherrypy/lib/cgtools.py: `isinstance(obj, _cprequest.Request)`) + """ + if v < StrictVersion('11.1.0'): + import uuid + from functools import update_wrapper + from cherrypy._cprequest import Request + + class LazyUUID4(object): + def __str__(self): + """Return UUID4 and keep it for future calls.""" + return str(self.uuid4) + + @property + def uuid4(self): + """Provide unique id on per-request basis using UUID4. + It's evaluated lazily on render. + """ + try: + self._uuid4 + except AttributeError: + # evaluate on first access + self._uuid4 = uuid.uuid4() + + return self._uuid4 + + old_init = Request.__init__ + + def init_with_unique_id(self, *args, **kwargs): + old_init(self, *args, **kwargs) + self.unique_id = LazyUUID4() + + Request.__init__ = update_wrapper(init_with_unique_id, old_init) + + +def patch_cherrypy(v): + patch_http_connection_init(v) + skip_wait_for_occupied_port(v) + accept_exceptions_from_builtin_ssl(v) + accept_socket_error_0(v) + patch_request_unique_id(v) diff --git a/src/pybind/mgr/dashboard/ci/check_grafana_uids.py b/src/pybind/mgr/dashboard/ci/check_grafana_uids.py new file mode 100644 index 00000000..134bb6e7 --- /dev/null +++ b/src/pybind/mgr/dashboard/ci/check_grafana_uids.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# pylint: disable=F0401 +""" +This script does: +* Scan through Angular html templates and extract tags +* Check if every tag has a corresponding Grafana dashboard by `uid` + +Usage: + python + + + + """.format(spec_url) + + return page + + @Endpoint(json_response=False) + def __call__(self, all_endpoints=False): + return self._swagger_ui_page(all_endpoints) diff --git a/src/pybind/mgr/dashboard/controllers/erasure_code_profile.py b/src/pybind/mgr/dashboard/controllers/erasure_code_profile.py new file mode 100644 index 00000000..34c9f651 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/erasure_code_profile.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from cherrypy import NotFound + +from . import ApiController, RESTController, Endpoint, ReadPermission +from ..security import Scope +from ..services.ceph_service import CephService +from .. import mgr + + +def _serialize_ecp(name, ecp): + def serialize_numbers(key): + value = ecp.get(key) + if value is not None: + ecp[key] = int(value) + + ecp['name'] = name + serialize_numbers('k') + serialize_numbers('m') + return ecp + + +@ApiController('/erasure_code_profile', Scope.POOL) +class ErasureCodeProfile(RESTController): + ''' + create() supports additional key-value arguments that are passed to the + ECP plugin. + ''' + + def list(self): + ret = [] + for name, ecp in mgr.get('osd_map').get('erasure_code_profiles', {}).items(): + ret.append(_serialize_ecp(name, ecp)) + return ret + + def get(self, name): + try: + ecp = mgr.get('osd_map')['erasure_code_profiles'][name] + return _serialize_ecp(name, ecp) + except KeyError: + raise NotFound('No such erasure code profile') + + def create(self, name, **kwargs): + profile = ['{}={}'.format(key, value) for key, value in kwargs.items()] + CephService.send_command('mon', 'osd erasure-code-profile set', name=name, + profile=profile) + + def delete(self, name): + CephService.send_command('mon', 'osd erasure-code-profile rm', name=name) + + @Endpoint() + @ReadPermission + def _info(self): + '''Used for profile creation and editing''' + config = mgr.get('config') + osd_map_crush = mgr.get('osd_map_crush') + return { + # Because 'shec' is experimental it's not included + 'plugins': config['osd_erasure_code_plugins'].split() + ['shec'], + 'directory': config['erasure_code_dir'], + 'devices': list({device['class'] for device in osd_map_crush['devices']}), + 'failure_domains': [domain['name'] for domain in osd_map_crush['types']], + 'names': [name for name, _ in + mgr.get('osd_map').get('erasure_code_profiles', {}).items()] + } diff --git a/src/pybind/mgr/dashboard/controllers/grafana.py b/src/pybind/mgr/dashboard/controllers/grafana.py new file mode 100644 index 00000000..001367c7 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/grafana.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import (ApiController, BaseController, Endpoint, ReadPermission, + UpdatePermission) +from .. import mgr +from ..exceptions import DashboardException +from ..grafana import GrafanaRestClient, push_local_dashboards +from ..security import Scope +from ..settings import Settings + + +@ApiController('/grafana', Scope.GRAFANA) +class Grafana(BaseController): + @Endpoint() + @ReadPermission + def url(self): + grafana_url = mgr.get_module_option('GRAFANA_API_URL') + grafana_frontend_url = mgr.get_module_option('GRAFANA_FRONTEND_API_URL') + if grafana_frontend_url != '' and grafana_url == '': + url = '' + else: + url = (mgr.get_module_option('GRAFANA_FRONTEND_API_URL') + or mgr.get_module_option('GRAFANA_API_URL')).rstrip('/') + response = {'instance': url} + return response + + @Endpoint() + @ReadPermission + def validation(self, params): + grafana = GrafanaRestClient() + method = 'GET' + url = str(Settings.GRAFANA_API_URL).rstrip('/') + \ + '/api/dashboards/uid/' + params + response = grafana.url_validation(method, url) + return response + + @Endpoint(method='POST') + @UpdatePermission + def dashboards(self): + response = dict() + try: + response['success'] = push_local_dashboards() + except Exception as e: # pylint: disable=broad-except + raise DashboardException( + msg=str(e), + component='grafana', + http_status_code=500, + ) + return response diff --git a/src/pybind/mgr/dashboard/controllers/health.py b/src/pybind/mgr/dashboard/controllers/health.py new file mode 100644 index 00000000..fab19bcb --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/health.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json + +from . import ApiController, Endpoint, BaseController + +from .. import mgr +from ..security import Permission, Scope +from ..services.ceph_service import CephService +from ..services.iscsi_cli import IscsiGatewaysConfig + + +class HealthData(object): + """ + A class to be used in combination with BaseController to allow either + "full" or "minimal" sets of health data to be collected. + + To function properly, it needs BaseCollector._has_permissions to be passed + in as ``auth_callback``. + """ + + def __init__(self, auth_callback, minimal=True): + self._has_permissions = auth_callback + self._minimal = minimal + + @staticmethod + def _partial_dict(orig, keys): + return {k: orig[k] for k in keys} + + def all_health(self): + result = { + "health": self.basic_health(), + } + + if self._has_permissions(Permission.READ, Scope.MONITOR): + result['mon_status'] = self.mon_status() + + if self._has_permissions(Permission.READ, Scope.CEPHFS): + result['fs_map'] = self.fs_map() + + if self._has_permissions(Permission.READ, Scope.OSD): + result['osd_map'] = self.osd_map() + result['scrub_status'] = self.scrub_status() + result['pg_info'] = self.pg_info() + + if self._has_permissions(Permission.READ, Scope.MANAGER): + result['mgr_map'] = self.mgr_map() + + if self._has_permissions(Permission.READ, Scope.POOL): + result['pools'] = self.pools() + result['df'] = self.df() + result['client_perf'] = self.client_perf() + + if self._has_permissions(Permission.READ, Scope.HOSTS): + result['hosts'] = self.host_count() + + if self._has_permissions(Permission.READ, Scope.RGW): + result['rgw'] = self.rgw_count() + + if self._has_permissions(Permission.READ, Scope.ISCSI): + result['iscsi_daemons'] = self.iscsi_daemons() + + return result + + def basic_health(self): + health_data = mgr.get("health") + health = json.loads(health_data['json']) + + # Transform the `checks` dict into a list for the convenience + # of rendering from javascript. + checks = [] + for k, v in health['checks'].items(): + v['type'] = k + checks.append(v) + + checks = sorted(checks, key=lambda c: c['severity']) + health['checks'] = checks + return health + + def client_perf(self): + result = CephService.get_client_perf() + if self._minimal: + result = self._partial_dict( + result, + ['read_bytes_sec', 'read_op_per_sec', + 'recovering_bytes_per_sec', 'write_bytes_sec', + 'write_op_per_sec'] + ) + return result + + def df(self): + df = mgr.get('df') + + del df['stats_by_class'] + + if self._minimal: + df = dict(stats=self._partial_dict( + df['stats'], + ['total_avail_bytes', 'total_bytes', + 'total_used_raw_bytes'] + )) + return df + + def fs_map(self): + fs_map = mgr.get('fs_map') + if self._minimal: + fs_map = self._partial_dict(fs_map, ['filesystems', 'standbys']) + fs_map['filesystems'] = [self._partial_dict(item, ['mdsmap']) for + item in fs_map['filesystems']] + for fs in fs_map['filesystems']: + mdsmap_info = fs['mdsmap']['info'] + min_mdsmap_info = dict() + for k, v in mdsmap_info.items(): + min_mdsmap_info[k] = self._partial_dict(v, ['state']) + return fs_map + + def host_count(self): + return len(mgr.list_servers()) + + def iscsi_daemons(self): + gateways = IscsiGatewaysConfig.get_gateways_config()['gateways'] + return len(gateways) if gateways else 0 + + def mgr_map(self): + mgr_map = mgr.get('mgr_map') + if self._minimal: + mgr_map = self._partial_dict(mgr_map, ['active_name', 'standbys']) + return mgr_map + + def mon_status(self): + mon_status = json.loads(mgr.get('mon_status')['json']) + if self._minimal: + mon_status = self._partial_dict(mon_status, ['monmap', 'quorum']) + mon_status['monmap'] = self._partial_dict( + mon_status['monmap'], ['mons'] + ) + mon_status['monmap']['mons'] = [{}] * \ + len(mon_status['monmap']['mons']) + return mon_status + + def osd_map(self): + osd_map = mgr.get('osd_map') + assert osd_map is not None + # Not needed, skip the effort of transmitting this to UI + del osd_map['pg_temp'] + if self._minimal: + osd_map = self._partial_dict(osd_map, ['osds']) + osd_map['osds'] = [ + self._partial_dict(item, ['in', 'up']) + for item in osd_map['osds'] + ] + else: + osd_map['tree'] = mgr.get('osd_map_tree') + osd_map['crush'] = mgr.get('osd_map_crush') + osd_map['crush_map_text'] = mgr.get('osd_map_crush_map_text') + osd_map['osd_metadata'] = mgr.get('osd_metadata') + return osd_map + + def pg_info(self): + return CephService.get_pg_info() + + def pools(self): + pools = CephService.get_pool_list_with_stats() + if self._minimal: + pools = [{}] * len(pools) + return pools + + def rgw_count(self): + return len(CephService.get_service_list('rgw')) + + def scrub_status(self): + return CephService.get_scrub_status() + + +@ApiController('/health') +class Health(BaseController): + def __init__(self): + super(Health, self).__init__() + self.health_full = HealthData(self._has_permissions, minimal=False) + self.health_minimal = HealthData(self._has_permissions, minimal=True) + + @Endpoint() + def full(self): + return self.health_full.all_health() + + @Endpoint() + def minimal(self): + return self.health_minimal.all_health() diff --git a/src/pybind/mgr/dashboard/controllers/home.py b/src/pybind/mgr/dashboard/controllers/home.py new file mode 100644 index 00000000..0fbe79f7 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/home.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import os +import re +import json +try: + from functools import lru_cache +except ImportError: + from ..plugins.lru_cache import lru_cache + +import cherrypy +from cherrypy.lib.static import serve_file + +from . import Controller, UiApiController, BaseController, Proxy, Endpoint +from .. import mgr, logger + + +class LanguageMixin(object): + def __init__(self): + self.LANGUAGES = { + f + for f in os.listdir(mgr.get_frontend_path()) + if os.path.isdir(os.path.join(mgr.get_frontend_path(), f)) + } + self.LANGUAGES_PATH_MAP = { + f.lower(): { + 'lang': f, + 'path': os.path.join(mgr.get_frontend_path(), f) + } + for f in self.LANGUAGES + } + # pre-populating with the primary language subtag. + for lang in list(self.LANGUAGES_PATH_MAP.keys()): + if '-' in lang: + self.LANGUAGES_PATH_MAP[lang.split('-')[0]] = { + 'lang': self.LANGUAGES_PATH_MAP[lang]['lang'], + 'path': self.LANGUAGES_PATH_MAP[lang]['path'] + } + with open("{}/../package.json".format(mgr.get_frontend_path()), + "r") as f: + config = json.load(f) + self.DEFAULT_LANGUAGE = config['config']['locale'] + self.DEFAULT_LANGUAGE_PATH = os.path.join(mgr.get_frontend_path(), + self.DEFAULT_LANGUAGE) + super(LanguageMixin, self).__init__() + + +@Controller("/", secure=False) +class HomeController(BaseController, LanguageMixin): + LANG_TAG_SEQ_RE = re.compile(r'\s*([^,]+)\s*,?\s*') + LANG_TAG_RE = re.compile( + r'^(?P[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})?)(;q=(?P[01]\.\d{0,3}))?$') + MAX_ACCEPTED_LANGS = 10 + + @lru_cache() + def _parse_accept_language(self, accept_lang_header): + result = [] + for i, m in enumerate(self.LANG_TAG_SEQ_RE.finditer(accept_lang_header)): + if i >= self.MAX_ACCEPTED_LANGS: + logger.debug("reached max accepted languages, skipping remaining") + break + + tag_match = self.LANG_TAG_RE.match(m.group(1)) + if tag_match is None: + raise cherrypy.HTTPError(400, "Malformed 'Accept-Language' header") + locale = tag_match.group('locale').lower() + weight = tag_match.group('weight') + if weight: + try: + ratio = float(weight) + except ValueError: + raise cherrypy.HTTPError(400, "Malformed 'Accept-Language' header") + else: + ratio = 1.0 + result.append((locale, ratio)) + + result.sort(key=lambda l: l[0]) + result.sort(key=lambda l: l[1], reverse=True) + logger.debug("language preference: %s", result) + return [l[0] for l in result] + + def _language_dir(self, langs): + for lang in langs: + if lang in self.LANGUAGES_PATH_MAP: + logger.debug("found directory for language '%s'", lang) + cherrypy.response.headers[ + 'Content-Language'] = self.LANGUAGES_PATH_MAP[lang]['lang'] + return self.LANGUAGES_PATH_MAP[lang]['path'] + + logger.debug("Languages '%s' not available, falling back to %s", + langs, self.DEFAULT_LANGUAGE) + cherrypy.response.headers['Content-Language'] = self.DEFAULT_LANGUAGE + return self.DEFAULT_LANGUAGE_PATH + + @Proxy() + def __call__(self, path, **params): + if not path: + path = "index.html" + + if 'cd-lang' in cherrypy.request.cookie: + langs = [cherrypy.request.cookie['cd-lang'].value.lower()] + logger.debug("frontend language from cookie: %s", langs) + else: + if 'Accept-Language' in cherrypy.request.headers: + accept_lang_header = cherrypy.request.headers['Accept-Language'] + langs = self._parse_accept_language(accept_lang_header) + else: + langs = [self.DEFAULT_LANGUAGE.lower()] + logger.debug("frontend language from headers: %s", langs) + + base_dir = self._language_dir(langs) + full_path = os.path.join(base_dir, path) + + # Block uplevel attacks + if not os.path.normpath(full_path).startswith(os.path.normpath(base_dir)): + raise cherrypy.HTTPError(403) # Forbidden + + logger.debug("serving static content: %s", full_path) + if 'Vary' in cherrypy.response.headers: + cherrypy.response.headers['Vary'] = "{}, Accept-Language" + else: + cherrypy.response.headers['Vary'] = "Accept-Language" + + cherrypy.response.headers['Cache-control'] = "no-cache" + return serve_file(full_path) + + +@UiApiController("/langs", secure=False) +class LangsController(BaseController, LanguageMixin): + @Endpoint('GET') + def __call__(self): + return list(self.LANGUAGES) diff --git a/src/pybind/mgr/dashboard/controllers/host.py b/src/pybind/mgr/dashboard/controllers/host.py new file mode 100644 index 00000000..e8518a14 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/host.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import ApiController, RESTController +from .. import mgr +from ..security import Scope + + +@ApiController('/host', Scope.HOSTS) +class Host(RESTController): + def list(self): + return mgr.list_servers() diff --git a/src/pybind/mgr/dashboard/controllers/iscsi.py b/src/pybind/mgr/dashboard/controllers/iscsi.py new file mode 100644 index 00000000..af753205 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/iscsi.py @@ -0,0 +1,1049 @@ +# -*- coding: utf-8 -*- +# pylint: disable=too-many-branches +# pylint: disable=too-many-lines +from __future__ import absolute_import + +from copy import deepcopy +import re +import json +import cherrypy + +import rados +import rbd + +from . import ApiController, UiApiController, RESTController, BaseController, Endpoint,\ + ReadPermission, UpdatePermission, Task +from .. import mgr +from ..rest_client import RequestException +from ..security import Scope +from ..services.iscsi_client import IscsiClient +from ..services.iscsi_cli import IscsiGatewaysConfig +from ..services.iscsi_config import IscsiGatewayDoesNotExist +from ..services.rbd import format_bitmask +from ..services.tcmu_service import TcmuService +from ..exceptions import DashboardException +from ..tools import str_to_bool, TaskManager + + +@UiApiController('/iscsi', Scope.ISCSI) +class IscsiUi(BaseController): + + REQUIRED_CEPH_ISCSI_CONFIG_MIN_VERSION = 10 + REQUIRED_CEPH_ISCSI_CONFIG_MAX_VERSION = 11 + + @Endpoint() + @ReadPermission + def status(self): + status = {'available': False} + try: + gateway = get_available_gateway() + except DashboardException as e: + status['message'] = str(e) + return status + try: + config = IscsiClient.instance(gateway_name=gateway).get_config() + if config['version'] < IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MIN_VERSION or \ + config['version'] > IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MAX_VERSION: + status['message'] = 'Unsupported `ceph-iscsi` config version. ' \ + 'Expected >= {} and <= {} but found' \ + ' {}.'.format(IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MIN_VERSION, + IscsiUi.REQUIRED_CEPH_ISCSI_CONFIG_MAX_VERSION, + config['version']) + return status + status['available'] = True + except RequestException as e: + if e.content: + try: + content = json.loads(e.content) + content_message = content.get('message') + except ValueError: + content_message = e.content + if content_message: + status['message'] = content_message + + return status + + @Endpoint() + @ReadPermission + def version(self): + gateway = get_available_gateway() + config = IscsiClient.instance(gateway_name=gateway).get_config() + return { + 'ceph_iscsi_config_version': config['version'] + } + + @Endpoint() + @ReadPermission + def settings(self): + gateway = get_available_gateway() + settings = IscsiClient.instance(gateway_name=gateway).get_settings() + if 'target_controls_limits' in settings: + target_default_controls = settings['target_default_controls'] + for ctrl_k, ctrl_v in target_default_controls.items(): + limits = settings['target_controls_limits'].get(ctrl_k, {}) + if 'type' not in limits: + # default + limits['type'] = 'int' + # backward compatibility + if target_default_controls[ctrl_k] in ['Yes', 'No']: + limits['type'] = 'bool' + target_default_controls[ctrl_k] = str_to_bool(ctrl_v) + settings['target_controls_limits'][ctrl_k] = limits + if 'disk_controls_limits' in settings: + for backstore, disk_controls_limits in settings['disk_controls_limits'].items(): + disk_default_controls = settings['disk_default_controls'][backstore] + for ctrl_k, ctrl_v in disk_default_controls.items(): + limits = disk_controls_limits.get(ctrl_k, {}) + if 'type' not in limits: + # default + limits['type'] = 'int' + settings['disk_controls_limits'][backstore][ctrl_k] = limits + return settings + + @Endpoint() + @ReadPermission + def portals(self): + portals = [] + gateways_config = IscsiGatewaysConfig.get_gateways_config() + for name in gateways_config['gateways']: + try: + ip_addresses = IscsiClient.instance(gateway_name=name).get_ip_addresses() + portals.append({'name': name, 'ip_addresses': ip_addresses['data']}) + except RequestException: + pass + return sorted(portals, key=lambda p: '{}.{}'.format(p['name'], p['ip_addresses'])) + + @Endpoint() + @ReadPermission + def overview(self): + result_gateways = [] + result_images = [] + gateways_names = IscsiGatewaysConfig.get_gateways_config()['gateways'].keys() + config = None + for gateway_name in gateways_names: + try: + config = IscsiClient.instance(gateway_name=gateway_name).get_config() + break + except RequestException: + pass + + # Gateways info + for gateway_name in gateways_names: + gateway = { + 'name': gateway_name, + 'state': '', + 'num_targets': 'n/a', + 'num_sessions': 'n/a' + } + try: + IscsiClient.instance(gateway_name=gateway_name).ping() + gateway['state'] = 'up' + if config: + gateway['num_sessions'] = 0 + if gateway_name in config['gateways']: + gatewayinfo = IscsiClient.instance( + gateway_name=gateway_name).get_gatewayinfo() + gateway['num_sessions'] = gatewayinfo['num_sessions'] + except RequestException: + gateway['state'] = 'down' + if config: + gateway['num_targets'] = len([target for _, target in config['targets'].items() + if gateway_name in target['portals']]) + result_gateways.append(gateway) + + # Images info + if config: + tcmu_info = TcmuService.get_iscsi_info() + for _, disk_config in config['disks'].items(): + image = { + 'pool': disk_config['pool'], + 'image': disk_config['image'], + 'backstore': disk_config['backstore'], + 'optimized_since': None, + 'stats': None, + 'stats_history': None + } + tcmu_image_info = TcmuService.get_image_info(image['pool'], + image['image'], + tcmu_info) + if tcmu_image_info: + if 'optimized_since' in tcmu_image_info: + image['optimized_since'] = tcmu_image_info['optimized_since'] + if 'stats' in tcmu_image_info: + image['stats'] = tcmu_image_info['stats'] + if 'stats_history' in tcmu_image_info: + image['stats_history'] = tcmu_image_info['stats_history'] + result_images.append(image) + + return { + 'gateways': sorted(result_gateways, key=lambda g: g['name']), + 'images': sorted(result_images, key=lambda i: '{}/{}'.format(i['pool'], i['image'])) + } + + +@ApiController('/iscsi', Scope.ISCSI) +class Iscsi(BaseController): + + @Endpoint('GET', 'discoveryauth') + @ReadPermission + def get_discoveryauth(self): + gateway = get_available_gateway() + return self._get_discoveryauth(gateway) + + @Endpoint('PUT', 'discoveryauth') + @UpdatePermission + def set_discoveryauth(self, user, password, mutual_user, mutual_password): + validate_auth({ + 'user': user, + 'password': password, + 'mutual_user': mutual_user, + 'mutual_password': mutual_password + }) + + gateway = get_available_gateway() + config = IscsiClient.instance(gateway_name=gateway).get_config() + gateway_names = list(config['gateways'].keys()) + validate_rest_api(gateway_names) + IscsiClient.instance(gateway_name=gateway).update_discoveryauth(user, + password, + mutual_user, + mutual_password) + return self._get_discoveryauth(gateway) + + def _get_discoveryauth(self, gateway): + config = IscsiClient.instance(gateway_name=gateway).get_config() + user = config['discovery_auth']['username'] + password = config['discovery_auth']['password'] + mutual_user = config['discovery_auth']['mutual_username'] + mutual_password = config['discovery_auth']['mutual_password'] + return { + 'user': user, + 'password': password, + 'mutual_user': mutual_user, + 'mutual_password': mutual_password + } + + +def iscsi_target_task(name, metadata, wait_for=2.0): + return Task("iscsi/target/{}".format(name), metadata, wait_for) + + +@ApiController('/iscsi/target', Scope.ISCSI) +class IscsiTarget(RESTController): + + def list(self): + gateway = get_available_gateway() + config = IscsiClient.instance(gateway_name=gateway).get_config() + targets = [] + for target_iqn in config['targets'].keys(): + target = IscsiTarget._config_to_target(target_iqn, config) + IscsiTarget._set_info(target) + targets.append(target) + return targets + + def get(self, target_iqn): + gateway = get_available_gateway() + config = IscsiClient.instance(gateway_name=gateway).get_config() + if target_iqn not in config['targets']: + raise cherrypy.HTTPError(404) + target = IscsiTarget._config_to_target(target_iqn, config) + IscsiTarget._set_info(target) + return target + + @iscsi_target_task('delete', {'target_iqn': '{target_iqn}'}) + def delete(self, target_iqn): + gateway = get_available_gateway() + config = IscsiClient.instance(gateway_name=gateway).get_config() + if target_iqn not in config['targets']: + raise DashboardException(msg='Target does not exist', + code='target_does_not_exist', + component='iscsi') + portal_names = list(config['targets'][target_iqn]['portals'].keys()) + validate_rest_api(portal_names) + if portal_names: + portal_name = portal_names[0] + target_info = IscsiClient.instance(gateway_name=portal_name).get_targetinfo(target_iqn) + if target_info['num_sessions'] > 0: + raise DashboardException(msg='Target has active sessions', + code='target_has_active_sessions', + component='iscsi') + IscsiTarget._delete(target_iqn, config, 0, 100) + + @iscsi_target_task('create', {'target_iqn': '{target_iqn}'}) + def create(self, target_iqn=None, target_controls=None, acl_enabled=None, + auth=None, portals=None, disks=None, clients=None, groups=None): + target_controls = target_controls or {} + portals = portals or [] + disks = disks or [] + clients = clients or [] + groups = groups or [] + + validate_auth(auth) + for client in clients: + validate_auth(client['auth']) + + gateway = get_available_gateway() + config = IscsiClient.instance(gateway_name=gateway).get_config() + if target_iqn in config['targets']: + raise DashboardException(msg='Target already exists', + code='target_already_exists', + component='iscsi') + settings = IscsiClient.instance(gateway_name=gateway).get_settings() + IscsiTarget._validate(target_iqn, target_controls, portals, disks, groups, settings) + + IscsiTarget._create(target_iqn, target_controls, acl_enabled, auth, portals, disks, + clients, groups, 0, 100, config, settings) + + @iscsi_target_task('edit', {'target_iqn': '{target_iqn}'}) + def set(self, target_iqn, new_target_iqn=None, target_controls=None, acl_enabled=None, + auth=None, portals=None, disks=None, clients=None, groups=None): + target_controls = target_controls or {} + portals = IscsiTarget._sorted_portals(portals) + disks = IscsiTarget._sorted_disks(disks) + clients = IscsiTarget._sorted_clients(clients) + groups = IscsiTarget._sorted_groups(groups) + + validate_auth(auth) + for client in clients: + validate_auth(client['auth']) + + gateway = get_available_gateway() + config = IscsiClient.instance(gateway_name=gateway).get_config() + if target_iqn not in config['targets']: + raise DashboardException(msg='Target does not exist', + code='target_does_not_exist', + component='iscsi') + if target_iqn != new_target_iqn and new_target_iqn in config['targets']: + raise DashboardException(msg='Target IQN already in use', + code='target_iqn_already_in_use', + component='iscsi') + + settings = IscsiClient.instance(gateway_name=gateway).get_settings() + new_portal_names = {p['host'] for p in portals} + old_portal_names = set(config['targets'][target_iqn]['portals'].keys()) + deleted_portal_names = list(old_portal_names - new_portal_names) + validate_rest_api(deleted_portal_names) + IscsiTarget._validate(new_target_iqn, target_controls, portals, disks, groups, settings) + IscsiTarget._validate_delete(gateway, target_iqn, config, new_target_iqn, target_controls, + disks, clients, groups) + config = IscsiTarget._delete(target_iqn, config, 0, 50, new_target_iqn, target_controls, + portals, disks, clients, groups) + IscsiTarget._create(new_target_iqn, target_controls, acl_enabled, auth, portals, disks, + clients, groups, 50, 100, config, settings) + + @staticmethod + def _delete(target_iqn, config, task_progress_begin, task_progress_end, new_target_iqn=None, + new_target_controls=None, new_portals=None, new_disks=None, new_clients=None, + new_groups=None): + new_target_controls = new_target_controls or {} + new_portals = new_portals or [] + new_disks = new_disks or [] + new_clients = new_clients or [] + new_groups = new_groups or [] + + TaskManager.current_task().set_progress(task_progress_begin) + target_config = config['targets'][target_iqn] + if not target_config['portals'].keys(): + raise DashboardException(msg="Cannot delete a target that doesn't contain any portal", + code='cannot_delete_target_without_portals', + component='iscsi') + target = IscsiTarget._config_to_target(target_iqn, config) + n_groups = len(target_config['groups']) + n_clients = len(target_config['clients']) + n_target_disks = len(target_config['disks']) + task_progress_steps = n_groups + n_clients + n_target_disks + task_progress_inc = 0 + if task_progress_steps != 0: + task_progress_inc = int((task_progress_end - task_progress_begin) / task_progress_steps) + gateway_name = list(target_config['portals'].keys())[0] + deleted_groups = [] + for group_id in list(target_config['groups'].keys()): + if IscsiTarget._group_deletion_required(target, new_target_iqn, new_target_controls, + new_groups, group_id): + deleted_groups.append(group_id) + IscsiClient.instance(gateway_name=gateway_name).delete_group(target_iqn, + group_id) + else: + group = IscsiTarget._get_group(new_groups, group_id) + + old_group_disks = set(target_config['groups'][group_id]['disks'].keys()) + new_group_disks = {'{}/{}'.format(x['pool'], x['image']) for x in group['disks']} + local_deleted_disks = list(old_group_disks - new_group_disks) + + old_group_members = set(target_config['groups'][group_id]['members']) + new_group_members = set(group['members']) + local_deleted_members = list(old_group_members - new_group_members) + + if local_deleted_disks or local_deleted_members: + IscsiClient.instance(gateway_name=gateway_name).update_group( + target_iqn, group_id, local_deleted_members, local_deleted_disks) + TaskManager.current_task().inc_progress(task_progress_inc) + deleted_clients = [] + deleted_client_luns = [] + for client_iqn, client_config in target_config['clients'].items(): + if IscsiTarget._client_deletion_required(target, new_target_iqn, new_target_controls, + new_clients, client_iqn): + deleted_clients.append(client_iqn) + IscsiClient.instance(gateway_name=gateway_name).delete_client(target_iqn, + client_iqn) + else: + for image_id in list(client_config.get('luns', {}).keys()): + if IscsiTarget._client_lun_deletion_required(target, client_iqn, image_id, + new_clients, new_groups): + deleted_client_luns.append((client_iqn, image_id)) + IscsiClient.instance(gateway_name=gateway_name).delete_client_lun( + target_iqn, client_iqn, image_id) + TaskManager.current_task().inc_progress(task_progress_inc) + for image_id in target_config['disks']: + if IscsiTarget._target_lun_deletion_required(target, new_target_iqn, + new_target_controls, new_disks, image_id): + all_clients = target_config['clients'].keys() + not_deleted_clients = [c for c in all_clients if c not in deleted_clients + and not IscsiTarget._client_in_group(target['groups'], c) + and not IscsiTarget._client_in_group(new_groups, c)] + for client_iqn in not_deleted_clients: + client_image_ids = target_config['clients'][client_iqn]['luns'].keys() + for client_image_id in client_image_ids: + if image_id == client_image_id and \ + (client_iqn, client_image_id) not in deleted_client_luns: + IscsiClient.instance(gateway_name=gateway_name).delete_client_lun( + target_iqn, client_iqn, client_image_id) + IscsiClient.instance(gateway_name=gateway_name).delete_target_lun(target_iqn, + image_id) + pool, image = image_id.split('/', 1) + IscsiClient.instance(gateway_name=gateway_name).delete_disk(pool, image) + TaskManager.current_task().inc_progress(task_progress_inc) + old_portals_by_host = IscsiTarget._get_portals_by_host(target['portals']) + new_portals_by_host = IscsiTarget._get_portals_by_host(new_portals) + for old_portal_host, old_portal_ip_list in old_portals_by_host.items(): + if IscsiTarget._target_portal_deletion_required(old_portal_host, + old_portal_ip_list, + new_portals_by_host): + IscsiClient.instance(gateway_name=gateway_name).delete_gateway(target_iqn, + old_portal_host) + if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls): + IscsiClient.instance(gateway_name=gateway_name).delete_target(target_iqn) + TaskManager.current_task().set_progress(task_progress_end) + return IscsiClient.instance(gateway_name=gateway_name).get_config() + + @staticmethod + def _get_group(groups, group_id): + for group in groups: + if group['group_id'] == group_id: + return group + return None + + @staticmethod + def _group_deletion_required(target, new_target_iqn, new_target_controls, + new_groups, group_id): + if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls): + return True + new_group = IscsiTarget._get_group(new_groups, group_id) + if not new_group: + return True + return False + + @staticmethod + def _get_client(clients, client_iqn): + for client in clients: + if client['client_iqn'] == client_iqn: + return client + return None + + @staticmethod + def _client_deletion_required(target, new_target_iqn, new_target_controls, + new_clients, client_iqn): + if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls): + return True + new_client = IscsiTarget._get_client(new_clients, client_iqn) + if not new_client: + return True + return False + + @staticmethod + def _client_in_group(groups, client_iqn): + for group in groups: + if client_iqn in group['members']: + return True + return False + + @staticmethod + def _client_lun_deletion_required(target, client_iqn, image_id, new_clients, new_groups): + new_client = IscsiTarget._get_client(new_clients, client_iqn) + if not new_client: + return True + + # Disks inherited from groups must be considered + was_in_group = IscsiTarget._client_in_group(target['groups'], client_iqn) + is_in_group = IscsiTarget._client_in_group(new_groups, client_iqn) + + if not was_in_group and is_in_group: + return True + + if is_in_group: + return False + + new_lun = IscsiTarget._get_disk(new_client.get('luns', []), image_id) + if not new_lun: + return True + + old_client = IscsiTarget._get_client(target['clients'], client_iqn) + if not old_client: + return False + + old_lun = IscsiTarget._get_disk(old_client.get('luns', []), image_id) + return new_lun != old_lun + + @staticmethod + def _get_disk(disks, image_id): + for disk in disks: + if '{}/{}'.format(disk['pool'], disk['image']) == image_id: + return disk + return None + + @staticmethod + def _target_lun_deletion_required(target, new_target_iqn, new_target_controls, + new_disks, image_id): + if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls): + return True + new_disk = IscsiTarget._get_disk(new_disks, image_id) + if not new_disk: + return True + old_disk = IscsiTarget._get_disk(target['disks'], image_id) + new_disk_without_controls = deepcopy(new_disk) + new_disk_without_controls.pop('controls') + old_disk_without_controls = deepcopy(old_disk) + old_disk_without_controls.pop('controls') + if new_disk_without_controls != old_disk_without_controls: + return True + return False + + @staticmethod + def _target_portal_deletion_required(old_portal_host, old_portal_ip_list, new_portals_by_host): + if old_portal_host not in new_portals_by_host: + return True + if sorted(old_portal_ip_list) != sorted(new_portals_by_host[old_portal_host]): + return True + return False + + @staticmethod + def _target_deletion_required(target, new_target_iqn, new_target_controls): + gateway = get_available_gateway() + settings = IscsiClient.instance(gateway_name=gateway).get_settings() + + if target['target_iqn'] != new_target_iqn: + return True + if settings['api_version'] < 2 and target['target_controls'] != new_target_controls: + return True + return False + + @staticmethod + def _validate(target_iqn, target_controls, portals, disks, groups, settings): + if not target_iqn: + raise DashboardException(msg='Target IQN is required', + code='target_iqn_required', + component='iscsi') + + minimum_gateways = max(1, settings['config']['minimum_gateways']) + portals_by_host = IscsiTarget._get_portals_by_host(portals) + if len(portals_by_host.keys()) < minimum_gateways: + if minimum_gateways == 1: + msg = 'At least one portal is required' + else: + msg = 'At least {} portals are required'.format(minimum_gateways) + raise DashboardException(msg=msg, + code='portals_required', + component='iscsi') + + # 'target_controls_limits' was introduced in ceph-iscsi > 3.2 + # When using an older `ceph-iscsi` version these validations will + # NOT be executed beforehand + if 'target_controls_limits' in settings: + for target_control_name, target_control_value in target_controls.items(): + limits = settings['target_controls_limits'].get(target_control_name) + if limits is not None: + min_value = limits.get('min') + if min_value is not None and target_control_value < min_value: + raise DashboardException(msg='Target control {} must be >= ' + '{}'.format(target_control_name, min_value), + code='target_control_invalid_min', + component='iscsi') + max_value = limits.get('max') + if max_value is not None and target_control_value > max_value: + raise DashboardException(msg='Target control {} must be <= ' + '{}'.format(target_control_name, max_value), + code='target_control_invalid_max', + component='iscsi') + + portal_names = [p['host'] for p in portals] + validate_rest_api(portal_names) + + for disk in disks: + pool = disk['pool'] + image = disk['image'] + backstore = disk['backstore'] + required_rbd_features = settings['required_rbd_features'][backstore] + unsupported_rbd_features = settings['unsupported_rbd_features'][backstore] + IscsiTarget._validate_image(pool, image, backstore, required_rbd_features, + unsupported_rbd_features) + + # 'disk_controls_limits' was introduced in ceph-iscsi > 3.2 + # When using an older `ceph-iscsi` version these validations will + # NOT be executed beforehand + if 'disk_controls_limits' in settings: + for disk_control_name, disk_control_value in disk['controls'].items(): + limits = settings['disk_controls_limits'][backstore].get(disk_control_name) + if limits is not None: + min_value = limits.get('min') + if min_value is not None and disk_control_value < min_value: + raise DashboardException(msg='Disk control {} must be >= ' + '{}'.format(disk_control_name, min_value), + code='disk_control_invalid_min', + component='iscsi') + max_value = limits.get('max') + if max_value is not None and disk_control_value > max_value: + raise DashboardException(msg='Disk control {} must be <= ' + '{}'.format(disk_control_name, max_value), + code='disk_control_invalid_max', + component='iscsi') + + initiators = [] + for group in groups: + initiators = initiators + group['members'] + if len(initiators) != len(set(initiators)): + raise DashboardException(msg='Each initiator can only be part of 1 group at a time', + code='initiator_in_multiple_groups', + component='iscsi') + + @staticmethod + def _validate_image(pool, image, backstore, required_rbd_features, unsupported_rbd_features): + try: + ioctx = mgr.rados.open_ioctx(pool) + try: + with rbd.Image(ioctx, image) as img: + if img.features() & required_rbd_features != required_rbd_features: + raise DashboardException(msg='Image {} cannot be exported using {} ' + 'backstore because required features are ' + 'missing (required features are ' + '{})'.format(image, + backstore, + format_bitmask( + required_rbd_features)), + code='image_missing_required_features', + component='iscsi') + if img.features() & unsupported_rbd_features != 0: + raise DashboardException(msg='Image {} cannot be exported using {} ' + 'backstore because it contains unsupported ' + 'features (' + '{})'.format(image, + backstore, + format_bitmask( + unsupported_rbd_features)), + code='image_contains_unsupported_features', + component='iscsi') + + except rbd.ImageNotFound: + raise DashboardException(msg='Image {} does not exist'.format(image), + code='image_does_not_exist', + component='iscsi') + except rados.ObjectNotFound: + raise DashboardException(msg='Pool {} does not exist'.format(pool), + code='pool_does_not_exist', + component='iscsi') + + @staticmethod + def _validate_delete(gateway, target_iqn, config, new_target_iqn=None, new_target_controls=None, + new_disks=None, new_clients=None, new_groups=None): + new_target_controls = new_target_controls or {} + new_disks = new_disks or [] + new_clients = new_clients or [] + new_groups = new_groups or [] + + target_config = config['targets'][target_iqn] + target = IscsiTarget._config_to_target(target_iqn, config) + for client_iqn in list(target_config['clients'].keys()): + if IscsiTarget._client_deletion_required(target, new_target_iqn, new_target_controls, + new_clients, client_iqn): + client_info = IscsiClient.instance(gateway_name=gateway).get_clientinfo(target_iqn, + client_iqn) + if client_info.get('state', {}).get('LOGGED_IN', []): + raise DashboardException(msg="Client '{}' cannot be deleted until it's logged " + "out".format(client_iqn), + code='client_logged_in', + component='iscsi') + + @staticmethod + def _update_targetauth(config, target_iqn, auth, gateway_name): + # Target level authentication was introduced in ceph-iscsi config v11 + if config['version'] > 10: + user = auth['user'] + password = auth['password'] + mutual_user = auth['mutual_user'] + mutual_password = auth['mutual_password'] + IscsiClient.instance(gateway_name=gateway_name).update_targetauth(target_iqn, + user, + password, + mutual_user, + mutual_password) + + @staticmethod + def _update_targetacl(target_config, target_iqn, acl_enabled, gateway_name): + if not target_config or target_config['acl_enabled'] != acl_enabled: + targetauth_action = ('enable_acl' if acl_enabled else 'disable_acl') + IscsiClient.instance(gateway_name=gateway_name).update_targetacl(target_iqn, + targetauth_action) + + @staticmethod + def _is_auth_equal(auth_config, auth): + return auth['user'] == auth_config['username'] and \ + auth['password'] == auth_config['password'] and \ + auth['mutual_user'] == auth_config['mutual_username'] and \ + auth['mutual_password'] == auth_config['mutual_password'] + + @staticmethod + def _create(target_iqn, target_controls, acl_enabled, + auth, portals, disks, clients, groups, + task_progress_begin, task_progress_end, config, settings): + target_config = config['targets'].get(target_iqn, None) + TaskManager.current_task().set_progress(task_progress_begin) + portals_by_host = IscsiTarget._get_portals_by_host(portals) + n_hosts = len(portals_by_host) + n_disks = len(disks) + n_clients = len(clients) + n_groups = len(groups) + task_progress_steps = n_hosts + n_disks + n_clients + n_groups + task_progress_inc = 0 + if task_progress_steps != 0: + task_progress_inc = int((task_progress_end - task_progress_begin) / task_progress_steps) + try: + gateway_name = portals[0]['host'] + if not target_config: + IscsiClient.instance(gateway_name=gateway_name).create_target(target_iqn, + target_controls) + for host, ip_list in portals_by_host.items(): + if not target_config or host not in target_config['portals']: + IscsiClient.instance(gateway_name=gateway_name).create_gateway(target_iqn, + host, + ip_list) + TaskManager.current_task().inc_progress(task_progress_inc) + + if not target_config or \ + acl_enabled != target_config['acl_enabled'] or \ + not IscsiTarget._is_auth_equal(target_config['auth'], auth): + if acl_enabled: + IscsiTarget._update_targetauth(config, target_iqn, auth, gateway_name) + IscsiTarget._update_targetacl(target_config, target_iqn, acl_enabled, + gateway_name) + else: + IscsiTarget._update_targetacl(target_config, target_iqn, acl_enabled, + gateway_name) + IscsiTarget._update_targetauth(config, target_iqn, auth, gateway_name) + + for disk in disks: + pool = disk['pool'] + image = disk['image'] + image_id = '{}/{}'.format(pool, image) + backstore = disk['backstore'] + wwn = disk.get('wwn') + lun = disk.get('lun') + if image_id not in config['disks']: + IscsiClient.instance(gateway_name=gateway_name).create_disk(pool, + image, + backstore, + wwn) + if not target_config or image_id not in target_config['disks']: + IscsiClient.instance(gateway_name=gateway_name).create_target_lun(target_iqn, + image_id, + lun) + + controls = disk['controls'] + d_conf_controls = {} + if image_id in config['disks']: + d_conf_controls = config['disks'][image_id]['controls'] + disk_default_controls = settings['disk_default_controls'][backstore] + for old_control in d_conf_controls.keys(): + # If control was removed, restore the default value + if old_control not in controls: + controls[old_control] = disk_default_controls[old_control] + + if (image_id not in config['disks'] or d_conf_controls != controls) and controls: + IscsiClient.instance(gateway_name=gateway_name).reconfigure_disk(pool, + image, + controls) + TaskManager.current_task().inc_progress(task_progress_inc) + for client in clients: + client_iqn = client['client_iqn'] + if not target_config or client_iqn not in target_config['clients']: + IscsiClient.instance(gateway_name=gateway_name).create_client(target_iqn, + client_iqn) + if not target_config or client_iqn not in target_config['clients'] or \ + not IscsiTarget._is_auth_equal(target_config['clients'][client_iqn]['auth'], + client['auth']): + user = client['auth']['user'] + password = client['auth']['password'] + m_user = client['auth']['mutual_user'] + m_password = client['auth']['mutual_password'] + IscsiClient.instance(gateway_name=gateway_name).create_client_auth( + target_iqn, client_iqn, user, password, m_user, m_password) + for lun in client['luns']: + pool = lun['pool'] + image = lun['image'] + image_id = '{}/{}'.format(pool, image) + # Disks inherited from groups must be considered + group_disks = [] + for group in groups: + if client_iqn in group['members']: + group_disks = ['{}/{}'.format(x['pool'], x['image']) + for x in group['disks']] + if not target_config or client_iqn not in target_config['clients'] or \ + (image_id not in target_config['clients'][client_iqn]['luns'] + and image_id not in group_disks): + IscsiClient.instance(gateway_name=gateway_name).create_client_lun( + target_iqn, client_iqn, image_id) + TaskManager.current_task().inc_progress(task_progress_inc) + for group in groups: + group_id = group['group_id'] + members = group['members'] + image_ids = [] + for disk in group['disks']: + image_ids.append('{}/{}'.format(disk['pool'], disk['image'])) + + if target_config and group_id in target_config['groups']: + old_members = target_config['groups'][group_id]['members'] + old_disks = target_config['groups'][group_id]['disks'].keys() + + if not target_config or group_id not in target_config['groups'] or \ + list(set(group['members']) - set(old_members)) or \ + list(set(image_ids) - set(old_disks)): + IscsiClient.instance(gateway_name=gateway_name).create_group( + target_iqn, group_id, members, image_ids) + TaskManager.current_task().inc_progress(task_progress_inc) + if target_controls: + if not target_config or target_controls != target_config['controls']: + IscsiClient.instance(gateway_name=gateway_name).reconfigure_target( + target_iqn, target_controls) + TaskManager.current_task().set_progress(task_progress_end) + except RequestException as e: + if e.content: + content = json.loads(e.content) + content_message = content.get('message') + if content_message: + raise DashboardException(msg=content_message, component='iscsi') + raise DashboardException(e=e, component='iscsi') + + @staticmethod + def _config_to_target(target_iqn, config): + target_config = config['targets'][target_iqn] + portals = [] + for host, portal_config in target_config['portals'].items(): + for portal_ip in portal_config['portal_ip_addresses']: + portal = { + 'host': host, + 'ip': portal_ip + } + portals.append(portal) + portals = IscsiTarget._sorted_portals(portals) + disks = [] + for target_disk in target_config['disks']: + disk_config = config['disks'][target_disk] + disk = { + 'pool': disk_config['pool'], + 'image': disk_config['image'], + 'controls': disk_config['controls'], + 'backstore': disk_config['backstore'], + 'wwn': disk_config['wwn'] + } + # lun_id was introduced in ceph-iscsi config v11 + if config['version'] > 10: + disk['lun'] = target_config['disks'][target_disk]['lun_id'] + disks.append(disk) + disks = IscsiTarget._sorted_disks(disks) + clients = [] + for client_iqn, client_config in target_config['clients'].items(): + luns = [] + for client_lun in client_config['luns'].keys(): + pool, image = client_lun.split('/', 1) + lun = { + 'pool': pool, + 'image': image + } + luns.append(lun) + user = client_config['auth']['username'] + password = client_config['auth']['password'] + mutual_user = client_config['auth']['mutual_username'] + mutual_password = client_config['auth']['mutual_password'] + client = { + 'client_iqn': client_iqn, + 'luns': luns, + 'auth': { + 'user': user, + 'password': password, + 'mutual_user': mutual_user, + 'mutual_password': mutual_password + } + } + clients.append(client) + clients = IscsiTarget._sorted_clients(clients) + groups = [] + for group_id, group_config in target_config['groups'].items(): + group_disks = [] + for group_disk_key, _ in group_config['disks'].items(): + pool, image = group_disk_key.split('/', 1) + group_disk = { + 'pool': pool, + 'image': image + } + group_disks.append(group_disk) + group = { + 'group_id': group_id, + 'disks': group_disks, + 'members': group_config['members'], + } + groups.append(group) + groups = IscsiTarget._sorted_groups(groups) + target_controls = target_config['controls'] + acl_enabled = target_config['acl_enabled'] + target = { + 'target_iqn': target_iqn, + 'portals': portals, + 'disks': disks, + 'clients': clients, + 'groups': groups, + 'target_controls': target_controls, + 'acl_enabled': acl_enabled + } + # Target level authentication was introduced in ceph-iscsi config v11 + if config['version'] > 10: + target_user = target_config['auth']['username'] + target_password = target_config['auth']['password'] + target_mutual_user = target_config['auth']['mutual_username'] + target_mutual_password = target_config['auth']['mutual_password'] + target['auth'] = { + 'user': target_user, + 'password': target_password, + 'mutual_user': target_mutual_user, + 'mutual_password': target_mutual_password + } + return target + + @staticmethod + def _is_executing(target_iqn): + executing_tasks, _ = TaskManager.list() + for t in executing_tasks: + if t.name.startswith('iscsi/target') and t.metadata.get('target_iqn') == target_iqn: + return True + return False + + @staticmethod + def _set_info(target): + if not target['portals']: + return + target_iqn = target['target_iqn'] + # During task execution, additional info is not available + if IscsiTarget._is_executing(target_iqn): + return + # If any portal is down, additional info is not available + for portal in target['portals']: + try: + IscsiClient.instance(gateway_name=portal['host']).ping() + except (IscsiGatewayDoesNotExist, RequestException): + return + gateway_name = target['portals'][0]['host'] + try: + target_info = IscsiClient.instance(gateway_name=gateway_name).get_targetinfo( + target_iqn) + target['info'] = target_info + for client in target['clients']: + client_iqn = client['client_iqn'] + client_info = IscsiClient.instance(gateway_name=gateway_name).get_clientinfo( + target_iqn, client_iqn) + client['info'] = client_info + except RequestException as e: + # Target/Client has been removed in the meanwhile (e.g. using gwcli) + if e.status_code != 404: + raise e + + @staticmethod + def _sorted_portals(portals): + portals = portals or [] + return sorted(portals, key=lambda p: '{}.{}'.format(p['host'], p['ip'])) + + @staticmethod + def _sorted_disks(disks): + disks = disks or [] + return sorted(disks, key=lambda d: '{}.{}'.format(d['pool'], d['image'])) + + @staticmethod + def _sorted_clients(clients): + clients = clients or [] + for client in clients: + client['luns'] = sorted(client['luns'], + key=lambda d: '{}.{}'.format(d['pool'], d['image'])) + return sorted(clients, key=lambda c: c['client_iqn']) + + @staticmethod + def _sorted_groups(groups): + groups = groups or [] + for group in groups: + group['disks'] = sorted(group['disks'], + key=lambda d: '{}.{}'.format(d['pool'], d['image'])) + group['members'] = sorted(group['members']) + return sorted(groups, key=lambda g: g['group_id']) + + @staticmethod + def _get_portals_by_host(portals): + portals_by_host = {} + for portal in portals: + host = portal['host'] + ip = portal['ip'] + if host not in portals_by_host: + portals_by_host[host] = [] + portals_by_host[host].append(ip) + return portals_by_host + + +def get_available_gateway(): + gateways = IscsiGatewaysConfig.get_gateways_config()['gateways'] + if not gateways: + raise DashboardException(msg='There are no gateways defined', + code='no_gateways_defined', + component='iscsi') + for gateway in gateways: + try: + IscsiClient.instance(gateway_name=gateway).ping() + return gateway + except RequestException: + pass + raise DashboardException(msg='There are no gateways available', + code='no_gateways_available', + component='iscsi') + + +def validate_rest_api(gateways): + for gateway in gateways: + try: + IscsiClient.instance(gateway_name=gateway).ping() + except RequestException: + raise DashboardException(msg='iSCSI REST Api not available for gateway ' + '{}'.format(gateway), + code='ceph_iscsi_rest_api_not_available_for_gateway', + component='iscsi') + + +def validate_auth(auth): + username_regex = re.compile(r'^[\w\.:@_-]{8,64}$') + password_regex = re.compile(r'^[\w@\-_\/]{12,16}$') + result = True + + if auth['user'] or auth['password']: + result = bool(username_regex.match(auth['user'])) and \ + bool(password_regex.match(auth['password'])) + + if auth['mutual_user'] or auth['mutual_password']: + result = result and bool(username_regex.match(auth['mutual_user'])) and \ + bool(password_regex.match(auth['mutual_password'])) and auth['user'] + + if not result: + raise DashboardException(msg='Bad authentication', + code='target_bad_auth', + component='iscsi') diff --git a/src/pybind/mgr/dashboard/controllers/logging.py b/src/pybind/mgr/dashboard/controllers/logging.py new file mode 100644 index 00000000..9c7d6de7 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/logging.py @@ -0,0 +1,10 @@ +from . import UiApiController, BaseController, Endpoint +from .. import logger + + +@UiApiController('/logging', secure=False) +class Logging(BaseController): + + @Endpoint('POST', path='js-error') + def jsError(self, url, message, stack=None): + logger.error('frontend error (%s): %s\n %s\n', url, message, stack) diff --git a/src/pybind/mgr/dashboard/controllers/logs.py b/src/pybind/mgr/dashboard/controllers/logs.py new file mode 100644 index 00000000..9dc5286f --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/logs.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import collections + +from . import ApiController, Endpoint, BaseController, ReadPermission +from ..security import Scope +from ..services.ceph_service import CephService +from ..tools import NotificationQueue + + +LOG_BUFFER_SIZE = 30 + + +@ApiController('/logs', Scope.LOG) +class Logs(BaseController): + def __init__(self): + super(Logs, self).__init__() + self._log_initialized = False + self.log_buffer = collections.deque(maxlen=LOG_BUFFER_SIZE) + self.audit_buffer = collections.deque(maxlen=LOG_BUFFER_SIZE) + + def append_log(self, log_struct): + if log_struct['channel'] == 'audit': + self.audit_buffer.appendleft(log_struct) + else: + self.log_buffer.appendleft(log_struct) + + def load_buffer(self, buf, channel_name): + lines = CephService.send_command( + 'mon', 'log last', channel=channel_name, num=LOG_BUFFER_SIZE) + for l in lines: + buf.appendleft(l) + + def initialize_buffers(self): + if not self._log_initialized: + self._log_initialized = True + + self.load_buffer(self.log_buffer, 'cluster') + self.load_buffer(self.audit_buffer, 'audit') + + NotificationQueue.register(self.append_log, 'clog') + + @Endpoint() + @ReadPermission + def all(self): + self.initialize_buffers() + return dict( + clog=list(self.log_buffer), + audit_log=list(self.audit_buffer), + ) diff --git a/src/pybind/mgr/dashboard/controllers/mgr_modules.py b/src/pybind/mgr/dashboard/controllers/mgr_modules.py new file mode 100644 index 00000000..c37225c9 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/mgr_modules.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import ApiController, RESTController, \ + allow_empty_body +from .. import mgr +from ..security import Scope +from ..services.ceph_service import CephService +from ..services.exception import handle_send_command_error +from ..tools import find_object_in_list, str_to_bool + + +@ApiController('/mgr/module', Scope.CONFIG_OPT) +class MgrModules(RESTController): + ignore_modules = ['selftest'] + + def list(self): + """ + Get the list of managed modules. + :return: A list of objects with the fields 'enabled', 'name' and 'options'. + :rtype: list + """ + result = [] + mgr_map = mgr.get('mgr_map') + always_on_modules = mgr_map['always_on_modules'][mgr.release_name] + for module_config in mgr_map['available_modules']: + module_name = module_config['name'] + if module_name not in self.ignore_modules: + always_on = module_name in always_on_modules + enabled = module_name in mgr_map['modules'] or always_on + result.append({ + 'name': module_name, + 'enabled': enabled, + 'always_on': always_on, + 'options': self._convert_module_options( + module_config['module_options']) + }) + return result + + def get(self, module_name): + """ + Retrieve the values of the persistent configuration settings. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + :return: The values of the module options. + :rtype: dict + """ + assert self._is_module_managed(module_name) + options = self._get_module_options(module_name) + result = {} + for name, option in options.items(): + result[name] = mgr.get_module_option_ex(module_name, name, + option['default_value']) + return result + + @RESTController.Resource('PUT') + def set(self, module_name, config): + """ + Set the values of the persistent configuration settings. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + :param config: The values of the module options to be stored. + :type config: dict + """ + assert self._is_module_managed(module_name) + options = self._get_module_options(module_name) + for name in options.keys(): + if name in config: + mgr.set_module_option_ex(module_name, name, config[name]) + + @RESTController.Resource('POST') + @handle_send_command_error('mgr_modules') + @allow_empty_body + def enable(self, module_name): + """ + Enable the specified Ceph Mgr module. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + """ + assert self._is_module_managed(module_name) + CephService.send_command( + 'mon', 'mgr module enable', module=module_name) + + @RESTController.Resource('POST') + @handle_send_command_error('mgr_modules') + @allow_empty_body + def disable(self, module_name): + """ + Disable the specified Ceph Mgr module. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + """ + assert self._is_module_managed(module_name) + CephService.send_command( + 'mon', 'mgr module disable', module=module_name) + + @RESTController.Resource('GET') + def options(self, module_name): + """ + Get the module options of the specified Ceph Mgr module. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + :return: The module options as list of dicts. + :rtype: list + """ + assert self._is_module_managed(module_name) + return self._get_module_options(module_name) + + def _is_module_managed(self, module_name): + """ + Check if the specified Ceph Mgr module is managed by this service. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + :return: Returns ``true`` if the Ceph Mgr module is managed by + this service, otherwise ``false``. + :rtype: bool + """ + if module_name in self.ignore_modules: + return False + mgr_map = mgr.get('mgr_map') + for module_config in mgr_map['available_modules']: + if module_name == module_config['name']: + return True + return False + + def _get_module_config(self, module_name): + """ + Helper function to get detailed module configuration. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + :return: The module information, e.g. module name, can run, + error string and available module options. + :rtype: dict or None + """ + mgr_map = mgr.get('mgr_map') + return find_object_in_list('name', module_name, + mgr_map['available_modules']) + + def _get_module_options(self, module_name): + """ + Helper function to get the module options. + :param module_name: The name of the Ceph Mgr module. + :type module_name: str + :return: The module options. + :rtype: dict + """ + options = self._get_module_config(module_name)['module_options'] + return self._convert_module_options(options) + + def _convert_module_options(self, options): + # Workaround a possible bug in the Ceph Mgr implementation. + # Various fields (e.g. default_value, min, max) are always + # returned as a string. + for option in options.values(): + if option['type'] == 'str': + if option['default_value'] == 'None': # This is Python None + option['default_value'] = '' + elif option['type'] == 'bool': + if option['default_value'] == '': + option['default_value'] = False + else: + option['default_value'] = str_to_bool( + option['default_value']) + elif option['type'] == 'float': + for name in ['default_value', 'min', 'max']: + if option[name]: # Skip empty entries + option[name] = float(option[name]) + elif option['type'] in ['uint', 'int', 'size', 'secs']: + for name in ['default_value', 'min', 'max']: + if option[name]: # Skip empty entries + option[name] = int(option[name]) + return options diff --git a/src/pybind/mgr/dashboard/controllers/monitor.py b/src/pybind/mgr/dashboard/controllers/monitor.py new file mode 100644 index 00000000..d4512fcf --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/monitor.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json + +from . import ApiController, Endpoint, BaseController, ReadPermission +from .. import mgr +from ..security import Scope + + +@ApiController('/monitor', Scope.MONITOR) +class Monitor(BaseController): + @Endpoint() + @ReadPermission + def __call__(self): + in_quorum, out_quorum = [], [] + + counters = ['mon.num_sessions'] + + mon_status_json = mgr.get("mon_status") + mon_status = json.loads(mon_status_json['json']) + + for mon in mon_status["monmap"]["mons"]: + mon["stats"] = {} + for counter in counters: + data = mgr.get_counter("mon", mon["name"], counter) + if data is not None: + mon["stats"][counter.split(".")[1]] = data[counter] + else: + mon["stats"][counter.split(".")[1]] = [] + if mon["rank"] in mon_status["quorum"]: + in_quorum.append(mon) + else: + out_quorum.append(mon) + + return { + 'mon_status': mon_status, + 'in_quorum': in_quorum, + 'out_quorum': out_quorum + } diff --git a/src/pybind/mgr/dashboard/controllers/nfsganesha.py b/src/pybind/mgr/dashboard/controllers/nfsganesha.py new file mode 100644 index 00000000..b9599d72 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/nfsganesha.py @@ -0,0 +1,315 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from functools import partial + +import cherrypy +import cephfs + +from . import ApiController, RESTController, UiApiController, BaseController, \ + Endpoint, Task, ReadPermission, ControllerDoc, EndpointDoc +from .. import logger +from ..security import Scope +from ..services.cephfs import CephFS +from ..services.cephx import CephX +from ..services.exception import serialize_dashboard_exception +from ..services.ganesha import Ganesha, GaneshaConf, NFSException +from ..services.rgw_client import RgwClient + + +# documentation helpers +EXPORT_SCHEMA = { + 'export_id': (int, 'Export ID'), + 'path': (str, 'Export path'), + 'cluster_id': (str, 'Cluster identifier'), + 'daemons': ([str], 'List of NFS Ganesha daemons identifiers'), + 'pseudo': (str, 'Pseudo FS path'), + 'tag': (str, 'NFSv3 export tag'), + 'access_type': (str, 'Export access type'), + 'squash': (str, 'Export squash policy'), + 'security_label': (str, 'Security label'), + 'protocols': ([int], 'List of protocol types'), + 'transports': ([str], 'List of transport types'), + 'fsal': ({ + 'name': (str, 'name of FSAL'), + 'user_id': (str, 'CephX user id', True), + 'filesystem': (str, 'CephFS filesystem ID', True), + 'sec_label_xattr': (str, 'Name of xattr for security label', True), + 'rgw_user_id': (str, 'RGW user id', True) + }, 'FSAL configuration'), + 'clients': ([{ + 'addresses': ([str], 'list of IP addresses'), + 'access_type': (str, 'Client access type'), + 'squash': (str, 'Client squash policy') + }], 'List of client configurations'), +} + + +CREATE_EXPORT_SCHEMA = { + 'path': (str, 'Export path'), + 'cluster_id': (str, 'Cluster identifier'), + 'daemons': ([str], 'List of NFS Ganesha daemons identifiers'), + 'pseudo': (str, 'Pseudo FS path'), + 'tag': (str, 'NFSv3 export tag'), + 'access_type': (str, 'Export access type'), + 'squash': (str, 'Export squash policy'), + 'security_label': (str, 'Security label'), + 'protocols': ([int], 'List of protocol types'), + 'transports': ([str], 'List of transport types'), + 'fsal': ({ + 'name': (str, 'name of FSAL'), + 'user_id': (str, 'CephX user id', True), + 'filesystem': (str, 'CephFS filesystem ID', True), + 'sec_label_xattr': (str, 'Name of xattr for security label', True), + 'rgw_user_id': (str, 'RGW user id', True) + }, 'FSAL configuration'), + 'clients': ([{ + 'addresses': ([str], 'list of IP addresses'), + 'access_type': (str, 'Client access type'), + 'squash': (str, 'Client squash policy') + }], 'List of client configurations'), + 'reload_daemons': (bool, + 'Trigger reload of NFS-Ganesha daemons configuration', + True) +} + + +# pylint: disable=not-callable +def NfsTask(name, metadata, wait_for): + def composed_decorator(func): + return Task("nfs/{}".format(name), metadata, wait_for, + partial(serialize_dashboard_exception, + include_http_status=True))(func) + return composed_decorator + + +@ApiController('/nfs-ganesha', Scope.NFS_GANESHA) +@ControllerDoc("NFS-Ganesha Management API", "NFS-Ganesha") +class NFSGanesha(RESTController): + + @EndpointDoc("Status of NFS-Ganesha management feature", + responses={200: { + 'available': (bool, "Is API available?"), + 'message': (str, "Error message") + }}) + @Endpoint() + @ReadPermission + def status(self): + status = {'available': True, 'message': None} + try: + Ganesha.get_ganesha_clusters() + except NFSException as e: + status['message'] = str(e) + status['available'] = False + + return status + + +@ApiController('/nfs-ganesha/export', Scope.NFS_GANESHA) +@ControllerDoc(group="NFS-Ganesha") +class NFSGaneshaExports(RESTController): + RESOURCE_ID = "cluster_id/export_id" + + @EndpointDoc("List all NFS-Ganesha exports", + responses={200: [EXPORT_SCHEMA]}) + def list(self): + result = [] + for cluster_id in Ganesha.get_ganesha_clusters(): + result.extend( + [export.to_dict() + for export in GaneshaConf.instance(cluster_id).list_exports()]) + return result + + @NfsTask('create', {'path': '{path}', 'fsal': '{fsal.name}', + 'cluster_id': '{cluster_id}'}, 2.0) + @EndpointDoc("Creates a new NFS-Ganesha export", + parameters=CREATE_EXPORT_SCHEMA, + responses={201: EXPORT_SCHEMA}) + def create(self, path, cluster_id, daemons, pseudo, tag, access_type, + squash, security_label, protocols, transports, fsal, clients, + reload_daemons=True): + if fsal['name'] not in Ganesha.fsals_available(): + raise NFSException("Cannot create this export. " + "FSAL '{}' cannot be managed by the dashboard." + .format(fsal['name'])) + + ganesha_conf = GaneshaConf.instance(cluster_id) + ex_id = ganesha_conf.create_export({ + 'path': path, + 'pseudo': pseudo, + 'cluster_id': cluster_id, + 'daemons': daemons, + 'tag': tag, + 'access_type': access_type, + 'squash': squash, + 'security_label': security_label, + 'protocols': protocols, + 'transports': transports, + 'fsal': fsal, + 'clients': clients + }) + if reload_daemons: + ganesha_conf.reload_daemons(daemons) + return ganesha_conf.get_export(ex_id).to_dict() + + @EndpointDoc("Get an NFS-Ganesha export", + parameters={ + 'cluster_id': (str, 'Cluster identifier'), + 'export_id': (int, "Export ID") + }, + responses={200: EXPORT_SCHEMA}) + def get(self, cluster_id, export_id): + export_id = int(export_id) + ganesha_conf = GaneshaConf.instance(cluster_id) + if not ganesha_conf.has_export(export_id): + raise cherrypy.HTTPError(404) + return ganesha_conf.get_export(export_id).to_dict() + + @NfsTask('edit', {'cluster_id': '{cluster_id}', 'export_id': '{export_id}'}, + 2.0) + @EndpointDoc("Updates an NFS-Ganesha export", + parameters=dict(export_id=(int, "Export ID"), + **CREATE_EXPORT_SCHEMA), + responses={200: EXPORT_SCHEMA}) + def set(self, cluster_id, export_id, path, daemons, pseudo, tag, access_type, + squash, security_label, protocols, transports, fsal, clients, + reload_daemons=True): + export_id = int(export_id) + ganesha_conf = GaneshaConf.instance(cluster_id) + + if not ganesha_conf.has_export(export_id): + raise cherrypy.HTTPError(404) + + if fsal['name'] not in Ganesha.fsals_available(): + raise NFSException("Cannot make modifications to this export. " + "FSAL '{}' cannot be managed by the dashboard." + .format(fsal['name'])) + + old_export = ganesha_conf.update_export({ + 'export_id': export_id, + 'path': path, + 'cluster_id': cluster_id, + 'daemons': daemons, + 'pseudo': pseudo, + 'tag': tag, + 'access_type': access_type, + 'squash': squash, + 'security_label': security_label, + 'protocols': protocols, + 'transports': transports, + 'fsal': fsal, + 'clients': clients + }) + daemons = list(daemons) + for d_id in old_export.daemons: + if d_id not in daemons: + daemons.append(d_id) + if reload_daemons: + ganesha_conf.reload_daemons(daemons) + return ganesha_conf.get_export(export_id).to_dict() + + @NfsTask('delete', {'cluster_id': '{cluster_id}', + 'export_id': '{export_id}'}, 2.0) + @EndpointDoc("Deletes an NFS-Ganesha export", + parameters={ + 'cluster_id': (str, 'Cluster identifier'), + 'export_id': (int, "Export ID"), + 'reload_daemons': (bool, + 'Trigger reload of NFS-Ganesha daemons' + ' configuration', + True) + }) + def delete(self, cluster_id, export_id, reload_daemons=True): + export_id = int(export_id) + ganesha_conf = GaneshaConf.instance(cluster_id) + + if not ganesha_conf.has_export(export_id): + raise cherrypy.HTTPError(404) + + export = ganesha_conf.remove_export(export_id) + if reload_daemons: + ganesha_conf.reload_daemons(export.daemons) + + +@ApiController('/nfs-ganesha/daemon', Scope.NFS_GANESHA) +@ControllerDoc(group="NFS-Ganesha") +class NFSGaneshaService(RESTController): + + @EndpointDoc("List NFS-Ganesha daemons information", + responses={200: [{ + 'daemon_id': (str, 'Daemon identifier'), + 'cluster_id': (str, 'Cluster identifier'), + 'status': (int, + 'Status of daemon (1=RUNNING, 0=STOPPED, -1=ERROR', + True), + 'desc': (str, 'Error description (if status==-1)', True) + }]}) + def list(self): + status_dict = Ganesha.get_daemons_status() + if status_dict: + return [ + { + 'daemon_id': daemon_id, + 'cluster_id': cluster_id, + 'status': status_dict[cluster_id][daemon_id]['status'], + 'desc': status_dict[cluster_id][daemon_id]['desc'] + } + for cluster_id in status_dict + for daemon_id in status_dict[cluster_id] + ] + + result = [] + for cluster_id in Ganesha.get_ganesha_clusters(): + result.extend( + [{'daemon_id': daemon_id, 'cluster_id': cluster_id} + for daemon_id in GaneshaConf.instance(cluster_id).list_daemons()]) + return result + + +@UiApiController('/nfs-ganesha', Scope.NFS_GANESHA) +class NFSGaneshaUi(BaseController): + @Endpoint('GET', '/cephx/clients') + @ReadPermission + def cephx_clients(self): + return [client for client in CephX.list_clients()] + + @Endpoint('GET', '/fsals') + @ReadPermission + def fsals(self): + return Ganesha.fsals_available() + + @Endpoint('GET', '/lsdir') + @ReadPermission + def lsdir(self, root_dir=None, depth=1): # pragma: no cover + if root_dir is None: + root_dir = "/" + depth = int(depth) + if depth > 5: + logger.warning("[NFS] Limiting depth to maximum value of 5: " + "input depth=%s", depth) + depth = 5 + root_dir = '{}/'.format(root_dir) \ + if not root_dir.endswith('/') else root_dir + + try: + cfs = CephFS() + paths = cfs.get_dir_list(root_dir, depth) + paths = [p[:-1] for p in paths if p != root_dir] + return {'paths': paths} + except (cephfs.ObjectNotFound, cephfs.PermissionError): + return {'paths': []} + + @Endpoint('GET', '/cephfs/filesystems') + @ReadPermission + def filesystems(self): + return CephFS.list_filesystems() + + @Endpoint('GET', '/rgw/buckets') + @ReadPermission + def buckets(self, user_id=None): + return RgwClient.instance(user_id).get_buckets() + + @Endpoint('GET', '/clusters') + @ReadPermission + def clusters(self): + return Ganesha.get_ganesha_clusters() diff --git a/src/pybind/mgr/dashboard/controllers/osd.py b/src/pybind/mgr/dashboard/controllers/osd.py new file mode 100644 index 00000000..a971a512 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/osd.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from mgr_util import get_most_recent_rate + +from . import ApiController, RESTController, UpdatePermission, \ + allow_empty_body +from .. import mgr, logger +from ..security import Scope +from ..services.ceph_service import CephService, SendCommandError +from ..services.exception import handle_send_command_error +from ..tools import str_to_bool +try: + from typing import Dict, List, Any, Union # pylint: disable=unused-import +except ImportError: + pass # For typing only + + +@ApiController('/osd', Scope.OSD) +class Osd(RESTController): + def list(self): + osds = self.get_osd_map() + + # Extending by osd stats information + for stat in mgr.get('osd_stats')['osd_stats']: + if stat['osd'] in osds: + osds[stat['osd']]['osd_stats'] = stat + + # Extending by osd node information + nodes = mgr.get('osd_map_tree')['nodes'] + for node in nodes: + if node['type'] == 'osd' and node['id'] in osds: + osds[node['id']]['tree'] = node + + # Extending by osd parent node information + for host in [n for n in nodes if n['type'] == 'host']: + for osd_id in host['children']: + if osd_id >= 0 and osd_id in osds: + osds[osd_id]['host'] = host + + # Extending by osd histogram data + for osd_id, osd in osds.items(): + osd['stats'] = {} + osd['stats_history'] = {} + osd_spec = str(osd_id) + if 'osd' not in osd: + continue + for stat in ['osd.op_w', 'osd.op_in_bytes', 'osd.op_r', 'osd.op_out_bytes']: + prop = stat.split('.')[1] + rates = CephService.get_rates('osd', osd_spec, stat) + osd['stats'][prop] = get_most_recent_rate(rates) + osd['stats_history'][prop] = rates + # Gauge stats + for stat in ['osd.numpg', 'osd.stat_bytes', 'osd.stat_bytes_used']: + osd['stats'][stat.split('.')[1]] = mgr.get_latest('osd', osd_spec, stat) + + return list(osds.values()) + + @staticmethod + def get_osd_map(svc_id=None): + # type: (Union[int, None]) -> Dict[int, Union[Dict[str, Any], Any]] + def add_id(osd): + osd['id'] = osd['osd'] + return osd + resp = { + osd['osd']: add_id(osd) + for osd in mgr.get('osd_map')['osds'] if svc_id is None or osd['osd'] == int(svc_id) + } + return resp if svc_id is None else resp[int(svc_id)] + + @handle_send_command_error('osd') + def get(self, svc_id): + """ + Returns collected data about an OSD. + + :return: Returns the requested data. The `histogram` key man contain a + string with an error that occurred when the OSD is down. + """ + try: + histogram = CephService.send_command('osd', srv_spec=svc_id, + prefix='perf histogram dump') + except SendCommandError as e: + if 'osd down' in str(e): + histogram = str(e) + else: + raise + + return { + 'osd_map': self.get_osd_map(svc_id), + 'osd_metadata': mgr.get_metadata('osd', svc_id), + 'histogram': histogram, + } + + @RESTController.Resource('POST', query_params=['deep']) + @UpdatePermission + @allow_empty_body + def scrub(self, svc_id, deep=False): + api_scrub = "osd deep-scrub" if str_to_bool(deep) else "osd scrub" + CephService.send_command("mon", api_scrub, who=svc_id) + + @RESTController.Resource('POST') + @allow_empty_body + def mark_out(self, svc_id): + CephService.send_command('mon', 'osd out', ids=[svc_id]) + + @RESTController.Resource('POST') + @allow_empty_body + def mark_in(self, svc_id): + CephService.send_command('mon', 'osd in', ids=[svc_id]) + + @RESTController.Resource('POST') + @allow_empty_body + def mark_down(self, svc_id): + CephService.send_command('mon', 'osd down', ids=[svc_id]) + + @RESTController.Resource('POST') + @allow_empty_body + def reweight(self, svc_id, weight): + """ + Reweights the OSD temporarily. + + Note that ‘ceph osd reweight’ is not a persistent setting. When an OSD + gets marked out, the osd weight will be set to 0. When it gets marked + in again, the weight will be changed to 1. + + Because of this ‘ceph osd reweight’ is a temporary solution. You should + only use it to keep your cluster running while you’re ordering more + hardware. + + - Craig Lewis (http://lists.ceph.com/pipermail/ceph-users-ceph.com/2014-June/040967.html) + """ + CephService.send_command( + 'mon', + 'osd reweight', + id=int(svc_id), + weight=float(weight)) + + @RESTController.Resource('POST') + @allow_empty_body + def mark_lost(self, svc_id): + """ + Note: osd must be marked `down` before marking lost. + """ + CephService.send_command( + 'mon', + 'osd lost', + id=int(svc_id), + yes_i_really_mean_it=True) + + def create(self, uuid=None, svc_id=None): + """ + :param uuid: Will be set automatically if the OSD starts up. + :param id: The ID is only used if a valid uuid is given. + :return: + """ + result = CephService.send_command( + 'mon', 'osd create', id=int(svc_id), uuid=uuid) + return { + 'result': result, + 'svc_id': int(svc_id), + 'uuid': uuid, + } + + @RESTController.Resource('POST') + @allow_empty_body + def purge(self, svc_id): + """ + Note: osd must be marked `down` before removal. + """ + CephService.send_command('mon', 'osd purge-actual', id=int(svc_id), + yes_i_really_mean_it=True) + + @RESTController.Resource('POST') + @allow_empty_body + def destroy(self, svc_id): + """ + Mark osd as being destroyed. Keeps the ID intact (allowing reuse), but + removes cephx keys, config-key data and lockbox keys, rendering data + permanently unreadable. + + The osd must be marked down before being destroyed. + """ + CephService.send_command( + 'mon', 'osd destroy-actual', id=int(svc_id), yes_i_really_mean_it=True) + + @RESTController.Resource('GET') + def safe_to_destroy(self, svc_id): + """ + :type svc_id: int|[int] + """ + if not isinstance(svc_id, list): + svc_id = [svc_id] + svc_id = list(map(str, svc_id)) + try: + result = CephService.send_command( + 'mon', 'osd safe-to-destroy', ids=svc_id, target=('mgr', '')) + result['is_safe_to_destroy'] = set(result['safe_to_destroy']) == set(map(int, svc_id)) + return result + + except SendCommandError as e: + return { + 'message': str(e), + 'is_safe_to_destroy': False, + } + + +@ApiController('/osd/flags', Scope.OSD) +class OsdFlagsController(RESTController): + @staticmethod + def _osd_flags(): + enabled_flags = mgr.get('osd_map')['flags_set'] + if 'pauserd' in enabled_flags and 'pausewr' in enabled_flags: + # 'pause' is set by calling `ceph osd set pause` and unset by + # calling `set osd unset pause`, but `ceph osd dump | jq '.flags'` + # will contain 'pauserd,pausewr' if pause is set. + # Let's pretend to the API that 'pause' is in fact a proper flag. + enabled_flags = list( + set(enabled_flags) - {'pauserd', 'pausewr'} | {'pause'}) + return sorted(enabled_flags) + + def list(self): + return self._osd_flags() + + def bulk_set(self, flags): + """ + The `recovery_deletes`, `sortbitwise` and `pglog_hardlimit` flags cannot be unset. + `purged_snapshots` cannot even be set. It is therefore required to at + least include those four flags for a successful operation. + """ + assert isinstance(flags, list) + + enabled_flags = set(self._osd_flags()) + data = set(flags) + added = data - enabled_flags + removed = enabled_flags - data + for flag in added: + CephService.send_command('mon', 'osd set', '', key=flag) + for flag in removed: + CephService.send_command('mon', 'osd unset', '', key=flag) + logger.info('Changed OSD flags: added=%s removed=%s', added, removed) + + return sorted(enabled_flags - removed | added) diff --git a/src/pybind/mgr/dashboard/controllers/perf_counters.py b/src/pybind/mgr/dashboard/controllers/perf_counters.py new file mode 100644 index 00000000..158641ca --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/perf_counters.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import cherrypy + +from . import ApiController, RESTController +from .. import mgr +from ..security import Scope +from ..services.ceph_service import CephService + + +class PerfCounter(RESTController): + service_type = None # type: str + + def get(self, service_id): + schema_dict = mgr.get_perf_schema(self.service_type, str(service_id)) + try: + schema = schema_dict["{}.{}".format(self.service_type, service_id)] + except KeyError as e: + raise cherrypy.HTTPError(404, "{0} not found".format(e)) + counters = [] + + for key, value in sorted(schema.items()): + counter = dict() + counter['name'] = str(key) + counter['description'] = value['description'] + # pylint: disable=W0212 + if mgr._stattype_to_str(value['type']) == 'counter': + counter['value'] = CephService.get_rate( + self.service_type, service_id, key) + counter['unit'] = mgr._unit_to_str(value['units']) + else: + counter['value'] = mgr.get_latest( + self.service_type, service_id, key) + counter['unit'] = '' + counters.append(counter) + + return { + 'service': { + 'type': self.service_type, + 'id': str(service_id) + }, + 'counters': counters + } + + +@ApiController('perf_counters/mds', Scope.CEPHFS) +class MdsPerfCounter(PerfCounter): + service_type = 'mds' + + +@ApiController('perf_counters/mon', Scope.MONITOR) +class MonPerfCounter(PerfCounter): + service_type = 'mon' + + +@ApiController('perf_counters/osd', Scope.OSD) +class OsdPerfCounter(PerfCounter): + service_type = 'osd' + + +@ApiController('perf_counters/rgw', Scope.RGW) +class RgwPerfCounter(PerfCounter): + service_type = 'rgw' + + +@ApiController('perf_counters/rbd-mirror', Scope.RBD_MIRRORING) +class RbdMirrorPerfCounter(PerfCounter): + service_type = 'rbd-mirror' + + +@ApiController('perf_counters/mgr', Scope.MANAGER) +class MgrPerfCounter(PerfCounter): + service_type = 'mgr' + + +@ApiController('perf_counters/tcmu-runner', Scope.ISCSI) +class TcmuRunnerPerfCounter(PerfCounter): + service_type = 'tcmu-runner' + + +@ApiController('perf_counters') +class PerfCounters(RESTController): + def list(self): + return mgr.get_all_perf_counters() diff --git a/src/pybind/mgr/dashboard/controllers/pool.py b/src/pybind/mgr/dashboard/controllers/pool.py new file mode 100644 index 00000000..c6919fc2 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/pool.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import time +import cherrypy + +from . import ApiController, RESTController, Endpoint, ReadPermission, Task +from .. import mgr +from ..security import Scope +from ..services.ceph_service import CephService +from ..services.rbd import RbdConfiguration +from ..services.exception import handle_send_command_error +from ..tools import str_to_bool, TaskManager + + +def pool_task(name, metadata, wait_for=2.0): + return Task("pool/{}".format(name), metadata, wait_for) + + +@ApiController('/pool', Scope.POOL) +class Pool(RESTController): + + @staticmethod + def _serialize_pool(pool, attrs): + if not attrs or not isinstance(attrs, list): + attrs = pool.keys() + + crush_rules = {r['rule_id']: r["rule_name"] for r in mgr.get('osd_map_crush')['rules']} + + res = {} + for attr in attrs: + if attr not in pool: + continue + if attr == 'type': + res[attr] = {1: 'replicated', 3: 'erasure'}[pool[attr]] + elif attr == 'crush_rule': + res[attr] = crush_rules[pool[attr]] + elif attr == 'application_metadata': + res[attr] = list(pool[attr].keys()) + else: + res[attr] = pool[attr] + + # pool_name is mandatory + res['pool_name'] = pool['pool_name'] + return res + + @classmethod + def _pool_list(cls, attrs=None, stats=False): + if attrs: + attrs = attrs.split(',') + + if str_to_bool(stats): + pools = CephService.get_pool_list_with_stats() + else: + pools = CephService.get_pool_list() + + return [cls._serialize_pool(pool, attrs) for pool in pools] + + def list(self, attrs=None, stats=False): + return self._pool_list(attrs, stats) + + @classmethod + def _get(cls, pool_name, attrs=None, stats=False): + # type: (str, str, bool) -> dict + pools = cls._pool_list(attrs, stats) + pool = [pool for pool in pools if pool['pool_name'] == pool_name] + if not pool: + raise cherrypy.NotFound('No such pool') + return pool[0] + + def get(self, pool_name, attrs=None, stats=False): + # type: (str, str, bool) -> dict + pool = self._get(pool_name, attrs, stats) + pool['configuration'] = RbdConfiguration(pool_name).list() + return pool + + @pool_task('delete', ['{pool_name}']) + @handle_send_command_error('pool') + def delete(self, pool_name): + return CephService.send_command('mon', 'osd pool delete', pool=pool_name, pool2=pool_name, + yes_i_really_really_mean_it=True) + + @pool_task('edit', ['{pool_name}']) + def set(self, pool_name, flags=None, application_metadata=None, configuration=None, **kwargs): + self._set_pool_values(pool_name, application_metadata, flags, True, kwargs) + if kwargs.get('pool'): + pool_name = kwargs['pool'] + RbdConfiguration(pool_name).set_configuration(configuration) + self._wait_for_pgs(pool_name) + + @pool_task('create', {'pool_name': '{pool}'}) + @handle_send_command_error('pool') + def create(self, pool, pg_num, pool_type, erasure_code_profile=None, flags=None, + application_metadata=None, rule_name=None, configuration=None, **kwargs): + ecp = erasure_code_profile if erasure_code_profile else None + CephService.send_command('mon', 'osd pool create', pool=pool, pg_num=int(pg_num), + pgp_num=int(pg_num), pool_type=pool_type, erasure_code_profile=ecp, + rule=rule_name) + self._set_pool_values(pool, application_metadata, flags, False, kwargs) + RbdConfiguration(pool).set_configuration(configuration) + self._wait_for_pgs(pool) + + def _set_pool_values(self, pool, application_metadata, flags, update_existing, kwargs): + update_name = False + current_pool = self._get(pool) + if update_existing and kwargs.get('compression_mode') == 'unset': + self._prepare_compression_removal(current_pool.get('options'), kwargs) + if flags and 'ec_overwrites' in flags: + CephService.send_command('mon', 'osd pool set', pool=pool, var='allow_ec_overwrites', + val='true') + if application_metadata is not None: + def set_app(what, app): + CephService.send_command('mon', 'osd pool application ' + what, pool=pool, app=app, + yes_i_really_mean_it=True) + if update_existing: + original_app_metadata = set( + current_pool.get('application_metadata')) + else: + original_app_metadata = set() + + for app in original_app_metadata - set(application_metadata): + set_app('disable', app) + for app in set(application_metadata) - original_app_metadata: + set_app('enable', app) + + def set_key(key, value): + CephService.send_command('mon', 'osd pool set', pool=pool, var=key, val=str(value)) + + for key, value in kwargs.items(): + if key == 'pool': + update_name = True + destpool = value + else: + set_key(key, value) + if key == 'pg_num': + set_key('pgp_num', value) + if update_name: + CephService.send_command('mon', 'osd pool rename', srcpool=pool, destpool=destpool) + + def _prepare_compression_removal(self, options, kwargs): + """ + Presets payload with values to remove compression attributes in case they are not + needed anymore. + + In case compression is not needed the dashboard will send 'compression_mode' with the + value 'unset'. + + :param options: All set options for the current pool. + :param kwargs: Payload of the PUT / POST call + """ + if options is not None: + def reset_arg(arg, value): + if options.get(arg): + kwargs[arg] = value + for arg in ['compression_min_blob_size', 'compression_max_blob_size', + 'compression_required_ratio']: + reset_arg(arg, '0') + reset_arg('compression_algorithm', 'unset') + + @classmethod + def _wait_for_pgs(cls, pool_name): + """ + Keep the task waiting for until all pg changes are complete + :param pool_name: The name of the pool. + :type pool_name: string + """ + current_pool = cls._get(pool_name) + initial_pgs = int(current_pool['pg_placement_num']) + int(current_pool['pg_num']) + cls._pg_wait_loop(current_pool, initial_pgs) + + @classmethod + def _pg_wait_loop(cls, pool, initial_pgs): + """ + Compares if all pg changes are completed, if not it will call itself + until all changes are completed. + :param pool: The dict that represents a pool. + :type pool: dict + :param initial_pgs: The pg and pg_num count before any change happened. + :type initial_pgs: int + """ + if 'pg_num_target' in pool: + target = int(pool['pg_num_target']) + int(pool['pg_placement_num_target']) + current = int(pool['pg_placement_num']) + int(pool['pg_num']) + if current != target: + max_diff = abs(target - initial_pgs) + diff = max_diff - abs(target - current) + percentage = int(round(diff / float(max_diff) * 100)) + TaskManager.current_task().set_progress(percentage) + time.sleep(4) + cls._pg_wait_loop(cls._get(pool['pool_name']), initial_pgs) + + @RESTController.Resource() + @ReadPermission + def configuration(self, pool_name): + return RbdConfiguration(pool_name).list() + + @Endpoint() + @ReadPermission + def _info(self, pool_name=''): + # type: (str) -> dict + """Used by the create-pool dialog""" + + def rules(pool_type): + return [r + for r in mgr.get('osd_map_crush')['rules'] + if r['type'] == pool_type] + + def all_bluestore(): + return all(o['osd_objectstore'] == 'bluestore' + for o in mgr.get('osd_metadata').values()) + + def get_config_option_enum(conf_name): + return [[v for v in o['enum_values'] if len(v) > 0] + for o in mgr.get('config_options')['options'] + if o['name'] == conf_name][0] + + mgr_config = mgr.get('config') + result = { + "pool_names": [p['pool_name'] for p in self._pool_list()], + "crush_rules_replicated": rules(1), + "crush_rules_erasure": rules(3), + "is_all_bluestore": all_bluestore(), + "osd_count": len(mgr.get('osd_map')['osds']), + "bluestore_compression_algorithm": mgr_config['bluestore_compression_algorithm'], + "compression_algorithms": get_config_option_enum('bluestore_compression_algorithm'), + "compression_modes": get_config_option_enum('bluestore_compression_mode'), + "pg_autoscale_default_mode": mgr_config['osd_pool_default_pg_autoscale_mode'], + "pg_autoscale_modes": get_config_option_enum('osd_pool_default_pg_autoscale_mode'), + } + + if pool_name: + result['pool_options'] = RbdConfiguration(pool_name).list() + + return result diff --git a/src/pybind/mgr/dashboard/controllers/prometheus.py b/src/pybind/mgr/dashboard/controllers/prometheus.py new file mode 100644 index 00000000..40333541 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/prometheus.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from datetime import datetime +import json +import requests + +from . import Controller, ApiController, BaseController, RESTController, Endpoint +from ..security import Scope +from ..settings import Settings +from ..exceptions import DashboardException + + +@Controller('/api/prometheus_receiver', secure=False) +class PrometheusReceiver(BaseController): + ''' The receiver is needed in order to receive alert notifications (reports) ''' + notifications = [] + + @Endpoint('POST', path='/') + def fetch_alert(self, **notification): + notification['notified'] = datetime.now().isoformat() + notification['id'] = str(len(self.notifications)) + self.notifications.append(notification) + + +class PrometheusRESTController(RESTController): + def prometheus_proxy(self, method, path, params=None, payload=None): + return self._proxy(self._get_api_url(Settings.PROMETHEUS_API_HOST), + method, path, params, payload) + + def alert_proxy(self, method, path, params=None, payload=None): + return self._proxy(self._get_api_url(Settings.ALERTMANAGER_API_HOST), + method, path, params, payload) + + def _get_api_url(self, host): + return host.rstrip('/') + '/api/v1' + + def _proxy(self, base_url, method, path, params=None, payload=None): + try: + response = requests.request(method, base_url + path, params=params, json=payload) + except Exception: + raise DashboardException('Could not reach external API', http_status_code=404, + component='prometheus') + content = json.loads(response.content) + if content['status'] == 'success': + if 'data' in content: + return content['data'] + return content + raise DashboardException(content, http_status_code=400, component='prometheus') + + +@ApiController('/prometheus', Scope.PROMETHEUS) +class Prometheus(PrometheusRESTController): + def list(self, **params): + return self.alert_proxy('GET', '/alerts', params) + + @RESTController.Collection(method='GET') + def rules(self, **params): + return self.prometheus_proxy('GET', '/rules', params) + + @RESTController.Collection(method='GET', path='/silences') + def get_silences(self, **params): + return self.alert_proxy('GET', '/silences', params) + + @RESTController.Collection(method='POST', path='/silence', status=201) + def create_silence(self, **params): + return self.alert_proxy('POST', '/silences', payload=params) + + @RESTController.Collection(method='DELETE', path='/silence/{s_id}', status=204) + def delete_silence(self, s_id): + return self.alert_proxy('DELETE', '/silence/' + s_id) if s_id else None + + +@ApiController('/prometheus/notifications', Scope.PROMETHEUS) +class PrometheusNotifications(RESTController): + + def list(self, **params): + if 'from' in params: + f = params['from'] + if f == 'last': + return PrometheusReceiver.notifications[-1:] + return PrometheusReceiver.notifications[int(f) + 1:] + return PrometheusReceiver.notifications diff --git a/src/pybind/mgr/dashboard/controllers/rbd.py b/src/pybind/mgr/dashboard/controllers/rbd.py new file mode 100644 index 00000000..52dca087 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/rbd.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# pylint: disable=unused-argument +# pylint: disable=too-many-statements,too-many-branches +from __future__ import absolute_import + +import math +from functools import partial +from datetime import datetime + +import cherrypy + +import rbd + +from . import ApiController, RESTController, Task, UpdatePermission, \ + DeletePermission, CreatePermission, ReadPermission, allow_empty_body +from .. import mgr, logger +from ..security import Scope +from ..services.ceph_service import CephService +from ..services.rbd import RbdConfiguration, format_bitmask, format_features +from ..tools import ViewCache, str_to_bool +from ..services.exception import handle_rados_error, handle_rbd_error, \ + serialize_dashboard_exception + + +# pylint: disable=not-callable +def RbdTask(name, metadata, wait_for): + def composed_decorator(func): + func = handle_rados_error('pool')(func) + func = handle_rbd_error()(func) + return Task("rbd/{}".format(name), metadata, wait_for, + partial(serialize_dashboard_exception, include_http_status=True))(func) + return composed_decorator + + +def _rbd_call(pool_name, func, *args, **kwargs): + with mgr.rados.open_ioctx(pool_name) as ioctx: + func(ioctx, *args, **kwargs) + + +def _rbd_image_call(pool_name, image_name, func, *args, **kwargs): + def _ioctx_func(ioctx, image_name, func, *args, **kwargs): + with rbd.Image(ioctx, image_name) as img: + func(ioctx, img, *args, **kwargs) + + return _rbd_call(pool_name, _ioctx_func, image_name, func, *args, **kwargs) + + +def _sort_features(features, enable=True): + """ + Sorts image features according to feature dependencies: + + object-map depends on exclusive-lock + journaling depends on exclusive-lock + fast-diff depends on object-map + """ + ORDER = ['exclusive-lock', 'journaling', 'object-map', 'fast-diff'] + + def key_func(feat): + try: + return ORDER.index(feat) + except ValueError: + return id(feat) + + features.sort(key=key_func, reverse=not enable) + + +@ApiController('/block/image', Scope.RBD_IMAGE) +class Rbd(RESTController): + + RESOURCE_ID = "pool_name/image_name" + + # set of image features that can be enable on existing images + ALLOW_ENABLE_FEATURES = {"exclusive-lock", "object-map", "fast-diff", "journaling"} + + # set of image features that can be disabled on existing images + ALLOW_DISABLE_FEATURES = {"exclusive-lock", "object-map", "fast-diff", "deep-flatten", + "journaling"} + + @classmethod + def _rbd_disk_usage(cls, image, snaps, whole_object=True): + class DUCallback(object): + def __init__(self): + self.used_size = 0 + + def __call__(self, offset, length, exists): + if exists: + self.used_size += length + + snap_map = {} + prev_snap = None + total_used_size = 0 + for _, size, name in snaps: + image.set_snap(name) + du_callb = DUCallback() + image.diff_iterate(0, size, prev_snap, du_callb, + whole_object=whole_object) + snap_map[name] = du_callb.used_size + total_used_size += du_callb.used_size + prev_snap = name + + return total_used_size, snap_map + + @classmethod + def _rbd_image(cls, ioctx, pool_name, image_name): + with rbd.Image(ioctx, image_name) as img: + stat = img.stat() + stat['name'] = image_name + if img.old_format(): + stat['unique_id'] = '{}/{}'.format(pool_name, stat['block_name_prefix']) + stat['id'] = stat['unique_id'] + stat['image_format'] = 1 + else: + stat['unique_id'] = '{}/{}'.format(pool_name, img.id()) + stat['id'] = img.id() + stat['image_format'] = 2 + + stat['pool_name'] = pool_name + features = img.features() + stat['features'] = features + stat['features_name'] = format_bitmask(features) + + # the following keys are deprecated + del stat['parent_pool'] + del stat['parent_name'] + + stat['timestamp'] = "{}Z".format(img.create_timestamp() + .isoformat()) + + stat['stripe_count'] = img.stripe_count() + stat['stripe_unit'] = img.stripe_unit() + + data_pool_name = CephService.get_pool_name_from_id( + img.data_pool_id()) + if data_pool_name == pool_name: + data_pool_name = None + stat['data_pool'] = data_pool_name + + try: + parent_info = img.parent_info() + stat['parent'] = { + 'pool_name': parent_info[0], + 'image_name': parent_info[1], + 'snap_name': parent_info[2] + } + except rbd.ImageNotFound: + # no parent image + stat['parent'] = None + + # snapshots + stat['snapshots'] = [] + for snap in img.list_snaps(): + snap['timestamp'] = "{}Z".format( + img.get_snap_timestamp(snap['id']).isoformat()) + snap['is_protected'] = img.is_protected_snap(snap['name']) + snap['used_bytes'] = None + snap['children'] = [] + img.set_snap(snap['name']) + for child_pool_name, child_image_name in img.list_children(): + snap['children'].append({ + 'pool_name': child_pool_name, + 'image_name': child_image_name + }) + stat['snapshots'].append(snap) + + # disk usage + img_flags = img.flags() + if 'fast-diff' in stat['features_name'] and \ + not rbd.RBD_FLAG_FAST_DIFF_INVALID & img_flags: + snaps = [(s['id'], s['size'], s['name']) + for s in stat['snapshots']] + snaps.sort(key=lambda s: s[0]) + snaps += [(snaps[-1][0]+1 if snaps else 0, stat['size'], None)] + total_prov_bytes, snaps_prov_bytes = cls._rbd_disk_usage( + img, snaps, True) + stat['total_disk_usage'] = total_prov_bytes + for snap, prov_bytes in snaps_prov_bytes.items(): + if snap is None: + stat['disk_usage'] = prov_bytes + continue + for ss in stat['snapshots']: + if ss['name'] == snap: + ss['disk_usage'] = prov_bytes + break + else: + stat['total_disk_usage'] = None + stat['disk_usage'] = None + + stat['configuration'] = RbdConfiguration(pool_ioctx=ioctx, image_name=image_name).list() + + return stat + + @classmethod + @ViewCache() + def _rbd_pool_list(cls, pool_name): + rbd_inst = rbd.RBD() + with mgr.rados.open_ioctx(pool_name) as ioctx: + names = rbd_inst.list(ioctx) + result = [] + for name in names: + try: + stat = cls._rbd_image(ioctx, pool_name, name) + except rbd.ImageNotFound: + # may have been removed in the meanwhile + continue + result.append(stat) + return result + + def _rbd_list(self, pool_name=None): + if pool_name: + pools = [pool_name] + else: + pools = [p['pool_name'] for p in CephService.get_pool_list('rbd')] + + result = [] + for pool in pools: + # pylint: disable=unbalanced-tuple-unpacking + status, value = self._rbd_pool_list(pool) + for i, image in enumerate(value): + value[i]['configuration'] = RbdConfiguration(pool, image['name']).list() + result.append({'status': status, 'value': value, 'pool_name': pool}) + return result + + @handle_rbd_error() + @handle_rados_error('pool') + def list(self, pool_name=None): + return self._rbd_list(pool_name) + + @handle_rbd_error() + @handle_rados_error('pool') + def get(self, pool_name, image_name): + ioctx = mgr.rados.open_ioctx(pool_name) + try: + return self._rbd_image(ioctx, pool_name, image_name) + except rbd.ImageNotFound: + raise cherrypy.HTTPError(404) + + @RbdTask('create', + {'pool_name': '{pool_name}', 'image_name': '{name}'}, 2.0) + def create(self, name, pool_name, size, obj_size=None, features=None, + stripe_unit=None, stripe_count=None, data_pool=None, configuration=None): + + size = int(size) + + def _create(ioctx): + rbd_inst = rbd.RBD() + + # Set order + l_order = None + if obj_size and obj_size > 0: + l_order = int(round(math.log(float(obj_size), 2))) + + # Set features + feature_bitmask = format_features(features) + + rbd_inst.create(ioctx, name, size, order=l_order, old_format=False, + features=feature_bitmask, stripe_unit=stripe_unit, + stripe_count=stripe_count, data_pool=data_pool) + RbdConfiguration(pool_ioctx=ioctx, image_name=name).set_configuration(configuration) + + _rbd_call(pool_name, _create) + + @RbdTask('delete', ['{pool_name}', '{image_name}'], 2.0) + def delete(self, pool_name, image_name): + rbd_inst = rbd.RBD() + return _rbd_call(pool_name, rbd_inst.remove, image_name) + + @RbdTask('edit', ['{pool_name}', '{image_name}', '{name}'], 4.0) + def set(self, pool_name, image_name, name=None, size=None, features=None, configuration=None): + def _edit(ioctx, image): + rbd_inst = rbd.RBD() + # check rename image + if name and name != image_name: + rbd_inst.rename(ioctx, image_name, name) + + # check resize + if size and size != image.size(): + image.resize(size) + + # check enable/disable features + if features is not None: + curr_features = format_bitmask(image.features()) + # check disabled features + _sort_features(curr_features, enable=False) + for feature in curr_features: + if feature not in features and feature in self.ALLOW_DISABLE_FEATURES: + if feature not in format_bitmask(image.features()): + continue + f_bitmask = format_features([feature]) + image.update_features(f_bitmask, False) + # check enabled features + _sort_features(features) + for feature in features: + if feature not in curr_features and feature in self.ALLOW_ENABLE_FEATURES: + if feature in format_bitmask(image.features()): + continue + f_bitmask = format_features([feature]) + image.update_features(f_bitmask, True) + + RbdConfiguration(pool_ioctx=ioctx, image_name=image_name).set_configuration( + configuration) + + return _rbd_image_call(pool_name, image_name, _edit) + + @RbdTask('copy', + {'src_pool_name': '{pool_name}', + 'src_image_name': '{image_name}', + 'dest_pool_name': '{dest_pool_name}', + 'dest_image_name': '{dest_image_name}'}, 2.0) + @RESTController.Resource('POST') + @allow_empty_body + def copy(self, pool_name, image_name, dest_pool_name, dest_image_name, + snapshot_name=None, obj_size=None, features=None, stripe_unit=None, + stripe_count=None, data_pool=None, configuration=None): + + def _src_copy(s_ioctx, s_img): + def _copy(d_ioctx): + # Set order + l_order = None + if obj_size and obj_size > 0: + l_order = int(round(math.log(float(obj_size), 2))) + + # Set features + feature_bitmask = format_features(features) + + if snapshot_name: + s_img.set_snap(snapshot_name) + + s_img.copy(d_ioctx, dest_image_name, feature_bitmask, l_order, + stripe_unit, stripe_count, data_pool) + RbdConfiguration(pool_ioctx=d_ioctx, image_name=dest_image_name).set_configuration( + configuration) + + return _rbd_call(dest_pool_name, _copy) + + return _rbd_image_call(pool_name, image_name, _src_copy) + + @RbdTask('flatten', ['{pool_name}', '{image_name}'], 2.0) + @RESTController.Resource('POST') + @UpdatePermission + @allow_empty_body + def flatten(self, pool_name, image_name): + + def _flatten(ioctx, image): + image.flatten() + + return _rbd_image_call(pool_name, image_name, _flatten) + + @RESTController.Collection('GET') + def default_features(self): + rbd_default_features = mgr.get('config')['rbd_default_features'] + return format_bitmask(int(rbd_default_features)) + + @RbdTask('trash/move', ['{pool_name}', '{image_name}'], 2.0) + @RESTController.Resource('POST') + @allow_empty_body + def move_trash(self, pool_name, image_name, delay=0): + """Move an image to the trash. + Images, even ones actively in-use by clones, + can be moved to the trash and deleted at a later time. + """ + rbd_inst = rbd.RBD() + return _rbd_call(pool_name, rbd_inst.trash_move, image_name, delay) + + @RESTController.Resource() + @ReadPermission + def configuration(self, pool_name, image_name): + return RbdConfiguration(pool_name, image_name).list() + + +@ApiController('/block/image/{pool_name}/{image_name}/snap', Scope.RBD_IMAGE) +class RbdSnapshot(RESTController): + + RESOURCE_ID = "snapshot_name" + + @RbdTask('snap/create', + ['{pool_name}', '{image_name}', '{snapshot_name}'], 2.0) + def create(self, pool_name, image_name, snapshot_name): + def _create_snapshot(ioctx, img, snapshot_name): + img.create_snap(snapshot_name) + + return _rbd_image_call(pool_name, image_name, _create_snapshot, + snapshot_name) + + @RbdTask('snap/delete', + ['{pool_name}', '{image_name}', '{snapshot_name}'], 2.0) + def delete(self, pool_name, image_name, snapshot_name): + def _remove_snapshot(ioctx, img, snapshot_name): + img.remove_snap(snapshot_name) + + return _rbd_image_call(pool_name, image_name, _remove_snapshot, + snapshot_name) + + @RbdTask('snap/edit', + ['{pool_name}', '{image_name}', '{snapshot_name}'], 4.0) + def set(self, pool_name, image_name, snapshot_name, new_snap_name=None, + is_protected=None): + def _edit(ioctx, img, snapshot_name): + if new_snap_name and new_snap_name != snapshot_name: + img.rename_snap(snapshot_name, new_snap_name) + snapshot_name = new_snap_name + if is_protected is not None and \ + is_protected != img.is_protected_snap(snapshot_name): + if is_protected: + img.protect_snap(snapshot_name) + else: + img.unprotect_snap(snapshot_name) + + return _rbd_image_call(pool_name, image_name, _edit, snapshot_name) + + @RbdTask('snap/rollback', + ['{pool_name}', '{image_name}', '{snapshot_name}'], 5.0) + @RESTController.Resource('POST') + @UpdatePermission + @allow_empty_body + def rollback(self, pool_name, image_name, snapshot_name): + def _rollback(ioctx, img, snapshot_name): + img.rollback_to_snap(snapshot_name) + return _rbd_image_call(pool_name, image_name, _rollback, snapshot_name) + + @RbdTask('clone', + {'parent_pool_name': '{pool_name}', + 'parent_image_name': '{image_name}', + 'parent_snap_name': '{snapshot_name}', + 'child_pool_name': '{child_pool_name}', + 'child_image_name': '{child_image_name}'}, 2.0) + @RESTController.Resource('POST') + @allow_empty_body + def clone(self, pool_name, image_name, snapshot_name, child_pool_name, + child_image_name, obj_size=None, features=None, stripe_unit=None, stripe_count=None, + data_pool=None, configuration=None): + """ + Clones a snapshot to an image + """ + + def _parent_clone(p_ioctx): + def _clone(ioctx): + # Set order + l_order = None + if obj_size and obj_size > 0: + l_order = int(round(math.log(float(obj_size), 2))) + + # Set features + feature_bitmask = format_features(features) + + rbd_inst = rbd.RBD() + rbd_inst.clone(p_ioctx, image_name, snapshot_name, ioctx, + child_image_name, feature_bitmask, l_order, + stripe_unit, stripe_count, data_pool) + + RbdConfiguration(pool_ioctx=ioctx, image_name=child_image_name).set_configuration( + configuration) + + return _rbd_call(child_pool_name, _clone) + + _rbd_call(pool_name, _parent_clone) + + +@ApiController('/block/image/trash', Scope.RBD_IMAGE) +class RbdTrash(RESTController): + RESOURCE_ID = "pool_name/image_id" + rbd_inst = rbd.RBD() + + @ViewCache() + def _trash_pool_list(self, pool_name): + with mgr.rados.open_ioctx(pool_name) as ioctx: + images = self.rbd_inst.trash_list(ioctx) + result = [] + for trash in images: + trash['pool_name'] = pool_name + trash['deletion_time'] = "{}Z".format(trash['deletion_time'].isoformat()) + trash['deferment_end_time'] = "{}Z".format(trash['deferment_end_time'].isoformat()) + result.append(trash) + return result + + def _trash_list(self, pool_name=None): + if pool_name: + pools = [pool_name] + else: + pools = [p['pool_name'] for p in CephService.get_pool_list('rbd')] + + result = [] + for pool in pools: + # pylint: disable=unbalanced-tuple-unpacking + status, value = self._trash_pool_list(pool) + result.append({'status': status, 'value': value, 'pool_name': pool}) + return result + + @handle_rbd_error() + @handle_rados_error('pool') + def list(self, pool_name=None): + """List all entries from trash.""" + return self._trash_list(pool_name) + + @handle_rbd_error() + @handle_rados_error('pool') + @RbdTask('trash/purge', ['{pool_name}'], 2.0) + @RESTController.Collection('POST', query_params=['pool_name']) + @DeletePermission + @allow_empty_body + def purge(self, pool_name=None): + """Remove all expired images from trash.""" + now = "{}Z".format(datetime.utcnow().isoformat()) + pools = self._trash_list(pool_name) + + for pool in pools: + for image in pool['value']: + if image['deferment_end_time'] < now: + logger.info('Removing trash image %s (pool=%s, name=%s)', + image['id'], pool['pool_name'], image['name']) + _rbd_call(pool['pool_name'], self.rbd_inst.trash_remove, image['id'], 0) + + @RbdTask('trash/restore', ['{pool_name}', '{image_id}', '{new_image_name}'], 2.0) + @RESTController.Resource('POST') + @CreatePermission + @allow_empty_body + def restore(self, pool_name, image_id, new_image_name): + """Restore an image from trash.""" + return _rbd_call(pool_name, self.rbd_inst.trash_restore, image_id, new_image_name) + + @RbdTask('trash/remove', ['{pool_name}', '{image_id}', '{image_name}'], 2.0) + def delete(self, pool_name, image_id, image_name, force=False): + """Delete an image from trash. + If image deferment time has not expired you can not removed it unless use force. + But an actively in-use by clones or has snapshots can not be removed. + """ + return _rbd_call(pool_name, self.rbd_inst.trash_remove, image_id, int(str_to_bool(force))) diff --git a/src/pybind/mgr/dashboard/controllers/rbd_mirroring.py b/src/pybind/mgr/dashboard/controllers/rbd_mirroring.py new file mode 100644 index 00000000..0f6574a4 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/rbd_mirroring.py @@ -0,0 +1,460 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json +import re + +from functools import partial + +import cherrypy + +import rbd + +from . import ApiController, Endpoint, Task, BaseController, ReadPermission, \ + RESTController +from .. import logger, mgr +from ..security import Scope +from ..services.ceph_service import CephService +from ..tools import ViewCache +from ..services.exception import handle_rados_error, handle_rbd_error, \ + serialize_dashboard_exception + + +# pylint: disable=not-callable +def handle_rbd_mirror_error(): + def composed_decorator(func): + func = handle_rados_error('rbd-mirroring')(func) + return handle_rbd_error()(func) + return composed_decorator + + +# pylint: disable=not-callable +def RbdMirroringTask(name, metadata, wait_for): + def composed_decorator(func): + func = handle_rbd_mirror_error()(func) + return Task("rbd/mirroring/{}".format(name), metadata, wait_for, + partial(serialize_dashboard_exception, include_http_status=True))(func) + return composed_decorator + + +def _rbd_call(pool_name, func, *args, **kwargs): + with mgr.rados.open_ioctx(pool_name) as ioctx: + func(ioctx, *args, **kwargs) + + +@ViewCache() +def get_daemons_and_pools(): # pylint: disable=R0915 + def get_daemons(): + daemons = [] + for hostname, server in CephService.get_service_map('rbd-mirror').items(): + for service in server['services']: + id = service['id'] # pylint: disable=W0622 + metadata = service['metadata'] + status = service['status'] or {} + + try: + status = json.loads(status['json']) + except (ValueError, KeyError) as _: + status = {} + + instance_id = metadata['instance_id'] + if id == instance_id: + # new version that supports per-cluster leader elections + id = metadata['id'] + + # extract per-daemon service data and health + daemon = { + 'id': id, + 'instance_id': instance_id, + 'version': metadata['ceph_version'], + 'server_hostname': hostname, + 'service': service, + 'server': server, + 'metadata': metadata, + 'status': status + } + daemon = dict(daemon, **get_daemon_health(daemon)) + daemons.append(daemon) + + return sorted(daemons, key=lambda k: k['instance_id']) + + def get_daemon_health(daemon): + health = { + 'health_color': 'info', + 'health': 'Unknown' + } + for _, pool_data in daemon['status'].items(): + if (health['health'] != 'error' + and [k for k, v in pool_data.get('callouts', {}).items() + if v['level'] == 'error']): + health = { + 'health_color': 'error', + 'health': 'Error' + } + elif (health['health'] != 'error' + and [k for k, v in pool_data.get('callouts', {}).items() + if v['level'] == 'warning']): + health = { + 'health_color': 'warning', + 'health': 'Warning' + } + elif health['health_color'] == 'info': + health = { + 'health_color': 'success', + 'health': 'OK' + } + return health + + def get_pools(daemons): # pylint: disable=R0912, R0915 + pool_names = [pool['pool_name'] for pool in CephService.get_pool_list('rbd') + if pool.get('type', 1) == 1] + pool_stats = {} + rbdctx = rbd.RBD() + for pool_name in pool_names: + logger.debug("Constructing IOCtx %s", pool_name) + try: + ioctx = mgr.rados.open_ioctx(pool_name) + except TypeError: + logger.exception("Failed to open pool %s", pool_name) + continue + + try: + mirror_mode = rbdctx.mirror_mode_get(ioctx) + peer_uuids = [x['uuid'] for x in rbdctx.mirror_peer_list(ioctx)] + except: # noqa pylint: disable=W0702 + logger.exception("Failed to query mirror settings %s", pool_name) + mirror_mode = None + peer_uuids = [] + + stats = {} + if mirror_mode == rbd.RBD_MIRROR_MODE_DISABLED: + mirror_mode = "disabled" + stats['health_color'] = "info" + stats['health'] = "Disabled" + elif mirror_mode == rbd.RBD_MIRROR_MODE_IMAGE: + mirror_mode = "image" + elif mirror_mode == rbd.RBD_MIRROR_MODE_POOL: + mirror_mode = "pool" + else: + mirror_mode = "unknown" + stats['health_color'] = "warning" + stats['health'] = "Warning" + + pool_stats[pool_name] = dict(stats, **{ + 'mirror_mode': mirror_mode, + 'peer_uuids': peer_uuids + }) + + for daemon in daemons: + for _, pool_data in daemon['status'].items(): + stats = pool_stats.get(pool_data['name'], None) + if stats is None: + continue + + if pool_data.get('leader', False): + # leader instance stores image counts + stats['leader_id'] = daemon['metadata']['instance_id'] + stats['image_local_count'] = pool_data.get('image_local_count', 0) + stats['image_remote_count'] = pool_data.get('image_remote_count', 0) + + if (stats.get('health_color', '') != 'error' + and pool_data.get('image_error_count', 0) > 0): + stats['health_color'] = 'error' + stats['health'] = 'Error' + elif (stats.get('health_color', '') != 'error' + and pool_data.get('image_warning_count', 0) > 0): + stats['health_color'] = 'warning' + stats['health'] = 'Warning' + elif stats.get('health', None) is None: + stats['health_color'] = 'success' + stats['health'] = 'OK' + + for _, stats in pool_stats.items(): + if stats['mirror_mode'] == 'disabled': + continue + if stats.get('health', None) is None: + # daemon doesn't know about pool + stats['health_color'] = 'error' + stats['health'] = 'Error' + elif stats.get('leader_id', None) is None: + # no daemons are managing the pool as leader instance + stats['health_color'] = 'warning' + stats['health'] = 'Warning' + return pool_stats + + daemons = get_daemons() + return { + 'daemons': daemons, + 'pools': get_pools(daemons) + } + + +@ViewCache() +def _get_pool_datum(pool_name): + data = {} + logger.debug("Constructing IOCtx %s", pool_name) + try: + ioctx = mgr.rados.open_ioctx(pool_name) + except TypeError: + logger.exception("Failed to open pool %s", pool_name) + return None + + mirror_state = { + 'down': { + 'health': 'issue', + 'state_color': 'warning', + 'state': 'Unknown', + 'description': None + }, + rbd.MIRROR_IMAGE_STATUS_STATE_UNKNOWN: { + 'health': 'issue', + 'state_color': 'warning', + 'state': 'Unknown' + }, + rbd.MIRROR_IMAGE_STATUS_STATE_ERROR: { + 'health': 'issue', + 'state_color': 'error', + 'state': 'Error' + }, + rbd.MIRROR_IMAGE_STATUS_STATE_SYNCING: { + 'health': 'syncing' + }, + rbd.MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY: { + 'health': 'ok', + 'state_color': 'success', + 'state': 'Starting' + }, + rbd.MIRROR_IMAGE_STATUS_STATE_REPLAYING: { + 'health': 'ok', + 'state_color': 'success', + 'state': 'Replaying' + }, + rbd.MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY: { + 'health': 'ok', + 'state_color': 'success', + 'state': 'Stopping' + }, + rbd.MIRROR_IMAGE_STATUS_STATE_STOPPED: { + 'health': 'ok', + 'state_color': 'info', + 'state': 'Primary' + } + } + + rbdctx = rbd.RBD() + try: + mirror_image_status = rbdctx.mirror_image_status_list(ioctx) + data['mirror_images'] = sorted([ + dict({ + 'name': image['name'], + 'description': image['description'] + }, **mirror_state['down' if not image['up'] else image['state']]) + for image in mirror_image_status + ], key=lambda k: k['name']) + except rbd.ImageNotFound: + pass + except: # noqa pylint: disable=W0702 + logger.exception("Failed to list mirror image status %s", pool_name) + raise + + return data + + +@ViewCache() +def _get_content_data(): # pylint: disable=R0914 + pool_names = [pool['pool_name'] for pool in CephService.get_pool_list('rbd') + if pool.get('type', 1) == 1] + _, data = get_daemons_and_pools() + daemons = data.get('daemons', []) + pool_stats = data.get('pools', {}) + + pools = [] + image_error = [] + image_syncing = [] + image_ready = [] + for pool_name in pool_names: + _, pool = _get_pool_datum(pool_name) + if not pool: + pool = {} + + stats = pool_stats.get(pool_name, {}) + if stats.get('mirror_mode', None) is None: + continue + + mirror_images = pool.get('mirror_images', []) + for mirror_image in mirror_images: + image = { + 'pool_name': pool_name, + 'name': mirror_image['name'] + } + + if mirror_image['health'] == 'ok': + image.update({ + 'state_color': mirror_image['state_color'], + 'state': mirror_image['state'], + 'description': mirror_image['description'] + }) + image_ready.append(image) + elif mirror_image['health'] == 'syncing': + p = re.compile("bootstrapping, IMAGE_COPY/COPY_OBJECT (.*)%") + image.update({ + 'progress': (p.findall(mirror_image['description']) or [0])[0] + }) + image_syncing.append(image) + else: + image.update({ + 'state_color': mirror_image['state_color'], + 'state': mirror_image['state'], + 'description': mirror_image['description'] + }) + image_error.append(image) + + pools.append(dict({ + 'name': pool_name + }, **stats)) + + return { + 'daemons': daemons, + 'pools': pools, + 'image_error': image_error, + 'image_syncing': image_syncing, + 'image_ready': image_ready + } + + +def _reset_view_cache(): + get_daemons_and_pools.reset() + _get_pool_datum.reset() + _get_content_data.reset() + + +@ApiController('/block/mirroring/summary', Scope.RBD_MIRRORING) +class RbdMirroringSummary(BaseController): + + @Endpoint() + @handle_rbd_mirror_error() + @ReadPermission + def __call__(self): + status, content_data = _get_content_data() + return {'status': status, 'content_data': content_data} + + +@ApiController('/block/mirroring/pool', Scope.RBD_MIRRORING) +class RbdMirroringPoolMode(RESTController): + + RESOURCE_ID = "pool_name" + MIRROR_MODES = { + rbd.RBD_MIRROR_MODE_DISABLED: 'disabled', + rbd.RBD_MIRROR_MODE_IMAGE: 'image', + rbd.RBD_MIRROR_MODE_POOL: 'pool' + } + + @handle_rbd_mirror_error() + def get(self, pool_name): + ioctx = mgr.rados.open_ioctx(pool_name) + mode = rbd.RBD().mirror_mode_get(ioctx) + data = { + 'mirror_mode': self.MIRROR_MODES.get(mode, 'unknown') + } + return data + + @RbdMirroringTask('pool/edit', {'pool_name': '{pool_name}'}, 5.0) + def set(self, pool_name, mirror_mode=None): + def _edit(ioctx, mirror_mode=None): + if mirror_mode: + mode_enum = {x[1]: x[0] for x in + self.MIRROR_MODES.items()}.get(mirror_mode, None) + if mode_enum is None: + raise rbd.Error('invalid mirror mode "{}"'.format(mirror_mode)) + + current_mode_enum = rbd.RBD().mirror_mode_get(ioctx) + if mode_enum != current_mode_enum: + rbd.RBD().mirror_mode_set(ioctx, mode_enum) + _reset_view_cache() + + return _rbd_call(pool_name, _edit, mirror_mode) + + +@ApiController('/block/mirroring/pool/{pool_name}/peer', Scope.RBD_MIRRORING) +class RbdMirroringPoolPeer(RESTController): + + RESOURCE_ID = "peer_uuid" + + @handle_rbd_mirror_error() + def list(self, pool_name): + ioctx = mgr.rados.open_ioctx(pool_name) + peer_list = rbd.RBD().mirror_peer_list(ioctx) + return [x['uuid'] for x in peer_list] + + @handle_rbd_mirror_error() + def create(self, pool_name, cluster_name, client_id, mon_host=None, + key=None): + ioctx = mgr.rados.open_ioctx(pool_name) + mode = rbd.RBD().mirror_mode_get(ioctx) + if mode == rbd.RBD_MIRROR_MODE_DISABLED: + raise rbd.Error('mirroring must be enabled') + + uuid = rbd.RBD().mirror_peer_add(ioctx, cluster_name, + 'client.{}'.format(client_id)) + + attributes = {} + if mon_host is not None: + attributes[rbd.RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST] = mon_host + if key is not None: + attributes[rbd.RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY] = key + if attributes: + rbd.RBD().mirror_peer_set_attributes(ioctx, uuid, attributes) + + _reset_view_cache() + return {'uuid': uuid} + + @handle_rbd_mirror_error() + def get(self, pool_name, peer_uuid): + ioctx = mgr.rados.open_ioctx(pool_name) + peer_list = rbd.RBD().mirror_peer_list(ioctx) + peer = next((x for x in peer_list if x['uuid'] == peer_uuid), None) + if not peer: + raise cherrypy.HTTPError(404) + + # convert full client name to just the client id + peer['client_id'] = peer['client_name'].split('.', 1)[-1] + del peer['client_name'] + + try: + attributes = rbd.RBD().mirror_peer_get_attributes(ioctx, peer_uuid) + except rbd.ImageNotFound: + attributes = {} + + peer['mon_host'] = attributes.get(rbd.RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST, '') + peer['key'] = attributes.get(rbd.RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY, '') + return peer + + @handle_rbd_mirror_error() + def delete(self, pool_name, peer_uuid): + ioctx = mgr.rados.open_ioctx(pool_name) + rbd.RBD().mirror_peer_remove(ioctx, peer_uuid) + _reset_view_cache() + + @handle_rbd_mirror_error() + def set(self, pool_name, peer_uuid, cluster_name=None, client_id=None, + mon_host=None, key=None): + ioctx = mgr.rados.open_ioctx(pool_name) + if cluster_name: + rbd.RBD().mirror_peer_set_cluster(ioctx, peer_uuid, cluster_name) + if client_id: + rbd.RBD().mirror_peer_set_client(ioctx, peer_uuid, + 'client.{}'.format(client_id)) + + if mon_host is not None or key is not None: + try: + attributes = rbd.RBD().mirror_peer_get_attributes(ioctx, peer_uuid) + except rbd.ImageNotFound: + attributes = {} + + if mon_host is not None: + attributes[rbd.RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST] = mon_host + if key is not None: + attributes[rbd.RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY] = key + rbd.RBD().mirror_peer_set_attributes(ioctx, peer_uuid, attributes) + + _reset_view_cache() diff --git a/src/pybind/mgr/dashboard/controllers/rgw.py b/src/pybind/mgr/dashboard/controllers/rgw.py new file mode 100644 index 00000000..085155aa --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/rgw.py @@ -0,0 +1,385 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json + +import cherrypy + +from . import ApiController, BaseController, RESTController, Endpoint, \ + ReadPermission, allow_empty_body +from .. import logger +from ..exceptions import DashboardException +from ..rest_client import RequestException +from ..security import Scope, Permission +from ..services.auth import AuthManager, JwtManager +from ..services.ceph_service import CephService +from ..services.rgw_client import RgwClient + + +@ApiController('/rgw', Scope.RGW) +class Rgw(BaseController): + + @Endpoint() + @ReadPermission + def status(self): + status = {'available': False, 'message': None} + try: + if not CephService.get_service_list('rgw'): + raise LookupError('No RGW service is running.') + instance = RgwClient.admin_instance() + # Check if the service is online. + try: + is_online = instance.is_service_online() + except RequestException as e: + # Drop this instance because the RGW client seems not to + # exist anymore (maybe removed via orchestrator). Removing + # the instance from the cache will result in the correct + # error message next time when the backend tries to + # establish a new connection (-> 'No RGW found' instead + # of 'RGW REST API failed request ...'). + # Note, this only applies to auto-detected RGW clients. + RgwClient.drop_instance(instance.userid) + raise e + if not is_online: + msg = 'Failed to connect to the Object Gateway\'s Admin Ops API.' + raise RequestException(msg) + # Ensure the API user ID is known by the RGW. + if not instance.user_exists(): + msg = 'The user "{}" is unknown to the Object Gateway.'.format( + instance.userid) + raise RequestException(msg) + # Ensure the system flag is set for the API user ID. + if not instance.is_system_user(): + msg = 'The system flag is not set for user "{}".'.format( + instance.userid) + raise RequestException(msg) + status['available'] = True + except (RequestException, LookupError) as ex: + status['message'] = str(ex) + return status + + +@ApiController('/rgw/daemon', Scope.RGW) +class RgwDaemon(RESTController): + + def list(self): + daemons = [] + for hostname, server in CephService.get_service_map('rgw').items(): + for service in server['services']: + metadata = service['metadata'] + + # extract per-daemon service data and health + daemon = { + 'id': service['id'], + 'version': metadata['ceph_version'], + 'server_hostname': hostname + } + + daemons.append(daemon) + + return sorted(daemons, key=lambda k: k['id']) + + def get(self, svc_id): + daemon = { + 'rgw_metadata': [], + 'rgw_id': svc_id, + 'rgw_status': [] + } + service = CephService.get_service('rgw', svc_id) + if not service: + raise cherrypy.NotFound('Service rgw {} is not available'.format(svc_id)) + + metadata = service['metadata'] + status = service['status'] + if 'json' in status: + try: + status = json.loads(status['json']) + except ValueError: + logger.warning('%s had invalid status json', service['id']) + status = {} + else: + logger.warning('%s has no key "json" in status', service['id']) + + daemon['rgw_metadata'] = metadata + daemon['rgw_status'] = status + return daemon + + +class RgwRESTController(RESTController): + + def proxy(self, method, path, params=None, json_response=True): + try: + instance = RgwClient.admin_instance() + result = instance.proxy(method, path, params, None) + if json_response and result != '': + result = json.loads(result.decode('utf-8')) + return result + except (DashboardException, RequestException) as e: + raise DashboardException(e, http_status_code=500, component='rgw') + + +@ApiController('/rgw/bucket', Scope.RGW) +class RgwBucket(RgwRESTController): + + def _append_bid(self, bucket): + """ + Append the bucket identifier that looks like [/]. + See http://docs.ceph.com/docs/nautilus/radosgw/multitenancy/ for + more information. + :param bucket: The bucket parameters. + :type bucket: dict + :return: The modified bucket parameters including the 'bid' parameter. + :rtype: dict + """ + if isinstance(bucket, dict): + bucket['bid'] = '{}/{}'.format(bucket['tenant'], bucket['bucket']) \ + if bucket['tenant'] else bucket['bucket'] + return bucket + + @staticmethod + def strip_tenant_from_bucket_name(bucket_name, uid): + # type (str, str) => str + """ + When linking a bucket to a new user belonging to same tenant + as the previous owner, tenant must be removed from the bucket name. + >>> RgwBucket.strip_tenant_from_bucket_name('tenant/bucket-name', 'tenant$user1') + 'bucket-name' + >>> RgwBucket.strip_tenant_from_bucket_name('tenant/bucket-name', 'tenant2$user2') + 'tenant/bucket-name' + >>> RgwBucket.strip_tenant_from_bucket_name('bucket-name', 'user1') + 'bucket-name' + """ + bucket_tenant = bucket_name[:bucket_name.find('/')] if bucket_name.find('/') >= 0 else None + uid_tenant = uid[:uid.find('$')] if uid.find('$') >= 0 else None + if bucket_tenant and uid_tenant and bucket_tenant == uid_tenant: + return bucket_name[bucket_name.find('/') + 1:] + + return bucket_name + + def list(self, stats=False): + query_params = '?stats' if stats else '' + result = self.proxy('GET', 'bucket{}'.format(query_params)) + + if stats: + result = [self._append_bid(bucket) for bucket in result] + + return result + + def get(self, bucket): + result = self.proxy('GET', 'bucket', {'bucket': bucket}) + return self._append_bid(result) + + @allow_empty_body + def create(self, bucket, uid): + try: + rgw_client = RgwClient.instance(uid) + return rgw_client.create_bucket(bucket) + except RequestException as e: + raise DashboardException(e, http_status_code=500, component='rgw') + + @allow_empty_body + def set(self, bucket, bucket_id, uid): + result = self.proxy('PUT', 'bucket', { + 'bucket': RgwBucket.strip_tenant_from_bucket_name(bucket, uid), + 'bucket-id': bucket_id, + 'uid': uid + }, json_response=False) + return self._append_bid(result) + + def delete(self, bucket, purge_objects='true'): + return self.proxy('DELETE', 'bucket', { + 'bucket': bucket, + 'purge-objects': purge_objects + }, json_response=False) + + +@ApiController('/rgw/user', Scope.RGW) +class RgwUser(RgwRESTController): + + def _append_uid(self, user): + """ + Append the user identifier that looks like [$]. + See http://docs.ceph.com/docs/jewel/radosgw/multitenancy/ for + more information. + :param user: The user parameters. + :type user: dict + :return: The modified user parameters including the 'uid' parameter. + :rtype: dict + """ + if isinstance(user, dict): + user['uid'] = '{}${}'.format(user['tenant'], user['user_id']) \ + if user['tenant'] else user['user_id'] + return user + + @staticmethod + def _keys_allowed(): + permissions = AuthManager.get_user(JwtManager.get_username()).permissions_dict() + edit_permissions = [Permission.CREATE, Permission.UPDATE, Permission.DELETE] + return Scope.RGW in permissions and Permission.READ in permissions[Scope.RGW] \ + and len(set(edit_permissions).intersection(set(permissions[Scope.RGW]))) > 0 + + def list(self): + users = [] + marker = None + while True: + params = {} + if marker: + params['marker'] = marker + result = self.proxy('GET', 'user?list', params) + users.extend(result['keys']) + if not result['truncated']: + break + # Make sure there is a marker. + assert result['marker'] + # Make sure the marker has changed. + assert marker != result['marker'] + marker = result['marker'] + return users + + def get(self, uid): + result = self.proxy('GET', 'user', {'uid': uid}) + if not self._keys_allowed(): + del result['keys'] + del result['swift_keys'] + return self._append_uid(result) + + @Endpoint() + @ReadPermission + def get_emails(self): + emails = [] + for uid in json.loads(self.list()): + user = json.loads(self.get(uid)) + if user["email"]: + emails.append(user["email"]) + return emails + + @allow_empty_body + def create(self, uid, display_name, email=None, max_buckets=None, + suspended=None, generate_key=None, access_key=None, + secret_key=None): + params = {'uid': uid} + if display_name is not None: + params['display-name'] = display_name + if email is not None: + params['email'] = email + if max_buckets is not None: + params['max-buckets'] = max_buckets + if suspended is not None: + params['suspended'] = suspended + if generate_key is not None: + params['generate-key'] = generate_key + if access_key is not None: + params['access-key'] = access_key + if secret_key is not None: + params['secret-key'] = secret_key + result = self.proxy('PUT', 'user', params) + return self._append_uid(result) + + @allow_empty_body + def set(self, uid, display_name=None, email=None, max_buckets=None, + suspended=None): + params = {'uid': uid} + if display_name is not None: + params['display-name'] = display_name + if email is not None: + params['email'] = email + if max_buckets is not None: + params['max-buckets'] = max_buckets + if suspended is not None: + params['suspended'] = suspended + result = self.proxy('POST', 'user', params) + return self._append_uid(result) + + def delete(self, uid): + try: + instance = RgwClient.admin_instance() + # Ensure the user is not configured to access the RGW Object Gateway. + if instance.userid == uid: + raise DashboardException(msg='Unable to delete "{}" - this user ' + 'account is required for managing the ' + 'Object Gateway'.format(uid)) + # Finally redirect request to the RGW proxy. + return self.proxy('DELETE', 'user', {'uid': uid}, json_response=False) + except (DashboardException, RequestException) as e: + raise DashboardException(e, component='rgw') + + # pylint: disable=redefined-builtin + @RESTController.Resource(method='POST', path='/capability', status=201) + @allow_empty_body + def create_cap(self, uid, type, perm): + return self.proxy('PUT', 'user?caps', { + 'uid': uid, + 'user-caps': '{}={}'.format(type, perm) + }) + + # pylint: disable=redefined-builtin + @RESTController.Resource(method='DELETE', path='/capability', status=204) + def delete_cap(self, uid, type, perm): + return self.proxy('DELETE', 'user?caps', { + 'uid': uid, + 'user-caps': '{}={}'.format(type, perm) + }) + + @RESTController.Resource(method='POST', path='/key', status=201) + @allow_empty_body + def create_key(self, uid, key_type='s3', subuser=None, generate_key='true', + access_key=None, secret_key=None): + params = {'uid': uid, 'key-type': key_type, 'generate-key': generate_key} + if subuser is not None: + params['subuser'] = subuser + if access_key is not None: + params['access-key'] = access_key + if secret_key is not None: + params['secret-key'] = secret_key + return self.proxy('PUT', 'user?key', params) + + @RESTController.Resource(method='DELETE', path='/key', status=204) + def delete_key(self, uid, key_type='s3', subuser=None, access_key=None): + params = {'uid': uid, 'key-type': key_type} + if subuser is not None: + params['subuser'] = subuser + if access_key is not None: + params['access-key'] = access_key + return self.proxy('DELETE', 'user?key', params, json_response=False) + + @RESTController.Resource(method='GET', path='/quota') + def get_quota(self, uid): + return self.proxy('GET', 'user?quota', {'uid': uid}) + + @RESTController.Resource(method='PUT', path='/quota') + @allow_empty_body + def set_quota(self, uid, quota_type, enabled, max_size_kb, max_objects): + return self.proxy('PUT', 'user?quota', { + 'uid': uid, + 'quota-type': quota_type, + 'enabled': enabled, + 'max-size-kb': max_size_kb, + 'max-objects': max_objects + }, json_response=False) + + @RESTController.Resource(method='POST', path='/subuser', status=201) + @allow_empty_body + def create_subuser(self, uid, subuser, access, key_type='s3', + generate_secret='true', access_key=None, + secret_key=None): + return self.proxy('PUT', 'user', { + 'uid': uid, + 'subuser': subuser, + 'key-type': key_type, + 'access': access, + 'generate-secret': generate_secret, + 'access-key': access_key, + 'secret-key': secret_key + }) + + @RESTController.Resource(method='DELETE', path='/subuser/{subuser}', status=204) + def delete_subuser(self, uid, subuser, purge_keys='true'): + """ + :param purge_keys: Set to False to do not purge the keys. + Note, this only works for s3 subusers. + """ + return self.proxy('DELETE', 'user', { + 'uid': uid, + 'subuser': subuser, + 'purge-keys': purge_keys + }, json_response=False) diff --git a/src/pybind/mgr/dashboard/controllers/role.py b/src/pybind/mgr/dashboard/controllers/role.py new file mode 100644 index 00000000..f87eff7b --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/role.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import cherrypy + +from . import ApiController, RESTController, UiApiController +from .. import mgr +from ..exceptions import RoleDoesNotExist, DashboardException,\ + RoleIsAssociatedWithUser, RoleAlreadyExists +from ..security import Scope as SecurityScope, Permission +from ..services.access_control import SYSTEM_ROLES + + +@ApiController('/role', SecurityScope.USER) +class Role(RESTController): + @staticmethod + def _role_to_dict(role): + role_dict = role.to_dict() + role_dict['system'] = role_dict['name'] in SYSTEM_ROLES + return role_dict + + @staticmethod + def _validate_permissions(scopes_permissions): + if scopes_permissions: + for scope, permissions in scopes_permissions.items(): + if scope not in SecurityScope.all_scopes(): + raise DashboardException(msg='Invalid scope', + code='invalid_scope', + component='role') + if any(permission not in Permission.all_permissions() + for permission in permissions): + raise DashboardException(msg='Invalid permission', + code='invalid_permission', + component='role') + + @staticmethod + def _set_permissions(role, scopes_permissions): + role.reset_scope_permissions() + if scopes_permissions: + for scope, permissions in scopes_permissions.items(): + if permissions: + role.set_scope_permissions(scope, permissions) + + def list(self): + roles = dict(mgr.ACCESS_CTRL_DB.roles) + roles.update(SYSTEM_ROLES) + roles = sorted(roles.values(), key=lambda role: role.name) + return [Role._role_to_dict(r) for r in roles] + + def get(self, name): + role = SYSTEM_ROLES.get(name) + if not role: + try: + role = mgr.ACCESS_CTRL_DB.get_role(name) + except RoleDoesNotExist: + raise cherrypy.HTTPError(404) + return Role._role_to_dict(role) + + def create(self, name=None, description=None, scopes_permissions=None): + if not name: + raise DashboardException(msg='Name is required', + code='name_required', + component='role') + Role._validate_permissions(scopes_permissions) + try: + role = mgr.ACCESS_CTRL_DB.create_role(name, description) + except RoleAlreadyExists: + raise DashboardException(msg='Role already exists', + code='role_already_exists', + component='role') + Role._set_permissions(role, scopes_permissions) + mgr.ACCESS_CTRL_DB.save() + return Role._role_to_dict(role) + + def set(self, name, description=None, scopes_permissions=None): + try: + role = mgr.ACCESS_CTRL_DB.get_role(name) + except RoleDoesNotExist: + if name in SYSTEM_ROLES: + raise DashboardException(msg='Cannot update system role', + code='cannot_update_system_role', + component='role') + raise cherrypy.HTTPError(404) + Role._validate_permissions(scopes_permissions) + Role._set_permissions(role, scopes_permissions) + role.description = description + mgr.ACCESS_CTRL_DB.update_users_with_roles(role) + mgr.ACCESS_CTRL_DB.save() + return Role._role_to_dict(role) + + def delete(self, name): + try: + mgr.ACCESS_CTRL_DB.delete_role(name) + except RoleDoesNotExist: + if name in SYSTEM_ROLES: + raise DashboardException(msg='Cannot delete system role', + code='cannot_delete_system_role', + component='role') + raise cherrypy.HTTPError(404) + except RoleIsAssociatedWithUser: + raise DashboardException(msg='Role is associated with user', + code='role_is_associated_with_user', + component='role') + mgr.ACCESS_CTRL_DB.save() + + +@UiApiController('/scope', SecurityScope.USER) +class Scope(RESTController): + def list(self): + return SecurityScope.all_scopes() diff --git a/src/pybind/mgr/dashboard/controllers/saml2.py b/src/pybind/mgr/dashboard/controllers/saml2.py new file mode 100644 index 00000000..f02f81fe --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/saml2.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import sys +import cherrypy + +try: + from onelogin.saml2.auth import OneLogin_Saml2_Auth + from onelogin.saml2.errors import OneLogin_Saml2_Error + from onelogin.saml2.settings import OneLogin_Saml2_Settings + + python_saml_imported = True +except ImportError: + python_saml_imported = False + +from .. import mgr +from ..exceptions import UserDoesNotExist +from ..services.auth import JwtManager +from ..tools import prepare_url_prefix +from . import BaseController, Controller, Endpoint, allow_empty_body, set_cookies + + +@Controller('/auth/saml2', secure=False) +class Saml2(BaseController): + + @staticmethod + def _build_req(request, post_data): + return { + 'https': 'on' if request.scheme == 'https' else 'off', + 'http_host': request.host, + 'script_name': request.path_info, + 'server_port': str(request.port), + 'get_data': {}, + 'post_data': post_data + } + + @staticmethod + def _check_python_saml(): + if not python_saml_imported: + python_saml_name = 'python3-saml' if sys.version_info >= (3, 0) else 'python-saml' + raise cherrypy.HTTPError(400, + 'Required library not found: `{}`'.format(python_saml_name)) + try: + OneLogin_Saml2_Settings(mgr.SSO_DB.saml2.onelogin_settings) + except OneLogin_Saml2_Error: + raise cherrypy.HTTPError(400, 'Single Sign-On is not configured.') + + @Endpoint('POST', path="") + @allow_empty_body + def auth_response(self, **kwargs): + Saml2._check_python_saml() + req = Saml2._build_req(self._request, kwargs) + auth = OneLogin_Saml2_Auth(req, mgr.SSO_DB.saml2.onelogin_settings) + auth.process_response() + errors = auth.get_errors() + + if auth.is_authenticated(): + JwtManager.reset_user() + username_attribute = auth.get_attribute(mgr.SSO_DB.saml2.get_username_attribute()) + if username_attribute is None: + raise cherrypy.HTTPError(400, + 'SSO error - `{}` not found in auth attributes. ' + 'Received attributes: {}' + .format( + mgr.SSO_DB.saml2.get_username_attribute(), + auth.get_attributes())) + username = username_attribute[0] + url_prefix = prepare_url_prefix(mgr.get_module_option('url_prefix', default='')) + try: + mgr.ACCESS_CTRL_DB.get_user(username) + except UserDoesNotExist: + raise cherrypy.HTTPRedirect("{}/#/sso/404".format(url_prefix)) + + token = JwtManager.gen_token(username) + JwtManager.set_user(JwtManager.decode_token(token)) + token = token.decode('utf-8') + set_cookies(url_prefix, token) + raise cherrypy.HTTPRedirect("{}/#/login?access_token={}".format(url_prefix, token)) + else: + return { + 'is_authenticated': auth.is_authenticated(), + 'errors': errors, + 'reason': auth.get_last_error_reason() + } + + @Endpoint(xml=True) + def metadata(self): + Saml2._check_python_saml() + saml_settings = OneLogin_Saml2_Settings(mgr.SSO_DB.saml2.onelogin_settings) + return saml_settings.get_sp_metadata() + + @Endpoint(json_response=False) + def login(self): + Saml2._check_python_saml() + req = Saml2._build_req(self._request, {}) + auth = OneLogin_Saml2_Auth(req, mgr.SSO_DB.saml2.onelogin_settings) + raise cherrypy.HTTPRedirect(auth.login()) + + @Endpoint(json_response=False) + def slo(self): + Saml2._check_python_saml() + req = Saml2._build_req(self._request, {}) + auth = OneLogin_Saml2_Auth(req, mgr.SSO_DB.saml2.onelogin_settings) + raise cherrypy.HTTPRedirect(auth.logout()) + + @Endpoint(json_response=False) + def logout(self, **kwargs): + # pylint: disable=unused-argument + Saml2._check_python_saml() + JwtManager.reset_user() + cherrypy.response.cookie['token'] = {'expires': 0, 'max-age': 0} + url_prefix = prepare_url_prefix(mgr.get_module_option('url_prefix', default='')) + raise cherrypy.HTTPRedirect("{}/#/login".format(url_prefix)) diff --git a/src/pybind/mgr/dashboard/controllers/settings.py b/src/pybind/mgr/dashboard/controllers/settings.py new file mode 100644 index 00000000..a484580e --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/settings.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import +from contextlib import contextmanager + +import cherrypy + +from . import ApiController, RESTController +from ..settings import Settings as SettingsModule, Options +from ..security import Scope + + +@ApiController('/settings', Scope.CONFIG_OPT) +class Settings(RESTController): + """ + Enables to manage the settings of the dashboard (not the Ceph cluster). + """ + @contextmanager + def _attribute_handler(self, name): + """ + :type name: str|dict[str, str] + :rtype: str|dict[str, str] + """ + if isinstance(name, dict): + result = {self._to_native(key): value + for key, value in name.items()} + else: + result = self._to_native(name) + + try: + yield result + except AttributeError: + raise cherrypy.NotFound(result) + + @staticmethod + def _to_native(setting): + return setting.upper().replace('-', '_') + + def list(self): + return [ + self._get(name) for name in Options.__dict__ + if name.isupper() and not name.startswith('_') + ] + + def _get(self, name): + with self._attribute_handler(name) as sname: + default, data_type = getattr(Options, sname) + return { + 'name': sname, + 'default': default, + 'type': data_type.__name__, + 'value': getattr(SettingsModule, sname) + } + + def get(self, name): + return self._get(name) + + def set(self, name, value): + with self._attribute_handler(name) as sname: + setattr(SettingsModule, self._to_native(sname), value) + + def delete(self, name): + with self._attribute_handler(name) as sname: + delattr(SettingsModule, self._to_native(sname)) + + def bulk_set(self, **kwargs): + with self._attribute_handler(kwargs) as data: + for name, value in data.items(): + setattr(SettingsModule, self._to_native(name), value) diff --git a/src/pybind/mgr/dashboard/controllers/summary.py b/src/pybind/mgr/dashboard/controllers/summary.py new file mode 100644 index 00000000..09d69ecf --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/summary.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json + +from . import ApiController, Endpoint, BaseController +from .. import mgr +from ..security import Permission, Scope +from ..controllers.rbd_mirroring import get_daemons_and_pools +from ..exceptions import ViewCacheNoDataException +from ..tools import TaskManager + + +@ApiController('/summary') +class Summary(BaseController): + def _health_status(self): + health_data = mgr.get("health") + return json.loads(health_data["json"])['status'] + + def _rbd_mirroring(self): + try: + _, data = get_daemons_and_pools() + except ViewCacheNoDataException: + return {} + + daemons = data.get('daemons', []) + pools = data.get('pools', {}) + + warnings = 0 + errors = 0 + for daemon in daemons: + if daemon['health_color'] == 'error': + errors += 1 + elif daemon['health_color'] == 'warning': + warnings += 1 + for _, pool in pools.items(): + if pool['health_color'] == 'error': + errors += 1 + elif pool['health_color'] == 'warning': + warnings += 1 + return {'warnings': warnings, 'errors': errors} + + def _task_permissions(self, name): + result = True + if name == 'pool/create': + result = self._has_permissions(Permission.CREATE, Scope.POOL) + elif name == 'pool/edit': + result = self._has_permissions(Permission.UPDATE, Scope.POOL) + elif name == 'pool/delete': + result = self._has_permissions(Permission.DELETE, Scope.POOL) + elif name in [ + 'rbd/create', 'rbd/copy', 'rbd/snap/create', + 'rbd/clone', 'rbd/trash/restore']: + result = self._has_permissions(Permission.CREATE, Scope.RBD_IMAGE) + elif name in [ + 'rbd/edit', 'rbd/snap/edit', 'rbd/flatten', + 'rbd/snap/rollback']: + result = self._has_permissions(Permission.UPDATE, Scope.RBD_IMAGE) + elif name in [ + 'rbd/delete', 'rbd/snap/delete', 'rbd/trash/move', + 'rbd/trash/remove', 'rbd/trash/purge']: + result = self._has_permissions(Permission.DELETE, Scope.RBD_IMAGE) + return result + + def _get_host(self): + # type: () -> str + services = mgr.get('mgr_map')['services'] + return services['dashboard'] if 'dashboard' in services else '' + + @Endpoint() + def __call__(self): + exe_t, fin_t = TaskManager.list_serializable() + executing_tasks = [task for task in exe_t if self._task_permissions(task['name'])] + finished_tasks = [task for task in fin_t if self._task_permissions(task['name'])] + + result = { + 'health_status': self._health_status(), + 'mgr_id': mgr.get_mgr_id(), + 'mgr_host': self._get_host(), + 'have_mon_connection': mgr.have_mon_connection(), + 'executing_tasks': executing_tasks, + 'finished_tasks': finished_tasks, + 'version': mgr.version + } + if self._has_permissions(Permission.READ, Scope.RBD_MIRRORING): + result['rbd_mirroring'] = self._rbd_mirroring() + return result diff --git a/src/pybind/mgr/dashboard/controllers/task.py b/src/pybind/mgr/dashboard/controllers/task.py new file mode 100644 index 00000000..9380f070 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/task.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import ApiController, RESTController +from ..tools import TaskManager + + +@ApiController('/task') +class Task(RESTController): + def list(self, name=None): + executing_t, finished_t = TaskManager.list_serializable(name) + return { + 'executing_tasks': executing_t, + 'finished_tasks': finished_t + } diff --git a/src/pybind/mgr/dashboard/controllers/user.py b/src/pybind/mgr/dashboard/controllers/user.py new file mode 100644 index 00000000..d99dead3 --- /dev/null +++ b/src/pybind/mgr/dashboard/controllers/user.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import cherrypy + +from . import ApiController, RESTController +from .. import mgr +from ..exceptions import DashboardException, UserAlreadyExists, \ + UserDoesNotExist +from ..security import Scope +from ..services.access_control import SYSTEM_ROLES +from ..services.auth import JwtManager + + +@ApiController('/user', Scope.USER) +class User(RESTController): + @staticmethod + def _user_to_dict(user): + result = user.to_dict() + del result['password'] + return result + + @staticmethod + def _get_user_roles(roles): + all_roles = dict(mgr.ACCESS_CTRL_DB.roles) + all_roles.update(SYSTEM_ROLES) + try: + return [all_roles[rolename] for rolename in roles] + except KeyError: + raise DashboardException(msg='Role does not exist', + code='role_does_not_exist', + component='user') + + def list(self): + users = mgr.ACCESS_CTRL_DB.users + result = [User._user_to_dict(u) for _, u in users.items()] + return result + + def get(self, username): + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + except UserDoesNotExist: + raise cherrypy.HTTPError(404) + return User._user_to_dict(user) + + def create(self, username=None, password=None, name=None, email=None, roles=None): + if not username: + raise DashboardException(msg='Username is required', + code='username_required', + component='user') + user_roles = None + if roles: + user_roles = User._get_user_roles(roles) + try: + user = mgr.ACCESS_CTRL_DB.create_user(username, password, name, email) + except UserAlreadyExists: + raise DashboardException(msg='Username already exists', + code='username_already_exists', + component='user') + if user_roles: + user.set_roles(user_roles) + mgr.ACCESS_CTRL_DB.save() + return User._user_to_dict(user) + + def delete(self, username): + session_username = JwtManager.get_username() + if session_username == username: + raise DashboardException(msg='Cannot delete current user', + code='cannot_delete_current_user', + component='user') + try: + mgr.ACCESS_CTRL_DB.delete_user(username) + except UserDoesNotExist: + raise cherrypy.HTTPError(404) + mgr.ACCESS_CTRL_DB.save() + + def set(self, username, password=None, name=None, email=None, roles=None): + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + except UserDoesNotExist: + raise cherrypy.HTTPError(404) + user_roles = [] + if roles: + user_roles = User._get_user_roles(roles) + if password: + user.set_password(password) + user.name = name + user.email = email + user.set_roles(user_roles) + mgr.ACCESS_CTRL_DB.save() + return User._user_to_dict(user) diff --git a/src/pybind/mgr/dashboard/exceptions.py b/src/pybind/mgr/dashboard/exceptions.py new file mode 100644 index 00000000..b44a3f15 --- /dev/null +++ b/src/pybind/mgr/dashboard/exceptions.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + + +class ViewCacheNoDataException(Exception): + def __init__(self): + self.status = 200 + super(ViewCacheNoDataException, self).__init__('ViewCache: unable to retrieve data') + + +class DashboardException(Exception): + """ + Used for exceptions that are already handled and should end up as a user error. + Or, as a replacement for cherrypy.HTTPError(...) + + Typically, you don't inherent from DashboardException + """ + + # pylint: disable=too-many-arguments + def __init__(self, e=None, code=None, component=None, http_status_code=None, msg=None): + super(DashboardException, self).__init__(msg) + self._code = code + self.component = component + if e: + self.e = e + if http_status_code: + self.status = http_status_code + else: + self.status = 400 + + def __str__(self): + try: + return str(self.e) + except AttributeError: + return super(DashboardException, self).__str__() + + @property + def errno(self): + return self.e.errno + + @property + def code(self): + if self._code: + return str(self._code) + return str(abs(self.errno)) + + +# access control module exceptions +class RoleAlreadyExists(Exception): + def __init__(self, name): + super(RoleAlreadyExists, self).__init__( + "Role '{}' already exists".format(name)) + + +class RoleDoesNotExist(Exception): + def __init__(self, name): + super(RoleDoesNotExist, self).__init__( + "Role '{}' does not exist".format(name)) + + +class ScopeNotValid(Exception): + def __init__(self, name): + super(ScopeNotValid, self).__init__( + "Scope '{}' is not valid".format(name)) + + +class PermissionNotValid(Exception): + def __init__(self, name): + super(PermissionNotValid, self).__init__( + "Permission '{}' is not valid".format(name)) + + +class RoleIsAssociatedWithUser(Exception): + def __init__(self, rolename, username): + super(RoleIsAssociatedWithUser, self).__init__( + "Role '{}' is still associated with user '{}'" + .format(rolename, username)) + + +class UserAlreadyExists(Exception): + def __init__(self, name): + super(UserAlreadyExists, self).__init__( + "User '{}' already exists".format(name)) + + +class UserDoesNotExist(Exception): + def __init__(self, name): + super(UserDoesNotExist, self).__init__( + "User '{}' does not exist".format(name)) + + +class ScopeNotInRole(Exception): + def __init__(self, scopename, rolename): + super(ScopeNotInRole, self).__init__( + "There are no permissions for scope '{}' in role '{}'" + .format(scopename, rolename)) + + +class RoleNotInUser(Exception): + def __init__(self, rolename, username): + super(RoleNotInUser, self).__init__( + "Role '{}' is not associated with user '{}'" + .format(rolename, username)) + + +class GrafanaError(Exception): + pass diff --git a/src/pybind/mgr/dashboard/frontend/.babelrc b/src/pybind/mgr/dashboard/frontend/.babelrc new file mode 100644 index 00000000..002b4aa0 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["env"] +} diff --git a/src/pybind/mgr/dashboard/frontend/.editorconfig b/src/pybind/mgr/dashboard/frontend/.editorconfig new file mode 100644 index 00000000..6e87a003 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/src/pybind/mgr/dashboard/frontend/.gitignore b/src/pybind/mgr/dashboard/frontend/.gitignore new file mode 100644 index 00000000..abe42200 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/.gitignore @@ -0,0 +1,49 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc + +# dependencies +/node_modules + +# IDEs and editors +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +testem.log +/typings +/src/unit-test-configuration.ts + +# e2e +/e2e/*.js +/e2e/*.map + +# System Files +.DS_Store +Thumbs.db + +# Package lock files +yarn.lock + +# Ceph +!core +!*.core diff --git a/src/pybind/mgr/dashboard/frontend/.prettierignore b/src/pybind/mgr/dashboard/frontend/.prettierignore new file mode 100644 index 00000000..2d19fc76 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/.prettierignore @@ -0,0 +1 @@ +*.html diff --git a/src/pybind/mgr/dashboard/frontend/.prettierrc b/src/pybind/mgr/dashboard/frontend/.prettierrc new file mode 100644 index 00000000..7d65e364 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/.prettierrc @@ -0,0 +1,5 @@ +{ + "arrowParens": "always", + "printWidth": 100, + "singleQuote": true +} diff --git a/src/pybind/mgr/dashboard/frontend/angular.json b/src/pybind/mgr/dashboard/frontend/angular.json new file mode 100644 index 00000000..fc8a78ab --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/angular.json @@ -0,0 +1,233 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "ceph-dashboard": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "aot": true, + "i18nFormat": "xlf", + "i18nMissingTranslation": "ignore", + "outputPath": "dist", + "index": "src/index.html", + "main": "src/main.ts", + "tsConfig": "src/tsconfig.app.json", + "polyfills": "src/polyfills.ts", + "assets": [ + "src/assets", + "src/favicon.ico", + { + "glob": "**/swagger-ui.css", + "input": "node_modules/swagger-ui-dist", + "output": "." + }, + { + "glob": "**/swagger-ui-bundle.js", + "input": "node_modules/swagger-ui-dist", + "output": "." + } + ], + "styles": [ + "node_modules/ngx-toastr/toastr.css", + "node_modules/bootstrap/dist/css/bootstrap.css", + "node_modules/fork-awesome/css/fork-awesome.css", + "node_modules/awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css", + "node_modules/ngx-bootstrap/datepicker/bs-datepicker.css", + "src/styles.scss", + "src/vendor.overrides.scss", + "node_modules/ng2-tree/styles.css" + ], + "scripts": [ + "node_modules/chart.js/dist/Chart.bundle.js" + ] + }, + "configurations": { + "production": { + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ] + }, + "cs": { + "outputPath": "dist/cs/", + "i18nFile": "src/locale/messages.cs.xlf", + "i18nLocale": "cs" + }, + "de-DE": { + "outputPath": "dist/de-DE/", + "i18nFile": "src/locale/messages.de-DE.xlf", + "i18nLocale": "de-DE" + }, + "en-US": { + "outputPath": "dist/en-US/", + "i18nFile": "src/locale/messages.en-US.xlf", + "i18nLocale": "en-US" + }, + "es-ES": { + "outputPath": "dist/es-ES/", + "i18nFile": "src/locale/messages.es-ES.xlf", + "i18nLocale": "es-ES" + }, + "fr-FR": { + "outputPath": "dist/fr-FR/", + "i18nFile": "src/locale/messages.fr-FR.xlf", + "i18nLocale": "fr-FR" + }, + "id-ID": { + "outputPath": "dist/id-ID/", + "i18nFile": "src/locale/messages.id-ID.xlf", + "i18nLocale": "id-ID" + }, + "it-IT": { + "outputPath": "dist/it-IT/", + "i18nFile": "src/locale/messages.it-IT.xlf", + "i18nLocale": "it-IT" + }, + "ja-JP": { + "outputPath": "dist/ja-JP/", + "i18nFile": "src/locale/messages.ja-JP.xlf", + "i18nLocale": "ja-JP" + }, + "pl-PL": { + "outputPath": "dist/pl-PL/", + "i18nFile": "src/locale/messages.pl-PL.xlf", + "i18nLocale": "pl-PL" + }, + "pt-BR": { + "outputPath": "dist/pt-BR/", + "i18nFile": "src/locale/messages.pt-BR.xlf", + "i18nLocale": "pt-BR" + }, + "zh-CN": { + "outputPath": "dist/zh-CN/", + "i18nFile": "src/locale/messages.zh-CN.xlf", + "i18nLocale": "zh-CN" + }, + "zh-TW": { + "outputPath": "dist/zh-TW/", + "i18nFile": "src/locale/messages.zh-TW.xlf", + "i18nLocale": "zh-TW" + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "ceph-dashboard:build", + "proxyConfig": "proxy.conf.json" + }, + "configurations": { + "production": { + "browserTarget": "ceph-dashboard:build:production" + }, + "cs": { + "browserTarget": "ceph-dashboard:build:cs" + }, + "de-DE": { + "browserTarget": "ceph-dashboard:build:de-DE" + }, + "en-US": { + "browserTarget": "ceph-dashboard:build:en-US" + }, + "es-ES": { + "browserTarget": "ceph-dashboard:build:es-ES" + }, + "fr-FR": { + "browserTarget": "ceph-dashboard:build:fr-FR" + }, + "id-ID": { + "browserTarget": "ceph-dashboard:build:id-ID" + }, + "it-IT": { + "browserTarget": "ceph-dashboard:build:it-IT" + }, + "ja-JP": { + "browserTarget": "ceph-dashboard:build:ja-JP" + }, + "pl-PL": { + "browserTarget": "ceph-dashboard:build:pl-PL" + }, + "pt-BR": { + "browserTarget": "ceph-dashboard:build:pt-BR" + }, + "zh-CN": { + "browserTarget": "ceph-dashboard:build:zh-CN" + }, + "zh-TW": { + "browserTarget": "ceph-dashboard:build:zh-TW" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "ceph-dashboard:build" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "ceph-dashboard-e2e": { + "root": "", + "sourceRoot": "", + "projectType": "application", + "architect": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "./protractor.conf.js", + "devServerTarget": "ceph-dashboard:serve" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "e2e/tsconfig.e2e.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "ceph-dashboard", + "schematics": { + "@schematics/angular:component": { + "prefix": "cd", + "styleext": "scss" + }, + "@schematics/angular:directive": { + "prefix": "cd" + } + } +} diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/2.22b12bf9358f95829e55.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/2.22b12bf9358f95829e55.js new file mode 100644 index 00000000..911e456b --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/2.22b12bf9358f95829e55.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{"+lcs":function(l,n,e){"use strict";e.d(n,"a",function(){return a});var t=e("gIcY"),u=e("K9Ia"),i=(e("F83c"),e("sne2"),e("QFaf")),o=e("kvvV"),a=(e("9nlD"),e("VXsX"),function(){function l(l,n,e,t,u,i){this.modalRef=l,this.rbdService=n,this.taskManagerService=e,this.notificationService=t,this.i18n=u,this.actionLabels=i,this.editing=!1,this.action=this.actionLabels.CREATE,this.resource=this.i18n("RBD Snapshot"),this.createForm()}return l.prototype.createForm=function(){this.snapshotForm=new i.a({snapshotName:new t.i("",{validators:[t.A.required]})})},l.prototype.ngOnInit=function(){this.onSubmit=new u.a},l.prototype.setSnapName=function(l){this.snapName=l,this.snapshotForm.get("snapshotName").setValue(l)},l.prototype.setEditing=function(l){void 0===l&&(l=!0),this.editing=l,this.action=this.editing?this.actionLabels.RENAME:this.actionLabels.CREATE},l.prototype.editAction=function(){var l=this,n=this.snapshotForm.getValue("snapshotName"),e=new o.a;e.name="rbd/snap/edit",e.metadata={pool_name:this.poolName,image_name:this.imageName,snapshot_name:n},this.rbdService.renameSnapshot(this.poolName,this.imageName,this.snapName,n).toPromise().then(function(){l.taskManagerService.subscribe(e.name,e.metadata,function(n){l.notificationService.notifyTask(n)}),l.modalRef.hide(),l.onSubmit.next(l.snapName)}).catch(function(){l.snapshotForm.setErrors({cdSubmitButton:!0})})},l.prototype.createAction=function(){var l=this,n=this.snapshotForm.getValue("snapshotName"),e=new o.a;e.name="rbd/snap/create",e.metadata={pool_name:this.poolName,image_name:this.imageName,snapshot_name:n},this.rbdService.createSnapshot(this.poolName,this.imageName,n).toPromise().then(function(){l.taskManagerService.subscribe(e.name,e.metadata,function(n){l.notificationService.notifyTask(n)}),l.modalRef.hide(),l.onSubmit.next(n)}).catch(function(){l.snapshotForm.setErrors({cdSubmitButton:!0})})},l.prototype.submit=function(){this.editing?this.editAction():this.createAction()},l}())},"0rTx":function(l,n,e){"use strict";var t=e("CcnG"),u=e("EEJc"),i=e("ajRT"),o=e("gIcY"),a=e("Ip0R"),r=e("IZUe"),s=e("ANnk"),d=e("f/UV"),c=e("aexS"),p=e("gp3X"),m=e("sb0X"),f=e("KVJa"),g=e("Z21x"),h=e("sne2"),v=e("2GqK"),b=e("F83c"),y=e("DQlY"),C=e("2EZI"),_=e("kn/O");e.d(n,"a",function(){return k});var w=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function R(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function I(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,45,"cd-modal",[],null,null,null,u.c,u.b)),t["\u0275did"](1,49152,null,0,i.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Restore Image"])),(l()(),t["\u0275eld"](4,0,null,1,41,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,40,"form",[["class","form"],["name","restoreForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,7).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,7).onReset()&&u),u},null,null)),t["\u0275did"](6,16384,null,0,o.D,[],null,null),t["\u0275did"](7,540672,[["formDir",4]],0,o.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,o.d,null,[o.l]),t["\u0275did"](9,16384,null,0,o.s,[[4,o.d]],null,null),(l()(),t["\u0275eld"](10,0,null,null,28,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,12,"p",[],null,null,null,null,null)),(l()(),t["\u0275eld"](12,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["To restore"])),(l()(),t["\u0275ted"](-1,null,["\xa0 "])),(l()(),t["\u0275eld"](15,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](16,null,["","/","@",""])),(l()(),t["\u0275ted"](-1,null,[",\xa0 "])),(l()(),t["\u0275eld"](18,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["type the image's new name and click"])),(l()(),t["\u0275ted"](-1,null,["\xa0 "])),(l()(),t["\u0275eld"](21,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Restore Image"])),(l()(),t["\u0275ted"](-1,null,[". "])),(l()(),t["\u0275eld"](24,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](25,278528,null,0,a.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](26,{"has-error":0}),(l()(),t["\u0275eld"](27,0,null,null,1,"label",[["for","name"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["New Name"])),(l()(),t["\u0275eld"](29,0,null,null,7,"input",[["autocomplete","off"],["autofocus",""],["class","form-control"],["formControlName","name"],["id","name"],["name","name"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,30)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,30).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,30)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,30)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](30,16384,null,0,o.e,[t.Renderer2,t.ElementRef,[2,o.b]],null,null),t["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),t["\u0275did"](32,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,o.q,null,[o.j]),t["\u0275did"](34,16384,null,0,o.r,[[4,o.q]],null,null),t["\u0275did"](35,4210688,null,0,r.a,[t.ElementRef],null,null),t["\u0275did"](36,4210688,null,0,s.a,[[2,d.a],c.a,t.ElementRef],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,R)),t["\u0275did"](38,16384,null,0,a.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](39,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](40,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](41,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.restore()&&t),t},p.b,p.a)),t["\u0275did"](42,114688,null,0,m.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Restore Image"])),(l()(),t["\u0275eld"](44,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,f.b,f.a)),t["\u0275did"](45,49152,null,0,g.a,[a.Location,h.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,1,0,e.modalRef),l(n,7,0,e.restoreForm);var u=l(n,26,0,e.restoreForm.showError("name",t["\u0275nov"](n,7)));l(n,25,0,"form-group",u),l(n,32,0,"name"),l(n,38,0,e.restoreForm.showError("name",t["\u0275nov"](n,7),"required")),l(n,42,0,e.restoreForm),l(n,45,0,"Cancel",e.modalRef.hide)},function(l,n){var e=n.component;l(n,5,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending),l(n,16,0,e.poolName,e.imageName,e.imageId),l(n,29,0,t["\u0275nov"](n,34).ngClassUntouched,t["\u0275nov"](n,34).ngClassTouched,t["\u0275nov"](n,34).ngClassPristine,t["\u0275nov"](n,34).ngClassDirty,t["\u0275nov"](n,34).ngClassValid,t["\u0275nov"](n,34).ngClassInvalid,t["\u0275nov"](n,34).ngClassPending)})}function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rbd-trash-restore-modal",[],null,null,null,I,w)),t["\u0275did"](1,114688,null,0,v.a,[b.a,y.a,C.a,_.a],null,null)],function(l,n){l(n,1,0)},null)}var k=t["\u0275ccf"]("cd-rbd-trash-restore-modal",v.a,S,{},{},[])},"2GqK":function(l,n,e){"use strict";e.d(n,"a",function(){return u}),e("F83c"),e("2EZI");var t=e("kvvV"),u=(e("kn/O"),function(){function l(l,n,e,t){this.rbdService=l,this.modalRef=n,this.fb=e,this.taskWrapper=t}return l.prototype.ngOnInit=function(){this.restoreForm=this.fb.group({name:this.imageName})},l.prototype.restore=function(){var l=this,n=this.restoreForm.getValue("name");this.taskWrapper.wrapTaskAroundCall({task:new t.a("rbd/trash/restore",{pool_name:this.poolName,image_id:this.imageId,new_image_name:n}),call:this.rbdService.restoreTrash(this.poolName,this.imageId,n)}).subscribe(void 0,function(){l.restoreForm.setErrors({cdSubmitButton:!0})},function(){l.modalRef.hide()})},l}())},"2JDI":function(l,n,e){"use strict";e.d(n,"a",function(){return o});var t=e("wd/R"),u=(e("F83c"),e("2EZI"),e("1Ni5")),i=e("kvvV"),o=(e("kn/O"),function(){function l(l,n,e,t){this.rbdService=l,this.modalRef=n,this.fb=e,this.taskWrapper=t,this.minDate=new Date,this.bsConfig={dateInputFormat:"YYYY-MM-DD HH:mm:ss",containerClass:"theme-default"},this.createForm()}return l.prototype.createForm=function(){this.moveForm=this.fb.group({expiresAt:["",[u.a.custom("format",function(l){return!(""===l||t(l,"YYYY-MM-DD HH:mm:ss").isValid())}),u.a.custom("expired",function(l){return t().isAfter(l)})]]})},l.prototype.ngOnInit=function(){this.pattern=this.poolName+"/"+this.imageName},l.prototype.moveImage=function(){var l=this,n=0,e=this.moveForm.getValue("expiresAt");e&&(n=t(e).diff(t(),"seconds",!0)),n<0&&(n=0),this.taskWrapper.wrapTaskAroundCall({task:new i.a("rbd/trash/move",{pool_name:this.poolName,image_name:this.imageName}),call:this.rbdService.moveTrash(this.poolName,this.imageName,n)}).subscribe(void 0,void 0,function(){l.modalRef.hide()})},l}())},"3ris":function(l,n,e){"use strict";e.d(n,"a",function(){return u});var t=e("LvDl"),u=(e("uIqm"),e("vCyI"),e("iExv"),e("uYzU"),function(){function l(l,n,e){this.i18n=l,this.iscsiBackstorePipe=n,this.booleanTextPipe=e,this.metadata={}}return Object.defineProperty(l.prototype,"content",{set:function(l){this.detailTable=l,l&&l.updateColumns()},enumerable:!0,configurable:!0}),l.prototype.ngOnInit=function(){this.columns=[{prop:"displayName",name:this.i18n("Name"),flexGrow:1,cellTemplate:this.highlightTpl},{prop:"current",name:this.i18n("Current"),flexGrow:1,cellTemplate:this.highlightTpl},{prop:"default",name:this.i18n("Default"),flexGrow:1,cellTemplate:this.highlightTpl}]},l.prototype.ngOnChanges=function(){this.selection.hasSelection&&(this.selectedItem=this.selection.first(),this.generateTree()),this.data=void 0},l.prototype.generateTree=function(){var l=this,n=t.cloneDeep(this.selectedItem.target_controls);this.cephIscsiConfigVersion>10&&t.extend(n,t.cloneDeep(this.selectedItem.auth)),this.metadata={root:n};var e={target:{expanded:this.selectedItem.cdExecuting?"fa fa-fw fa-spinner fa-spin fa-lg":"fa fa-fw fa-bullseye fa-lg"},initiators:{expanded:"fa fa-fw fa-user fa-lg",leaf:"fa fa-fw fa-user"},groups:{expanded:"fa fa-fw fa-users fa-lg",leaf:"fa fa-fw fa-users"},disks:{expanded:"fa fa-fw fa-hdd-o fa-lg",leaf:"fa fa-fw fa-hdd-o"},portals:{expanded:"fa fa-fw fa-server fa-lg",leaf:"fa fa-fw fa-server fa-lg"}},u=[];t.forEach(this.selectedItem.disks,function(n){var e="disk_"+n.pool+"_"+n.image;l.metadata[e]={controls:n.controls,backstore:n.backstore},["wwn","lun"].forEach(function(t){t in n&&(l.metadata[e][t]=n[t])}),u.push({value:n.pool+"/"+n.image,id:e})});var i=[];t.forEach(this.selectedItem.portals,function(l){i.push({value:l.host+":"+l.ip})});var o=[];t.forEach(this.selectedItem.clients,function(n){var u=t.cloneDeep(n.auth);n.info&&(t.extend(u,n.info),delete u.state,t.forEach(Object.keys(n.info.state),function(l){u[l.toLowerCase()]=n.info.state[l]})),l.metadata["client_"+n.client_iqn]=u;var i=[];n.luns.forEach(function(l){i.push({value:l.pool+"/"+l.image,id:"disk_"+l.pool+"_"+l.image,settings:{cssClasses:e.disks}})});var a="";n.info&&(a=Object.keys(n.info.state).includes("LOGGED_IN")?"logged_in":"logged_out"),o.push({value:n.client_iqn,status:a,id:"client_"+n.client_iqn,children:i})});var a=[];t.forEach(this.selectedItem.groups,function(l){var n=[];l.disks.forEach(function(l){n.push({value:l.pool+"/"+l.image,id:"disk_"+l.pool+"_"+l.image})});var t=[];l.members.forEach(function(l){t.push({value:l,id:"client_"+l})}),a.push({value:l.group_id,children:[{value:"Disks",children:n,settings:{selectionAllowed:!1,cssClasses:e.disks}},{value:"Initiators",children:t,settings:{selectionAllowed:!1,cssClasses:e.initiators}}]})}),this.tree={value:this.selectedItem.target_iqn,id:"root",settings:{static:!0,cssClasses:e.target},children:[{value:"Disks",children:u,settings:{selectionAllowed:!1,cssClasses:e.disks}},{value:"Portals",children:i,settings:{selectionAllowed:!1,cssClasses:e.portals}},{value:"Initiators",children:o,settings:{selectionAllowed:!1,cssClasses:e.initiators}},{value:"Groups",children:a,settings:{selectionAllowed:!1,cssClasses:e.groups}}]}},l.prototype.format=function(l){return"boolean"==typeof l?this.booleanTextPipe.transform(l):l},l.prototype.onNodeSelected=function(l){var n=this;if(l.node.id){this.title=l.node.value;var e=this.metadata[l.node.id]||{};"root"===l.node.id?(this.columns[2].isHidden=!1,this.data=t.map(this.settings.target_default_controls,function(l,u){return{displayName:u,default:l=n.format(l),current:t.isUndefined(e[u])?l:n.format(e[u])}}),this.cephIscsiConfigVersion>10&&["user","password","mutual_user","mutual_password"].forEach(function(l){n.data.push({displayName:l,default:null,current:e[l]})})):l.node.id.toString().startsWith("disk_")?(this.columns[2].isHidden=!1,this.data=t.map(this.settings.disk_default_controls[e.backstore],function(l,u){return{displayName:u,default:l=n.format(l),current:t.isUndefined(e.controls[u])?l:n.format(e.controls[u])}}),this.data.push({displayName:"backstore",default:this.iscsiBackstorePipe.transform(this.settings.default_backstore),current:this.iscsiBackstorePipe.transform(e.backstore)}),["wwn","lun"].forEach(function(l){l in e&&n.data.push({displayName:l,default:void 0,current:e[l]})})):(this.columns[2].isHidden=!0,this.data=t.map(e,function(l,e){return{displayName:e,default:void 0,current:n.format(l)}}))}else this.data=void 0;this.detailTable&&this.detailTable.updateColumns()},l}())},BH9v:function(l,n,e){"use strict";var t=e("CcnG"),u=e("gIcY"),i=e("aXbf"),o=function(){function l(l,n){this.control=l,this.formatter=n}return l.prototype.setValue=function(l){var n=this.formatter.toMilliseconds(l);this.control.control.setValue(n+" ms")},l.prototype.ngOnInit=function(){var l=this;this.setValue(this.control.value),this.ngDataReady&&this.ngDataReady.subscribe(function(){return l.setValue(l.control.value)})},l.prototype.onUpdate=function(l){this.setValue(l)},l}(),a=e("ANnk"),r=e("f/UV"),s=e("aexS"),d=e("LvDl"),c=e("IzCI"),p=function(){function l(l,n,e,u){this.elementRef=l,this.control=n,this.dimlessBinaryPerSecondPipe=e,this.formatter=u,this.ngModelChange=new t.EventEmitter,this.el=this.elementRef.nativeElement}return l.prototype.ngOnInit=function(){var l=this;this.setValue(this.el.value),this.ngDataReady&&this.ngDataReady.subscribe(function(){return l.setValue(l.el.value)})},l.prototype.setValue=function(l){/^[\d.]+$/.test(l)&&(l+=this.defaultUnit||"m");var n=this.formatter.toBytes(l,0),e=this.round(n);this.el.value=this.dimlessBinaryPerSecondPipe.transform(e),null!==n?(this.ngModelChange.emit(this.el.value),this.control.control.setValue(this.el.value)):(this.ngModelChange.emit(null),this.control.control.setValue(null))},l.prototype.round=function(l){if(null!==l&&0!==l){if(!d.isUndefined(this.minBytes)&&lthis.maxBytes)return this.maxBytes;if(!d.isUndefined(this.roundPower)){var n=Math.round(Math.log(l)/Math.log(this.roundPower));return Math.pow(this.roundPower,n)}}return l},l.prototype.onBlur=function(l){this.setValue(l)},l}(),m=function(){function l(l,n){this.formatter=l,this.ngControl=n}return l.prototype.setValue=function(l){var n=this.formatter.toIops(l);this.ngControl.control.setValue(n+" IOPS")},l.prototype.ngOnInit=function(){var l=this;this.setValue(this.ngControl.value),this.ngDataReady&&this.ngDataReady.subscribe(function(){return l.setValue(l.ngControl.value)})},l.prototype.onUpdate=function(l){this.setValue(l)},l}(),f=e("Ip0R"),g=e("4HWh"),h=e("p4Cf");e("rFfW"),e("o8EM"),e.d(n,"a",function(){return v}),e.d(n,"b",function(){return I});var v=t["\u0275crt"]({encapsulation:0,styles:[[".collapsible[_ngcontent-%COMP%]{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"]],data:{}});function b(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,8,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,7,"input",[["cdMilliseconds",""],["class","form-control"],["type","text"]],[[8,"id",0],[8,"name",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,2)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,2).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,2)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,2)._compositionEnd(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,7).onUpdate(e.target.value)&&u),u},null,null)),t["\u0275did"](2,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.e]),t["\u0275did"](4,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](6,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](7,81920,null,0,o,[u.q,i.a],{ngDataReady:[0,"ngDataReady"]},null),t["\u0275did"](8,4210688,null,0,a.a,[[2,r.a],s.a,t.ElementRef],null,null)],function(l,n){var e=n.component;l(n,4,0,n.parent.context.$implicit.name),l(n,7,0,e.ngDataReady)},function(l,n){l(n,1,0,n.parent.context.$implicit.name,n.parent.context.$implicit.name,t["\u0275nov"](n,6).ngClassUntouched,t["\u0275nov"](n,6).ngClassTouched,t["\u0275nov"](n,6).ngClassPristine,t["\u0275nov"](n,6).ngClassDirty,t["\u0275nov"](n,6).ngClassValid,t["\u0275nov"](n,6).ngClassInvalid,t["\u0275nov"](n,6).ngClassPending)})}function y(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,8,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,7,"input",[["cdDimlessBinaryPerSecond",""],["class","form-control"],["defaultUnit","b"],["type","text"]],[[8,"id",0],[8,"name",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,2)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,2).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,2)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,2)._compositionEnd(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,7).onBlur(e.target.value)&&u),u},null,null)),t["\u0275did"](2,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.e]),t["\u0275did"](4,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](6,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](7,81920,null,0,p,[t.ElementRef,u.q,c.a,i.a],{ngDataReady:[0,"ngDataReady"],defaultUnit:[1,"defaultUnit"]},null),t["\u0275did"](8,4210688,null,0,a.a,[[2,r.a],s.a,t.ElementRef],null,null)],function(l,n){var e=n.component;l(n,4,0,n.parent.context.$implicit.name),l(n,7,0,e.ngDataReady,"b")},function(l,n){l(n,1,0,n.parent.context.$implicit.name,n.parent.context.$implicit.name,t["\u0275nov"](n,6).ngClassUntouched,t["\u0275nov"](n,6).ngClassTouched,t["\u0275nov"](n,6).ngClassPristine,t["\u0275nov"](n,6).ngClassDirty,t["\u0275nov"](n,6).ngClassValid,t["\u0275nov"](n,6).ngClassInvalid,t["\u0275nov"](n,6).ngClassPending)})}function C(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,8,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,7,"input",[["cdIops",""],["class","form-control"],["type","text"]],[[8,"id",0],[8,"name",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,2)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,2).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,2)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,2)._compositionEnd(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,7).onUpdate(e.target.value)&&u),u},null,null)),t["\u0275did"](2,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.e]),t["\u0275did"](4,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](6,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](7,81920,null,0,m,[i.a,u.q],{ngDataReady:[0,"ngDataReady"]},null),t["\u0275did"](8,4210688,null,0,a.a,[[2,r.a],s.a,t.ElementRef],null,null)],function(l,n){var e=n.component;l(n,4,0,n.parent.context.$implicit.name),l(n,7,0,e.ngDataReady)},function(l,n){l(n,1,0,n.parent.context.$implicit.name,n.parent.context.$implicit.name,t["\u0275nov"](n,6).ngClassUntouched,t["\u0275nov"](n,6).ngClassTouched,t["\u0275nov"](n,6).ngClassPristine,t["\u0275nov"](n,6).ngClassDirty,t["\u0275nov"](n,6).ngClassValid,t["\u0275nov"](n,6).ngClassInvalid,t["\u0275nov"](n,6).ngClassPending)})}function _(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The mininum value is 0"]))],null,null)}function w(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,24,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,f.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,4,"label",[["class","control-label col-sm-3"]],[[8,"htmlFor",0]],null,null,null,null)),(l()(),t["\u0275ted"](4,null,["",""])),(l()(),t["\u0275eld"](5,0,null,null,2,"cd-helper",[],null,null,null,g.b,g.a)),t["\u0275did"](6,49152,null,0,h.a,[],null,null),(l()(),t["\u0275ted"](7,0,["",""])),(l()(),t["\u0275eld"](8,0,null,null,16,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,13,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](10,0,null,null,7,null,null,null,null,null,null,null)),t["\u0275did"](11,16384,null,0,f.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,b)),t["\u0275did"](13,278528,null,0,f.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,f.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,y)),t["\u0275did"](15,278528,null,0,f.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,f.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,C)),t["\u0275did"](17,278528,null,0,f.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,f.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275eld"](18,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](19,0,null,null,3,"button",[["class","btn btn-default"],["data-toggle","button"],["title","Remove the local configuration value. The parent configuration value will be inherited and used instead."],["type","button"]],null,[[null,"click"]],function(l,n,e){var t=!0;return"click"===n&&(t=!1!==l.component.reset(l.context.$implicit.name)&&t),t},null,null)),t["\u0275did"](20,278528,null,0,f.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](21,{active:0}),(l()(),t["\u0275eld"](22,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-eraser"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,_)),t["\u0275did"](24,16384,null,0,f.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,u=l(n,2,0,e.form.showError("configuration."+n.context.$implicit.name,t["\u0275nov"](n.parent.parent,0)));l(n,1,0,"form-group",u),l(n,11,0,n.context.$implicit.type),l(n,13,0,e.configurationType.milliseconds),l(n,15,0,e.configurationType.bps),l(n,17,0,e.configurationType.iops);var i=l(n,21,0,e.isDisabled(n.context.$implicit.name));l(n,20,0,"btn btn-default",i),l(n,24,0,e.form.showError("configuration."+n.context.$implicit.name,t["\u0275nov"](n.parent.parent,0),"min"))},function(l,n){l(n,3,0,n.context.$implicit.name),l(n,4,0,n.context.$implicit.displayName),l(n,7,0,n.context.$implicit.description),l(n,8,0,t["\u0275inlineInterpolate"](1,"col-sm-9 ",n.parent.context.$implicit.heading,""))})}function R(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,9,"div",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,5,"h3",[["class","page-header"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,4,"span",[["class","collapsible"]],null,[[null,"click"]],function(l,n,e){var t=!0;return"click"===n&&(t=!1!==l.component.toggleSectionVisibility(l.context.$implicit.class)&&t),t},null,null)),(l()(),t["\u0275ted"](3,null,[""," "])),(l()(),t["\u0275eld"](4,0,null,null,2,"i",[["aria-hidden","true"],["class","fa"]],null,null,null,null,null)),t["\u0275did"](5,278528,null,0,f.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](6,{"fa-plus-circle":0,"fa-minus-circle":1}),(l()(),t["\u0275eld"](7,0,null,null,2,"div",[],[[8,"className",0],[8,"hidden",0]],null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,w)),t["\u0275did"](9,278528,null,0,f.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component,t=l(n,6,0,!e.sectionVisibility[n.context.$implicit.class],e.sectionVisibility[n.context.$implicit.class]);l(n,5,0,"fa",t),l(n,9,0,n.context.$implicit.options)},function(l,n){var e=n.component;l(n,3,0,n.context.$implicit.heading),l(n,7,0,t["\u0275inlineInterpolate"](1,"",n.context.$implicit.class,""),!e.sectionVisibility[n.context.$implicit.class])})}function I(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,[["cfgFormGroup",1]],null,7,"fieldset",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,1).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,1).onReset()&&u),u},null,null)),t["\u0275did"](1,540672,null,0,u.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,u.d,null,[u.l]),t["\u0275did"](3,16384,null,0,u.s,[[4,u.d]],null,null),(l()(),t["\u0275eld"](4,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["RBD Configuration"])),(l()(),t["\u0275and"](16777216,null,null,1,null,R)),t["\u0275did"](7,278528,null,0,f.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component;l(n,1,0,e.form.get("configuration")),l(n,7,0,e.rbdConfigurationService.sections)},function(l,n){l(n,0,0,t["\u0275nov"](n,3).ngClassUntouched,t["\u0275nov"](n,3).ngClassTouched,t["\u0275nov"](n,3).ngClassPristine,t["\u0275nov"](n,3).ngClassDirty,t["\u0275nov"](n,3).ngClassValid,t["\u0275nov"](n,3).ngClassInvalid,t["\u0275nov"](n,3).ngClassPending)})}},EFGL:function(l,n,e){"use strict";var t=e("CcnG"),u=e("Ip0R"),i=e("IzCI"),o=e("aXbf"),a=e("dEH0"),r=e("BQkM"),s=e("25BL"),d=e("uIqm");e("aAWM"),e("o8EM"),e("Jm/i"),e.d(n,"a",function(){return c}),e.d(n,"b",function(){return _});var c=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function p(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Global"]))],null,null)}function m(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Image"]))],null,null)}function f(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Pool"]))],null,null)}function g(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,7,"div",[],null,null,null,null,null)),t["\u0275did"](1,16384,null,0,u.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,p)),t["\u0275did"](3,278528,null,0,u.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,u.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,m)),t["\u0275did"](5,278528,null,0,u.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,u.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,f)),t["\u0275did"](7,278528,null,0,u.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,u.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null)],function(l,n){l(n,1,0,n.context.value),l(n,3,0,"global"),l(n,5,0,"image"),l(n,7,0,"pool")},null)}function h(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,["",""])),t["\u0275ppd"](2,1)],null,function(l,n){var e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent.parent,0),n.parent.context.value));l(n,1,0,e)})}function v(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,["",""])),t["\u0275ppd"](2,1)],null,function(l,n){var e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent.parent,1),n.parent.context.value));l(n,1,0,e)})}function b(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,["",""])),t["\u0275ppd"](2,1)],null,function(l,n){var e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent.parent,2),n.parent.context.value));l(n,1,0,e)})}function y(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,["",""]))],null,function(l,n){l(n,1,0,n.parent.context.value)})}function C(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,9,"div",[],null,null,null,null,null)),t["\u0275did"](1,16384,null,0,u.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,h)),t["\u0275did"](3,278528,null,0,u.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,u.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,v)),t["\u0275did"](5,278528,null,0,u.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,u.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,b)),t["\u0275did"](7,278528,null,0,u.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,u.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,y)),t["\u0275did"](9,16384,null,0,u.NgSwitchDefault,[t.ViewContainerRef,t.TemplateRef,u.NgSwitch],null,null)],function(l,n){var e=n.component;l(n,1,0,n.context.row.type),l(n,3,0,e.typeField.bps),l(n,5,0,e.typeField.milliseconds),l(n,7,0,e.typeField.iops)},null)}function _(l){return t["\u0275vid"](0,[t["\u0275pid"](0,i.a,[o.a]),t["\u0275pid"](0,a.a,[]),t["\u0275pid"](0,r.a,[]),t["\u0275qud"](402653184,1,{configurationSourceTpl:0}),t["\u0275qud"](402653184,2,{configurationValueTpl:0}),t["\u0275qud"](402653184,3,{poolConfTable:0}),(l()(),t["\u0275eld"](6,0,null,null,1,"cd-table",[["identifier","name"]],null,null,null,s.b,s.a)),t["\u0275did"](7,2867200,[[3,4],["poolConfTable",4]],0,d.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],identifier:[2,"identifier"]},null),(l()(),t["\u0275and"](0,[[1,2],["configurationSourceTpl",2]],null,0,null,g)),(l()(),t["\u0275and"](0,[[2,2],["configurationValueTpl",2]],null,0,null,C))],function(l,n){var e=n.component;l(n,7,0,e.data,e.poolConfigurationColumns,"name")},null)}},Ekvf:function(l,n,e){"use strict";e.d(n,"a",function(){return d});var t=e("mrSG"),u=e("t/Na"),i=e("67Y/"),o=e("xTzq"),a=e("o8EM"),r=e("CcnG"),s=e("pL04"),d=function(){function l(l,n){this.http=l,this.rbdConfigurationService=n,this.apiPath="api/pool"}return l.prototype.create=function(l){return this.http.post(this.apiPath,l,{observe:"response"})},l.prototype.update=function(l){var n;return l.hasOwnProperty("srcpool")?(n=l.srcpool,delete l.srcpool):(n=l.pool,delete l.pool),this.http.put(this.apiPath+"/"+encodeURIComponent(n),l,{observe:"response"})},l.prototype.delete=function(l){return this.http.delete(this.apiPath+"/"+l,{observe:"response"})},l.prototype.get=function(l){return this.http.get(this.apiPath+"/"+l)},l.prototype.getList=function(){return this.http.get(this.apiPath+"?stats=true")},l.prototype.getConfiguration=function(l){var n=this;return this.http.get(this.apiPath+"/"+l+"/configuration").pipe(Object(i.a)(function(l){return l.map(function(l){return Object.assign(l,n.rbdConfigurationService.getOptionByName(l.name))})}))},l.prototype.getInfo=function(l){return this.http.get(this.apiPath+"/_info"+(l?"?pool_name="+l:""))},l.prototype.list=function(l){void 0===l&&(l=[]);var n=l.join(",");return this.http.get(this.apiPath+"?attrs="+n).toPromise().then(function(l){return l})},l.ngInjectableDef=r.defineInjectable({factory:function(){return new l(r.inject(u.c),r.inject(a.a))},token:l,providedIn:s.a}),l=t.__decorate([o.a,t.__metadata("design:paramtypes",[u.c,a.a])],l)}()},EmSq:function(l,n,e){"use strict";e.d(n,"a",function(){return i});var t=e("CcnG"),u=e("LvDl"),i=(e("Fgil"),e("aXbf"),function(){function l(l,n,e,u){this.elementRef=l,this.control=n,this.dimlessBinaryPipe=e,this.formatter=u,this.ngModelChange=new t.EventEmitter,this.el=this.elementRef.nativeElement}return l.prototype.ngOnInit=function(){this.setValue(this.el.value)},l.prototype.setValue=function(l){/^[\d.]+$/.test(l)&&(l+=this.defaultUnit||"m");var n=this.formatter.toBytes(l),e=this.round(n);this.el.value=this.dimlessBinaryPipe.transform(e),null!==n?(this.ngModelChange.emit(this.el.value),this.control.control.setValue(this.el.value)):(this.ngModelChange.emit(null),this.control.control.setValue(null))},l.prototype.round=function(l){if(null!==l&&0!==l){if(!u.isUndefined(this.minBytes)&&lthis.maxBytes)return this.maxBytes;if(!u.isUndefined(this.roundPower)){var n=Math.round(Math.log(l)/Math.log(this.roundPower));return Math.pow(this.roundPower,n)}}return l},l.prototype.onBlur=function(l){this.setValue(l)},l}())},F83c:function(l,n,e){"use strict";e.d(n,"a",function(){return d});var t=e("mrSG"),u=e("t/Na"),i=e("67Y/"),o=e("xTzq"),a=e("o8EM"),r=e("CcnG"),s=e("pL04"),d=function(){function l(l,n){this.http=l,this.rbdConfigurationService=n}return l.prototype.create=function(l){return this.http.post("api/block/image",l,{observe:"response"})},l.prototype.delete=function(l,n){return this.http.delete("api/block/image/"+l+"/"+n,{observe:"response"})},l.prototype.update=function(l,n,e){return this.http.put("api/block/image/"+l+"/"+n,e,{observe:"response"})},l.prototype.get=function(l,n){return this.http.get("api/block/image/"+l+"/"+n)},l.prototype.list=function(){var l=this;return this.http.get("api/block/image").pipe(Object(i.a)(function(n){return n.map(function(n){return n.value.map(function(n){return n.configuration?(n.configuration.map(function(n){return Object.assign(n,l.rbdConfigurationService.getOptionByName(n.name))}),n):n}),n})}))},l.prototype.copy=function(l,n,e){return this.http.post("api/block/image/"+l+"/"+n+"/copy",e,{observe:"response"})},l.prototype.flatten=function(l,n){return this.http.post("api/block/image/"+l+"/"+n+"/flatten",null,{observe:"response"})},l.prototype.defaultFeatures=function(){return this.http.get("api/block/image/default_features")},l.prototype.createSnapshot=function(l,n,e){return this.http.post("api/block/image/"+l+"/"+n+"/snap",{snapshot_name:e},{observe:"response"})},l.prototype.renameSnapshot=function(l,n,e,t){return this.http.put("api/block/image/"+l+"/"+n+"/snap/"+e,{new_snap_name:t},{observe:"response"})},l.prototype.protectSnapshot=function(l,n,e,t){return this.http.put("api/block/image/"+l+"/"+n+"/snap/"+e,{is_protected:t},{observe:"response"})},l.prototype.rollbackSnapshot=function(l,n,e){return this.http.post("api/block/image/"+l+"/"+n+"/snap/"+e+"/rollback",null,{observe:"response"})},l.prototype.cloneSnapshot=function(l,n,e,t){return this.http.post("api/block/image/"+l+"/"+n+"/snap/"+e+"/clone",t,{observe:"response"})},l.prototype.deleteSnapshot=function(l,n,e){return this.http.delete("api/block/image/"+l+"/"+n+"/snap/"+e,{observe:"response"})},l.prototype.listTrash=function(){return this.http.get("api/block/image/trash/")},l.prototype.moveTrash=function(l,n,e){return this.http.post("api/block/image/"+l+"/"+n+"/move_trash",{delay:e},{observe:"response"})},l.prototype.purgeTrash=function(l){return this.http.post("api/block/image/trash/purge/?pool_name="+l,null,{observe:"response"})},l.prototype.restoreTrash=function(l,n,e){return this.http.post("api/block/image/trash/"+l+"/"+n+"/restore",{new_image_name:e},{observe:"response"})},l.prototype.removeTrash=function(l,n,e,t){return void 0===t&&(t=!1),this.http.delete("api/block/image/trash/"+l+"/"+n+"/?image_name="+e+"&force="+t,{observe:"response"})},l.ngInjectableDef=r.defineInjectable({factory:function(){return new l(r.inject(u.c),r.inject(a.a))},token:l,providedIn:s.a}),t.__decorate([t.__param(2,o.b),t.__metadata("design:type",Function),t.__metadata("design:paramtypes",[Object,Object,Object]),t.__metadata("design:returntype",void 0)],l.prototype,"createSnapshot",null),t.__decorate([t.__param(3,o.b),t.__metadata("design:type",Function),t.__metadata("design:paramtypes",[Object,Object,Object,Object]),t.__metadata("design:returntype",void 0)],l.prototype,"renameSnapshot",null),t.__decorate([t.__param(3,o.b),t.__metadata("design:type",Function),t.__metadata("design:paramtypes",[Object,Object,Object,Object]),t.__metadata("design:returntype",void 0)],l.prototype,"protectSnapshot",null),t.__decorate([t.__param(2,o.b),t.__metadata("design:type",Function),t.__metadata("design:paramtypes",[Object,Object,Object]),t.__metadata("design:returntype",void 0)],l.prototype,"restoreTrash",null),l=t.__decorate([o.a,t.__metadata("design:paramtypes",[u.c,a.a])],l)}()},I4Qz:function(l,n,e){"use strict";var t=e("CcnG"),u=e("EEJc"),i=e("ajRT"),o=e("gIcY"),a=e("Ip0R"),r=e("ARl4"),s=e("lqqz"),d=e("ANnk"),c=e("f/UV"),p=e("aexS"),m=e("gp3X"),f=e("sb0X"),g=e("KVJa"),h=e("Z21x"),v=e("sne2"),b=e("2JDI"),y=e("F83c"),C=e("DQlY"),_=e("2EZI"),w=e("kn/O");e.d(n,"a",function(){return F});var R=t["\u0275crt"]({encapsulation:0,styles:[[".bs-datepicker-head bs-datepicker-navigation-view{display:-webkit-box;display:flex;-webkit-box-pack:justify;justify-content:space-between}"]],data:{}});function I(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,['Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".']))],null,null)}function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Protection has already expired. Please pick a future date or leave it empty."]))],null,null)}function k(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,44,"cd-modal",[],null,null,null,u.c,u.b)),t["\u0275did"](1,49152,null,0,i.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Move an image to trash"])),(l()(),t["\u0275eld"](4,0,null,1,40,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,39,"form",[["class","form"],["name","moveForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,7).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,7).onReset()&&u),u},null,null)),t["\u0275did"](6,16384,null,0,o.D,[],null,null),t["\u0275did"](7,540672,[["formDir",4]],0,o.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,o.d,null,[o.l]),t["\u0275did"](9,16384,null,0,o.s,[[4,o.d]],null,null),(l()(),t["\u0275eld"](10,0,null,null,27,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,7,"p",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["To move "])),(l()(),t["\u0275eld"](13,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](14,null,["","/",""])),(l()(),t["\u0275ted"](-1,null,[" to trash, click "])),(l()(),t["\u0275eld"](16,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Move Image"])),(l()(),t["\u0275ted"](-1,null,[". Optionally, you can pick an expiration date."])),(l()(),t["\u0275eld"](19,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](20,278528,null,0,a.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](21,{"has-error":0}),(l()(),t["\u0275eld"](22,0,null,null,1,"label",[["for","expires"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Protection expires at"])),(l()(),t["\u0275eld"](24,16777216,null,null,9,"input",[["bsDatepicker",""],["class","form-control"],["formControlName","expiresAt"],["placeholder","NOT PROTECTED"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"],[null,"keyup.esc"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,25)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,25).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,25)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,25)._compositionEnd(e.target.value)&&u),"change"===n&&(u=!1!==t["\u0275nov"](l,27).onChange(e)&&u),"keyup.esc"===n&&(u=!1!==t["\u0275nov"](l,27).hide()&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,27).onBlur()&&u),u},null,null)),t["\u0275did"](25,16384,null,0,o.e,[t.Renderer2,t.ElementRef,[2,o.b]],null,null),t["\u0275did"](26,737280,null,0,r.c,[r.a,t.ElementRef,t.Renderer2,t.ViewContainerRef,s.a],{bsConfig:[0,"bsConfig"],minDate:[1,"minDate"]},null),t["\u0275did"](27,16384,null,0,r.f,[r.c,r.j,t.Renderer2,t.ElementRef,t.ChangeDetectorRef],null,null),t["\u0275prd"](1024,null,o.o,function(l){return[l]},[r.f]),t["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,r.f]),t["\u0275did"](30,671744,null,0,o.j,[[3,o.d],[6,o.o],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,o.q,null,[o.j]),t["\u0275did"](32,16384,null,0,o.r,[[4,o.q]],null,null),t["\u0275did"](33,4210688,null,0,d.a,[[2,c.a],p.a,t.ElementRef],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,I)),t["\u0275did"](35,16384,null,0,a.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,S)),t["\u0275did"](37,16384,null,0,a.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](38,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](39,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](40,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.moveImage()&&t),t},m.b,m.a)),t["\u0275did"](41,114688,null,0,f.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Move Image"])),(l()(),t["\u0275eld"](43,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,g.b,g.a)),t["\u0275did"](44,49152,null,0,h.a,[a.Location,v.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,1,0,e.modalRef),l(n,7,0,e.moveForm);var u=l(n,21,0,e.moveForm.showError("expiresAt",t["\u0275nov"](n,7)));l(n,20,0,"form-group",u),l(n,26,0,e.bsConfig,e.minDate),l(n,30,0,"expiresAt"),l(n,35,0,e.moveForm.showError("expiresAt",t["\u0275nov"](n,7),"format")),l(n,37,0,e.moveForm.showError("expiresAt",t["\u0275nov"](n,7),"expired")),l(n,41,0,e.moveForm),l(n,44,0,"Cancel",e.modalRef.hide)},function(l,n){var e=n.component;l(n,5,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending),l(n,14,0,e.poolName,e.imageName),l(n,24,0,t["\u0275nov"](n,32).ngClassUntouched,t["\u0275nov"](n,32).ngClassTouched,t["\u0275nov"](n,32).ngClassPristine,t["\u0275nov"](n,32).ngClassDirty,t["\u0275nov"](n,32).ngClassValid,t["\u0275nov"](n,32).ngClassInvalid,t["\u0275nov"](n,32).ngClassPending)})}function E(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rbd-trash-move-modal",[],null,null,null,k,R)),t["\u0275did"](1,114688,null,0,b.a,[y.a,C.a,_.a,w.a],null,null)],function(l,n){l(n,1,0)},null)}var F=t["\u0275ccf"]("cd-rbd-trash-move-modal",b.a,E,{},{},[])},JBea:function(l,n,e){"use strict";e.d(n,"a",function(){return t}),e("vCyI");var t=function(){function l(){}return l.prototype.ngOnChanges=function(){this.selection.hasSelection&&(this.selectedItem=this.selection.first())},l}()},"JIi+":function(l,n,e){"use strict";var t=e("CcnG"),u=e("eajB"),i=e("lqqz"),o=e("NJnL"),a=e("pKUh"),r=e("YAQW"),s=e("Ip0R"),d=e("25BL"),c=e("uIqm"),p=e("NUGo"),m=e("S7zO"),f=e("VTlA"),g=e("ufoC"),h=e("mSOc"),v=e("wd/R"),b=e("F/XL"),y=e("F83c"),C=e("OLbh"),_=e("0+/T"),w=e("sne2"),R=e("x38r"),I=e("vCyI"),S=e("QTAa"),k=e("kvvV"),E=e("a0VL"),F=e("Fgil"),D=e("aexS"),V=e("9nlD"),T=e("VXsX"),N=e("+lcs"),P=function(){return function(l,n){this.i18n=l,this.create={permission:"create",icon:"fa-plus",name:n.CREATE},this.rename={permission:"update",icon:"fa-pencil",name:n.RENAME},this.protect={permission:"update",icon:"fa-lock",visible:function(l){return l.hasSingleSelection&&!l.first().is_protected},name:n.PROTECT},this.unprotect={permission:"update",icon:"fa-unlock",visible:function(l){return l.hasSingleSelection&&l.first().is_protected},name:n.UNPROTECT},this.clone={permission:"create",canBePrimary:function(l){return l.hasSingleSelection},disable:function(l){return!l.hasSingleSelection||l.first().cdExecuting},icon:"fa-clone",name:n.CLONE},this.copy={permission:"create",canBePrimary:function(l){return l.hasSingleSelection},disable:function(l){return!l.hasSingleSelection||l.first().cdExecuting},icon:"fa-copy",name:n.COPY},this.rollback={permission:"update",icon:"fa-undo",name:n.ROLLBACK},this.deleteSnap={permission:"delete",icon:"fa-times",disable:function(l){var n=l.first();return!l.hasSingleSelection||n.cdExecuting||n.is_protected},name:n.DELETE},this.ordering=[this.create,this.rename,this.protect,this.unprotect,this.clone,this.copy,this.rollback,this.deleteSnap]}}(),x=function(){return function(){}}(),O=function(){function l(l,n,e,t,u,i,o,a,r,s,d){var c=this;this.authStorageService=l,this.modalService=n,this.dimlessBinaryPipe=e,this.cdDatePipe=t,this.rbdService=u,this.taskManagerService=i,this.notificationService=o,this.summaryService=a,this.taskListService=r,this.i18n=s,this.actionLabels=d,this.snapshots=[],this.selection=new I.a,this.builders={"rbd/snap/create":function(l){var n=new x;return n.name=l.snapshot_name,n}},this.permission=this.authStorageService.getPermissions().rbdImage;var p=new P(this.i18n,this.actionLabels);p.create.click=function(){return c.openCreateSnapshotModal()},p.rename.click=function(){return c.openEditSnapshotModal()},p.protect.click=function(){return c.toggleProtection()},p.unprotect.click=function(){return c.toggleProtection()};var m=function(){return c.selection.first()&&encodeURIComponent(c.poolName)+"/"+encodeURIComponent(c.rbdName)+"/"+encodeURIComponent(c.selection.first().name)};p.clone.routerLink=function(){return"/block/rbd/clone/"+m()},p.copy.routerLink=function(){return"/block/rbd/copy/"+m()},p.rollback.click=function(){return c.rollbackModal()},p.deleteSnap.click=function(){return c.deleteSnapshotModal()},this.tableActions=p.ordering}return l.prototype.ngOnInit=function(){this.columns=[{name:this.i18n("Name"),prop:"name",cellTransformation:R.a.executing,flexGrow:2},{name:this.i18n("Size"),prop:"size",flexGrow:1,cellClass:"text-right",pipe:this.dimlessBinaryPipe},{name:this.i18n("Provisioned"),prop:"disk_usage",flexGrow:1,cellClass:"text-right",pipe:this.dimlessBinaryPipe},{name:this.i18n("State"),prop:"is_protected",flexGrow:1,cellClass:"text-center",cellTemplate:this.protectTpl},{name:this.i18n("Created"),prop:"timestamp",flexGrow:1,pipe:this.cdDatePipe}]},l.prototype.ngOnChanges=function(){var l=this;this.taskListService.init(function(){return Object(b.a)(l.snapshots)},null,function(n){return l.data=n},function(){return l.data=l.snapshots},function(n){return["rbd/snap/create","rbd/snap/delete","rbd/snap/edit","rbd/snap/rollback"].includes(n.name)&&l.poolName===n.metadata.pool_name&&l.rbdName===n.metadata.image_name},function(l,n){return l.name===n.metadata.snapshot_name},this.builders)},l.prototype.openSnapshotModal=function(l,n){var e=this;void 0===n&&(n=null),this.modalRef=this.modalService.show(N.a),this.modalRef.content.poolName=this.poolName,this.modalRef.content.imageName=this.rbdName,n?this.modalRef.content.setEditing():n=this.rbdName+"_"+v().toISOString(!0),this.modalRef.content.setSnapName(n),this.modalRef.content.onSubmit.subscribe(function(n){var t=new S.a;t.name=l,t.metadata={image_name:e.rbdName,pool_name:e.poolName,snapshot_name:n},e.summaryService.addRunningTask(t),e.ngOnChanges()})},l.prototype.openCreateSnapshotModal=function(){this.openSnapshotModal("rbd/snap/create")},l.prototype.openEditSnapshotModal=function(){this.openSnapshotModal("rbd/snap/edit",this.selection.first().name)},l.prototype.toggleProtection=function(){var l=this,n=this.selection.first().name,e=this.selection.first().is_protected,t=new k.a;t.name="rbd/snap/edit",t.metadata={pool_name:this.poolName,image_name:this.rbdName,snapshot_name:n},this.rbdService.protectSnapshot(this.poolName,this.rbdName,n,!e).toPromise().then(function(){var n=new S.a;n.name=t.name,n.metadata=t.metadata,l.summaryService.addRunningTask(n),l.ngOnChanges(),l.taskManagerService.subscribe(t.name,t.metadata,function(n){l.notificationService.notifyTask(n)})})},l.prototype._asyncTask=function(l,n,e){var t=this,u=new k.a;u.name=n,u.metadata={pool_name:this.poolName,image_name:this.rbdName,snapshot_name:e},this.rbdService[l](this.poolName,this.rbdName,e).toPromise().then(function(){var l=new S.a;l.name=u.name,l.metadata=u.metadata,t.summaryService.addRunningTask(l),t.modalRef.hide(),t.ngOnChanges(),t.taskManagerService.subscribe(l.name,l.metadata,function(l){t.notificationService.notifyTask(l)})}).catch(function(){t.modalRef.content.stopLoadingSpinner()})},l.prototype.rollbackModal=function(){var l=this,n=this.selection.selected[0].name,e={titleText:this.i18n("RBD snapshot rollback"),buttonText:this.i18n("Rollback"),bodyTpl:this.rollbackTpl,bodyData:{snapName:this.poolName+"/"+this.rbdName+"@"+n},onSubmit:function(){l._asyncTask("rollbackSnapshot","rbd/snap/rollback",n)}};this.modalRef=this.modalService.show(C.a,{initialState:e})},l.prototype.deleteSnapshotModal=function(){var l=this,n=this.selection.selected[0].name;this.modalRef=this.modalService.show(_.a,{initialState:{itemDescription:this.i18n("RBD snapshot"),itemNames:[n],submitAction:function(){return l._asyncTask("deleteSnapshot","rbd/snap/delete",n)}}})},l.prototype.updateSelection=function(l){this.selection=l},l}(),q=e("DQlY"),M=e("Jm/i"),A=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function B(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","label label-success"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["PROTECTED"]))],null,null)}function j(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","label label-info"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["UNPROTECTED"]))],null,null)}function U(l){return t["\u0275vid"](0,[(l()(),t["\u0275and"](16777216,null,null,1,null,B)),t["\u0275did"](1,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,j)),t["\u0275did"](3,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,n.context.value),l(n,3,0,!n.context.value)},null)}function G(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["You are about to rollback"])),(l()(),t["\u0275eld"](2,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),t["\u0275ted"](3,null,["",""])),(l()(),t["\u0275ted"](-1,null,[".\n"]))],null,function(l,n){l(n,3,0,n.context.$implicit.snapName)})}function L(l){return t["\u0275vid"](0,[t["\u0275qud"](402653184,1,{nameTpl:0}),t["\u0275qud"](402653184,2,{protectTpl:0}),t["\u0275qud"](402653184,3,{rollbackTpl:0}),(l()(),t["\u0275eld"](3,0,null,null,3,"cd-table",[["columnMode","flex"],["selectionType","single"]],null,[[null,"updateSelection"]],function(l,n,e){var t=!0;return"updateSelection"===n&&(t=!1!==l.component.updateSelection(e)&&t),t},d.b,d.a)),t["\u0275did"](4,2867200,null,0,c.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],selectionType:[3,"selectionType"]},{updateSelection:"updateSelection"}),(l()(),t["\u0275eld"](5,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,p.b,p.a)),t["\u0275did"](6,114688,null,0,m.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),t["\u0275and"](0,[[2,2],["protectTpl",2]],null,0,null,U)),(l()(),t["\u0275and"](0,[[3,2],["rollbackTpl",2]],null,0,null,G))],function(l,n){var e=n.component;l(n,4,0,e.data,e.columns,"flex","single"),l(n,6,0,e.permission,e.selection,e.tableActions)},null)}var z=e("EFGL"),W=e("aAWM"),$=e("aXbf"),X=e("o8EM"),Y=e("nSDx"),K=e("o4+5"),J=e("JBea");e.d(n,"b",function(){return Z}),e.d(n,"c",function(){return dl}),e.d(n,"a",function(){return pl});var Z=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Q(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,4,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Only available for RBD images with "])),(l()(),t["\u0275eld"](2,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["fast-diff"])),(l()(),t["\u0275ted"](-1,null,[" enabled"]))],null,null)}function H(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"span",[["class","badge badge-pill badge-primary margin-right-sm"]],null,null,null,null,null)),(l()(),t["\u0275ted"](2,null,["",""]))],null,function(l,n){l(n,2,0,n.context.$implicit)})}function ll(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,16777216,null,null,2,"span",[["class","text-muted"],["placement","top"]],[[1,"aria-describedby",0]],null,null,null,null)),t["\u0275did"](2,212992,null,0,u.c,[t.ViewContainerRef,i.a,u.a,t.ElementRef,t.Renderer2,o.a],{tooltip:[0,"tooltip"],placement:[1,"placement"]},null),(l()(),t["\u0275ted"](-1,null,["N/A"]))],function(l,n){l(n,2,0,t["\u0275nov"](n.parent.parent,5),"top")},function(l,n){l(n,1,0,t["\u0275nov"](n,2).ariaDescribedby)})}function nl(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," "])),t["\u0275ppd"](2,1)],null,function(l,n){var e=n.component,u=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent.parent,2),e.selectedItem.disk_usage));l(n,1,0,u)})}function el(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,16777216,null,null,2,"span",[["class","text-muted"],["placement","top"]],[[1,"aria-describedby",0]],null,null,null,null)),t["\u0275did"](2,212992,null,0,u.c,[t.ViewContainerRef,i.a,u.a,t.ElementRef,t.Renderer2,o.a],{tooltip:[0,"tooltip"],placement:[1,"placement"]},null),(l()(),t["\u0275ted"](-1,null,["N/A"]))],function(l,n){l(n,2,0,t["\u0275nov"](n.parent.parent,5),"top")},function(l,n){l(n,1,0,t["\u0275nov"](n,2).ariaDescribedby)})}function tl(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," "])),t["\u0275ppd"](2,1)],null,function(l,n){var e=n.component,u=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent.parent,2),e.selectedItem.total_disk_usage));l(n,1,0,u)})}function ul(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[""," /"," @",""]))],null,function(l,n){var e=n.component;l(n,1,0,e.selectedItem.parent.pool_name,e.selectedItem.parent.image_name,e.selectedItem.parent.snap_name)})}function il(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["-"]))],null,null)}function ol(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,110,"tabset",[],[[2,"tab-container",null]],null,null,a.b,a.a)),t["\u0275did"](1,180224,null,0,r.d,[r.e,t.Renderer2,t.ElementRef],null,null),(l()(),t["\u0275eld"](2,0,null,0,99,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](3,212992,null,0,r.b,[r.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](4,0,null,null,97,"table",[["class","table table-striped table-bordered"]],null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,96,"tbody",[],null,null,null,null,null)),(l()(),t["\u0275eld"](6,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Name"])),(l()(),t["\u0275eld"](9,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](10,null,["",""])),(l()(),t["\u0275eld"](11,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](12,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Pool"])),(l()(),t["\u0275eld"](14,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](15,null,["",""])),(l()(),t["\u0275eld"](16,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Data Pool"])),(l()(),t["\u0275eld"](19,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](20,null,["",""])),t["\u0275ppd"](21,1),(l()(),t["\u0275eld"](22,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](23,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Created"])),(l()(),t["\u0275eld"](25,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](26,null,["",""])),t["\u0275ppd"](27,1),(l()(),t["\u0275eld"](28,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](29,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Size"])),(l()(),t["\u0275eld"](31,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](32,null,["",""])),t["\u0275ppd"](33,1),(l()(),t["\u0275eld"](34,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](35,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Objects"])),(l()(),t["\u0275eld"](37,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](38,null,["",""])),t["\u0275ppd"](39,1),(l()(),t["\u0275eld"](40,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](41,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Object size"])),(l()(),t["\u0275eld"](43,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](44,null,["",""])),t["\u0275ppd"](45,1),(l()(),t["\u0275eld"](46,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](47,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Features"])),(l()(),t["\u0275eld"](49,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,H)),t["\u0275did"](51,278528,null,0,s.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275eld"](52,0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](53,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Provisioned"])),(l()(),t["\u0275eld"](55,0,null,null,4,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,ll)),t["\u0275did"](57,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,nl)),t["\u0275did"](59,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](60,0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](61,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Total provisioned"])),(l()(),t["\u0275eld"](63,0,null,null,4,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,el)),t["\u0275did"](65,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,tl)),t["\u0275did"](67,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](68,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](69,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Striping unit"])),(l()(),t["\u0275eld"](71,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](72,null,["",""])),t["\u0275ppd"](73,1),(l()(),t["\u0275eld"](74,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](75,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Striping count"])),(l()(),t["\u0275eld"](77,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](78,null,["",""])),(l()(),t["\u0275eld"](79,0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](80,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Parent"])),(l()(),t["\u0275eld"](82,0,null,null,4,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,ul)),t["\u0275did"](84,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,il)),t["\u0275did"](86,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](87,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](88,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Block name prefix"])),(l()(),t["\u0275eld"](90,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](91,null,["",""])),(l()(),t["\u0275eld"](92,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](93,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Order"])),(l()(),t["\u0275eld"](95,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](96,null,["",""])),(l()(),t["\u0275eld"](97,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](98,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Format Version"])),(l()(),t["\u0275eld"](100,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](101,null,["",""])),(l()(),t["\u0275eld"](102,0,null,0,4,"tab",[["heading","Snapshots"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](103,212992,null,0,r.b,[r.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](104,0,null,null,2,"cd-rbd-snapshot-list",[],null,null,null,L,A)),t["\u0275prd"](131584,null,f.a,f.a,[g.a,h.a]),t["\u0275did"](106,638976,null,0,O,[D.a,q.b,F.a,E.a,y.a,T.a,V.a,h.a,f.a,M.a,w.b],{snapshots:[0,"snapshots"],poolName:[1,"poolName"],rbdName:[2,"rbdName"]},null),(l()(),t["\u0275eld"](107,0,null,0,3,"tab",[["heading","Configuration"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](108,212992,null,0,r.b,[r.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](109,0,null,null,1,"cd-rbd-configuration-table",[],null,null,null,z.b,z.a)),t["\u0275did"](110,638976,null,0,W.a,[$.a,X.a,M.a],{data:[0,"data"]},null)],function(l,n){var e=n.component;l(n,3,0,"Details"),l(n,51,0,e.selectedItem.features_name),l(n,57,0,-1===(null==e.selectedItem.features_name?null:e.selectedItem.features_name.indexOf("fast-diff"))),l(n,59,0,-1!==(null==e.selectedItem.features_name?null:e.selectedItem.features_name.indexOf("fast-diff"))),l(n,65,0,-1===(null==e.selectedItem.features_name?null:e.selectedItem.features_name.indexOf("fast-diff"))),l(n,67,0,-1!==(null==e.selectedItem.features_name?null:e.selectedItem.features_name.indexOf("fast-diff"))),l(n,84,0,e.selectedItem.parent),l(n,86,0,!e.selectedItem.parent),l(n,103,0,"Snapshots"),l(n,106,0,e.selectedItem.snapshots,e.selectedItem.pool_name,e.selectedItem.name),l(n,108,0,"Configuration"),l(n,110,0,e.selectedItem.configuration)},function(l,n){var e=n.component;l(n,0,0,t["\u0275nov"](n,1).clazz),l(n,2,0,t["\u0275nov"](n,3).id,t["\u0275nov"](n,3).active,t["\u0275nov"](n,3).addClass),l(n,10,0,e.selectedItem.name),l(n,15,0,e.selectedItem.pool_name);var u=t["\u0275unv"](n,20,0,l(n,21,0,t["\u0275nov"](n.parent,0),e.selectedItem.data_pool));l(n,20,0,u);var i=t["\u0275unv"](n,26,0,l(n,27,0,t["\u0275nov"](n.parent,1),e.selectedItem.timestamp));l(n,26,0,i);var o=t["\u0275unv"](n,32,0,l(n,33,0,t["\u0275nov"](n.parent,2),e.selectedItem.size));l(n,32,0,o);var a=t["\u0275unv"](n,38,0,l(n,39,0,t["\u0275nov"](n.parent,3),e.selectedItem.num_objs));l(n,38,0,a);var r=t["\u0275unv"](n,44,0,l(n,45,0,t["\u0275nov"](n.parent,2),e.selectedItem.obj_size));l(n,44,0,r);var s=t["\u0275unv"](n,72,0,l(n,73,0,t["\u0275nov"](n.parent,2),e.selectedItem.stripe_unit));l(n,72,0,s),l(n,78,0,e.selectedItem.stripe_count),l(n,91,0,e.selectedItem.block_name_prefix),l(n,96,0,e.selectedItem.order),l(n,101,0,e.selection.image_format),l(n,102,0,t["\u0275nov"](n,103).id,t["\u0275nov"](n,103).active,t["\u0275nov"](n,103).addClass),l(n,107,0,t["\u0275nov"](n,108).id,t["\u0275nov"](n,108).active,t["\u0275nov"](n,108).addClass)})}function al(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](1,16777216,null,null,2,"strong",[["tooltip","This setting overrides the global value"]],[[1,"aria-describedby",0]],null,null,null,null)),t["\u0275did"](2,212992,null,0,u.c,[t.ViewContainerRef,i.a,u.a,t.ElementRef,t.Renderer2,o.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275ted"](-1,null,["Image"])),(l()(),t["\u0275and"](0,null,null,0))],function(l,n){l(n,2,0,"This setting overrides the global value")},function(l,n){l(n,1,0,t["\u0275nov"](n,2).ariaDescribedby)})}function rl(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,16777216,null,null,2,"span",[["tooltip","This is the global value. No value for this option has been set for this image."]],[[1,"aria-describedby",0]],null,null,null,null)),t["\u0275did"](1,212992,null,0,u.c,[t.ViewContainerRef,i.a,u.a,t.ElementRef,t.Renderer2,o.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275ted"](-1,null,["Global"])),(l()(),t["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,"This is the global value. No value for this option has been set for this image.")},function(l,n){l(n,0,0,t["\u0275nov"](n,1).ariaDescribedby)})}function sl(l){return t["\u0275vid"](0,[(l()(),t["\u0275and"](16777216,null,null,1,null,al)),t["\u0275did"](1,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),t["\u0275and"](0,[["global",2]],null,0,null,rl))],function(l,n){l(n,1,0,n.context.value-0,t["\u0275nov"](n,2))},null)}function dl(l){return t["\u0275vid"](0,[t["\u0275pid"](0,Y.a,[]),t["\u0275pid"](0,E.a,[s.DatePipe]),t["\u0275pid"](0,F.a,[$.a]),t["\u0275pid"](0,K.a,[$.a]),t["\u0275qud"](402653184,1,{poolConfigurationSourceTpl:0}),(l()(),t["\u0275and"](0,[["usageNotAvailableTooltipTpl",2]],null,0,null,Q)),(l()(),t["\u0275and"](16777216,null,null,1,null,ol)),t["\u0275did"](7,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](0,[[1,2],["poolConfigurationSourceTpl",2]],null,0,null,sl))],function(l,n){var e=n.component;l(n,7,0,null==e.selection?null:e.selection.hasSingleSelection)},null)}function cl(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rbd-details",[],null,null,null,dl,Z)),t["\u0275did"](1,573440,null,0,J.a,[],null,null)],null,null)}var pl=t["\u0275ccf"]("cd-rbd-details",J.a,cl,{selection:"selection",images:"images"},{},[])},L4us:function(l,n,e){"use strict";var t=e("gIcY"),u=(e("XED3"),e("QFaf")),i=e("kvvV"),o=(e("kn/O"),function(){return function(){}}());e.d(n,"a",function(){return a});var a=function(){function l(l,n,e){this.modalRef=l,this.rbdMirroringService=n,this.taskWrapper=e,this.bsConfig={containerClass:"theme-default"},this.createForm()}return l.prototype.createForm=function(){this.editPeerForm=new u.a({clusterName:new t.i("",{validators:[t.A.required,this.validateClusterName]}),clientID:new t.i("",{validators:[t.A.required,this.validateClientID]}),monAddr:new t.i("",{validators:[this.validateMonAddr]}),key:new t.i("",{validators:[this.validateKey]})})},l.prototype.ngOnInit=function(){var l=this;this.pattern=this.poolName+"/"+this.peerUUID,"edit"===this.mode&&this.rbdMirroringService.getPeer(this.poolName,this.peerUUID).subscribe(function(n){l.setResponse(n)})},l.prototype.validateClusterName=function(l){if(!l.value.match(/^[\w\-_]*$/))return{invalidClusterName:{value:l.value}}},l.prototype.validateClientID=function(l){if(!l.value.match(/^(?!client\.)[\w\-_.]*$/))return{invalidClientID:{value:l.value}}},l.prototype.validateMonAddr=function(l){if(!l.value.match(/^[,; ]*([\w.\-_\[\]]+(:[\d]+)?[,; ]*)*$/))return{invalidMonAddr:{value:l.value}}},l.prototype.validateKey=function(l){try{if(""===l.value||atob(l.value))return null}catch(n){}return{invalidKey:{value:l.value}}},l.prototype.setResponse=function(l){this.response=l,this.editPeerForm.get("clusterName").setValue(l.cluster_name),this.editPeerForm.get("clientID").setValue(l.client_id),this.editPeerForm.get("monAddr").setValue(l.mon_host),this.editPeerForm.get("key").setValue(l.key)},l.prototype.update=function(){var l=this,n=new o;n.cluster_name=this.editPeerForm.getValue("clusterName"),n.client_id=this.editPeerForm.getValue("clientID"),n.mon_host=this.editPeerForm.getValue("monAddr"),n.key=this.editPeerForm.getValue("key"),this.taskWrapper.wrapTaskAroundCall("edit"===this.mode?{task:new i.a("rbd/mirroring/peer/edit",{pool_name:this.poolName}),call:this.rbdMirroringService.updatePeer(this.poolName,this.peerUUID,n)}:{task:new i.a("rbd/mirroring/peer/add",{pool_name:this.poolName}),call:this.rbdMirroringService.addPeer(this.poolName,n)}).subscribe(void 0,function(){return l.editPeerForm.setErrors({cdSubmitButton:!0})},function(){l.rbdMirroringService.refresh(),l.modalRef.hide()})},l}()},MyVl:function(l,n,e){"use strict";var t,u=e("CcnG"),i=e("gIcY"),o=e("LvDl"),a=e("svcd"),r=e("15JJ"),s=(e("Ekvf"),e("F83c"),e("sne2"),e("QFaf")),d=e("PhyI"),c=e("kvvV"),p=(e("Fgil"),e("aexS"),e("aXbf"),e("kn/O"),e("u0yg")),m=function(){return function(){this.features=[]}}(),f=function(){return function(){this.features=[]}}(),g=e("mrSG"),h=function(l){function n(){var n=null!==l&&l.apply(this,arguments)||this;return n.features=[],n}return g.__extends(n,l),n}(function(){return function(){}}()),v=function(){return function(){this.features=[]}}();!function(l){l.editing="editing",l.cloning="cloning",l.copying="copying"}(t||(t={})),e.d(n,"a",function(){return b});var b=function(){function l(l,n,e,i,o,r,s,d,c,p){this.authStorageService=l,this.route=n,this.poolService=e,this.rbdService=i,this.formatter=o,this.taskWrapper=r,this.dimlessBinaryPipe=s,this.i18n=d,this.actionLabels=c,this.router=p,this.pools=null,this.allPools=null,this.dataPools=null,this.allDataPools=null,this.featuresList=[],this.initializeConfigData=new u.EventEmitter,this.advancedEnabled=!1,this.rbdFormMode=t,this.defaultObjectSize="4 MiB",this.objectSizes=["4 KiB","8 KiB","16 KiB","32 KiB","64 KiB","128 KiB","256 KiB","512 KiB","1 MiB","2 MiB","4 MiB","8 MiB","16 MiB","32 MiB"],this.rbdImage=new a.a,this.poolPermission=this.authStorageService.getPermissions().pool,this.resource=this.i18n("RBD"),this.features={"deep-flatten":{desc:this.i18n("Deep flatten"),requires:null,allowEnable:!1,allowDisable:!0},layering:{desc:this.i18n("Layering"),requires:null,allowEnable:!1,allowDisable:!1},"exclusive-lock":{desc:this.i18n("Exclusive lock"),requires:null,allowEnable:!0,allowDisable:!0},"object-map":{desc:this.i18n("Object map (requires exclusive-lock)"),requires:"exclusive-lock",allowEnable:!0,allowDisable:!0,initDisabled:!0},journaling:{desc:this.i18n("Journaling (requires exclusive-lock)"),requires:"exclusive-lock",allowEnable:!0,allowDisable:!0,initDisabled:!0},"fast-diff":{desc:this.i18n("Fast diff (interlocked with object-map)"),requires:"object-map",allowEnable:!0,allowDisable:!0,interlockedWith:"object-map",initDisabled:!0}},this.featuresList=this.objToArray(this.features),this.createForm()}return l.prototype.objToArray=function(l){return o.map(l,function(l,n){return Object.assign(l,{key:n})})},l.prototype.createForm=function(){this.rbdForm=new s.a({parent:new i.i(""),name:new i.i("",{validators:[i.A.required,i.A.pattern(/^[^@\/]+?$/)]}),pool:new i.i(null,{validators:[i.A.required]}),useDataPool:new i.i(!1),dataPool:new i.i(null),size:new i.i(null,{updateOn:"blur"}),obj_size:new i.i(this.defaultObjectSize),features:new s.a(this.featuresList.reduce(function(l,n){return l[n.key]=new i.i({value:!1,disabled:!!n.initDisabled}),l},{})),stripingUnit:new i.i(null),stripingCount:new i.i(null,{updateOn:"blur"})},this.validateRbdForm(this.formatter))},l.prototype.disableForEdit=function(){var l=this;this.rbdForm.get("parent").disable(),this.rbdForm.get("pool").disable(),this.rbdForm.get("useDataPool").disable(),this.rbdForm.get("dataPool").disable(),this.rbdForm.get("obj_size").disable(),this.rbdForm.get("stripingUnit").disable(),this.rbdForm.get("stripingCount").disable(),this.rbdImage.subscribe(function(n){n.image_format===p.a.V1&&(l.rbdForm.get("deep-flatten").disable(),l.rbdForm.get("layering").disable(),l.rbdForm.get("exclusive-lock").disable())})},l.prototype.disableForClone=function(){this.rbdForm.get("parent").disable(),this.rbdForm.get("size").disable()},l.prototype.disableForCopy=function(){this.rbdForm.get("parent").disable(),this.rbdForm.get("size").disable()},l.prototype.ngOnInit=function(){var l=this;this.router.url.startsWith("/block/rbd/edit")?(this.mode=this.rbdFormMode.editing,this.action=this.actionLabels.EDIT,this.disableForEdit()):this.router.url.startsWith("/block/rbd/clone")?(this.mode=this.rbdFormMode.cloning,this.disableForClone(),this.action=this.actionLabels.CLONE):this.router.url.startsWith("/block/rbd/copy")?(this.mode=this.rbdFormMode.copying,this.action=this.actionLabels.COPY,this.disableForCopy()):this.action=this.actionLabels.CREATE,this.mode===this.rbdFormMode.editing||this.mode===this.rbdFormMode.cloning||this.mode===this.rbdFormMode.copying?this.route.params.subscribe(function(n){var e=decodeURIComponent(n.pool),t=decodeURIComponent(n.name);n.snap&&(l.snapName=decodeURIComponent(n.snap)),l.rbdService.get(e,t).subscribe(function(n){l.setResponse(n,l.snapName),l.rbdImage.next(n)})}):this.rbdService.defaultFeatures().subscribe(function(n){l.setFeatures(n)}),this.mode!==this.rbdFormMode.editing&&this.poolPermission.read&&this.poolService.list(["pool_name","type","flags_names","application_metadata"]).then(function(n){for(var e=[],t=[],u=0,i=n;ul.toBytes(o.value)&&(c={invalidSizeObject:!0}),o.setErrors(c);var p=e.get("stripingUnit"),m=null;null===p.value&&null!==s.value?m={required:!0}:null!==p.value&&l.toBytes(p.value)>r&&(m={invalidStripingUnit:!0}),p.setErrors(m);var f=null;return null===s.value&&null!==p.value?f={required:!0}:d<1&&(f={min:!0}),s.setErrors(f),null}},l.prototype.getDependendChildFeatures=function(l){return o.filter(this.features,function(n){return n.requires===l})||[]},l.prototype.deepBoxCheck=function(l,n){var e=this;this.getDependendChildFeatures(l).forEach(function(l){var t=e.rbdForm.get(l.key);n?t.enable({emitEvent:!1}):(t.disable({emitEvent:!1}),t.setValue(!1,{emitEvent:!1}),e.deepBoxCheck(l.key,n));var u=e.rbdForm.get("features");e.mode===e.rbdFormMode.editing&&u.get(l.key).enabled&&((-1===e.response.features_name.indexOf(l.key)||l.allowDisable)&&(-1!==e.response.features_name.indexOf(l.key)||l.allowEnable)||u.get(l.key).disable())})},l.prototype.interlockCheck=function(l,n){var e=this,t=this.featuresList.find(function(n){return n.key===l});if(this.response){var u=null!=t.interlockedWith,i=this.featuresList.find(function(l){return l.interlockedWith===t.key}),a=!!this.response.features_name.find(function(l){return l===t.key});if(u){if(a!==!!this.response.features_name.find(function(l){return l===t.interlockedWith}))return}else if(i&&!!this.response.features_name.find(function(l){return l===i.key})!==a)return}n?o.filter(this.features,function(n){return n.interlockedWith===l}).forEach(function(l){return e.rbdForm.get(l.key).setValue(!0,{emitEvent:!1})}):t.interlockedWith&&this.rbdForm.get("features").get(t.interlockedWith).setValue(!1)},l.prototype.featureFormUpdate=function(l,n){if(n){var e=this.features[l].requires;if(e&&!this.rbdForm.getValue(e))return void this.rbdForm.get("features."+l).setValue(!1)}this.deepBoxCheck(l,n),this.interlockCheck(l,n)},l.prototype.setFeatures=function(l){var n=this,e=this.rbdForm.get("features");o.forIn(this.features,function(t){-1!==l.indexOf(t.key)&&e.get(t.key).setValue(!0),n.featureFormUpdate(t.key,e.get(t.key).value)})},l.prototype.setResponse=function(l,n){if(this.response=l,this.mode===this.rbdFormMode.cloning)this.rbdForm.get("parent").setValue(l.pool_name+"/"+l.name+"@"+n);else if(this.mode===this.rbdFormMode.copying)n?this.rbdForm.get("parent").setValue(l.pool_name+"/"+l.name+"@"+n):this.rbdForm.get("parent").setValue(l.pool_name+"/"+l.name);else if(l.parent){var e=l.parent;this.rbdForm.get("parent").setValue(e.pool_name+"/"+e.image_name+"@"+e.snap_name)}this.mode===this.rbdFormMode.editing&&this.rbdForm.get("name").setValue(l.name),this.rbdForm.get("pool").setValue(l.pool_name),l.data_pool&&(this.rbdForm.get("useDataPool").setValue(!0),this.rbdForm.get("dataPool").setValue(l.data_pool)),this.rbdForm.get("size").setValue(this.dimlessBinaryPipe.transform(l.size)),this.rbdForm.get("obj_size").setValue(this.dimlessBinaryPipe.transform(l.obj_size)),this.setFeatures(l.features_name),this.rbdForm.get("stripingUnit").setValue(this.dimlessBinaryPipe.transform(l.stripe_unit)),this.rbdForm.get("stripingCount").setValue(l.stripe_count),this.initializeConfigData.emit({initialData:this.response.configuration,sourceType:d.a.image})},l.prototype.createRequest=function(){var l=this,n=new h;return n.pool_name=this.rbdForm.getValue("pool"),n.name=this.rbdForm.getValue("name"),n.size=this.formatter.toBytes(this.rbdForm.getValue("size")),n.obj_size=this.formatter.toBytes(this.rbdForm.getValue("obj_size")),o.forIn(this.features,function(e){l.rbdForm.getValue(e.key)&&n.features.push(e.key)}),n.stripe_unit=this.formatter.toBytes(this.rbdForm.getValue("stripingUnit")),n.stripe_count=this.rbdForm.getValue("stripingCount"),n.data_pool=this.rbdForm.getValue("dataPool"),n.configuration=this.getDirtyConfigurationValues(),n},l.prototype.createAction=function(){var l=this.createRequest();return this.taskWrapper.wrapTaskAroundCall({task:new c.a("rbd/create",{pool_name:l.pool_name,image_name:l.name}),call:this.rbdService.create(l)})},l.prototype.editRequest=function(){var l=this,n=new v;return n.name=this.rbdForm.getValue("name"),n.size=this.formatter.toBytes(this.rbdForm.getValue("size")),o.forIn(this.features,function(e){l.rbdForm.getValue(e.key)&&n.features.push(e.key)}),n.configuration=this.getDirtyConfigurationValues(),n},l.prototype.cloneRequest=function(){var l=this,n=new m;return n.child_pool_name=this.rbdForm.getValue("pool"),n.child_image_name=this.rbdForm.getValue("name"),n.obj_size=this.formatter.toBytes(this.rbdForm.getValue("obj_size")),o.forIn(this.features,function(e){l.rbdForm.getValue(e.key)&&n.features.push(e.key)}),n.stripe_unit=this.formatter.toBytes(this.rbdForm.getValue("stripingUnit")),n.stripe_count=this.rbdForm.getValue("stripingCount"),n.data_pool=this.rbdForm.getValue("dataPool"),n.configuration=this.getDirtyConfigurationValues(!0,d.a.image),n},l.prototype.editAction=function(){return this.taskWrapper.wrapTaskAroundCall({task:new c.a("rbd/edit",{pool_name:this.response.pool_name,image_name:this.response.name}),call:this.rbdService.update(this.response.pool_name,this.response.name,this.editRequest())})},l.prototype.cloneAction=function(){var l=this.cloneRequest();return this.taskWrapper.wrapTaskAroundCall({task:new c.a("rbd/clone",{parent_pool_name:this.response.pool_name,parent_image_name:this.response.name,parent_snap_name:this.snapName,child_pool_name:l.child_pool_name,child_image_name:l.child_image_name}),call:this.rbdService.cloneSnapshot(this.response.pool_name,this.response.name,this.snapName,l)})},l.prototype.copyRequest=function(){var l=this,n=new f;return this.snapName&&(n.snapshot_name=this.snapName),n.dest_pool_name=this.rbdForm.getValue("pool"),n.dest_image_name=this.rbdForm.getValue("name"),n.obj_size=this.formatter.toBytes(this.rbdForm.getValue("obj_size")),o.forIn(this.features,function(e){l.rbdForm.getValue(e.key)&&n.features.push(e.key)}),n.stripe_unit=this.formatter.toBytes(this.rbdForm.getValue("stripingUnit")),n.stripe_count=this.rbdForm.getValue("stripingCount"),n.data_pool=this.rbdForm.getValue("dataPool"),n.configuration=this.getDirtyConfigurationValues(!0,d.a.image),n},l.prototype.copyAction=function(){var l=this.copyRequest();return this.taskWrapper.wrapTaskAroundCall({task:new c.a("rbd/copy",{src_pool_name:this.response.pool_name,src_image_name:this.response.name,dest_pool_name:l.dest_pool_name,dest_image_name:l.dest_image_name}),call:this.rbdService.copy(this.response.pool_name,this.response.name,l)})},l.prototype.submit=function(){var l=this;this.mode||this.rbdImage.next("create"),this.rbdImage.complete(),this.rbdImage.pipe(Object(r.a)(function(){return l.mode===l.rbdFormMode.editing?l.editAction():l.mode===l.rbdFormMode.cloning?l.cloneAction():l.mode===l.rbdFormMode.copying?l.copyAction():l.createAction()})).subscribe(function(){},function(){return l.rbdForm.setErrors({cdSubmitButton:!0})},function(){return l.router.navigate(["/block/rbd"])})},l}()},OcYo:function(l,n,e){"use strict";e.d(n,"a",function(){return t});var t=function(){function l(l,n,e){this.elementRef=l,this.renderer=n,this.toastr=e}return l.prototype.ngOnInit=function(){var l=this.renderer.createElement("i");this.renderer.addClass(l,"icon-prepend"),this.renderer.addClass(l,"fa"),this.renderer.addClass(l,"fa-clipboard"),this.renderer.appendChild(this.elementRef.nativeElement,l)},l.prototype.getInputElement=function(){return document.getElementById(this.cdCopy2ClipboardButton)},l.prototype.onClick=function(){try{var l=document.createElement("input");l.value=this.getInputElement().value,document.body.appendChild(l),l.select(),document.execCommand("copy"),document.body.removeChild(l),this.toastr.success("Copied text to the clipboard successfully.")}catch(n){this.toastr.error("Failed to copy text to the clipboard.")}},l}()},PhyI:function(l,n,e){"use strict";e.d(n,"a",function(){return t}),e.d(n,"b",function(){return u});var t=function(l){return l[l.global=0]="global",l[l.pool=1]="pool",l[l.image=2]="image",l}({}),u=function(l){return l[l.bps=0]="bps",l[l.iops=1]="iops",l[l.milliseconds=2]="milliseconds",l}({})},RIVN:function(l,n,e){"use strict";var t=e("CcnG"),u=e("C6Ij"),i=e("AWcq"),o=e("Ip0R"),a=function(){function l(){}return l.prototype.transform=function(l){return"warning"===l?"label label-warning":"error"===l?"label label-danger":"success"===l?"label label-success":"label label-info"},l}(),r=e("25BL"),s=e("uIqm"),d=e("XED3"),c=e("85J/"),p=function(){function l(l,n,e){this.rbdMirroringService=l,this.cephShortVersionPipe=n,this.i18n=e}return l.prototype.ngOnInit=function(){var l=this;this.columns=[{prop:"instance_id",name:this.i18n("Instance"),flexGrow:2},{prop:"id",name:this.i18n("ID"),flexGrow:2},{prop:"server_hostname",name:this.i18n("Hostname"),flexGrow:2},{prop:"version",name:this.i18n("Version"),pipe:this.cephShortVersionPipe,flexGrow:2},{prop:"health",name:this.i18n("Health"),cellTemplate:this.healthTmpl,flexGrow:1}],this.subs=this.rbdMirroringService.subscribeSummary(function(n){n&&(l.data=n.content_data.daemons)})},l.prototype.ngOnDestroy=function(){this.subs.unsubscribe()},l.prototype.refresh=function(){this.rbdMirroringService.refresh()},l}(),m=e("Jm/i"),f=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function g(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,o.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{ngClass:[0,"ngClass"]},null),t["\u0275ppd"](2,1),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){var e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent,0),n.context.row.health_color));l(n,1,0,e)},function(l,n){l(n,3,0,n.context.value)})}function h(l){return t["\u0275vid"](0,[t["\u0275pid"](0,a,[]),t["\u0275qud"](402653184,1,{healthTmpl:0}),(l()(),t["\u0275eld"](2,0,null,null,1,"cd-table",[["columnMode","flex"]],null,[[null,"fetchData"]],function(l,n,e){var t=!0;return"fetchData"===n&&(t=!1!==l.component.refresh()&&t),t},r.b,r.a)),t["\u0275did"](3,2867200,null,0,s.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoReload:[3,"autoReload"]},{fetchData:"fetchData"}),(l()(),t["\u0275and"](0,[[1,2],["healthTmpl",2]],null,0,null,g))],function(l,n){var e=n.component;l(n,3,0,e.data,e.columns,"flex",0)},null)}var v=e("NUGo"),b=e("S7zO"),y=e("6blF"),C=e("0+/T"),_=e("vCyI"),w=e("kvvV"),R=e("aexS"),I=e("kn/O"),S=e("aa9H"),k=e("L4us"),E=function(){function l(l,n,e,t,u){var i=this;this.authStorageService=l,this.rbdMirroringService=n,this.modalService=e,this.taskWrapper=t,this.i18n=u,this.selection=new _.a,this.data=[],this.permission=this.authStorageService.getPermissions().rbdMirroring;var o={permission:"update",icon:"fa-edit",click:function(){return i.editModeModal()},name:this.i18n("Edit Mode"),canBePrimary:function(){return!0}},a={permission:"create",icon:"fa-plus",name:this.i18n("Add Peer"),click:function(){return i.editPeersModal("add")},disable:function(){return!i.selection.first()||"disabled"===i.selection.first().mirror_mode},visible:function(){return!i.getPeerUUID()},canBePrimary:function(){return!1}},r={permission:"update",icon:"fa-exchange",name:this.i18n("Edit Peer"),click:function(){return i.editPeersModal("edit")},visible:function(){return!!i.getPeerUUID()}},s={permission:"delete",icon:"fa-times",name:this.i18n("Delete Peer"),click:function(){return i.deletePeersModal()},visible:function(){return!!i.getPeerUUID()}};this.tableActions=[o,a,r,s]}return l.prototype.ngOnInit=function(){var l=this;this.columns=[{prop:"name",name:this.i18n("Name"),flexGrow:2},{prop:"mirror_mode",name:this.i18n("Mode"),flexGrow:2},{prop:"leader_id",name:this.i18n("Leader"),flexGrow:2},{prop:"image_local_count",name:this.i18n("# Local"),flexGrow:2},{prop:"image_remote_count",name:this.i18n("# Remote"),flexGrow:2},{prop:"health",name:this.i18n("Health"),cellTemplate:this.healthTmpl,flexGrow:1}],this.subs=this.rbdMirroringService.subscribeSummary(function(n){n&&(l.data=n.content_data.pools)})},l.prototype.ngOnDestroy=function(){this.subs.unsubscribe()},l.prototype.refresh=function(){this.rbdMirroringService.refresh()},l.prototype.editModeModal=function(){var l={poolName:this.selection.first().name};this.modalRef=this.modalService.show(S.a,{initialState:l})},l.prototype.editPeersModal=function(l){var n={poolName:this.selection.first().name,mode:l};"edit"===l&&(n.peerUUID=this.getPeerUUID()),this.modalRef=this.modalService.show(k.a,{initialState:n})},l.prototype.deletePeersModal=function(){var l=this,n=this.selection.first().name,e=this.getPeerUUID();this.modalRef=this.modalService.show(C.a,{initialState:{itemDescription:this.i18n("mirror peer"),itemNames:[n+" ("+e+")"],submitActionObservable:function(){return new y.a(function(t){l.taskWrapper.wrapTaskAroundCall({task:new w.a("rbd/mirroring/peer/delete",{pool_name:n}),call:l.rbdMirroringService.deletePeer(n,e)}).subscribe(void 0,function(l){return t.error(l)},function(){l.rbdMirroringService.refresh(),t.complete()})})}}})},l.prototype.getPeerUUID=function(){var l=this.selection.first(),n=this.data.find(function(n){return l&&l.name===n.name});if(n&&n.peer_uuids)return n.peer_uuids[0]},l.prototype.updateSelection=function(l){this.selection=l},l}(),F=e("DQlY"),D=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function V(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,o.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{ngClass:[0,"ngClass"]},null),t["\u0275ppd"](2,1),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){var e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent,0),n.context.row.health_color));l(n,1,0,e)},function(l,n){l(n,3,0,n.context.value)})}function T(l){return t["\u0275vid"](0,[t["\u0275pid"](0,a,[]),t["\u0275qud"](402653184,1,{healthTmpl:0}),(l()(),t["\u0275eld"](2,0,null,null,3,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["identifier","name"],["selectionType","single"]],null,[[null,"fetchData"],[null,"updateSelection"]],function(l,n,e){var t=!0,u=l.component;return"fetchData"===n&&(t=!1!==u.refresh()&&t),"updateSelection"===n&&(t=!1!==u.updateSelection(e)&&t),t},r.b,r.a)),t["\u0275did"](3,2867200,null,0,s.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoReload:[3,"autoReload"],identifier:[4,"identifier"],forceIdentifier:[5,"forceIdentifier"],selectionType:[6,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(l()(),t["\u0275eld"](4,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,v.b,v.a)),t["\u0275did"](5,114688,null,0,b.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),t["\u0275and"](0,[[1,2],["healthTmpl",2]],null,0,null,V))],function(l,n){var e=n.component;l(n,3,0,e.data,e.columns,"flex",0,"name","true","single"),l(n,5,0,e.permission,e.selection,e.tableActions)},null)}var N=e("Da1D"),P=t["\u0275crt"]({encapsulation:2,styles:[],data:{}});function x(l){return t["\u0275vid"](0,[t["\u0275ncd"](null,0)],null,null)}var O=t["\u0275crt"]({encapsulation:0,styles:["[_nghost-%COMP%] {\n width: 100%;\n display: flex;\n }"],data:{}});function q(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"bar",[["aria-valuemin","0"],["role","progressbar"]],[[8,"className",0],[2,"progress-bar-animated",null],[2,"progress-bar-striped",null],[2,"active",null],[1,"aria-valuenow",0],[1,"aria-valuetext",0],[1,"aria-valuemax",0],[4,"height","%"],[4,"width","%"]],null,null,x,P)),t["\u0275did"](1,245760,null,0,N.a,[N.b],{type:[0,"type"],value:[1,"value"]},null),t["\u0275ncd"](0,0)],function(l,n){var e=n.component;l(n,1,0,e.type,e._value)},function(l,n){l(n,0,0,"progress-bar "+(t["\u0275nov"](n,1).type?"progress-bar-"+t["\u0275nov"](n,1).type+" bg-"+t["\u0275nov"](n,1).type:""),!t["\u0275nov"](n,1).isBs3&&t["\u0275nov"](n,1).animate,t["\u0275nov"](n,1).striped,t["\u0275nov"](n,1).isBs3&&t["\u0275nov"](n,1).animate,t["\u0275nov"](n,1).value,t["\u0275nov"](n,1).percent?t["\u0275nov"](n,1).percent.toFixed(0)+"%":"",t["\u0275nov"](n,1).max,"100",t["\u0275nov"](n,1).setBarWidth)})}function M(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"bar",[["aria-valuemin","0"],["role","progressbar"]],[[8,"className",0],[2,"progress-bar-animated",null],[2,"progress-bar-striped",null],[2,"active",null],[1,"aria-valuenow",0],[1,"aria-valuetext",0],[1,"aria-valuemax",0],[4,"height","%"],[4,"width","%"]],null,null,x,P)),t["\u0275did"](1,245760,null,0,N.a,[N.b],{type:[0,"type"],value:[1,"value"]},null),(l()(),t["\u0275ted"](2,0,["",""]))],function(l,n){l(n,1,0,n.context.$implicit.type,n.context.$implicit.value)},function(l,n){l(n,0,0,"progress-bar "+(t["\u0275nov"](n,1).type?"progress-bar-"+t["\u0275nov"](n,1).type+" bg-"+t["\u0275nov"](n,1).type:""),!t["\u0275nov"](n,1).isBs3&&t["\u0275nov"](n,1).animate,t["\u0275nov"](n,1).striped,t["\u0275nov"](n,1).isBs3&&t["\u0275nov"](n,1).animate,t["\u0275nov"](n,1).value,t["\u0275nov"](n,1).percent?t["\u0275nov"](n,1).percent.toFixed(0)+"%":"",t["\u0275nov"](n,1).max,"100",t["\u0275nov"](n,1).setBarWidth),l(n,2,0,n.context.$implicit.label)})}function A(l){return t["\u0275vid"](0,[(l()(),t["\u0275and"](16777216,null,null,1,null,M)),t["\u0275did"](1,278528,null,0,o.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,n.component._value)},null)}function B(l){return t["\u0275vid"](0,[(l()(),t["\u0275and"](16777216,null,null,1,null,q)),t["\u0275did"](1,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,A)),t["\u0275did"](3,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,1,0,!e.isStacked),l(n,3,0,e.isStacked)},null)}var j=e("pKUh"),U=e("YAQW"),G=function(){function l(l,n){this.rbdMirroringService=l,this.i18n=n,this.image_error={data:[],columns:{}},this.image_syncing={data:[],columns:{}},this.image_ready={data:[],columns:{}}}return l.prototype.ngOnInit=function(){var l=this;this.image_error.columns=[{prop:"pool_name",name:this.i18n("Pool"),flexGrow:2},{prop:"name",name:this.i18n("Image"),flexGrow:2},{prop:"description",name:this.i18n("Issue"),flexGrow:4},{prop:"state",name:this.i18n("State"),cellTemplate:this.stateTmpl,flexGrow:1}],this.image_syncing.columns=[{prop:"pool_name",name:this.i18n("Pool"),flexGrow:2},{prop:"name",name:this.i18n("Image"),flexGrow:2},{prop:"progress",name:this.i18n("Progress"),cellTemplate:this.progressTmpl,flexGrow:2},{prop:"state",name:this.i18n("State"),cellTemplate:this.syncTmpl,flexGrow:1}],this.image_ready.columns=[{prop:"pool_name",name:this.i18n("Pool"),flexGrow:2},{prop:"name",name:this.i18n("Image"),flexGrow:2},{prop:"description",name:this.i18n("Description"),flexGrow:4},{prop:"state",name:this.i18n("State"),cellTemplate:this.stateTmpl,flexGrow:1}],this.subs=this.rbdMirroringService.subscribeSummary(function(n){n&&(l.image_error.data=n.content_data.image_error,l.image_syncing.data=n.content_data.image_syncing,l.image_ready.data=n.content_data.image_ready)})},l.prototype.ngOnDestroy=function(){this.subs.unsubscribe()},l.prototype.refresh=function(){this.rbdMirroringService.refresh()},l}(),L=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function z(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,o.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{ngClass:[0,"ngClass"]},null),t["\u0275ppd"](2,1),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){var e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent,0),n.context.row.state_color));l(n,1,0,e)},function(l,n){l(n,3,0,n.context.value)})}function W(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","label label-info"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Syncing"]))],null,null)}function $(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"progressbar",[["type","info"]],[[1,"max",0],[2,"progress",null]],null,null,B,O)),t["\u0275did"](1,49152,null,0,N.b,[N.c],{type:[0,"type"],value:[1,"value"]},null)],function(l,n){l(n,1,0,"info",n.context.value)},function(l,n){l(n,0,0,t["\u0275nov"](n,1).max,t["\u0275nov"](n,1).addClass)})}function X(l){return t["\u0275vid"](0,[t["\u0275pid"](0,a,[]),t["\u0275qud"](402653184,1,{stateTmpl:0}),t["\u0275qud"](402653184,2,{syncTmpl:0}),t["\u0275qud"](402653184,3,{progressTmpl:0}),(l()(),t["\u0275eld"](4,0,null,null,13,"tabset",[],[[2,"tab-container",null]],null,null,j.b,j.a)),t["\u0275did"](5,180224,null,0,U.d,[U.e,t.Renderer2,t.ElementRef],null,null),(l()(),t["\u0275eld"](6,0,null,0,3,"tab",[["heading","Issues"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](7,212992,null,0,U.b,[U.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](8,0,null,null,1,"cd-table",[["columnMode","flex"]],null,[[null,"fetchData"]],function(l,n,e){var t=!0;return"fetchData"===n&&(t=!1!==l.component.refresh()&&t),t},r.b,r.a)),t["\u0275did"](9,2867200,null,0,s.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoReload:[3,"autoReload"]},{fetchData:"fetchData"}),(l()(),t["\u0275eld"](10,0,null,0,3,"tab",[["heading","Syncing"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](11,212992,null,0,U.b,[U.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](12,0,null,null,1,"cd-table",[["columnMode","flex"]],null,[[null,"fetchData"]],function(l,n,e){var t=!0;return"fetchData"===n&&(t=!1!==l.component.refresh()&&t),t},r.b,r.a)),t["\u0275did"](13,2867200,null,0,s.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoReload:[3,"autoReload"]},{fetchData:"fetchData"}),(l()(),t["\u0275eld"](14,0,null,0,3,"tab",[["heading","Ready"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](15,212992,null,0,U.b,[U.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](16,0,null,null,1,"cd-table",[["columnMode","flex"]],null,[[null,"fetchData"]],function(l,n,e){var t=!0;return"fetchData"===n&&(t=!1!==l.component.refresh()&&t),t},r.b,r.a)),t["\u0275did"](17,2867200,null,0,s.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoReload:[3,"autoReload"]},{fetchData:"fetchData"}),(l()(),t["\u0275and"](0,[[1,2],["stateTmpl",2]],null,0,null,z)),(l()(),t["\u0275and"](0,[[2,2],["syncTmpl",2]],null,0,null,W)),(l()(),t["\u0275and"](0,[[3,2],["progressTmpl",2]],null,0,null,$))],function(l,n){var e=n.component;l(n,7,0,"Issues"),l(n,9,0,e.image_error.data,e.image_error.columns,"flex",0),l(n,11,0,"Syncing"),l(n,13,0,e.image_syncing.data,e.image_syncing.columns,"flex",0),l(n,15,0,"Ready"),l(n,17,0,e.image_ready.data,e.image_ready.columns,"flex",0)},function(l,n){l(n,4,0,t["\u0275nov"](n,5).clazz),l(n,6,0,t["\u0275nov"](n,7).id,t["\u0275nov"](n,7).active,t["\u0275nov"](n,7).addClass),l(n,10,0,t["\u0275nov"](n,11).id,t["\u0275nov"](n,11).active,t["\u0275nov"](n,11).addClass),l(n,14,0,t["\u0275nov"](n,15).id,t["\u0275nov"](n,15).active,t["\u0275nov"](n,15).addClass)})}var Y=e("cxJu");e.d(n,"a",function(){return Q});var K=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function J(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-view-cache",[],null,null,null,u.b,u.a)),t["\u0275did"](1,114688,null,0,i.a,[],{status:[0,"status"]},null),(l()(),t["\u0275eld"](2,0,null,null,10,"div",[["class","row"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,4,"div",[["class","col-sm-6"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Daemons"])),(l()(),t["\u0275eld"](6,0,null,null,1,"cd-mirroring-daemons",[],null,null,null,h,f)),t["\u0275did"](7,245760,null,0,p,[d.a,c.a,m.a],null,null),(l()(),t["\u0275eld"](8,0,null,null,4,"div",[["class","col-sm-6"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Pools"])),(l()(),t["\u0275eld"](11,0,null,null,1,"cd-mirroring-pools",[],null,null,null,T,D)),t["\u0275did"](12,245760,null,0,E,[R.a,d.a,F.b,I.a,m.a],null,null),(l()(),t["\u0275eld"](13,0,null,null,5,"div",[["class","row"]],null,null,null,null,null)),(l()(),t["\u0275eld"](14,0,null,null,4,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),t["\u0275eld"](15,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Images"])),(l()(),t["\u0275eld"](17,0,null,null,1,"cd-mirroring-images",[],null,null,null,X,L)),t["\u0275did"](18,245760,null,0,G,[d.a,m.a],null,null)],function(l,n){l(n,1,0,n.component.status),l(n,7,0),l(n,12,0),l(n,18,0)},null)}function Z(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-mirroring",[],null,null,null,J,K)),t["\u0275did"](1,245760,null,0,Y.a,[d.a],null,null)],function(l,n){l(n,1,0)},null)}var Q=t["\u0275ccf"]("cd-mirroring",Y.a,Z,{},{},[])},Sofw:function(l,n,e){"use strict";e.d(n,"a",function(){return a});var t=e("gIcY"),u=(e("my5R"),e("mtw6")),i=e("QFaf"),o=e("1Ni5"),a=(e("aexS"),e("9nlD"),function(){function l(l,n,e,t,u){this.authStorageService=l,this.bsModalRef=n,this.iscsiService=e,this.notificationService=t,this.i18n=u,this.USER_REGEX=/^[\w\.:@_-]{8,64}$/,this.PASSWORD_REGEX=/^[\w@\-_\/]{12,16}$/,this.permission=this.authStorageService.getPermissions().iscsi}return l.prototype.ngOnInit=function(){var l=this;this.hasPermission=this.permission.update,this.createForm(),this.iscsiService.getDiscovery().subscribe(function(n){l.discoveryForm.patchValue(n)})},l.prototype.createForm=function(){var l=this;this.discoveryForm=new i.a({user:new t.i({value:"",disabled:!this.hasPermission}),password:new t.i({value:"",disabled:!this.hasPermission}),mutual_user:new t.i({value:"",disabled:!this.hasPermission}),mutual_password:new t.i({value:"",disabled:!this.hasPermission})}),o.a.validateIf(this.discoveryForm.get("user"),function(){return l.discoveryForm.getValue("password")||l.discoveryForm.getValue("mutual_user")||l.discoveryForm.getValue("mutual_password")},[t.A.required],[t.A.pattern(this.USER_REGEX)],[this.discoveryForm.get("password"),this.discoveryForm.get("mutual_user"),this.discoveryForm.get("mutual_password")]),o.a.validateIf(this.discoveryForm.get("password"),function(){return l.discoveryForm.getValue("user")||l.discoveryForm.getValue("mutual_user")||l.discoveryForm.getValue("mutual_password")},[t.A.required],[t.A.pattern(this.PASSWORD_REGEX)],[this.discoveryForm.get("user"),this.discoveryForm.get("mutual_user"),this.discoveryForm.get("mutual_password")]),o.a.validateIf(this.discoveryForm.get("mutual_user"),function(){return l.discoveryForm.getValue("mutual_password")},[t.A.required],[t.A.pattern(this.USER_REGEX)],[this.discoveryForm.get("user"),this.discoveryForm.get("password"),this.discoveryForm.get("mutual_password")]),o.a.validateIf(this.discoveryForm.get("mutual_password"),function(){return l.discoveryForm.getValue("mutual_user")},[t.A.required],[t.A.pattern(this.PASSWORD_REGEX)],[this.discoveryForm.get("user"),this.discoveryForm.get("password"),this.discoveryForm.get("mutual_user")])},l.prototype.submitAction=function(){var l=this;this.iscsiService.updateDiscovery(this.discoveryForm.value).subscribe(function(){l.notificationService.show(u.a.success,l.i18n("Updated discovery authentication")),l.bsModalRef.hide()},function(){l.discoveryForm.setErrors({cdSubmitButton:!0})})},l}())},Ur3J:function(l,n,e){"use strict";var t=e("CcnG"),u=e("Ip0R"),i=e("8xTl"),o=e("gIcY"),a=e("IZUe"),r=e("ANnk"),s=e("f/UV"),d=e("aexS"),c=e("gp3X"),p=e("sb0X"),m=e("KVJa"),f=e("Z21x"),g=e("sne2"),h=e("+lcs"),v=e("DQlY"),b=e("F83c"),y=e("VXsX"),C=e("9nlD"),_=e("Jm/i");e.d(n,"a",function(){return k});var w=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function R(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function I(l){return t["\u0275vid"](0,[t["\u0275pid"](0,u.TitleCasePipe,[]),t["\u0275pid"](0,i.a,[]),(l()(),t["\u0275eld"](2,0,null,null,7,"div",[["class","modal-header"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,3,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),(l()(),t["\u0275ted"](4,null,[""," ",""])),t["\u0275ppd"](5,1),t["\u0275ppd"](6,1),(l()(),t["\u0275eld"](7,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(l,n,e){var t=!0;return"click"===n&&(t=!1!==l.component.modalRef.hide()&&t),t},null,null)),(l()(),t["\u0275eld"](8,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["\xd7"])),(l()(),t["\u0275eld"](10,0,null,null,32,"form",[["class","form-horizontal"],["name","snapshotForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,12).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,12).onReset()&&u),u},null,null)),t["\u0275did"](11,16384,null,0,o.D,[],null,null),t["\u0275did"](12,540672,[["formDir",4]],0,o.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,o.d,null,[o.l]),t["\u0275did"](14,16384,null,0,o.s,[[4,o.d]],null,null),(l()(),t["\u0275eld"](15,0,null,null,18,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](16,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](17,278528,null,0,u.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](18,{"has-error":0}),(l()(),t["\u0275eld"](19,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","snapshotName"]],null,null,null,null,null)),(l()(),t["\u0275eld"](20,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Name"])),(l()(),t["\u0275eld"](22,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](23,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](24,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","snapshotName"],["id","snapshotName"],["name","snapshotName"],["placeholder","Snapshot name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,25)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,25).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,25)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,25)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](25,16384,null,0,o.e,[t.Renderer2,t.ElementRef,[2,o.b]],null,null),t["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),t["\u0275did"](27,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,o.q,null,[o.j]),t["\u0275did"](29,16384,null,0,o.r,[[4,o.q]],null,null),t["\u0275did"](30,4210688,null,0,a.a,[t.ElementRef],null,null),t["\u0275did"](31,4210688,null,0,r.a,[[2,s.a],d.a,t.ElementRef],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,R)),t["\u0275did"](33,16384,null,0,u.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](34,0,null,null,8,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](35,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](36,0,null,null,4,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.submit()&&t),t},c.b,c.a)),t["\u0275did"](37,114688,null,0,p.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](38,0,[""," ",""])),t["\u0275ppd"](39,1),t["\u0275ppd"](40,1),(l()(),t["\u0275eld"](41,0,null,null,1,"cd-back-button",[["name","Close"]],null,null,null,m.b,m.a)),t["\u0275did"](42,49152,null,0,f.a,[u.Location,g.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,12,0,e.snapshotForm);var u=l(n,18,0,e.snapshotForm.showError("snapshotName",t["\u0275nov"](n,12)));l(n,17,0,"form-group",u),l(n,27,0,"snapshotName"),l(n,33,0,e.snapshotForm.showError("snapshotName",t["\u0275nov"](n,12),"required")),l(n,37,0,e.snapshotForm),l(n,42,0,"Close",e.modalRef.hide)},function(l,n){var e=n.component,u=t["\u0275unv"](n,4,0,l(n,5,0,t["\u0275nov"](n,0),e.action)),i=t["\u0275unv"](n,4,1,l(n,6,0,t["\u0275nov"](n,1),e.resource));l(n,4,0,u,i),l(n,10,0,t["\u0275nov"](n,14).ngClassUntouched,t["\u0275nov"](n,14).ngClassTouched,t["\u0275nov"](n,14).ngClassPristine,t["\u0275nov"](n,14).ngClassDirty,t["\u0275nov"](n,14).ngClassValid,t["\u0275nov"](n,14).ngClassInvalid,t["\u0275nov"](n,14).ngClassPending),l(n,24,0,t["\u0275nov"](n,29).ngClassUntouched,t["\u0275nov"](n,29).ngClassTouched,t["\u0275nov"](n,29).ngClassPristine,t["\u0275nov"](n,29).ngClassDirty,t["\u0275nov"](n,29).ngClassValid,t["\u0275nov"](n,29).ngClassInvalid,t["\u0275nov"](n,29).ngClassPending);var o=t["\u0275unv"](n,38,0,l(n,39,0,t["\u0275nov"](n,0),e.action)),a=t["\u0275unv"](n,38,1,l(n,40,0,t["\u0275nov"](n,1),e.resource));l(n,38,0,o,a)})}function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rbd-snapshot-form",[],null,null,null,I,w)),t["\u0275did"](1,114688,null,0,h.a,[v.a,b.a,y.a,C.a,_.a,g.b],null,null)],function(l,n){l(n,1,0)},null)}var k=t["\u0275ccf"]("cd-rbd-snapshot-form",h.a,S,{},{},[])},VBM6:function(l,n,e){"use strict";var t=e("CcnG"),u=e("EEJc"),i=e("ajRT"),o=e("Ip0R"),a=e("gIcY"),r=e("IZUe"),s=e("ANnk"),d=e("f/UV"),c=e("aexS"),p=e("gp3X"),m=e("sb0X"),f=e("KVJa"),g=e("Z21x"),h=e("sne2"),v=e("L4us"),b=e("DQlY"),y=e("XED3"),C=e("kn/O");e.d(n,"a",function(){return x});var _=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function w(l){return t["\u0275vid"](0,[(l()(),t["\u0275ted"](-1,null,["Edit"]))],null,null)}function R(l){return t["\u0275vid"](0,[(l()(),t["\u0275ted"](-1,null,["Add"]))],null,null)}function I(l){return t["\u0275vid"](0,[(l()(),t["\u0275ted"](-1,null,["Edit"]))],null,null)}function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275ted"](-1,null,["Add"]))],null,null)}function k(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function E(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The cluster name is not valid."]))],null,null)}function F(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function D(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The CephX ID is not valid."]))],null,null)}function V(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The monitory address is not valid."]))],null,null)}function T(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["CephX key must be base64 encoded."]))],null,null)}function N(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,105,"cd-modal",[],null,null,null,u.c,u.b)),t["\u0275did"](1,49152,null,0,i.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](2,0,null,0,7,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,5,null,null,null,null,null,null,null)),t["\u0275did"](4,16384,null,0,o.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,w)),t["\u0275did"](6,278528,null,0,o.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,o.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,R)),t["\u0275did"](8,16384,null,0,o.NgSwitchDefault,[t.ViewContainerRef,t.TemplateRef,o.NgSwitch],null,null),(l()(),t["\u0275ted"](-1,null,[" pool mirror peer"])),(l()(),t["\u0275eld"](10,0,null,1,95,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,94,"form",[["class","form"],["name","editPeerForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,13).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,13).onReset()&&u),u},null,null)),t["\u0275did"](12,16384,null,0,a.D,[],null,null),t["\u0275did"](13,540672,[["formDir",4]],0,a.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,a.d,null,[a.l]),t["\u0275did"](15,16384,null,0,a.s,[[4,a.d]],null,null),(l()(),t["\u0275eld"](16,0,null,null,82,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,14,"p",[],null,null,null,null,null)),(l()(),t["\u0275eld"](18,0,null,null,13,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](19,0,null,null,5,null,null,null,null,null,null,null)),t["\u0275did"](20,16384,null,0,o.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,I)),t["\u0275did"](22,278528,null,0,o.NgSwitchCase,[t.ViewContainerRef,t.TemplateRef,o.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,S)),t["\u0275did"](24,16384,null,0,o.NgSwitchDefault,[t.ViewContainerRef,t.TemplateRef,o.NgSwitch],null,null),(l()(),t["\u0275ted"](-1,null,[" the pool mirror peer attributes for pool "])),(l()(),t["\u0275eld"](26,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](27,null,["",""])),(l()(),t["\u0275ted"](-1,null,[" and click "])),(l()(),t["\u0275eld"](29,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Submit"])),(l()(),t["\u0275ted"](-1,null,["."])),(l()(),t["\u0275eld"](32,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](33,278528,null,0,o.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](34,{"has-error":0}),(l()(),t["\u0275eld"](35,0,null,null,3,"label",[["class","control-label"],["for","clusterName"]],null,null,null,null,null)),(l()(),t["\u0275eld"](36,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Cluster Name"])),(l()(),t["\u0275eld"](38,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](39,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","clusterName"],["id","clusterName"],["name","clusterName"],["placeholder","Name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,42)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,42).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,42)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,42)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](40,4210688,null,0,r.a,[t.ElementRef],null,null),t["\u0275did"](41,4210688,null,0,s.a,[[2,d.a],c.a,t.ElementRef],null,null),t["\u0275did"](42,16384,null,0,a.e,[t.Renderer2,t.ElementRef,[2,a.b]],null,null),t["\u0275prd"](1024,null,a.p,function(l){return[l]},[a.e]),t["\u0275did"](44,671744,null,0,a.j,[[3,a.d],[8,null],[8,null],[6,a.p],[2,a.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,a.q,null,[a.j]),t["\u0275did"](46,16384,null,0,a.r,[[4,a.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,k)),t["\u0275did"](48,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,E)),t["\u0275did"](50,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](51,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](52,278528,null,0,o.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](53,{"has-error":0}),(l()(),t["\u0275eld"](54,0,null,null,3,"label",[["class","control-label"],["for","clientID"]],null,null,null,null,null)),(l()(),t["\u0275eld"](55,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["CephX ID"])),(l()(),t["\u0275eld"](57,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](58,0,null,null,6,"input",[["class","form-control"],["formControlName","clientID"],["id","clientID"],["name","clientID"],["placeholder","CephX ID..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,60)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,60).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,60)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,60)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](59,4210688,null,0,s.a,[[2,d.a],c.a,t.ElementRef],null,null),t["\u0275did"](60,16384,null,0,a.e,[t.Renderer2,t.ElementRef,[2,a.b]],null,null),t["\u0275prd"](1024,null,a.p,function(l){return[l]},[a.e]),t["\u0275did"](62,671744,null,0,a.j,[[3,a.d],[8,null],[8,null],[6,a.p],[2,a.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,a.q,null,[a.j]),t["\u0275did"](64,16384,null,0,a.r,[[4,a.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,F)),t["\u0275did"](66,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,D)),t["\u0275did"](68,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](69,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](70,278528,null,0,o.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](71,{"has-error":0}),(l()(),t["\u0275eld"](72,0,null,null,2,"label",[["class","control-label"],["for","monAddr"]],null,null,null,null,null)),(l()(),t["\u0275eld"](73,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Monitor Addresses"])),(l()(),t["\u0275eld"](75,0,null,null,6,"input",[["class","form-control"],["formControlName","monAddr"],["id","monAddr"],["name","monAddr"],["placeholder","Comma-delimited addresses..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,77)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,77).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,77)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,77)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](76,4210688,null,0,s.a,[[2,d.a],c.a,t.ElementRef],null,null),t["\u0275did"](77,16384,null,0,a.e,[t.Renderer2,t.ElementRef,[2,a.b]],null,null),t["\u0275prd"](1024,null,a.p,function(l){return[l]},[a.e]),t["\u0275did"](79,671744,null,0,a.j,[[3,a.d],[8,null],[8,null],[6,a.p],[2,a.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,a.q,null,[a.j]),t["\u0275did"](81,16384,null,0,a.r,[[4,a.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,V)),t["\u0275did"](83,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](84,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](85,278528,null,0,o.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](86,{"has-error":0}),(l()(),t["\u0275eld"](87,0,null,null,2,"label",[["class","control-label"],["for","key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](88,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["CephX Key"])),(l()(),t["\u0275eld"](90,0,null,null,6,"input",[["class","form-control"],["formControlName","key"],["id","key"],["name","key"],["placeholder","Base64-encoded key..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,92)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,92).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,92)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,92)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](91,4210688,null,0,s.a,[[2,d.a],c.a,t.ElementRef],null,null),t["\u0275did"](92,16384,null,0,a.e,[t.Renderer2,t.ElementRef,[2,a.b]],null,null),t["\u0275prd"](1024,null,a.p,function(l){return[l]},[a.e]),t["\u0275did"](94,671744,null,0,a.j,[[3,a.d],[8,null],[8,null],[6,a.p],[2,a.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,a.q,null,[a.j]),t["\u0275did"](96,16384,null,0,a.r,[[4,a.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,T)),t["\u0275did"](98,16384,null,0,o.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](99,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](100,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](101,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.update()&&t),t},p.b,p.a)),t["\u0275did"](102,114688,null,0,m.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Submit"])),(l()(),t["\u0275eld"](104,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,f.b,f.a)),t["\u0275did"](105,49152,null,0,g.a,[o.Location,h.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,1,0,e.modalRef),l(n,4,0,e.mode),l(n,6,0,"edit"),l(n,13,0,e.editPeerForm),l(n,20,0,e.mode),l(n,22,0,"edit");var u=l(n,34,0,e.editPeerForm.showError("clusterName",t["\u0275nov"](n,13)));l(n,33,0,"form-group",u),l(n,44,0,"clusterName"),l(n,48,0,e.editPeerForm.showError("clusterName",t["\u0275nov"](n,13),"required")),l(n,50,0,e.editPeerForm.showError("clusterName",t["\u0275nov"](n,13),"invalidClusterName"));var i=l(n,53,0,e.editPeerForm.showError("clientID",t["\u0275nov"](n,13)));l(n,52,0,"form-group",i),l(n,62,0,"clientID"),l(n,66,0,e.editPeerForm.showError("clientID",t["\u0275nov"](n,13),"required")),l(n,68,0,e.editPeerForm.showError("clientID",t["\u0275nov"](n,13),"invalidClientID"));var o=l(n,71,0,e.editPeerForm.showError("monAddr",t["\u0275nov"](n,13)));l(n,70,0,"form-group",o),l(n,79,0,"monAddr"),l(n,83,0,e.editPeerForm.showError("monAddr",t["\u0275nov"](n,13),"invalidMonAddr"));var a=l(n,86,0,e.editPeerForm.showError("key",t["\u0275nov"](n,13)));l(n,85,0,"form-group",a),l(n,94,0,"key"),l(n,98,0,e.editPeerForm.showError("key",t["\u0275nov"](n,13),"invalidKey")),l(n,102,0,e.editPeerForm),l(n,105,0,"Cancel",e.modalRef.hide)},function(l,n){var e=n.component;l(n,11,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending),l(n,27,0,e.poolName),l(n,39,0,t["\u0275nov"](n,46).ngClassUntouched,t["\u0275nov"](n,46).ngClassTouched,t["\u0275nov"](n,46).ngClassPristine,t["\u0275nov"](n,46).ngClassDirty,t["\u0275nov"](n,46).ngClassValid,t["\u0275nov"](n,46).ngClassInvalid,t["\u0275nov"](n,46).ngClassPending),l(n,58,0,t["\u0275nov"](n,64).ngClassUntouched,t["\u0275nov"](n,64).ngClassTouched,t["\u0275nov"](n,64).ngClassPristine,t["\u0275nov"](n,64).ngClassDirty,t["\u0275nov"](n,64).ngClassValid,t["\u0275nov"](n,64).ngClassInvalid,t["\u0275nov"](n,64).ngClassPending),l(n,75,0,t["\u0275nov"](n,81).ngClassUntouched,t["\u0275nov"](n,81).ngClassTouched,t["\u0275nov"](n,81).ngClassPristine,t["\u0275nov"](n,81).ngClassDirty,t["\u0275nov"](n,81).ngClassValid,t["\u0275nov"](n,81).ngClassInvalid,t["\u0275nov"](n,81).ngClassPending),l(n,90,0,t["\u0275nov"](n,96).ngClassUntouched,t["\u0275nov"](n,96).ngClassTouched,t["\u0275nov"](n,96).ngClassPristine,t["\u0275nov"](n,96).ngClassDirty,t["\u0275nov"](n,96).ngClassValid,t["\u0275nov"](n,96).ngClassInvalid,t["\u0275nov"](n,96).ngClassPending)})}function P(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-pool-edit-peer-modal",[],null,null,null,N,_)),t["\u0275did"](1,114688,null,0,v.a,[b.a,y.a,C.a],null,null)],function(l,n){l(n,1,0)},null)}var x=t["\u0275ccf"]("cd-pool-edit-peer-modal",v.a,P,{},{},[])},WxU5:function(l,n,e){"use strict";e.d(n,"a",function(){return u}),e("Ekvf"),e("F83c"),e("2EZI");var t=e("kvvV"),u=(e("aexS"),e("kn/O"),function(){function l(l,n,e,t,u,i){this.authStorageService=l,this.rbdService=n,this.modalRef=e,this.fb=t,this.poolService=u,this.taskWrapper=i,this.poolPermission=this.authStorageService.getPermissions().pool}return l.prototype.createForm=function(){this.purgeForm=this.fb.group({poolName:""})},l.prototype.ngOnInit=function(){var l=this;this.poolPermission.read&&this.poolService.list(["pool_name","application_metadata"]).then(function(n){l.pools=n.filter(function(l){return l.application_metadata.includes("rbd")}).map(function(l){return l.pool_name})}),this.createForm()},l.prototype.purge=function(){var l=this,n=this.purgeForm.getValue("poolName")||"";this.taskWrapper.wrapTaskAroundCall({task:new t.a("rbd/trash/purge",{pool_name:n}),call:this.rbdService.purgeTrash(n)}).subscribe(void 0,function(){l.purgeForm.setErrors({cdSubmitButton:!0})},function(){l.modalRef.hide()})},l}())},XED3:function(l,n,e){"use strict";e.d(n,"a",function(){return a});var t=e("26FU"),u=e("CcnG"),i=e("t/Na"),o=e("pL04"),a=function(){function l(l,n){this.http=l,this.ngZone=n,this.summaryDataSource=new t.a(null),this.summaryData$=this.summaryDataSource.asObservable(),this.refreshAndSchedule()}return l.prototype.refresh=function(){var l=this;this.http.get("api/block/mirroring/summary").subscribe(function(n){l.summaryDataSource.next(n)})},l.prototype.refreshAndSchedule=function(){var l=this;this.refresh(),this.ngZone.runOutsideAngular(function(){setTimeout(function(){l.ngZone.run(function(){l.refreshAndSchedule()})},3e4)})},l.prototype.getCurrentSummary=function(){return this.summaryDataSource.getValue()},l.prototype.subscribeSummary=function(l,n){return this.summaryData$.subscribe(l,n)},l.prototype.getPool=function(l){return this.http.get("api/block/mirroring/pool/"+l)},l.prototype.updatePool=function(l,n){return this.http.put("api/block/mirroring/pool/"+l,n,{observe:"response"})},l.prototype.getPeer=function(l,n){return this.http.get("api/block/mirroring/pool/"+l+"/peer/"+n)},l.prototype.addPeer=function(l,n){return this.http.post("api/block/mirroring/pool/"+l+"/peer",n,{observe:"response"})},l.prototype.updatePeer=function(l,n,e){return this.http.put("api/block/mirroring/pool/"+l+"/peer/"+n,e,{observe:"response"})},l.prototype.deletePeer=function(l,n){return this.http.delete("api/block/mirroring/pool/"+l+"/peer/"+n,{observe:"response"})},l.ngInjectableDef=u.defineInjectable({factory:function(){return new l(u.inject(i.c),u.inject(u.NgZone))},token:l,providedIn:o.a}),l}()},Z4cD:function(l,n,e){"use strict";e.d(n,"a",function(){return a});var t=e("mrSG"),u=e("gIcY"),i=e("LvDl"),o=(e("my5R"),e("QFaf")),a=function(){function l(l,n){this.modalRef=l,this.iscsiService=n}return l.prototype.ngOnInit=function(){var l=this,n={backstore:new u.i(this.imagesSettings[this.image].backstore),lun:new u.i(this.imagesSettings[this.image].lun),wwn:new u.i(this.imagesSettings[this.image].wwn)};i.forEach(this.backstores,function(e){var t=l.imagesSettings[l.image][e]||{};i.forIn(l.disk_default_controls[e],function(l,e){n[e]=new u.i(t[e])})}),this.settingsForm=new o.a(n)},l.prototype.getDiskControlLimits=function(l,n){return this.disk_controls_limits?this.disk_controls_limits[l][n]:{type:"int"}},l.prototype.save=function(){var l=this,n=this.settingsForm.controls.backstore.value,e=this.settingsForm.controls.lun.value,u=this.settingsForm.controls.wwn.value,o={};i.forIn(this.settingsForm.controls,function(e,t){""!==e.value&&null!==e.value&&t in l.disk_default_controls[l.settingsForm.value.backstore]&&(o[t]=e.value,i.forEach(l.backstores,function(u){u!==n&&t in(l.imagesSettings[l.image][u]||{})&&(l.imagesSettings[l.image][u][t]=e.value)}))}),this.imagesSettings[this.image].backstore=n,this.imagesSettings[this.image].lun=e,this.imagesSettings[this.image].wwn=u,this.imagesSettings[this.image][n]=o,this.imagesSettings=t.__assign({},this.imagesSettings),this.control.updateValueAndValidity({emitEvent:!1}),this.modalRef.hide()},l}()},a6qe:function(l,n,e){"use strict";e.d(n,"a",function(){return o});var t=e("gIcY"),u=e("LvDl"),i=(e("my5R"),e("QFaf")),o=function(){function l(l,n){this.modalRef=l,this.iscsiService=n}return l.prototype.ngOnInit=function(){var l=this,n={};u.forIn(this.target_default_controls,function(e,u){n[u]=new t.i(l.target_controls.value[u])}),this.settingsForm=new i.a(n)},l.prototype.save=function(){var l={};u.forIn(this.settingsForm.controls,function(n,e){""!==n.value&&null!==n.value&&(l[e]=n.value)}),this.target_controls.setValue(l),this.modalRef.hide()},l.prototype.getTargetControlLimits=function(l){return this.target_controls_limits?this.target_controls_limits[l]:["Yes","No"].includes(this.target_default_controls[l])?{type:"bool"}:{type:"int"}},l}()},aAWM:function(l,n,e){"use strict";e("uIqm");var t=e("PhyI"),u=function(){function l(){}return l.prototype.transform=function(l){return{0:"global",1:"pool",2:"image"}[l]},l}();e("aXbf"),e("o8EM"),e.d(n,"a",function(){return i});var i=function(){function l(l,n,e){this.formatterService=l,this.rbdConfigurationService=n,this.i18n=e,this.sourceField=t.a,this.typeField=t.b}return l.prototype.ngOnInit=function(){this.poolConfigurationColumns=[{prop:"displayName",name:this.i18n("Name")},{prop:"description",name:this.i18n("Description")},{prop:"name",name:this.i18n("Key")},{prop:"source",name:this.i18n("Source"),cellTemplate:this.configurationSourceTpl,pipe:new u},{prop:"value",name:this.i18n("Value"),cellTemplate:this.configurationValueTpl}]},l.prototype.ngOnChanges=function(){var l=this;this.data&&(this.data=this.data.filter(function(n){return l.rbdConfigurationService.getOptionFields().map(function(l){return l.name}).includes(n.name)}))},l}()},aa9H:function(l,n,e){"use strict";var t=e("gIcY"),u=(e("XED3"),e("QFaf")),i=e("kvvV"),o=(e("kn/O"),function(){return function(){}}());e.d(n,"a",function(){return a});var a=function(){function l(l,n,e,t){this.modalRef=l,this.i18n=n,this.rbdMirroringService=e,this.taskWrapper=t,this.bsConfig={containerClass:"theme-default"},this.peerExists=!1,this.mirrorModes=[{id:"disabled",name:this.i18n("Disabled")},{id:"pool",name:this.i18n("Pool")},{id:"image",name:this.i18n("Image")}],this.createForm()}return l.prototype.createForm=function(){this.editModeForm=new u.a({mirrorMode:new t.i("",{validators:[t.A.required,this.validateMode.bind(this)]})})},l.prototype.ngOnInit=function(){var l=this;this.pattern=""+this.poolName,this.rbdMirroringService.getPool(this.poolName).subscribe(function(n){l.setResponse(n)}),this.subs=this.rbdMirroringService.subscribeSummary(function(n){if(l.peerExists=!1,n){var e=n.content_data.pools.find(function(n){return l.poolName===n.name});l.peerExists=e&&e.peer_uuids.length}})},l.prototype.ngOnDestroy=function(){this.subs.unsubscribe()},l.prototype.validateMode=function(l){return"disabled"===l.value&&this.peerExists?{cannotDisable:{value:l.value}}:null},l.prototype.setResponse=function(l){this.editModeForm.get("mirrorMode").setValue(l.mirror_mode)},l.prototype.update=function(){var l=this,n=new o;n.mirror_mode=this.editModeForm.getValue("mirrorMode"),this.taskWrapper.wrapTaskAroundCall({task:new i.a("rbd/mirroring/pool/edit",{pool_name:this.poolName}),call:this.rbdMirroringService.updatePool(this.poolName,n)}).subscribe(void 0,function(){return l.editModeForm.setErrors({cdSubmitButton:!0})},function(){l.rbdMirroringService.refresh(),l.modalRef.hide()})},l}()},bUo2:function(l,n,e){"use strict";var t=e("CcnG"),u=e("gp3X"),i=e("sb0X"),o=e("EEJc"),a=e("ajRT"),r=e("gIcY"),s=e("Ip0R"),d=e("ANnk"),c=e("f/UV"),p=e("aexS"),m=e("D4zM"),f=e("OcYo"),g=e("SZbH"),h=e("KVJa"),v=e("Z21x"),b=e("sne2"),y=e("Sofw"),C=e("DQlY"),_=e("my5R"),w=e("9nlD"),R=e("Jm/i");e.d(n,"a",function(){return q});var I=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function k(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Usernames must have a length of 8 to 64 characters and can only contain letters, '.', '@', '-', '_' or ':'."]))],null,null)}function E(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function F(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Passwords must have a length of 12 to 16 characters and can only contain letters, '@', '-', '_' or '/'."]))],null,null)}function D(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function V(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Usernames must have a length of 8 to 64 characters and can only contain letters, '.', '@', '-', '_' or ':'."]))],null,null)}function T(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function N(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Passwords must have a length of 12 to 16 characters and can only contain letters, '@', '-', '_' or '/'."]))],null,null)}function P(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.submitAction()&&t),t},u.b,u.a)),t["\u0275did"](1,114688,null,0,i.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Submit"]))],function(l,n){l(n,1,0,n.component.discoveryForm)},null)}function x(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,97,"cd-modal",[],null,null,null,o.c,o.b)),t["\u0275did"](1,49152,null,0,a.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Discovery Authentication"])),(l()(),t["\u0275eld"](4,0,null,1,93,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,92,"form",[["class","form-horizontal"],["name","discoveryForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,7).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,7).onReset()&&u),u},null,null)),t["\u0275did"](6,16384,null,0,r.D,[],null,null),t["\u0275did"](7,540672,[["formDir",4]],0,r.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,r.d,null,[r.l]),t["\u0275did"](9,16384,null,0,r.s,[[4,r.d]],null,null),(l()(),t["\u0275eld"](10,0,null,null,81,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](12,278528,null,0,s.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](13,{"has-error":0}),(l()(),t["\u0275eld"](14,0,null,null,1,"label",[["class","control-label col-sm-4"],["for","user"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["User"])),(l()(),t["\u0275eld"](16,0,null,null,11,"div",[["class","col-sm-8"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,6,"input",[["autocomplete","off"],["class","form-control"],["formControlName","user"],["id","user"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,18)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,18).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,18)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,18)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](18,16384,null,0,r.e,[t.Renderer2,t.ElementRef,[2,r.b]],null,null),t["\u0275prd"](1024,null,r.p,function(l){return[l]},[r.e]),t["\u0275did"](20,671744,null,0,r.j,[[3,r.d],[8,null],[8,null],[6,r.p],[2,r.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,r.q,null,[r.j]),t["\u0275did"](22,16384,null,0,r.r,[[4,r.q]],null,null),t["\u0275did"](23,4210688,null,0,d.a,[[2,c.a],p.a,t.ElementRef],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,S)),t["\u0275did"](25,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,k)),t["\u0275did"](27,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](28,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](29,278528,null,0,s.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](30,{"has-error":0}),(l()(),t["\u0275eld"](31,0,null,null,1,"label",[["class","control-label col-sm-4"],["for","password"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Password"])),(l()(),t["\u0275eld"](33,0,null,null,17,"div",[["class","col-sm-8"]],null,null,null,null,null)),(l()(),t["\u0275eld"](34,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](35,0,null,null,6,"input",[["autocomplete","new-password"],["class","form-control"],["formControlName","password"],["id","password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,36)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,36).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,36)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,36)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](36,16384,null,0,r.e,[t.Renderer2,t.ElementRef,[2,r.b]],null,null),t["\u0275prd"](1024,null,r.p,function(l){return[l]},[r.e]),t["\u0275did"](38,671744,null,0,r.j,[[3,r.d],[8,null],[8,null],[6,r.p],[2,r.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,r.q,null,[r.j]),t["\u0275did"](40,16384,null,0,r.r,[[4,r.q]],null,null),t["\u0275did"](41,4210688,null,0,d.a,[[2,c.a],p.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](42,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](43,0,null,null,1,"button",[["cdPasswordButton","password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==t["\u0275nov"](l,44).onClick()&&u),u},null,null)),t["\u0275did"](44,81920,null,0,m.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](45,0,null,null,1,"button",[["cdCopy2ClipboardButton","password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==t["\u0275nov"](l,46).onClick()&&u),u},null,null)),t["\u0275did"](46,81920,null,0,f.a,[t.ElementRef,t.Renderer2,g.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,E)),t["\u0275did"](48,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,F)),t["\u0275did"](50,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](51,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](52,278528,null,0,s.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](53,{"has-error":0}),(l()(),t["\u0275eld"](54,0,null,null,2,"label",[["class","control-label col-sm-4"],["for","mutual_user"]],null,null,null,null,null)),(l()(),t["\u0275eld"](55,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Mutual User"])),(l()(),t["\u0275eld"](57,0,null,null,11,"div",[["class","col-sm-8"]],null,null,null,null,null)),(l()(),t["\u0275eld"](58,0,null,null,6,"input",[["autocomplete","off"],["class","form-control"],["formControlName","mutual_user"],["id","mutual_user"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,59)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,59).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,59)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,59)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](59,16384,null,0,r.e,[t.Renderer2,t.ElementRef,[2,r.b]],null,null),t["\u0275prd"](1024,null,r.p,function(l){return[l]},[r.e]),t["\u0275did"](61,671744,null,0,r.j,[[3,r.d],[8,null],[8,null],[6,r.p],[2,r.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,r.q,null,[r.j]),t["\u0275did"](63,16384,null,0,r.r,[[4,r.q]],null,null),t["\u0275did"](64,4210688,null,0,d.a,[[2,c.a],p.a,t.ElementRef],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,D)),t["\u0275did"](66,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,V)),t["\u0275did"](68,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](69,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](70,278528,null,0,s.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](71,{"has-error":0}),(l()(),t["\u0275eld"](72,0,null,null,1,"label",[["class","control-label col-sm-4"],["for","mutual_password"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Mutual Password"])),(l()(),t["\u0275eld"](74,0,null,null,17,"div",[["class","col-sm-8"]],null,null,null,null,null)),(l()(),t["\u0275eld"](75,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](76,0,null,null,6,"input",[["autocomplete","new-password"],["class","form-control"],["formControlName","mutual_password"],["id","mutual_password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,77)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,77).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,77)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,77)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](77,16384,null,0,r.e,[t.Renderer2,t.ElementRef,[2,r.b]],null,null),t["\u0275prd"](1024,null,r.p,function(l){return[l]},[r.e]),t["\u0275did"](79,671744,null,0,r.j,[[3,r.d],[8,null],[8,null],[6,r.p],[2,r.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,r.q,null,[r.j]),t["\u0275did"](81,16384,null,0,r.r,[[4,r.q]],null,null),t["\u0275did"](82,4210688,null,0,d.a,[[2,c.a],p.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](83,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](84,0,null,null,1,"button",[["cdPasswordButton","mutual_password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==t["\u0275nov"](l,85).onClick()&&u),u},null,null)),t["\u0275did"](85,81920,null,0,m.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](86,0,null,null,1,"button",[["cdCopy2ClipboardButton","mutual_password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==t["\u0275nov"](l,87).onClick()&&u),u},null,null)),t["\u0275did"](87,81920,null,0,f.a,[t.ElementRef,t.Renderer2,g.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,T)),t["\u0275did"](89,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,N)),t["\u0275did"](91,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](92,0,null,null,5,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](93,0,null,null,4,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,P)),t["\u0275did"](95,16384,null,0,s.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](96,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,h.b,h.a)),t["\u0275did"](97,49152,null,0,v.a,[s.Location,b.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,1,0,e.bsModalRef),l(n,7,0,e.discoveryForm);var u=l(n,13,0,e.discoveryForm.showError("user",t["\u0275nov"](n,7)));l(n,12,0,"form-group",u),l(n,20,0,"user"),l(n,25,0,e.discoveryForm.showError("user",t["\u0275nov"](n,7),"required")),l(n,27,0,e.discoveryForm.showError("user",t["\u0275nov"](n,7),"pattern"));var i=l(n,30,0,e.discoveryForm.showError("password",t["\u0275nov"](n,7)));l(n,29,0,"form-group",i),l(n,38,0,"password"),l(n,44,0,"password"),l(n,46,0,"password"),l(n,48,0,e.discoveryForm.showError("password",t["\u0275nov"](n,7),"required")),l(n,50,0,e.discoveryForm.showError("password",t["\u0275nov"](n,7),"pattern"));var o=l(n,53,0,e.discoveryForm.showError("mutual_user",t["\u0275nov"](n,7)));l(n,52,0,"form-group",o),l(n,61,0,"mutual_user"),l(n,66,0,e.discoveryForm.showError("mutual_user",t["\u0275nov"](n,7),"required")),l(n,68,0,e.discoveryForm.showError("mutual_user",t["\u0275nov"](n,7),"pattern"));var a=l(n,71,0,e.discoveryForm.showError("mutual_password",t["\u0275nov"](n,7)));l(n,70,0,"form-group",a),l(n,79,0,"mutual_password"),l(n,85,0,"mutual_password"),l(n,87,0,"mutual_password"),l(n,89,0,e.discoveryForm.showError("mutual_password",t["\u0275nov"](n,7),"required")),l(n,91,0,e.discoveryForm.showError("mutual_password",t["\u0275nov"](n,7),"pattern")),l(n,95,0,e.hasPermission),l(n,97,0,"Cancel",e.bsModalRef.hide)},function(l,n){l(n,5,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending),l(n,17,0,t["\u0275nov"](n,22).ngClassUntouched,t["\u0275nov"](n,22).ngClassTouched,t["\u0275nov"](n,22).ngClassPristine,t["\u0275nov"](n,22).ngClassDirty,t["\u0275nov"](n,22).ngClassValid,t["\u0275nov"](n,22).ngClassInvalid,t["\u0275nov"](n,22).ngClassPending),l(n,35,0,t["\u0275nov"](n,40).ngClassUntouched,t["\u0275nov"](n,40).ngClassTouched,t["\u0275nov"](n,40).ngClassPristine,t["\u0275nov"](n,40).ngClassDirty,t["\u0275nov"](n,40).ngClassValid,t["\u0275nov"](n,40).ngClassInvalid,t["\u0275nov"](n,40).ngClassPending),l(n,58,0,t["\u0275nov"](n,63).ngClassUntouched,t["\u0275nov"](n,63).ngClassTouched,t["\u0275nov"](n,63).ngClassPristine,t["\u0275nov"](n,63).ngClassDirty,t["\u0275nov"](n,63).ngClassValid,t["\u0275nov"](n,63).ngClassInvalid,t["\u0275nov"](n,63).ngClassPending),l(n,76,0,t["\u0275nov"](n,81).ngClassUntouched,t["\u0275nov"](n,81).ngClassTouched,t["\u0275nov"](n,81).ngClassPristine,t["\u0275nov"](n,81).ngClassDirty,t["\u0275nov"](n,81).ngClassValid,t["\u0275nov"](n,81).ngClassInvalid,t["\u0275nov"](n,81).ngClassPending)})}function O(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-iscsi-target-discovery-modal",[],null,null,null,x,I)),t["\u0275did"](1,114688,null,0,y.a,[p.a,C.a,_.a,w.a,R.a],null,null)],function(l,n){l(n,1,0)},null)}var q=t["\u0275ccf"]("cd-iscsi-target-discovery-modal",y.a,O,{},{},[])},cxJu:function(l,n,e){"use strict";e.d(n,"a",function(){return t}),e("XED3");var t=function(){function l(l){this.rbdMirroringService=l}return l.prototype.ngOnInit=function(){var l=this;this.subs=this.rbdMirroringService.subscribeSummary(function(n){n&&(l.status=n.content_data.status)})},l.prototype.ngOnDestroy=function(){this.subs.unsubscribe()},l}()},"e/kN":function(l,n,e){"use strict";e.d(n,"a",function(){return s});var t=e("LvDl"),u=(e("my5R"),e("0+/T")),i=(e("sne2"),e("uIqm"),e("x38r")),o=e("vCyI"),a=e("kvvV"),r=(e("+0ag"),e("uhwM"),e("G1/K"),e("aexS"),e("mSOc"),e("VTlA"),e("kn/O"),e("Sofw")),s=function(){function l(l,n,e,u,i,a,r,s,d,c,p){var m=this;this.authStorageService=l,this.i18n=n,this.iscsiService=e,this.listPipe=u,this.taskListService=i,this.cephReleaseNamePipe=a,this.notAvailablePipe=r,this.summaryservice=s,this.modalService=d,this.taskWrapper=c,this.actionLabels=p,this.available=void 0,this.selection=new o.a,this.targets=[],this.builders={"iscsi/target/create":function(l){return{target_iqn:l.target_iqn}}},this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{permission:"create",icon:"fa-plus",routerLink:function(){return"/block/iscsi/targets/create"},name:this.actionLabels.CREATE},{permission:"update",icon:"fa-pencil",routerLink:function(){return"/block/iscsi/targets/edit/"+m.selection.first().target_iqn},name:this.actionLabels.EDIT,disable:function(){return!m.selection.first()||!t.isUndefined(m.getEditDisableDesc())},disableDesc:function(){return m.getEditDisableDesc()}},{permission:"delete",icon:"fa-times",click:function(){return m.deleteIscsiTargetModal()},name:this.actionLabels.DELETE,disable:function(){return!m.selection.first()||!t.isUndefined(m.getDeleteDisableDesc())},disableDesc:function(){return m.getDeleteDisableDesc()}}]}return l.prototype.ngOnInit=function(){var l=this;this.columns=[{name:this.i18n("Target"),prop:"target_iqn",flexGrow:2,cellTransformation:i.a.executing},{name:this.i18n("Portals"),prop:"cdPortals",pipe:this.listPipe,flexGrow:2},{name:this.i18n("Images"),prop:"cdImages",pipe:this.listPipe,flexGrow:2},{name:this.i18n("# Sessions"),prop:"info.num_sessions",pipe:this.notAvailablePipe,flexGrow:1}],this.iscsiService.status().subscribe(function(n){if(l.available=n.available,n.available)l.iscsiService.version().subscribe(function(n){l.cephIscsiConfigVersion=n.ceph_iscsi_config_version,l.taskListService.init(function(){return l.iscsiService.listTargets()},function(n){return l.prepareResponse(n)},function(n){return l.targets=n},function(){return l.onFetchError()},l.taskFilter,l.itemFilter,l.builders)}),l.iscsiService.settings().subscribe(function(n){l.settings=n});else{var e=l.summaryservice.getCurrentSummary(),t=l.cephReleaseNamePipe.transform(e.version);l.docsUrl="http://docs.ceph.com/docs/"+t+"/mgr/dashboard/#enabling-iscsi-management",l.status=n.message}})},l.prototype.ngOnDestroy=function(){this.summaryDataSubscription&&this.summaryDataSubscription.unsubscribe()},l.prototype.getEditDisableDesc=function(){var l=this.selection.first();return l&&l.cdExecuting?l.cdExecuting:l&&t.isUndefined(l.info)?this.i18n("Unavailable gateway(s)"):void 0},l.prototype.getDeleteDisableDesc=function(){var l=this.selection.first();return l&&l.cdExecuting?l.cdExecuting:l&&t.isUndefined(l.info)?this.i18n("Unavailable gateway(s)"):l&&l.info&&l.info.num_sessions?this.i18n("Target has active sessions"):void 0},l.prototype.prepareResponse=function(l){return l.forEach(function(l){l.cdPortals=l.portals.map(function(l){return l.host+":"+l.ip}),l.cdImages=l.disks.map(function(l){return l.pool+"/"+l.image})}),l},l.prototype.onFetchError=function(){this.table.reset()},l.prototype.itemFilter=function(l,n){return l.target_iqn===n.metadata.target_iqn},l.prototype.taskFilter=function(l){return["iscsi/target/create","iscsi/target/edit","iscsi/target/delete"].includes(l.name)},l.prototype.updateSelection=function(l){this.selection=l},l.prototype.deleteIscsiTargetModal=function(){var l=this,n=this.selection.first().target_iqn;this.modalRef=this.modalService.show(u.a,{initialState:{itemDescription:this.i18n("iSCSI target"),itemNames:[n],submitActionObservable:function(){return l.taskWrapper.wrapTaskAroundCall({task:new a.a("iscsi/target/delete",{target_iqn:n}),call:l.iscsiService.deleteTarget(n)})}}})},l.prototype.configureDiscoveryAuth=function(){this.modalService.show(r.a,{})},l}()},eF8U:function(l,n,e){"use strict";var t=e("CcnG"),u=e("gIcY"),i=e("ANnk"),o=e("f/UV"),a=e("aexS"),r=e("Ip0R");e("jMP8"),e.d(n,"a",function(){return s}),e.d(n,"b",function(){return b});var s=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function d(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,u.v,[t.ElementRef,t.Renderer2,[2,u.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](2,147456,null,0,u.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function c(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"select",[["class","form-control custom-select"]],[[8,"id",0],[8,"name",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var u=!0;return"change"===n&&(u=!1!==t["\u0275nov"](l,1).onChange(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,1).onTouched()&&u),u},null,null)),t["\u0275did"](1,16384,null,0,u.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.z]),t["\u0275did"](3,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](5,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](6,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](7,0,null,null,2,"option",[],null,null,null,null,null)),t["\u0275did"](8,147456,null,0,u.v,[t.ElementRef,t.Renderer2,[2,u.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](9,147456,null,0,u.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,d)),t["\u0275did"](11,278528,null,0,r.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component;l(n,3,0,e.setting),l(n,8,0,null),l(n,9,0,null),l(n,11,0,e.limits.values)},function(l,n){var e=n.component;l(n,0,0,t["\u0275inlineInterpolate"](1,"",e.setting,""),t["\u0275inlineInterpolate"](1,"",e.setting,""),t["\u0275nov"](n,5).ngClassUntouched,t["\u0275nov"](n,5).ngClassTouched,t["\u0275nov"](n,5).ngClassPristine,t["\u0275nov"](n,5).ngClassDirty,t["\u0275nov"](n,5).ngClassValid,t["\u0275nov"](n,5).ngClassInvalid,t["\u0275nov"](n,5).ngClassPending)})}function p(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,7,"input",[["class","form-control"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,1)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,1).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,1)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,1)._compositionEnd(e.target.value)&&u),"change"===n&&(u=!1!==t["\u0275nov"](l,2).onChange(e.target.value)&&u),"input"===n&&(u=!1!==t["\u0275nov"](l,2).onChange(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,2).onTouched()&&u),u},null,null)),t["\u0275did"](1,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275did"](2,16384,null,0,u.C,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,u.p,function(l,n){return[l,n]},[u.e,u.C]),t["\u0275did"](4,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](6,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](7,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null)],function(l,n){l(n,4,0,n.component.setting)},function(l,n){l(n,0,0,t["\u0275nov"](n,6).ngClassUntouched,t["\u0275nov"](n,6).ngClassTouched,t["\u0275nov"](n,6).ngClassPristine,t["\u0275nov"](n,6).ngClassDirty,t["\u0275nov"](n,6).ngClassValid,t["\u0275nov"](n,6).ngClassInvalid,t["\u0275nov"](n,6).ngClassPending)})}function m(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,6,"input",[["class","form-control"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,1)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,1).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,1)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,1)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](1,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.e]),t["\u0275did"](3,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](5,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](6,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null)],function(l,n){l(n,3,0,n.component.setting)},function(l,n){l(n,0,0,t["\u0275nov"](n,5).ngClassUntouched,t["\u0275nov"](n,5).ngClassTouched,t["\u0275nov"](n,5).ngClassPristine,t["\u0275nov"](n,5).ngClassDirty,t["\u0275nov"](n,5).ngClassValid,t["\u0275nov"](n,5).ngClassInvalid,t["\u0275nov"](n,5).ngClassPending)})}function f(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,23,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,10,"div",[["class","radio radio-inline"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,7,"input",[["class","custom-control-input"],["type","radio"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,4)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,4).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,4)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,4)._compositionEnd(e.target.value)&&u),"change"===n&&(u=!1!==t["\u0275nov"](l,5).onChange()&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,5).onTouched()&&u),u},null,null)),t["\u0275did"](4,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275did"](5,212992,null,0,u.w,[t.Renderer2,t.ElementRef,u.E,t.Injector],{formControlName:[0,"formControlName"],value:[1,"value"]},null),t["\u0275prd"](1024,null,u.p,function(l,n){return[l,n]},[u.e,u.w]),t["\u0275did"](7,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](9,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](10,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](11,0,null,null,1,"label",[["class","custom-control-label"]],[[8,"htmlFor",0]],null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Yes"])),(l()(),t["\u0275eld"](13,0,null,null,10,"div",[["class","radio radio-inline"]],null,null,null,null,null)),(l()(),t["\u0275eld"](14,0,null,null,7,"input",[["class","custom-control-input"],["type","radio"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,15)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,15).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,15)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,15)._compositionEnd(e.target.value)&&u),"change"===n&&(u=!1!==t["\u0275nov"](l,16).onChange()&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,16).onTouched()&&u),u},null,null)),t["\u0275did"](15,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275did"](16,212992,null,0,u.w,[t.Renderer2,t.ElementRef,u.E,t.Injector],{formControlName:[0,"formControlName"],value:[1,"value"]},null),t["\u0275prd"](1024,null,u.p,function(l,n){return[l,n]},[u.e,u.w]),t["\u0275did"](18,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](20,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](21,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](22,0,null,null,1,"label",[["class","custom-control-label"]],[[8,"htmlFor",0]],null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["No"]))],function(l,n){var e=n.component;l(n,5,0,e.setting,!0),l(n,7,0,e.setting),l(n,16,0,e.setting,!1),l(n,18,0,e.setting)},function(l,n){var e=n.component;l(n,3,0,e.setting+"True",t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending),l(n,11,0,e.setting+"True"),l(n,14,0,e.setting+"False",t["\u0275nov"](n,20).ngClassUntouched,t["\u0275nov"](n,20).ngClassTouched,t["\u0275nov"](n,20).ngClassPristine,t["\u0275nov"](n,20).ngClassDirty,t["\u0275nov"](n,20).ngClassValid,t["\u0275nov"](n,20).ngClassInvalid,t["\u0275nov"](n,20).ngClassPending),l(n,22,0,e.setting+"False")})}function g(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,6,"span",[],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,p)),t["\u0275did"](2,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,m)),t["\u0275did"](4,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,f)),t["\u0275did"](6,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,2,0,"int"===e.limits.type),l(n,4,0,"str"===e.limits.type),l(n,6,0,"bool"===e.limits.type)},null)}function h(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](2,null,["Must be greater than or equal to ","."]))],null,function(l,n){l(n,2,0,n.component.limits.min)})}function v(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](2,null,["Must be less than or equal to ","."]))],null,function(l,n){l(n,2,0,n.component.limits.max)})}function b(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,15,"div",[["class","form-group"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,3).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,3).onReset()&&u),u},null,null)),t["\u0275did"](1,278528,null,0,r.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),t["\u0275did"](3,540672,null,0,u.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,u.d,null,[u.l]),t["\u0275did"](5,16384,null,0,u.s,[[4,u.d]],null,null),(l()(),t["\u0275eld"](6,0,null,null,1,"label",[["class","col-form-label"]],[[8,"htmlFor",0]],null,null,null,null)),(l()(),t["\u0275ted"](7,null,["",""])),(l()(),t["\u0275and"](16777216,null,null,1,null,c)),t["\u0275did"](9,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,g)),t["\u0275did"](11,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,h)),t["\u0275did"](13,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,v)),t["\u0275did"](15,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,2,0,e.settingsForm.showError(e.setting,e.formDir));l(n,1,0,"form-group",t),l(n,3,0,e.settingsForm),l(n,9,0,"enum"===e.limits.type),l(n,11,0,"enum"!==e.limits.type),l(n,13,0,e.settingsForm.showError(e.setting,e.formDir,"min")),l(n,15,0,e.settingsForm.showError(e.setting,e.formDir,"max"))},function(l,n){var e=n.component;l(n,0,0,t["\u0275nov"](n,5).ngClassUntouched,t["\u0275nov"](n,5).ngClassTouched,t["\u0275nov"](n,5).ngClassPristine,t["\u0275nov"](n,5).ngClassDirty,t["\u0275nov"](n,5).ngClassValid,t["\u0275nov"](n,5).ngClassInvalid,t["\u0275nov"](n,5).ngClassPending),l(n,6,0,t["\u0275inlineInterpolate"](1,"",e.setting,"")),l(n,7,0,e.setting)})}},gr3l:function(l,n,e){"use strict";e.d(n,"a",function(){return m});var t=e("gIcY"),u=e("LvDl"),i=e("VNr4"),o=(e("my5R"),e("F83c"),e("DNAf")),a=e("a96k"),r=(e("sne2"),e("QFaf")),s=e("1Ni5"),d=e("kvvV"),c=(e("kn/O"),e("Z4cD")),p=e("a6qe"),m=function(){function l(l,n,e,t,u,i,a,r){this.iscsiService=l,this.modalService=n,this.rbdService=e,this.router=t,this.route=u,this.i18n=i,this.taskWrapper=a,this.actionLabels=r,this.api_version=0,this.minimum_gateways=1,this.isEdit=!1,this.portalsSelections=[],this.imagesInitiatorSelections=[],this.groupDiskSelections=[],this.groupMembersSelections=[],this.imagesSettings={},this.messages={portals:new o.a({noOptions:this.i18n("There are no portals available.")},this.i18n),images:new o.a({noOptions:this.i18n("There are no images available.")},this.i18n),initiatorImage:new o.a({noOptions:this.i18n("There are no images available. Please make sure you add an image to the target.")},this.i18n),groupInitiator:new o.a({noOptions:this.i18n("There are no initiators available. Please make sure you add an initiator to the target.")},this.i18n)},this.IQN_REGEX=/^iqn\.(19|20)\d\d-(0[1-9]|1[0-2])\.\D{2,3}(\.[A-Za-z0-9-]+)+(:[A-Za-z0-9-\.]+)*$/,this.USER_REGEX=/^[\w\.:@_-]{8,64}$/,this.PASSWORD_REGEX=/^[\w@\-_\/]{12,16}$/,this.resource=this.i18n("target")}return l.prototype.ngOnInit=function(){var l=this,n=[this.iscsiService.listTargets(),this.rbdService.list(),this.iscsiService.portals(),this.iscsiService.settings(),this.iscsiService.version()];this.router.url.startsWith("/block/iscsi/targets/edit")&&(this.isEdit=!0,this.route.params.subscribe(function(e){l.target_iqn=decodeURIComponent(e.target_iqn),n.push(l.iscsiService.getTarget(l.target_iqn))})),this.action=this.isEdit?this.actionLabels.EDIT:this.actionLabels.CREATE,Object(i.a)(n).subscribe(function(n){var e=u(n[0]).filter(function(n){return n.target_iqn!==l.target_iqn}).flatMap(function(l){return l.disks}).map(function(l){return l.pool+"/"+l.image}).value();"api_version"in n[3]&&(l.api_version=n[3].api_version),l.minimum_gateways=n[3].config.minimum_gateways,l.target_default_controls=n[3].target_default_controls,l.target_controls_limits=n[3].target_controls_limits,l.disk_default_controls=n[3].disk_default_controls,l.disk_controls_limits=n[3].disk_controls_limits,l.backstores=n[3].backstores,l.default_backstore=n[3].default_backstore,l.unsupported_rbd_features=n[3].unsupported_rbd_features,l.required_rbd_features=n[3].required_rbd_features,l.imagesAll=u(n[1]).flatMap(function(l){return l.value}).filter(function(n){return-1===e.indexOf(n.pool_name+"/"+n.name)&&0!==l.getValidBackstores(n).length}).value(),l.imagesSelections=l.imagesAll.map(function(l){return new a.a(!1,l.pool_name+"/"+l.name,"")});var t=[];n[2].forEach(function(l){l.ip_addresses.forEach(function(n){t.push(new a.a(!1,l.name+":"+n,""))})}),l.portalsSelections=t.slice(),l.cephIscsiConfigVersion=n[4].ceph_iscsi_config_version,l.createForm(),n[5]&&l.resolveModel(n[5])})},l.prototype.createForm=function(){var l=this;if(this.targetForm=new r.a({target_iqn:new t.i("iqn.2001-07.com.ceph:"+Date.now(),{validators:[t.A.required,t.A.pattern(this.IQN_REGEX)]}),target_controls:new t.i({}),portals:new t.i([],{validators:[s.a.custom("minGateways",function(n){return u.uniq(n.map(function(l){return l.split(":")[0]})).length10){var n=new r.a({user:new t.i(""),password:new t.i(""),mutual_user:new t.i(""),mutual_password:new t.i("")});this.setAuthValidator(n),this.targetForm.addControl("auth",n)}},l.prototype.resolveModel=function(l){var n=this;this.targetForm.patchValue({target_iqn:l.target_iqn,target_controls:l.target_controls,acl_enabled:l.acl_enabled}),this.cephIscsiConfigVersion>10&&this.targetForm.patchValue({auth:l.auth});var e=[];u.forEach(l.portals,function(l){e.push(l.host+":"+l.ip)}),this.targetForm.patchValue({portals:e});var t=[];u.forEach(l.disks,function(l){var e=l.pool+"/"+l.image;t.push(e),n.imagesSettings[e]={backstore:l.backstore},n.imagesSettings[e][l.backstore]=l.controls,"lun"in l&&(n.imagesSettings[e].lun=l.lun),"wwn"in l&&(n.imagesSettings[e].wwn=l.wwn),n.onImageSelection({option:{name:e,selected:!0}})}),this.targetForm.patchValue({disks:t}),u.forEach(l.clients,function(l){var e=n.addInitiator();l.luns=u.map(l.luns,function(l){return l.pool+"/"+l.image}),e.patchValue(l)}),u.forEach(l.groups,function(l){var e=n.addGroup();l.disks=u.map(l.disks,function(l){return l.pool+"/"+l.image}),e.patchValue(l),u.forEach(l.members,function(l){n.onGroupMemberSelection({option:new a.a(!0,l,"")})})})},l.prototype.hasAdvancedSettings=function(l){return Object.values(l).length>0},Object.defineProperty(l.prototype,"portals",{get:function(){return this.targetForm.get("portals")},enumerable:!0,configurable:!0}),l.prototype.onPortalSelection=function(){this.portals.setValue(this.portals.value)},l.prototype.removePortal=function(l,n){return this.portalsSelections.forEach(function(l){l.name===n&&(l.selected=!1)}),this.portals.value.splice(l,1),this.portals.setValue(this.portals.value),!1},Object.defineProperty(l.prototype,"disks",{get:function(){return this.targetForm.get("disks")},enumerable:!0,configurable:!0}),l.prototype.removeImage=function(l,n){return this.imagesSelections.forEach(function(l){l.name===n&&(l.selected=!1)}),this.disks.value.splice(l,1),this.removeImageRefs(n),this.targetForm.get("disks").updateValueAndValidity({emitEvent:!1}),!1},l.prototype.removeImageRefs=function(l){var n=this;this.initiators.controls.forEach(function(n){var e=n.value.luns.filter(function(n){return n!==l});n.get("luns").setValue(e)}),this.groups.controls.forEach(function(n){var e=n.value.disks.filter(function(n){return n!==l});n.get("disks").setValue(e)}),u.forEach(this.imagesInitiatorSelections,function(e,t){n.imagesInitiatorSelections[t]=e.filter(function(n){return n.name!==l})}),u.forEach(this.groupDiskSelections,function(e,t){n.groupDiskSelections[t]=e.filter(function(n){return n.name!==l})})},l.prototype.getDefaultBackstore=function(l){var n=this,e=this.default_backstore,t=this.getImageById(l);return this.validFeatures(t,this.default_backstore)||this.backstores.forEach(function(l){l!==n.default_backstore&&n.validFeatures(t,l)&&(e=l)}),e},l.prototype.isLunIdInUse=function(l,n){var e=this.disks.value.filter(function(l){return l!==n});return this.getLunIds(e).includes(l)},l.prototype.getLunIds=function(l){var n=this;return u.map(l,function(l){return n.imagesSettings[l].lun})},l.prototype.nextLunId=function(l){for(var n=this.disks.value.filter(function(n){return n!==l}),e=this.getLunIds(n),t=0;e.includes(t);)t++;return t},l.prototype.getWwns=function(l){var n=this;return u.map(l,function(l){return n.imagesSettings[l].wwn}).filter(function(l){return u.isString(l)&&""!==l})},l.prototype.onImageSelection=function(l){var n=this,e=l.option;if(e.selected){if(this.imagesSettings[e.name])this.isLunIdInUse(this.imagesSettings[e.name].lun,e.name)&&(this.imagesSettings[e.name].lun=this.nextLunId(e.name));else{var t=this.getDefaultBackstore(e.name);this.imagesSettings[e.name]={backstore:t,lun:this.nextLunId(e.name)},this.imagesSettings[e.name][t]={}}u.forEach(this.imagesInitiatorSelections,function(l,t){l.push(new a.a(!1,e.name,"")),n.imagesInitiatorSelections[t]=l.slice()}),u.forEach(this.groupDiskSelections,function(l,t){l.push(new a.a(!1,e.name,"")),n.groupDiskSelections[t]=l.slice()})}else this.removeImageRefs(e.name);this.targetForm.get("disks").updateValueAndValidity({emitEvent:!1})},Object.defineProperty(l.prototype,"initiators",{get:function(){return this.targetForm.get("initiators")},enumerable:!0,configurable:!0}),l.prototype.addInitiator=function(){var l=this,n=new r.a({client_iqn:new t.i("",{validators:[t.A.required,s.a.custom("notUnique",function(n){var e=l.initiators.controls.reduce(function(l,n){return l.concat(n.value.client_iqn)},[]);return e.indexOf(n)!==e.lastIndexOf(n)}),t.A.pattern(this.IQN_REGEX)]}),auth:new r.a({user:new t.i(""),password:new t.i(""),mutual_user:new t.i(""),mutual_password:new t.i("")}),luns:new t.i([]),cdIsInGroup:new t.i(!1)});this.setAuthValidator(n),this.initiators.push(n),u.forEach(this.groupMembersSelections,function(n,e){n.push(new a.a(!1,"","")),l.groupMembersSelections[e]=n.slice()});var e=u.map(this.targetForm.getValue("disks"),function(l){return new a.a(!1,l,"")});return this.imagesInitiatorSelections.push(e),n},l.prototype.setAuthValidator=function(l){s.a.validateIf(l.get("user"),function(){return l.getValue("password")||l.getValue("mutual_user")||l.getValue("mutual_password")},[t.A.required],[t.A.pattern(this.USER_REGEX)],[l.get("password"),l.get("mutual_user"),l.get("mutual_password")]),s.a.validateIf(l.get("password"),function(){return l.getValue("user")||l.getValue("mutual_user")||l.getValue("mutual_password")},[t.A.required],[t.A.pattern(this.PASSWORD_REGEX)],[l.get("user"),l.get("mutual_user"),l.get("mutual_password")]),s.a.validateIf(l.get("mutual_user"),function(){return l.getValue("mutual_password")},[t.A.required],[t.A.pattern(this.USER_REGEX)],[l.get("user"),l.get("password"),l.get("mutual_password")]),s.a.validateIf(l.get("mutual_password"),function(){return l.getValue("mutual_user")},[t.A.required],[t.A.pattern(this.PASSWORD_REGEX)],[l.get("user"),l.get("password"),l.get("mutual_user")])},l.prototype.removeInitiator=function(l){var n=this,e=this.initiators.value[l];this.initiators.removeAt(l),u.forEach(this.groupMembersSelections,function(e,t){e.splice(l,1),n.groupMembersSelections[t]=e.slice()}),this.groups.controls.forEach(function(l){var n=l.value.members.filter(function(l){return l!==e.client_iqn});l.get("members").setValue(n)}),this.imagesInitiatorSelections.splice(l,1)},l.prototype.updatedInitiatorSelector=function(){var l=this;this.initiators.controls.forEach(function(l){l.get("client_iqn").updateValueAndValidity({emitEvent:!1})}),u.forEach(this.groupMembersSelections,function(n,e){u.forEach(n,function(n,e){var t=n.name;n.name=l.initiators.controls[e].value.client_iqn,l.groups.controls.forEach(function(l){var e=l.value.members,u=e.indexOf(t);-1!==u&&(e[u]=n.name),l.get("members").setValue(e)})}),l.groupMembersSelections[e]=l.groupMembersSelections[e].slice()})},l.prototype.removeInitiatorImage=function(l,n,e,t){var u=l.getValue("luns");return u.splice(n,1),l.patchValue({luns:u}),this.imagesInitiatorSelections[e].forEach(function(l){l.name===t&&(l.selected=!1)}),!1},Object.defineProperty(l.prototype,"groups",{get:function(){return this.targetForm.get("groups")},enumerable:!0,configurable:!0}),l.prototype.addGroup=function(){var l=new r.a({group_id:new t.i("",{validators:[t.A.required]}),members:new t.i([]),disks:new t.i([])});this.groups.push(l);var n=u.map(this.targetForm.getValue("disks"),function(l){return new a.a(!1,l,"")});this.groupDiskSelections.push(n);var e=u.map(this.initiators.value,function(l){return new a.a(!1,l.client_iqn,"",!l.cdIsInGroup)});return this.groupMembersSelections.push(e),l},l.prototype.removeGroup=function(l){this.groups.removeAt(l),this.groupDiskSelections.splice(l,1)},l.prototype.onGroupMemberSelection=function(l){var n,e=l.option;this.initiators.controls.forEach(function(l,t){l.value.client_iqn===e.name&&(l.patchValue({luns:[]}),l.get("cdIsInGroup").setValue(e.selected),n=t)}),u.forEach(this.groupMembersSelections,function(l){l[n].enabled=!e.selected})},l.prototype.removeGroupInitiator=function(l,n,e){var t=l.getValue("members")[n];l.getValue("members").splice(n,1),this.groupMembersSelections[e].forEach(function(l){l.name===t&&(l.selected=!1)}),this.groupMembersSelections[e]=this.groupMembersSelections[e].slice(),this.onGroupMemberSelection({option:new a.a(!1,t,"")})},l.prototype.removeGroupDisk=function(l,n,e){var t=l.getValue("disks")[n];l.getValue("disks").splice(n,1),this.groupDiskSelections[e].forEach(function(l){l.name===t&&(l.selected=!1)}),this.groupDiskSelections[e]=this.groupDiskSelections[e].slice()},l.prototype.submit=function(){var l,n=this,e=u.cloneDeep(this.targetForm.value),t={target_iqn:this.targetForm.getValue("target_iqn"),target_controls:this.targetForm.getValue("target_controls"),acl_enabled:this.targetForm.getValue("acl_enabled"),portals:[],disks:[],clients:[],groups:[]};if(this.cephIscsiConfigVersion>10){var i=this.targetForm.get("auth");i.getValue("user")||i.get("user").setValue(""),i.getValue("password")||i.get("password").setValue(""),i.getValue("mutual_user")||i.get("mutual_user").setValue(""),i.getValue("mutual_password")||i.get("mutual_password").setValue("");var o=this.targetForm.getValue("acl_enabled");t.auth={user:o?"":i.getValue("user"),password:o?"":i.getValue("password"),mutual_user:o?"":i.getValue("mutual_user"),mutual_password:o?"":i.getValue("mutual_password")}}e.disks.forEach(function(l){var e=l.split("/"),u=n.imagesSettings[l].backstore;t.disks.push({pool:e[0],image:e[1],backstore:u,controls:n.imagesSettings[l][u],lun:n.imagesSettings[l].lun,wwn:n.imagesSettings[l].wwn})}),e.portals.forEach(function(l){var n=l.indexOf(":");t.portals.push({host:l.substring(0,n),ip:l.substring(n+1)})}),t.acl_enabled&&(e.initiators.forEach(function(l){l.auth.user||(l.auth.user=""),l.auth.password||(l.auth.password=""),l.auth.mutual_user||(l.auth.mutual_user=""),l.auth.mutual_password||(l.auth.mutual_password=""),delete l.cdIsInGroup;var n=[];l.luns.forEach(function(l){var e=l.split("/");n.push({pool:e[0],image:e[1]})}),l.luns=n}),t.clients=e.initiators),t.acl_enabled&&(e.groups.forEach(function(l){var n=[];l.disks.forEach(function(l){var e=l.split("/");n.push({pool:e[0],image:e[1]})}),l.disks=n}),t.groups=e.groups),this.isEdit?(t.new_target_iqn=t.target_iqn,t.target_iqn=this.target_iqn,l=this.taskWrapper.wrapTaskAroundCall({task:new d.a("iscsi/target/edit",{target_iqn:t.target_iqn}),call:this.iscsiService.updateTarget(this.target_iqn,t)})):l=this.taskWrapper.wrapTaskAroundCall({task:new d.a("iscsi/target/create",{target_iqn:t.target_iqn}),call:this.iscsiService.createTarget(t)}),l.subscribe(void 0,function(){n.targetForm.setErrors({cdSubmitButton:!0})},function(){return n.router.navigate(["/block/iscsi/targets"])})},l.prototype.targetSettingsModal=function(){var l={target_controls:this.targetForm.get("target_controls"),target_default_controls:this.target_default_controls,target_controls_limits:this.target_controls_limits};this.modalRef=this.modalService.show(p.a,{initialState:l})},l.prototype.imageSettingsModal=function(l){var n={imagesSettings:this.imagesSettings,image:l,api_version:this.api_version,disk_default_controls:this.disk_default_controls,disk_controls_limits:this.disk_controls_limits,backstores:this.getValidBackstores(this.getImageById(l)),control:this.targetForm.get("disks")};this.modalRef=this.modalService.show(c.a,{initialState:n})},l.prototype.validFeatures=function(l,n){var e=l.features,t=this.required_rbd_features[n];return(e&t)===t&&0==(e&this.unsupported_rbd_features[n])},l.prototype.getImageById=function(l){return this.imagesAll.find(function(n){return l===n.pool_name+"/"+n.name})},l.prototype.getValidBackstores=function(l){var n=this;return this.backstores.filter(function(e){return n.validFeatures(l,e)})},l}()},jMP8:function(l,n,e){"use strict";e.d(n,"a",function(){return u});var t=e("gIcY"),u=(e("QFaf"),function(){function l(){}return l.prototype.ngOnInit=function(){var l=[];"min"in this.limits&&l.push(t.A.min(this.limits.min)),"max"in this.limits&&l.push(t.A.max(this.limits.max)),this.settingsForm.get(this.setting).setValidators(l)},l}())},"k/xb":function(l,n,e){"use strict";e.d(n,"a",function(){return u}),e.d(n,"b",function(){return v}),e.d(n,"c",function(){return i}),e.d(n,"d",function(){return o}),e.d(n,"g",function(){return a}),e.d(n,"h",function(){return r}),e.d(n,"i",function(){return s}),e.d(n,"j",function(){return d}),e.d(n,"k",function(){return c}),e.d(n,"l",function(){return p}),e.d(n,"m",function(){return m}),e.d(n,"n",function(){return f}),e.d(n,"e",function(){return g}),e.d(n,"f",function(){return h});var t=e("sne2"),u=(e("Vhfg"),e("gr3l"),e("e/kN"),e("roDX"),e("cxJu"),e("MyVl"),e("wG1H"),function(){return function(){}}()),i={breadcrumbs:"Images"},o={breadcrumbs:t.a.CREATE},a={breadcrumbs:t.a.EDIT},r={breadcrumbs:t.a.CLONE},s={breadcrumbs:t.a.COPY},d={breadcrumbs:t.a.COPY},c={breadcrumbs:"Mirroring"},p={breadcrumbs:"iSCSI"},m={breadcrumbs:"Overview"},f={breadcrumbs:"Targets"},g={breadcrumbs:t.a.CREATE},h={breadcrumbs:t.a.EDIT},v=function(){return function(){}}()},kccj:function(l,n,e){"use strict";e.d(n,"a",function(){return t});var t=function(){return function(){}}()},l7Jr:function(l,n,e){"use strict";var t=e("CcnG"),u=e("Ip0R"),i=e("eF8U"),o=e("jMP8"),a=e("EEJc"),r=e("ajRT"),s=e("gIcY"),d=e("gp3X"),c=e("sb0X"),p=e("KVJa"),m=e("Z21x"),f=e("sne2"),g=e("a6qe"),h=e("DQlY"),v=e("my5R");e.d(n,"a",function(){return w});var b=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function y(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,5,"div",[["class","form-group row"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,u.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,2,"div",[["class","col-sm-12"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"cd-iscsi-setting",[],null,null,null,i.b,i.a)),t["\u0275did"](5,114688,null,0,o.a,[],{settingsForm:[0,"settingsForm"],formDir:[1,"formDir"],setting:[2,"setting"],limits:[3,"limits"]},null)],function(l,n){var e=n.component,u=l(n,2,0,e.settingsForm.showError(n.context.$implicit.key,t["\u0275nov"](n.parent,7)));l(n,1,0,"form-group row",u),l(n,5,0,e.settingsForm,t["\u0275nov"](n.parent,7),n.context.$implicit.key,e.getTargetControlLimits(n.context.$implicit.key))},null)}function C(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,22,"cd-modal",[],null,null,null,a.c,a.b)),t["\u0275did"](1,49152,null,0,r.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Advanced Settings"])),(l()(),t["\u0275eld"](4,0,null,1,18,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,17,"form",[["class","form"],["name","settingsForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,7).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,7).onReset()&&u),u},null,null)),t["\u0275did"](6,16384,null,0,s.D,[],null,null),t["\u0275did"](7,540672,[["formDir",4]],0,s.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,s.d,null,[s.l]),t["\u0275did"](9,16384,null,0,s.s,[[4,s.d]],null,null),(l()(),t["\u0275eld"](10,0,null,null,5,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,1,"p",[["class","alert-warning"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Changing these parameters from their default values is usually not necessary."])),(l()(),t["\u0275and"](16777216,null,null,2,null,y)),t["\u0275did"](14,278528,null,0,u.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),t["\u0275pid"](0,u.KeyValuePipe,[t.KeyValueDiffers]),(l()(),t["\u0275eld"](16,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](18,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.save()&&t),t},d.b,d.a)),t["\u0275did"](19,114688,null,0,c.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Confirm"])),(l()(),t["\u0275eld"](21,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,p.b,p.a)),t["\u0275did"](22,49152,null,0,m.a,[u.Location,f.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,1,0,e.modalRef),l(n,7,0,e.settingsForm),l(n,14,0,t["\u0275unv"](n,14,0,t["\u0275nov"](n,15).transform(e.settingsForm.controls))),l(n,19,0,e.settingsForm),l(n,22,0,"Cancel",e.modalRef.hide)},function(l,n){l(n,5,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending)})}function _(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-iscsi-target-iqn-settings-modal",[],null,null,null,C,b)),t["\u0275did"](1,114688,null,0,g.a,[h.a,v.a],null,null)],function(l,n){l(n,1,0)},null)}var w=t["\u0275ccf"]("cd-iscsi-target-iqn-settings-modal",g.a,_,{},{},[])},"lz+O":function(l,n,e){"use strict";var t=e("CcnG"),u=e("gIcY"),i=e("ANnk"),o=e("f/UV"),a=e("aexS"),r=e("Ip0R"),s=e("EEJc"),d=e("ajRT"),c=e("gp3X"),p=e("sb0X"),m=e("KVJa"),f=e("Z21x"),g=e("sne2"),h=e("WxU5"),v=e("F83c"),b=e("DQlY"),y=e("2EZI"),C=e("Ekvf"),_=e("kn/O");e.d(n,"a",function(){return F});var w=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function R(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,6,"input",[["class","form-control"],["formControlName","poolName"],["placeholder","Pool name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,1)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,1).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,1)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,1)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](1,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.e]),t["\u0275did"](3,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](5,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](6,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null)],function(l,n){l(n,3,0,"poolName")},function(l,n){l(n,0,0,t["\u0275nov"](n,5).ngClassUntouched,t["\u0275nov"](n,5).ngClassTouched,t["\u0275nov"](n,5).ngClassPristine,t["\u0275nov"](n,5).ngClassDirty,t["\u0275nov"](n,5).ngClassValid,t["\u0275nov"](n,5).ngClassInvalid,t["\u0275nov"](n,5).ngClassPending)})}function I(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,u.v,[t.ElementRef,t.Renderer2,[2,u.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,u.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,12,"select",[["class","form-control"],["formControlName","poolName"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var u=!0;return"change"===n&&(u=!1!==t["\u0275nov"](l,1).onChange(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,1).onTouched()&&u),u},null,null)),t["\u0275did"](1,16384,null,0,u.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.z]),t["\u0275did"](3,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](5,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](6,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](7,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),t["\u0275did"](8,147456,null,0,u.v,[t.ElementRef,t.Renderer2,[2,u.z]],{value:[0,"value"]},null),t["\u0275did"](9,147456,null,0,u.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](-1,null,["All"])),(l()(),t["\u0275and"](16777216,null,null,1,null,I)),t["\u0275did"](12,278528,null,0,r.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component;l(n,3,0,"poolName"),l(n,8,0,""),l(n,9,0,""),l(n,12,0,e.pools)},function(l,n){l(n,0,0,t["\u0275nov"](n,5).ngClassUntouched,t["\u0275nov"](n,5).ngClassTouched,t["\u0275nov"](n,5).ngClassPristine,t["\u0275nov"](n,5).ngClassDirty,t["\u0275nov"](n,5).ngClassValid,t["\u0275nov"](n,5).ngClassInvalid,t["\u0275nov"](n,5).ngClassPending)})}function k(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,37,"cd-modal",[],null,null,null,s.c,s.b)),t["\u0275did"](1,49152,null,0,d.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Purge Trash"])),(l()(),t["\u0275eld"](4,0,null,1,33,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,32,"form",[["class","form"],["name","purgeForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,7).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,7).onReset()&&u),u},null,null)),t["\u0275did"](6,16384,null,0,u.D,[],null,null),t["\u0275did"](7,540672,[["formDir",4]],0,u.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,u.d,null,[u.l]),t["\u0275did"](9,16384,null,0,u.s,[[4,u.d]],null,null),(l()(),t["\u0275eld"](10,0,null,null,20,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,12,"p",[],null,null,null,null,null)),(l()(),t["\u0275eld"](12,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["To purge, select one or"])),(l()(),t["\u0275ted"](-1,null,["\xa0 "])),(l()(),t["\u0275eld"](15,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["All"])),(l()(),t["\u0275ted"](-1,null,["\xa0 "])),(l()(),t["\u0275eld"](18,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["pools and click"])),(l()(),t["\u0275ted"](-1,null,["\xa0 "])),(l()(),t["\u0275eld"](21,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Purge Trash"])),(l()(),t["\u0275ted"](-1,null,[".\xa0 "])),(l()(),t["\u0275eld"](24,0,null,null,6,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](25,0,null,null,1,"label",[["class","center-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Pool:"])),(l()(),t["\u0275and"](16777216,null,null,1,null,R)),t["\u0275did"](28,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,S)),t["\u0275did"](30,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](31,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](32,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](33,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.purge()&&t),t},c.b,c.a)),t["\u0275did"](34,114688,null,0,p.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Purge Trash"])),(l()(),t["\u0275eld"](36,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,m.b,m.a)),t["\u0275did"](37,49152,null,0,f.a,[r.Location,g.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,1,0,e.modalRef),l(n,7,0,e.purgeForm),l(n,28,0,!e.poolPermission.read),l(n,30,0,e.poolPermission.read),l(n,34,0,e.purgeForm),l(n,37,0,"Cancel",e.modalRef.hide)},function(l,n){l(n,5,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending)})}function E(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rbd-trash-purge-modal",[],null,null,null,k,w)),t["\u0275did"](1,114688,null,0,h.a,[a.a,v.a,b.a,y.a,C.a,_.a],null,null)],function(l,n){l(n,1,0)},null)}var F=t["\u0275ccf"]("cd-rbd-trash-purge-modal",h.a,E,{},{},[])},my5R:function(l,n,e){"use strict";e.d(n,"a",function(){return r});var t=e("mrSG"),u=e("t/Na"),i=e("xTzq"),o=e("CcnG"),a=e("pL04"),r=function(){function l(l){this.http=l}return l.prototype.listTargets=function(){return this.http.get("api/iscsi/target")},l.prototype.getTarget=function(l){return this.http.get("api/iscsi/target/"+l)},l.prototype.updateTarget=function(l,n){return this.http.put("api/iscsi/target/"+l,n,{observe:"response"})},l.prototype.status=function(){return this.http.get("ui-api/iscsi/status")},l.prototype.settings=function(){return this.http.get("ui-api/iscsi/settings")},l.prototype.version=function(){return this.http.get("ui-api/iscsi/version")},l.prototype.portals=function(){return this.http.get("ui-api/iscsi/portals")},l.prototype.createTarget=function(l){return this.http.post("api/iscsi/target",l,{observe:"response"})},l.prototype.deleteTarget=function(l){return this.http.delete("api/iscsi/target/"+l,{observe:"response"})},l.prototype.getDiscovery=function(){return this.http.get("api/iscsi/discoveryauth")},l.prototype.updateDiscovery=function(l){return this.http.put("api/iscsi/discoveryauth",l)},l.prototype.overview=function(){return this.http.get("ui-api/iscsi/overview")},l.ngInjectableDef=o.defineInjectable({factory:function(){return new l(o.inject(u.c))},token:l,providedIn:a.a}),l=t.__decorate([i.a,t.__metadata("design:paramtypes",[u.c])],l)}()},nP0W:function(l,n,e){"use strict";var t=e("CcnG"),u=e("gIcY"),i=e("EEJc"),o=e("ajRT"),a=e("Ip0R"),r=e("ANnk"),s=e("f/UV"),d=e("aexS"),c=e("gp3X"),p=e("sb0X"),m=e("KVJa"),f=e("Z21x"),g=e("sne2"),h=e("aa9H"),v=e("DQlY"),b=e("Jm/i"),y=e("XED3"),C=e("kn/O");e.d(n,"a",function(){return k});var _=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function w(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,u.v,[t.ElementRef,t.Renderer2,[2,u.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,u.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit.id),l(n,2,0,n.context.$implicit.id)},function(l,n){l(n,3,0,n.context.$implicit.name)})}function R(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Peer clusters must be removed prior to disabling mirror."]))],null,null)}function I(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,43,"cd-modal",[],null,null,null,i.c,i.b)),t["\u0275did"](1,49152,null,0,o.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Edit pool mirror mode"])),(l()(),t["\u0275eld"](4,0,null,1,39,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,38,"form",[["class","form"],["name","editModeForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,7).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,7).onReset()&&u),u},null,null)),t["\u0275did"](6,16384,null,0,u.D,[],null,null),t["\u0275did"](7,540672,[["formDir",4]],0,u.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,u.d,null,[u.l]),t["\u0275did"](9,16384,null,0,u.s,[[4,u.d]],null,null),(l()(),t["\u0275eld"](10,0,null,null,26,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,8,"p",[],null,null,null,null,null)),(l()(),t["\u0275eld"](12,0,null,null,7,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["To edit the mirror mode for pool\xa0 "])),(l()(),t["\u0275eld"](14,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](15,null,["",""])),(l()(),t["\u0275ted"](-1,null,[", select a new mode from the list and click\xa0 "])),(l()(),t["\u0275eld"](17,0,null,null,1,"kbd",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Update"])),(l()(),t["\u0275ted"](-1,null,["."])),(l()(),t["\u0275eld"](20,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](21,278528,null,0,a.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](22,{"has-error":0}),(l()(),t["\u0275eld"](23,0,null,null,2,"label",[["class","control-label"],["for","mirrorMode"]],null,null,null,null,null)),(l()(),t["\u0275eld"](24,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Mode"])),(l()(),t["\u0275eld"](26,0,null,null,8,"select",[["class","form-control"],["formControlName","mirrorMode"],["id","mirrorMode"],["name","mirrorMode"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var u=!0;return"change"===n&&(u=!1!==t["\u0275nov"](l,28).onChange(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,28).onTouched()&&u),u},null,null)),t["\u0275did"](27,4210688,null,0,r.a,[[2,s.a],d.a,t.ElementRef],null,null),t["\u0275did"](28,16384,null,0,u.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.z]),t["\u0275did"](30,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](32,16384,null,0,u.r,[[4,u.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,w)),t["\u0275did"](34,278528,null,0,a.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,R)),t["\u0275did"](36,16384,null,0,a.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](37,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](38,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](39,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.update()&&t),t},c.b,c.a)),t["\u0275did"](40,114688,null,0,p.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Update"])),(l()(),t["\u0275eld"](42,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,m.b,m.a)),t["\u0275did"](43,49152,null,0,f.a,[a.Location,g.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,1,0,e.modalRef),l(n,7,0,e.editModeForm);var u=l(n,22,0,e.editModeForm.showError("mirrorMode",t["\u0275nov"](n,7)));l(n,21,0,"form-group",u),l(n,30,0,"mirrorMode"),l(n,34,0,e.mirrorModes),l(n,36,0,e.editModeForm.showError("mirrorMode",t["\u0275nov"](n,7),"cannotDisable")),l(n,40,0,e.editModeForm),l(n,43,0,"Cancel",e.modalRef.hide)},function(l,n){var e=n.component;l(n,5,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending),l(n,15,0,e.poolName),l(n,26,0,t["\u0275nov"](n,32).ngClassUntouched,t["\u0275nov"](n,32).ngClassTouched,t["\u0275nov"](n,32).ngClassPristine,t["\u0275nov"](n,32).ngClassDirty,t["\u0275nov"](n,32).ngClassValid,t["\u0275nov"](n,32).ngClassInvalid,t["\u0275nov"](n,32).ngClassPending)})}function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-pool-edit-mode-modal",[],null,null,null,I,_)),t["\u0275did"](1,245760,null,0,h.a,[v.a,b.a,y.a,C.a],null,null)],function(l,n){l(n,1,0)},null)}var k=t["\u0275ccf"]("cd-pool-edit-mode-modal",h.a,S,{},{},[])},nhAp:function(l,n,e){"use strict";var t=e("CcnG"),u=e("gIcY"),i=e("ANnk"),o=e("f/UV"),a=e("aexS"),r=e("Ip0R"),s=e("eF8U"),d=e("jMP8"),c=e("uYzU"),p=e("EEJc"),m=e("ajRT"),f=e("gp3X"),g=e("sb0X"),h=e("KVJa"),v=e("Z21x"),b=e("sne2"),y=e("Z4cD"),C=e("DQlY"),_=e("my5R");e.d(n,"a",function(){return T});var w=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function R(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","invalid-feedback"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function I(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,29,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[["class","cd-header"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Identifier"])),(l()(),t["\u0275eld"](3,0,null,null,15,"div",[["class","form-group row"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,14,"div",[["class","col-sm-12"]],null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,3,"label",[["class","col-form-label"],["for","lun"]],null,null,null,null,null)),(l()(),t["\u0275eld"](6,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["lun"])),(l()(),t["\u0275eld"](8,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,7,"input",[["class","form-control"],["formControlName","lun"],["id","lun"],["name","lun"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,10)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,10).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,10)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,10)._compositionEnd(e.target.value)&&u),"change"===n&&(u=!1!==t["\u0275nov"](l,11).onChange(e.target.value)&&u),"input"===n&&(u=!1!==t["\u0275nov"](l,11).onChange(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,11).onTouched()&&u),u},null,null)),t["\u0275did"](10,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275did"](11,16384,null,0,u.C,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,u.p,function(l,n){return[l,n]},[u.e,u.C]),t["\u0275did"](13,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](15,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](16,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,R)),t["\u0275did"](18,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](19,0,null,null,10,"div",[["class","form-group row"]],null,null,null,null,null)),(l()(),t["\u0275eld"](20,0,null,null,9,"div",[["class","col-sm-12"]],null,null,null,null,null)),(l()(),t["\u0275eld"](21,0,null,null,1,"label",[["class","col-form-label"],["for","wwn"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["wwn"])),(l()(),t["\u0275eld"](23,0,null,null,6,"input",[["class","form-control"],["formControlName","wwn"],["id","wwn"],["name","wwn"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var u=!0;return"input"===n&&(u=!1!==t["\u0275nov"](l,24)._handleInput(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,24).onTouched()&&u),"compositionstart"===n&&(u=!1!==t["\u0275nov"](l,24)._compositionStart()&&u),"compositionend"===n&&(u=!1!==t["\u0275nov"](l,24)._compositionEnd(e.target.value)&&u),u},null,null)),t["\u0275did"](24,16384,null,0,u.e,[t.Renderer2,t.ElementRef,[2,u.b]],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.e]),t["\u0275did"](26,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](28,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](29,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null)],function(l,n){var e=n.component;l(n,13,0,"lun"),l(n,18,0,e.settingsForm.showError("lun",t["\u0275nov"](n.parent,12),"required")),l(n,26,0,"wwn")},function(l,n){l(n,9,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending),l(n,23,0,t["\u0275nov"](n,28).ngClassUntouched,t["\u0275nov"](n,28).ngClassTouched,t["\u0275nov"](n,28).ngClassPristine,t["\u0275nov"](n,28).ngClassDirty,t["\u0275nov"](n,28).ngClassValid,t["\u0275nov"](n,28).ngClassInvalid,t["\u0275nov"](n,28).ngClassPending)})}function S(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,4,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,u.v,[t.ElementRef,t.Renderer2,[2,u.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,u.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,["",""])),t["\u0275ppd"](4,1)],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){var e=t["\u0275unv"](n,3,0,l(n,4,0,t["\u0275nov"](n.parent,0),n.context.$implicit));l(n,3,0,e)})}function k(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,5,"div",[["class","form-group row"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,r.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,2,"div",[["class","col-sm-12"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"cd-iscsi-setting",[],null,null,null,s.b,s.a)),t["\u0275did"](5,114688,null,0,d.a,[],{settingsForm:[0,"settingsForm"],formDir:[1,"formDir"],setting:[2,"setting"],limits:[3,"limits"]},null)],function(l,n){var e=n.component,u=l(n,2,0,e.settingsForm.showError(n.context.$implicit.key,t["\u0275nov"](n.parent.parent.parent,12)));l(n,1,0,"form-group row",u),l(n,5,0,e.settingsForm,t["\u0275nov"](n.parent.parent.parent,12),n.context.$implicit.key,e.getDiskControlLimits(n.parent.parent.context.$implicit,n.context.$implicit.key))},null)}function E(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,null,null,null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,2,null,k)),t["\u0275did"](2,278528,null,0,r.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),t["\u0275pid"](0,r.KeyValuePipe,[t.KeyValueDiffers]),(l()(),t["\u0275and"](0,null,null,0))],function(l,n){var e=n.component;l(n,2,0,t["\u0275unv"](n,2,0,t["\u0275nov"](n,3).transform(e.disk_default_controls[n.parent.context.$implicit])))},null)}function F(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,null,null,null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,E)),t["\u0275did"](2,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](0,null,null,0))],function(l,n){l(n,2,0,n.component.settingsForm.value.backstore===n.context.$implicit)},null)}function D(l){return t["\u0275vid"](0,[t["\u0275pid"](0,c.a,[]),(l()(),t["\u0275eld"](1,0,null,null,42,"cd-modal",[],null,null,null,p.c,p.b)),t["\u0275did"](2,49152,null,0,m.a,[],{modalRef:[0,"modalRef"]},null),(l()(),t["\u0275eld"](3,0,null,0,5,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Configure"])),(l()(),t["\u0275ted"](-1,null,["\xa0 "])),(l()(),t["\u0275eld"](7,0,null,null,1,"small",[],null,null,null,null,null)),(l()(),t["\u0275ted"](8,null,["",""])),(l()(),t["\u0275eld"](9,0,null,1,34,null,null,null,null,null,null,null)),(l()(),t["\u0275eld"](10,0,null,null,33,"form",[["class","form"],["name","settingsForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var u=!0;return"submit"===n&&(u=!1!==t["\u0275nov"](l,12).onSubmit(e)&&u),"reset"===n&&(u=!1!==t["\u0275nov"](l,12).onReset()&&u),u},null,null)),t["\u0275did"](11,16384,null,0,u.D,[],null,null),t["\u0275did"](12,540672,[["formDir",4]],0,u.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,u.d,null,[u.l]),t["\u0275did"](14,16384,null,0,u.s,[[4,u.d]],null,null),(l()(),t["\u0275eld"](15,0,null,null,21,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](16,0,null,null,1,"p",[["class","alert-warning"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Changing these parameters from their default values is usually not necessary."])),(l()(),t["\u0275and"](16777216,null,null,1,null,I)),t["\u0275did"](19,16384,null,0,r.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](20,0,null,null,1,"legend",[["class","cd-header"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Settings"])),(l()(),t["\u0275eld"](22,0,null,null,12,"div",[["class","form-group row"]],null,null,null,null,null)),(l()(),t["\u0275eld"](23,0,null,null,11,"div",[["class","col-sm-12"]],null,null,null,null,null)),(l()(),t["\u0275eld"](24,0,null,null,1,"label",[["class","control-label"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Backstore"])),(l()(),t["\u0275eld"](26,0,null,null,8,"select",[["class","form-control"],["formControlName","backstore"],["id","backstore"],["name","backstore"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var u=!0;return"change"===n&&(u=!1!==t["\u0275nov"](l,27).onChange(e.target.value)&&u),"blur"===n&&(u=!1!==t["\u0275nov"](l,27).onTouched()&&u),u},null,null)),t["\u0275did"](27,16384,null,0,u.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,u.p,function(l){return[l]},[u.z]),t["\u0275did"](29,671744,null,0,u.j,[[3,u.d],[8,null],[8,null],[6,u.p],[2,u.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,u.q,null,[u.j]),t["\u0275did"](31,16384,null,0,u.r,[[4,u.q]],null,null),t["\u0275did"](32,4210688,null,0,i.a,[[2,o.a],a.a,t.ElementRef],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,S)),t["\u0275did"](34,278528,null,0,r.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,F)),t["\u0275did"](36,278528,null,0,r.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275eld"](37,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](38,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](39,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var t=!0;return"submitAction"===n&&(t=!1!==l.component.save()&&t),t},f.b,f.a)),t["\u0275did"](40,114688,null,0,g.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](-1,0,["Confirm"])),(l()(),t["\u0275eld"](42,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,h.b,h.a)),t["\u0275did"](43,49152,null,0,v.a,[r.Location,b.b],{name:[0,"name"],back:[1,"back"]},null)],function(l,n){var e=n.component;l(n,2,0,e.modalRef),l(n,12,0,e.settingsForm),l(n,19,0,e.api_version>=1),l(n,29,0,"backstore"),l(n,34,0,e.backstores),l(n,36,0,e.backstores),l(n,40,0,e.settingsForm),l(n,43,0,"Cancel",e.modalRef.hide)},function(l,n){l(n,8,0,n.component.image),l(n,10,0,t["\u0275nov"](n,14).ngClassUntouched,t["\u0275nov"](n,14).ngClassTouched,t["\u0275nov"](n,14).ngClassPristine,t["\u0275nov"](n,14).ngClassDirty,t["\u0275nov"](n,14).ngClassValid,t["\u0275nov"](n,14).ngClassInvalid,t["\u0275nov"](n,14).ngClassPending),l(n,26,0,t["\u0275nov"](n,31).ngClassUntouched,t["\u0275nov"](n,31).ngClassTouched,t["\u0275nov"](n,31).ngClassPristine,t["\u0275nov"](n,31).ngClassDirty,t["\u0275nov"](n,31).ngClassValid,t["\u0275nov"](n,31).ngClassInvalid,t["\u0275nov"](n,31).ngClassPending)})}function V(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-iscsi-target-image-settings-modal",[],null,null,null,D,w)),t["\u0275did"](1,114688,null,0,y.a,[C.a,_.a],null,null)],function(l,n){l(n,1,0)},null)}var T=t["\u0275ccf"]("cd-iscsi-target-image-settings-modal",y.a,V,{},{},[])},o8EM:function(l,n,e){"use strict";e.d(n,"a",function(){return o});var t=e("PhyI"),u=e("CcnG"),i=e("Jm/i"),o=function(){function l(l){this.i18n=l,this.sections=[{heading:this.i18n("Quality of Service"),class:"quality-of-service",options:[{name:"rbd_qos_bps_limit",displayName:this.i18n("BPS Limit"),description:this.i18n("The desired limit of IO bytes per second."),type:t.b.bps},{name:"rbd_qos_iops_limit",displayName:this.i18n("IOPS Limit"),description:this.i18n("The desired limit of IO operations per second."),type:t.b.iops},{name:"rbd_qos_read_bps_limit",displayName:this.i18n("Read BPS Limit"),description:this.i18n("The desired limit of read bytes per second."),type:t.b.bps},{name:"rbd_qos_read_iops_limit",displayName:this.i18n("Read IOPS Limit"),description:this.i18n("The desired limit of read operations per second."),type:t.b.iops},{name:"rbd_qos_write_bps_limit",displayName:this.i18n("Write BPS Limit"),description:this.i18n("The desired limit of write bytes per second."),type:t.b.bps},{name:"rbd_qos_write_iops_limit",displayName:this.i18n("Write IOPS Limit"),description:this.i18n("The desired limit of write operations per second."),type:t.b.iops},{name:"rbd_qos_bps_burst",displayName:this.i18n("BPS Burst"),description:this.i18n("The desired burst limit of IO bytes."),type:t.b.bps},{name:"rbd_qos_iops_burst",displayName:this.i18n("IOPS Burst"),description:this.i18n("The desired burst limit of IO operations."),type:t.b.iops},{name:"rbd_qos_read_bps_burst",displayName:this.i18n("Read BPS Burst"),description:this.i18n("The desired burst limit of read bytes."),type:t.b.bps},{name:"rbd_qos_read_iops_burst",displayName:this.i18n("Read IOPS Burst"),description:this.i18n("The desired burst limit of read operations."),type:t.b.iops},{name:"rbd_qos_write_bps_burst",displayName:this.i18n("Write BPS Burst"),description:this.i18n("The desired burst limit of write bytes."),type:t.b.bps},{name:"rbd_qos_write_iops_burst",displayName:this.i18n("Write IOPS Burst"),description:this.i18n("The desired burst limit of write operations."),type:t.b.iops}]}]}return l.getOptionsFromSections=function(l){return l.map(function(l){return l.options}).reduce(function(l,n){return l.concat(n)})},l.prototype.filterConfigOptionsByName=function(n){return l.getOptionsFromSections(this.sections).filter(function(l){return l.name===n})},l.prototype.getOptionValueByName=function(l,n,e){void 0===e&&(e="");var t=this.filterConfigOptionsByName(l);return 1===t.length?t.pop()[n]:e},l.prototype.getWritableSections=function(){return this.sections.map(function(l){return l.options=l.options.filter(function(l){return!l.readOnly}),l})},l.prototype.getOptionFields=function(){return l.getOptionsFromSections(this.sections)},l.prototype.getWritableOptionFields=function(){return l.getOptionsFromSections(this.getWritableSections())},l.prototype.getOptionByName=function(l){return this.filterConfigOptionsByName(l).pop()},l.prototype.getDisplayName=function(l){return this.getOptionValueByName(l,"displayName")},l.prototype.getDescription=function(l){return this.getOptionValueByName(l,"description")},l.ngInjectableDef=u.defineInjectable({factory:function(){return new l(u.inject(i.a))},token:l,providedIn:"root"}),l}()},rFfW:function(l,n,e){"use strict";e.d(n,"a",function(){return a});var t=e("CcnG"),u=e("gIcY"),i=e("QFaf"),o=e("PhyI"),a=(e("aXbf"),e("o8EM"),function(){function l(l,n){this.formatterService=l,this.rbdConfigurationService=n,this.changes=new t.EventEmitter,this.ngDataReady=new t.EventEmitter,this.configurationType=o.b,this.sectionVisibility={}}return l.prototype.ngOnInit=function(){var l=this,n=this.createConfigurationFormGroup();this.form.addControl("configuration",n),n.valueChanges.subscribe(function(){l.changes.emit(l.getDirtyValues.bind(l))}),this.initializeData&&this.initializeData.subscribe(function(n){l.initialData=n.initialData;var e=n.sourceType;l.rbdConfigurationService.getWritableOptionFields().forEach(function(t){var u=n.initialData.filter(function(l){return l.name===t.name}).pop();u&&u.source===e&&l.form.get("configuration."+t.name).setValue(u.value)}),l.ngDataReady.emit()}),this.rbdConfigurationService.getWritableSections().forEach(function(n){return l.sectionVisibility[n.class]=!1})},l.prototype.getDirtyValues=function(l,n){var e=this;if(void 0===l&&(l=!1),l&&!n)throw new Error("ProgrammingError: If local values shall be included, a proper localFieldType argument has to be provided, too");var t={};return this.rbdConfigurationService.getWritableOptionFields().forEach(function(u){var i=e.form.get("configuration").get(u.name);e.initialData&&e.initialData[u.name]===i.value||(i.dirty||l&&i.source===n)&&(t[u.name]=null===i.value?i.value:u.type===o.b.bps?e.formatterService.toBytes(i.value):u.type===o.b.milliseconds?e.formatterService.toMilliseconds(i.value):u.type===o.b.iops?e.formatterService.toIops(i.value):i.value)}),t},l.prototype.createConfigurationFormGroup=function(){var l=new i.a({});return this.rbdConfigurationService.getWritableOptionFields().forEach(function(n){var e;if(n.type!==o.b.milliseconds&&n.type!==o.b.iops&&n.type!==o.b.bps)throw new Error("Type "+n.type+" is unknown, you may need to add it to RbdConfiguration class");e=new u.i(0,u.A.min(0)),l.addControl(n.name,e)}),l},l.prototype.reset=function(l){var n=this.form.get("configuration").get(l);n.disabled?(n.setValue(n.previousValue||0),n.enable(),n.previousValue||n.markAsPristine()):(n.previousValue=n.value,n.setValue(null),n.markAsDirty(),n.disable())},l.prototype.isDisabled=function(l){return this.form.get("configuration").get(l).disabled},l.prototype.toggleSectionVisibility=function(l){this.sectionVisibility[l]=!this.sectionVisibility[l]},l}())},roDX:function(l,n,e){"use strict";e.d(n,"a",function(){return t}),e("my5R"),e("o4+5"),e("uYzU");var t=function(){function l(l,n,e,t){this.iscsiService=l,this.dimlessPipe=n,this.iscsiBackstorePipe=e,this.i18n=t,this.gateways=[],this.images=[]}return l.prototype.ngOnInit=function(){this.gatewaysColumns=[{name:this.i18n("Name"),prop:"name"},{name:this.i18n("State"),prop:"state",cellTemplate:this.statusColorTpl},{name:this.i18n("# Targets"),prop:"num_targets"},{name:this.i18n("# Sessions"),prop:"num_sessions"}],this.imagesColumns=[{name:this.i18n("Pool"),prop:"pool"},{name:this.i18n("Image"),prop:"image"},{name:this.i18n("Backstore"),prop:"backstore",pipe:this.iscsiBackstorePipe},{name:this.i18n("Read Bytes"),prop:"stats_history.rd_bytes",cellTemplate:this.iscsiSparklineTpl},{name:this.i18n("Write Bytes"),prop:"stats_history.wr_bytes",cellTemplate:this.iscsiSparklineTpl},{name:this.i18n("Read Ops"),prop:"stats.rd",pipe:this.dimlessPipe,cellTemplate:this.iscsiPerSecondTpl},{name:this.i18n("Write Ops"),prop:"stats.wr",pipe:this.dimlessPipe,cellTemplate:this.iscsiPerSecondTpl},{name:this.i18n("A/O Since"),prop:"optimized_since",cellTemplate:this.iscsiRelativeDateTpl}]},l.prototype.refresh=function(){var l=this;this.iscsiService.overview().subscribe(function(n){l.gateways=n.gateways,l.images=n.images,l.images.map(function(l){return l.stats_history&&(l.stats_history.rd_bytes=l.stats_history.rd_bytes.map(function(l){return l[1]}),l.stats_history.wr_bytes=l.stats_history.wr_bytes.map(function(l){return l[1]})),l.cdIsBinary=!0,l})})},l}()},u0yg:function(l,n,e){"use strict";e.d(n,"b",function(){return t}),e.d(n,"a",function(){return u});var t=function(){return function(){}}(),u=function(l){return l[l.V1=1]="V1",l[l.V2=2]="V2",l}({})},u2XS:function(l,n,e){"use strict";var t=e("CcnG"),u=e("Ip0R"),i=e("25BL"),o=e("uIqm"),a=e("nuQ0"),r=e("Tff5"),s=e("urB8"),d=e("xtUU"),c=e("3ris"),p=e("Jm/i"),m=e("uYzU"),f=e("iExv");e.d(n,"b",function(){return g}),e.d(n,"c",function(){return _}),e.d(n,"a",function(){return R});var g=t["\u0275crt"]({encapsulation:0,styles:[["tree .fa{font-weight:unset!important}"]],data:{}});function h(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","node-name"]],[[8,"innerHTML",1]],null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["\xa0"])),(l()(),t["\u0275eld"](3,0,null,null,5,"span",[["class","label"]],null,null,null,null,null)),t["\u0275did"](4,278528,null,0,u.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pad"](5,1),t["\u0275pad"](6,1),t["\u0275pod"](7,{"label-success":0,"label-danger":1}),(l()(),t["\u0275ted"](8,null,[" "," "]))],function(l,n){var e=l(n,7,0,l(n,5,0,"logged_in").includes(n.context.$implicit.status),l(n,6,0,"logged_out").includes(n.context.$implicit.status));l(n,4,0,"label",e)},function(l,n){l(n,0,0,n.context.$implicit.value),l(n,8,0,n.context.$implicit.status)})}function v(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,4,"div",[["class","col-sm-6 col-lg-6 metadata"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](2,null,["",""])),(l()(),t["\u0275eld"](3,0,null,null,1,"cd-table",[["columnMode","flex"]],null,null,null,i.b,i.a)),t["\u0275did"](4,2867200,[[2,4],["detailTable",4]],0,o.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],limit:[3,"limit"]},null)],function(l,n){var e=n.component;l(n,4,0,e.data,e.columns,"flex",0)},function(l,n){l(n,2,0,n.component.title)})}function b(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,["",""]))],null,function(l,n){l(n,1,0,n.parent.context.value)})}function y(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,["",""]))],null,function(l,n){l(n,1,0,n.parent.context.value)})}function C(l){return t["\u0275vid"](0,[(l()(),t["\u0275and"](16777216,null,null,1,null,b)),t["\u0275did"](1,16384,null,0,u.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,y)),t["\u0275did"](3,16384,null,0,u.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,void 0===n.context.row.default||n.context.row.default===n.context.row.current),l(n,3,0,void 0!==n.context.row.default&&n.context.row.default!==n.context.row.current)},null)}function _(l){return t["\u0275vid"](0,[t["\u0275qud"](402653184,1,{highlightTpl:0}),t["\u0275qud"](671088640,2,{content:0}),(l()(),t["\u0275eld"](2,0,null,null,7,"div",[["class","col-sm-6 col-lg-6"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["iSCSI Topology"])),(l()(),t["\u0275eld"](5,0,null,null,4,"tree",[],null,[[null,"nodeSelected"]],function(l,n,e){var t=!0;return"nodeSelected"===n&&(t=!1!==l.component.onNodeSelected(e)&&t),t},a.b,a.a)),t["\u0275prd"](512,null,r.TreeService,r.TreeService,[s.NodeDraggableService]),t["\u0275did"](7,770048,null,1,d.TreeComponent,[r.TreeService],{treeModel:[0,"treeModel"]},{nodeSelected:"nodeSelected"}),t["\u0275qud"](335544320,3,{template:0}),(l()(),t["\u0275and"](0,[[3,2]],null,0,null,h)),(l()(),t["\u0275and"](16777216,null,null,1,null,v)),t["\u0275did"](11,16384,null,0,u.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](0,[[1,2],["highlightTpl",2]],null,0,null,C))],function(l,n){var e=n.component;l(n,7,0,e.tree),l(n,11,0,e.data)},null)}function w(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-iscsi-target-details",[],null,null,null,_,g)),t["\u0275did"](1,638976,null,0,c.a,[p.a,m.a,f.a],null,null)],function(l,n){l(n,1,0)},null)}var R=t["\u0275ccf"]("cd-iscsi-target-details",c.a,w,{selection:"selection",settings:"settings",cephIscsiConfigVersion:"cephIscsiConfigVersion"},{},[])},wG1H:function(l,n,e){"use strict";e.d(n,"a",function(){return t}),e("aexS");var t=function(){function l(l){this.authStorageService=l,this.grafanaPermission=this.authStorageService.getPermissions().grafana}return l.prototype.ngOnInit=function(){},l}()}}]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt b/src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt new file mode 100644 index 00000000..ebb3801d --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/3rdpartylicenses.txt @@ -0,0 +1,1462 @@ +@angular/animations +MIT + +@angular/common +MIT + +@angular/core +MIT + +@angular/forms +MIT + +@angular/platform-browser +MIT + +@angular/router +MIT + +@ngx-translate/i18n-polyfill +MIT + +@swimlane/ngx-datatable +MIT +(The MIT License) + +Copyright (c) 2016 Swimlane + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +awesome-bootstrap-checkbox +MIT +The MIT License (MIT) + +Copyright (c) 2014 flatlogic.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +bootstrap +MIT +The MIT License (MIT) + +Copyright (c) 2011-2019 Twitter, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +chart.js +MIT +The MIT License (MIT) + +Copyright (c) 2018 Chart.js Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +chartjs-color +MIT +Copyright (c) 2012 Heather Arthur + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +chartjs-color-string +MIT +Copyright (c) 2011 Heather Arthur + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +color-convert +Copyright (c) 2011 Heather Arthur + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +color-name +MIT +The MIT License (MIT) +Copyright (c) 2015 Dmitry Ivanov + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +core-js +MIT +Copyright (c) 2014-2019 Denis Pushkarev + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +detect-browser +MIT +The MIT License (MIT) + +Copyright (c) 2019 Damon Oehlman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +fork-awesome +(OFL-1.1 AND MIT) +/!\ The MIT License only applies to all CSS and LESS files in the following +directories: fork-awesome/css/, fork-awesome/less/, and fork-awesome/scss/. + +MIT License + +Copyright (c) 2018 Dave Gandy & Fork Awesome + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +******************************************************************************* + +/!\ The Creative Commons Attribution 3.0 Unported License applies to all Fork +Awesome project files that are not a part of the Font or Code licenses. + +Creative Commons Legal Code + +Attribution 3.0 Unported + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR + DAMAGES RESULTING FROM ITS USE. + +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +CONDITIONS. + +1. Definitions + + a. "Adaptation" means a work based upon the Work, or upon the Work and + other pre-existing works, such as a translation, adaptation, + derivative work, arrangement of music or other alterations of a + literary or artistic work, or phonogram or performance and includes + cinematographic adaptations or any other form in which the Work may be + recast, transformed, or adapted including in any form recognizably + derived from the original, except that a work that constitutes a + Collection will not be considered an Adaptation for the purpose of + this License. For the avoidance of doubt, where the Work is a musical + work, performance or phonogram, the synchronization of the Work in + timed-relation with a moving image ("synching") will be considered an + Adaptation for the purpose of this License. + b. "Collection" means a collection of literary or artistic works, such as + encyclopedias and anthologies, or performances, phonograms or + broadcasts, or other works or subject matter other than works listed + in Section 1(f) below, which, by reason of the selection and + arrangement of their contents, constitute intellectual creations, in + which the Work is included in its entirety in unmodified form along + with one or more other contributions, each constituting separate and + independent works in themselves, which together are assembled into a + collective whole. A work that constitutes a Collection will not be + considered an Adaptation (as defined above) for the purposes of this + License. + c. "Distribute" means to make available to the public the original and + copies of the Work or Adaptation, as appropriate, through sale or + other transfer of ownership. + d. "Licensor" means the individual, individuals, entity or entities that + offer(s) the Work under the terms of this License. + e. "Original Author" means, in the case of a literary or artistic work, + the individual, individuals, entity or entities who created the Work + or if no individual or entity can be identified, the publisher; and in + addition (i) in the case of a performance the actors, singers, + musicians, dancers, and other persons who act, sing, deliver, declaim, + play in, interpret or otherwise perform literary or artistic works or + expressions of folklore; (ii) in the case of a phonogram the producer + being the person or legal entity who first fixes the sounds of a + performance or other sounds; and, (iii) in the case of broadcasts, the + organization that transmits the broadcast. + f. "Work" means the literary and/or artistic work offered under the terms + of this License including without limitation any production in the + literary, scientific and artistic domain, whatever may be the mode or + form of its expression including digital form, such as a book, + pamphlet and other writing; a lecture, address, sermon or other work + of the same nature; a dramatic or dramatico-musical work; a + choreographic work or entertainment in dumb show; a musical + composition with or without words; a cinematographic work to which are + assimilated works expressed by a process analogous to cinematography; + a work of drawing, painting, architecture, sculpture, engraving or + lithography; a photographic work to which are assimilated works + expressed by a process analogous to photography; a work of applied + art; an illustration, map, plan, sketch or three-dimensional work + relative to geography, topography, architecture or science; a + performance; a broadcast; a phonogram; a compilation of data to the + extent it is protected as a copyrightable work; or a work performed by + a variety or circus performer to the extent it is not otherwise + considered a literary or artistic work. + g. "You" means an individual or entity exercising rights under this + License who has not previously violated the terms of this License with + respect to the Work, or who has received express permission from the + Licensor to exercise rights under this License despite a previous + violation. + h. "Publicly Perform" means to perform public recitations of the Work and + to communicate to the public those public recitations, by any means or + process, including by wire or wireless means or public digital + performances; to make available to the public Works in such a way that + members of the public may access these Works from a place and at a + place individually chosen by them; to perform the Work to the public + by any means or process and the communication to the public of the + performances of the Work, including by public digital performance; to + broadcast and rebroadcast the Work by any means including signs, + sounds or images. + i. "Reproduce" means to make copies of the Work by any means including + without limitation by sound or visual recordings and the right of + fixation and reproducing fixations of the Work, including storage of a + protected performance or phonogram in digital form or other electronic + medium. + +2. Fair Dealing Rights. Nothing in this License is intended to reduce, +limit, or restrict any uses free from copyright or rights arising from +limitations or exceptions that are provided for in connection with the +copyright protection under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, +Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +perpetual (for the duration of the applicable copyright) license to +exercise the rights in the Work as stated below: + + a. to Reproduce the Work, to incorporate the Work into one or more + Collections, and to Reproduce the Work as incorporated in the + Collections; + b. to create and Reproduce Adaptations provided that any such Adaptation, + including any translation in any medium, takes reasonable steps to + clearly label, demarcate or otherwise identify that changes were made + to the original Work. For example, a translation could be marked "The + original work was translated from English to Spanish," or a + modification could indicate "The original work has been modified."; + c. to Distribute and Publicly Perform the Work including as incorporated + in Collections; and, + d. to Distribute and Publicly Perform Adaptations. + e. For the avoidance of doubt: + + i. Non-waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme cannot be waived, the Licensor + reserves the exclusive right to collect such royalties for any + exercise by You of the rights granted under this License; + ii. Waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme can be waived, the Licensor waives the + exclusive right to collect such royalties for any exercise by You + of the rights granted under this License; and, + iii. Voluntary License Schemes. The Licensor waives the right to + collect royalties, whether individually or, in the event that the + Licensor is a member of a collecting society that administers + voluntary licensing schemes, via that society, from any exercise + by You of the rights granted under this License. + +The above rights may be exercised in all media and formats whether now +known or hereafter devised. The above rights include the right to make +such modifications as are technically necessary to exercise the rights in +other media and formats. Subject to Section 8(f), all rights not expressly +granted by Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly made +subject to and limited by the following restrictions: + + a. You may Distribute or Publicly Perform the Work only under the terms + of this License. You must include a copy of, or the Uniform Resource + Identifier (URI) for, this License with every copy of the Work You + Distribute or Publicly Perform. You may not offer or impose any terms + on the Work that restrict the terms of this License or the ability of + the recipient of the Work to exercise the rights granted to that + recipient under the terms of the License. You may not sublicense the + Work. You must keep intact all notices that refer to this License and + to the disclaimer of warranties with every copy of the Work You + Distribute or Publicly Perform. When You Distribute or Publicly + Perform the Work, You may not impose any effective technological + measures on the Work that restrict the ability of a recipient of the + Work from You to exercise the rights granted to that recipient under + the terms of the License. This Section 4(a) applies to the Work as + incorporated in a Collection, but this does not require the Collection + apart from the Work itself to be made subject to the terms of this + License. If You create a Collection, upon notice from any Licensor You + must, to the extent practicable, remove from the Collection any credit + as required by Section 4(b), as requested. If You create an + Adaptation, upon notice from any Licensor You must, to the extent + practicable, remove from the Adaptation any credit as required by + Section 4(b), as requested. + b. If You Distribute, or Publicly Perform the Work or any Adaptations or + Collections, You must, unless a request has been made pursuant to + Section 4(a), keep intact all copyright notices for the Work and + provide, reasonable to the medium or means You are utilizing: (i) the + name of the Original Author (or pseudonym, if applicable) if supplied, + and/or if the Original Author and/or Licensor designate another party + or parties (e.g., a sponsor institute, publishing entity, journal) for + attribution ("Attribution Parties") in Licensor's copyright notice, + terms of service or by other reasonable means, the name of such party + or parties; (ii) the title of the Work if supplied; (iii) to the + extent reasonably practicable, the URI, if any, that Licensor + specifies to be associated with the Work, unless such URI does not + refer to the copyright notice or licensing information for the Work; + and (iv) , consistent with Section 3(b), in the case of an Adaptation, + a credit identifying the use of the Work in the Adaptation (e.g., + "French translation of the Work by Original Author," or "Screenplay + based on original Work by Original Author"). The credit required by + this Section 4 (b) may be implemented in any reasonable manner; + provided, however, that in the case of a Adaptation or Collection, at + a minimum such credit will appear, if a credit for all contributing + authors of the Adaptation or Collection appears, then as part of these + credits and in a manner at least as prominent as the credits for the + other contributing authors. For the avoidance of doubt, You may only + use the credit required by this Section for the purpose of attribution + in the manner set out above and, by exercising Your rights under this + License, You may not implicitly or explicitly assert or imply any + connection with, sponsorship or endorsement by the Original Author, + Licensor and/or Attribution Parties, as appropriate, of You or Your + use of the Work, without the separate, express prior written + permission of the Original Author, Licensor and/or Attribution + Parties. + c. Except as otherwise agreed in writing by the Licensor or as may be + otherwise permitted by applicable law, if You Reproduce, Distribute or + Publicly Perform the Work either by itself or as part of any + Adaptations or Collections, You must not distort, mutilate, modify or + take other derogatory action in relation to the Work which would be + prejudicial to the Original Author's honor or reputation. Licensor + agrees that in those jurisdictions (e.g. Japan), in which any exercise + of the right granted in Section 3(b) of this License (the right to + make Adaptations) would be deemed to be a distortion, mutilation, + modification or other derogatory action prejudicial to the Original + Author's honor and reputation, the Licensor will waive or not assert, + as appropriate, this Section, to the fullest extent permitted by the + applicable national law, to enable You to reasonably exercise Your + right under Section 3(b) of this License (right to make Adaptations) + but not otherwise. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION +OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE +LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR +ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES +ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + a. This License and the rights granted hereunder will terminate + automatically upon any breach by You of the terms of this License. + Individuals or entities who have received Adaptations or Collections + from You under this License, however, will not have their licenses + terminated provided such individuals or entities remain in full + compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will + survive any termination of this License. + b. Subject to the above terms and conditions, the license granted here is + perpetual (for the duration of the applicable copyright in the Work). + Notwithstanding the above, Licensor reserves the right to release the + Work under different license terms or to stop distributing the Work at + any time; provided, however that any such election will not serve to + withdraw this License (or any other license that has been, or is + required to be, granted under the terms of this License), and this + License will continue in full force and effect unless terminated as + stated above. + +8. Miscellaneous + + a. Each time You Distribute or Publicly Perform the Work or a Collection, + the Licensor offers to the recipient a license to the Work on the same + terms and conditions as the license granted to You under this License. + b. Each time You Distribute or Publicly Perform an Adaptation, Licensor + offers to the recipient a license to the original Work on the same + terms and conditions as the license granted to You under this License. + c. If any provision of this License is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this License, and without further action + by the parties to this agreement, such provision shall be reformed to + the minimum extent necessary to make such provision valid and + enforceable. + d. No term or provision of this License shall be deemed waived and no + breach consented to unless such waiver or consent shall be in writing + and signed by the party to be charged with such waiver or consent. + e. This License constitutes the entire agreement between the parties with + respect to the Work licensed here. There are no understandings, + agreements or representations with respect to the Work not specified + here. Licensor shall not be bound by any additional provisions that + may appear in any communication from You. This License may not be + modified without the mutual written agreement of the Licensor and You. + f. The rights granted under, and the subject matter referenced, in this + License were drafted utilizing the terminology of the Berne Convention + for the Protection of Literary and Artistic Works (as amended on + September 28, 1979), the Rome Convention of 1961, the WIPO Copyright + Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 + and the Universal Copyright Convention (as revised on July 24, 1971). + These rights and subject matter take effect in the relevant + jurisdiction in which the License terms are sought to be enforced + according to the corresponding provisions of the implementation of + those treaty provisions in the applicable national law. If the + standard suite of rights granted under applicable copyright law + includes additional rights not granted under this License, such + additional rights are deemed to be included in the License; this + License is not intended to restrict the license of any rights under + applicable law. + + +Creative Commons Notice + + Creative Commons is not a party to this License, and makes no warranty + whatsoever in connection with the Work. Creative Commons will not be + liable to You or any party on any legal theory for any damages + whatsoever, including without limitation any general, special, + incidental or consequential damages arising in connection to this + license. Notwithstanding the foregoing two (2) sentences, if Creative + Commons has expressly identified itself as the Licensor hereunder, it + shall have all rights and obligations of Licensor. + + Except for the limited purpose of indicating to the public that the + Work is licensed under the CCPL, Creative Commons does not authorize + the use by either party of the trademark "Creative Commons" or any + related trademark or logo of Creative Commons without the prior + written consent of Creative Commons. Any permitted use will be in + compliance with Creative Commons' then-current trademark usage + guidelines, as may be published on its website or otherwise made + available upon request from time to time. For the avoidance of doubt, + this trademark restriction does not form part of this License. + + Creative Commons may be contacted at https://creativecommons.org/. + +******************************************************************************* + +/!\ The SIL OPEN FONT LICENSE applies to all desktop and webfont files in the +following directory: fonts/ and to all glyphs and SVG files in the following +directory: src/icons/svg/. + + +Copyright (c) 2018, Fork Awesome (https://forkawesome.github.io), +with Reserved Font Name Fork Awesome. + + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + +lodash +MIT +Copyright OpenJS Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +moment +MIT +Copyright (c) JS Foundation and other contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + +ng-block-ui +MIT +MIT License + +Copyright (c) 2017 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +ng2-charts +MIT +The MIT License (MIT) + +Copyright (c) 2015-2017 Dmitriy Shekhovtsov +Copyright (c) 2015-2017 Valor Software + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + +ng2-tree +MIT + +ngx-bootstrap/accordion + +ngx-bootstrap/alert + +ngx-bootstrap/chronos +The MIT License (MIT) + +Copyright (c) Valor Software +Copyright (c) Dmitriy Shekhovtsov +Copyright (c) moment/moment +Copyright (c) JS Foundation and other contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + +ngx-bootstrap/collapse + +ngx-bootstrap/component-loader + +ngx-bootstrap/datepicker + +ngx-bootstrap/dropdown + +ngx-bootstrap/mini-ngrx + +ngx-bootstrap/modal + +ngx-bootstrap/popover + +ngx-bootstrap/positioning + +ngx-bootstrap/progressbar + +ngx-bootstrap/tabs + +ngx-bootstrap/timepicker + +ngx-bootstrap/tooltip + +ngx-bootstrap/typeahead + +ngx-bootstrap/utils + +ngx-toastr +MIT +The MIT License (MIT) + +Copyright (c) 2018 Scott Cooper + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +undefined + +rxjs +Apache-2.0 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2015-2018 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +rxjs-compat +Apache-2.0 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2015-2018 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +tslib +Apache-2.0 +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + + +uuid +MIT +The MIT License (MIT) + +Copyright (c) 2010-2016 Robert Kieffer and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +webpack +MIT +Copyright JS Foundation and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +zone.js +MIT +The MIT License + +Copyright (c) 2016-2018 Google, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/6.f054f1f260c137d64363.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/6.f054f1f260c137d64363.js new file mode 100644 index 00000000..361e2741 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/6.f054f1f260c137d64363.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{EmSq:function(l,n,u){"use strict";u.d(n,"a",function(){return i});var e=u("CcnG"),t=u("LvDl"),i=(u("Fgil"),u("aXbf"),function(){function l(l,n,u,t){this.elementRef=l,this.control=n,this.dimlessBinaryPipe=u,this.formatter=t,this.ngModelChange=new e.EventEmitter,this.el=this.elementRef.nativeElement}return l.prototype.ngOnInit=function(){this.setValue(this.el.value)},l.prototype.setValue=function(l){/^[\d.]+$/.test(l)&&(l+=this.defaultUnit||"m");var n=this.formatter.toBytes(l),u=this.round(n);this.el.value=this.dimlessBinaryPipe.transform(u),null!==n?(this.ngModelChange.emit(this.el.value),this.control.control.setValue(this.el.value)):(this.ngModelChange.emit(null),this.control.control.setValue(null))},l.prototype.round=function(l){if(null!==l&&0!==l){if(!t.isUndefined(this.minBytes)&&lthis.maxBytes)return this.maxBytes;if(!t.isUndefined(this.roundPower)){var n=Math.round(Math.log(l)/Math.log(this.roundPower));return Math.pow(this.roundPower,n)}}return l},l.prototype.onBlur=function(l){this.setValue(l)},l}())},OcYo:function(l,n,u){"use strict";u.d(n,"a",function(){return e});var e=function(){function l(l,n,u){this.elementRef=l,this.renderer=n,this.toastr=u}return l.prototype.ngOnInit=function(){var l=this.renderer.createElement("i");this.renderer.addClass(l,"icon-prepend"),this.renderer.addClass(l,"fa"),this.renderer.addClass(l,"fa-clipboard"),this.renderer.appendChild(this.elementRef.nativeElement,l)},l.prototype.getInputElement=function(){return document.getElementById(this.cdCopy2ClipboardButton)},l.prototype.onClick=function(){try{var l=document.createElement("input");l.value=this.getInputElement().value,document.body.appendChild(l),l.select(),document.execCommand("copy"),document.body.removeChild(l),this.toastr.success("Copied text to the clipboard successfully.")}catch(n){this.toastr.error("Failed to copy text to the clipboard.")}},l}()},Znkk:function(l,n,u){"use strict";u.r(n);var e,t=u("CcnG"),i=u("sne2"),o=u("Avrn"),a=u("+0ag"),r=u("mSOc"),s=function(){function l(l,n,u){this.route=l,this.summaryService=n,this.cephReleaseNamePipe=u,this.message="The Object Gateway service is not configured."}return l.prototype.ngOnInit=function(){var l=this,n=this.summaryService.subscribe(function(u){if(u){var e=l.cephReleaseNamePipe.transform(u.version);l.docsUrl="http://docs.ceph.com/docs/"+e+"/mgr/dashboard/#enabling-the-object-gateway-management-frontend",setTimeout(function(){n.unsubscribe()},0)}});this.routeParamsSubscribe=this.route.params.subscribe(function(n){l.message=n.message})},l.prototype.ngOnDestroy=function(){this.routeParamsSubscribe.unsubscribe()},l}(),d=u("gIcY"),c=u("LvDl"),p=u("mrSG"),f=u("t/Na"),m=u("F/XL"),g=u("psW0"),v=u("xTzq"),b=u("pL04"),h=function(){function l(l){this.http=l,this.url="api/rgw/bucket"}return l.prototype.list=function(){var l=new f.h;return l=l.append("stats","true"),this.http.get(this.url,{params:l})},l.prototype.enumerate=function(){return this.http.get(this.url)},l.prototype.get=function(l){return this.http.get(this.url+"/"+l)},l.prototype.create=function(l,n){var u=new f.h;return u=(u=u.append("bucket",l)).append("uid",n),this.http.post(this.url,null,{params:u})},l.prototype.update=function(l,n,u){var e=new f.h;return e=(e=e.append("bucket_id",n)).append("uid",u),this.http.put(this.url+"/"+l,null,{params:e})},l.prototype.delete=function(l,n){void 0===n&&(n=!0);var u=new f.h;return u=u.append("purge_objects",n?"true":"false"),this.http.delete(this.url+"/"+l,{params:u})},l.prototype.exists=function(l){return this.enumerate().pipe(Object(g.a)(function(n){var u=c.indexOf(n,l);return Object(m.a)(-1!==u)}))},l.ngInjectableDef=t.defineInjectable({factory:function(){return new l(t.inject(f.c))},token:l,providedIn:b.a}),l=p.__decorate([v.a,p.__metadata("design:paramtypes",[f.c])],l)}(),y=u("P8lu"),C=u("mtw6"),_=u("2EZI"),k=u("9nlD"),R=function(){function l(l,n,u,e,t,o,a,r){this.route=l,this.router=n,this.formBuilder=u,this.rgwBucketService=e,this.rgwUserService=t,this.notificationService=o,this.i18n=a,this.actionLabels=r,this.editing=!1,this.error=!1,this.loading=!1,this.owners=null,this.editing=this.router.url.startsWith("/rgw/bucket/"+i.e.EDIT),this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE,this.resource=this.i18n("bucket"),this.createForm()}return l.prototype.createForm=function(){this.bucketForm=this.formBuilder.group({id:[null],bid:[null,[d.A.required],[this.bucketNameValidator()]],owner:[null,[d.A.required]]})},l.prototype.ngOnInit=function(){var l=this;this.rgwUserService.enumerate().subscribe(function(n){l.owners=n.sort()}),this.route.params.subscribe(function(n){if(n.hasOwnProperty("bid")){var u=decodeURIComponent(n.bid);l.loading=!0,l.rgwBucketService.get(u).subscribe(function(n){l.loading=!1;var u=c.clone(l.bucketForm.value),e=c.pick(n,c.keys(l.bucketForm.value));e=c.merge(u,e),l.bucketForm.setValue(e)})}},function(n){l.error=n})},l.prototype.goToListView=function(){this.router.navigate(["/rgw/bucket"])},l.prototype.submit=function(){var l=this;if(this.bucketForm.pristine)this.goToListView();else{var n=this.bucketForm.get("bid"),u=this.bucketForm.get("owner");if(this.editing){var e=this.bucketForm.get("id");this.rgwBucketService.update(n.value,e.value,u.value).subscribe(function(){l.notificationService.show(C.a.success,l.i18n('Updated Object Gateway bucket "{{bid}}"',{bid:n.value})),l.goToListView()},function(){l.bucketForm.setErrors({cdSubmitButton:!0})})}else this.rgwBucketService.create(n.value,u.value).subscribe(function(){l.notificationService.show(C.a.success,l.i18n('Created Object Gateway bucket "{{bid}}"',{bid:n.value})),l.goToListView()},function(){l.bucketForm.setErrors({cdSubmitButton:!0})})}},l.prototype.bucketNameValidator=function(){var l=this.rgwBucketService;return function(n){return new Promise(function(u){n.pristine||""===n.value?u(null):/^[0-9A-Za-z][\w-\.]{2,254}$/.test(n.value)?l.exists(n.value).subscribe(function(l){u(l?{bucketNameExists:!0}:null)}):u({bucketNameInvalid:!0})})}},l}(),I=u("6blF"),w=u("VNr4"),E=u("0+/T"),x=u("uIqm"),T=u("vCyI"),q=u("Fgil"),V=u("o4+5"),S=u("aexS"),D=u("EgGo"),N=new D.a("rgw/bucket"),F=function(){function l(l,n,u,e,t,i,o,a,r){var s=this;this.authStorageService=l,this.dimlessBinaryPipe=n,this.dimlessPipe=u,this.rgwBucketService=e,this.bsModalService=t,this.i18n=i,this.urlBuilder=o,this.actionLabels=a,this.changeDetectorRef=r,this.columns=[],this.buckets=[],this.selection=new T.a,this.permission=this.authStorageService.getPermissions().rgw,this.tableActions=[{permission:"create",icon:"fa-plus",routerLink:function(){return s.urlBuilder.getCreate()},name:this.actionLabels.CREATE},{permission:"update",icon:"fa-pencil",routerLink:function(){return s.urlBuilder.getEdit(s.selection.first()&&""+encodeURIComponent(s.selection.first().bid))},name:this.actionLabels.EDIT},{permission:"delete",icon:"fa-times",click:function(){return s.deleteAction()},name:this.actionLabels.DELETE}]}return l.prototype.ngOnInit=function(){this.columns=[{name:this.i18n("Name"),prop:"bid",flexGrow:2},{name:this.i18n("Owner"),prop:"owner",flexGrow:3},{name:this.i18n("Used Capacity"),prop:"bucket_size",flexGrow:.5,pipe:this.dimlessBinaryPipe},{name:this.i18n("Capacity Limit %"),prop:"size_usage",cellTemplate:this.bucketSizeTpl,flexGrow:1},{name:this.i18n("Objects"),prop:"num_objects",flexGrow:.5,pipe:this.dimlessPipe},{name:this.i18n("Object Limit %"),prop:"object_usage",cellTemplate:this.bucketObjectTpl,flexGrow:1}]},l.prototype.transformBucketData=function(){c.forEach(this.buckets,function(l){var n=l.bucket_quota.max_size,u=l.bucket_quota.max_objects,e=0,t=0;c.forEach(l.usage,function(l){e+=l.size_actual,t+=l.num_objects}),l.bucket_size=e,l.num_objects=t,l.size_usage=n>0?e/n:void 0,l.object_usage=u>0?t/u:void 0})},l.prototype.getBucketList=function(l){var n=this;this.rgwBucketService.list().subscribe(function(l){n.buckets=l,n.transformBucketData(),n.changeDetectorRef.detectChanges()},function(){l.error()})},l.prototype.updateSelection=function(l){this.selection=l},l.prototype.deleteAction=function(){var l=this;this.bsModalService.show(E.a,{initialState:{itemDescription:this.i18n(this.selection.hasSingleSelection?"bucket":"buckets"),itemNames:this.selection.selected.map(function(l){return l.bid}),submitActionObservable:function(){return new I.a(function(n){Object(w.a)(l.selection.selected.map(function(n){return l.rgwBucketService.delete(n.bid)})).subscribe(null,function(u){n.error(u),l.table.refreshBtn()},function(){n.complete(),l.table.refreshBtn()})})}}})},l}(),j=function(){function l(l){this.http=l,this.url="api/rgw/daemon"}return l.prototype.list=function(){return this.http.get(this.url)},l.prototype.get=function(l){return this.http.get(this.url+"/"+l)},l.ngInjectableDef=t.defineInjectable({factory:function(){return new l(t.inject(f.c))},token:l,providedIn:b.a}),l=p.__decorate([v.a,p.__metadata("design:paramtypes",[f.c])],l)}(),P=u("85J/"),z=function(){function l(l,n,u,e){this.rgwDaemonService=l,this.authStorageService=n,this.i18n=e,this.columns=[],this.daemons=[],this.selection=new T.a,this.grafanaPermission=this.authStorageService.getPermissions().grafana,this.columns=[{name:this.i18n("ID"),prop:"id",flexGrow:2},{name:this.i18n("Hostname"),prop:"server_hostname",flexGrow:2},{name:this.i18n("Version"),prop:"version",flexGrow:1,pipe:u}]}return l.prototype.getDaemonList=function(l){var n=this;this.rgwDaemonService.list().subscribe(function(l){n.daemons=l},function(){l.error()})},l.prototype.updateSelection=function(l){this.selection=l},l}(),A=u("dEwP"),B=u("1Ni5"),U=u("aXbf");!function(l){l.USERS="users",l.BUCKETS="buckets",l.METADATA="metadata",l.USAGE="usage",l.ZONE="zone"}(e||(e={}));var M=function(){function l(){}return l.getAll=function(){return Object.values(l.capabilities)},l.capabilities=e,l}(),O=function(){function l(l,n,u,e){this.formBuilder=l,this.bsModalRef=n,this.i18n=u,this.actionLabels=e,this.submitAction=new t.EventEmitter,this.editing=!0,this.types=[],this.resource=this.i18n("capability"),this.createForm()}return l.prototype.createForm=function(){this.formGroup=this.formBuilder.group({type:[null,[d.A.required]],perm:[null,[d.A.required]]})},l.prototype.setEditing=function(l){void 0===l&&(l=!0),this.editing=l,this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.ADD},l.prototype.setValues=function(l,n){this.formGroup.setValue({type:l,perm:n})},l.prototype.setCapabilities=function(l){var n=this,u=[];l.forEach(function(l){u.push(l.type)}),this.types=[],M.getAll().forEach(function(l){-1===c.indexOf(u,l)&&n.types.push(l)})},l.prototype.onSubmit=function(){this.submitAction.emit(this.formGroup.value),this.bsModalRef.hide()},l}(),L=function(){function l(l,n,u,e){this.formBuilder=l,this.bsModalRef=n,this.i18n=u,this.actionLabels=e,this.submitAction=new t.EventEmitter,this.viewing=!0,this.userCandidates=[],this.resource=this.i18n("S3 Key"),this.createForm()}return l.prototype.createForm=function(){this.formGroup=this.formBuilder.group({user:[null,[d.A.required]],generate_key:[!0],access_key:[null,[B.a.requiredIf({generate_key:!1})]],secret_key:[null,[B.a.requiredIf({generate_key:!1})]]})},l.prototype.setViewing=function(l){void 0===l&&(l=!0),this.viewing=l,this.action=this.viewing?this.actionLabels.SHOW:this.actionLabels.CREATE},l.prototype.setValues=function(l,n,u){this.formGroup.setValue({user:l,generate_key:c.isEmpty(n),access_key:n,secret_key:u})},l.prototype.setUserCandidates=function(l){this.userCandidates=l},l.prototype.onSubmit=function(){this.submitAction.emit(this.formGroup.value),this.bsModalRef.hide()},l}(),G=function(){return function(){}}(),K=function(){function l(l,n,u,e){this.formBuilder=l,this.bsModalRef=n,this.i18n=u,this.actionLabels=e,this.submitAction=new t.EventEmitter,this.editing=!0,this.subusers=[],this.resource=this.i18n("Subuser"),this.createForm()}return l.prototype.createForm=function(){this.formGroup=this.formBuilder.group({uid:[null],subuid:[null,[d.A.required,this.subuserValidator()]],perm:[null,[d.A.required]],generate_secret:[!0],secret_key:[null,[B.a.requiredIf({generate_secret:!1})]]})},l.prototype.subuserValidator=function(){var l=this;return function(n){return l.editing?null:Object(B.b)(n.value)?null:l.subusers.some(function(u){return c.isEqual(l.getSubuserName(u.id),n.value)})?{subuserIdExists:!0}:null}},l.prototype.getSubuserName=function(l){if(c.isEmpty(l))return l;var n=l.match(/([^:]+)(:(.+))?/);return c.isUndefined(n[3])?n[1]:n[3]},l.prototype.setEditing=function(l){void 0===l&&(l=!0),this.editing=l,this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE},l.prototype.setValues=function(l,n,u){void 0===n&&(n=""),void 0===u&&(u=""),this.formGroup.setValue({uid:l,subuid:this.getSubuserName(n),perm:u,generate_secret:!0,secret_key:null})},l.prototype.setSubusers=function(l){this.subusers=l},l.prototype.onSubmit=function(){var l=this.formGroup.value,n=new G;n.id=l.uid+":"+l.subuid,n.permissions=l.perm,n.generate_secret=l.generate_secret,n.secret_key=l.secret_key,this.submitAction.emit(n),this.bsModalRef.hide()},l}(),$=function(){function l(l,n,u){this.bsModalRef=l,this.i18n=n,this.actionLabels=u,this.resource=this.i18n("Swift Key"),this.action=this.actionLabels.SHOW}return l.prototype.setValues=function(l,n){this.user=l,this.secret_key=n},l}(),Z=function(){function l(l,n,u,e,t,o,a,r){this.formBuilder=l,this.route=n,this.router=u,this.rgwUserService=e,this.bsModalService=t,this.notificationService=o,this.i18n=a,this.actionLabels=r,this.editing=!1,this.error=!1,this.loading=!1,this.submitObservables=[],this.subusers=[],this.s3Keys=[],this.swiftKeys=[],this.capabilities=[],this.resource=this.i18n("user"),this.subuserLabel=this.i18n("subuser"),this.s3keyLabel=this.i18n("S3 Key"),this.capabilityLabel=this.i18n("capability"),this.editing=this.router.url.startsWith("/rgw/user/"+i.e.EDIT),this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE,this.createForm()}return l.prototype.createForm=function(){this.userForm=this.formBuilder.group({uid:[null,[d.A.required],this.editing?[]:[B.a.unique(this.rgwUserService.exists,this.rgwUserService)]],display_name:[null,[d.A.required]],email:[null,[B.a.email],[B.a.unique(this.rgwUserService.emailExists,this.rgwUserService)]],max_buckets_mode:["1"],max_buckets:[1e3,[B.a.requiredIf({max_buckets_mode:"1"}),B.a.number(!1),d.A.min(1)]],suspended:[!1],generate_key:[!0],access_key:[null,[B.a.requiredIf({generate_key:!1})]],secret_key:[null,[B.a.requiredIf({generate_key:!1})]],user_quota_enabled:[!1],user_quota_max_size_unlimited:[!0],user_quota_max_size:[null,[B.a.requiredIf({user_quota_enabled:!0,user_quota_max_size_unlimited:!1}),this.quotaMaxSizeValidator]],user_quota_max_objects_unlimited:[!0],user_quota_max_objects:[null,[d.A.min(0),B.a.requiredIf({user_quota_enabled:!0,user_quota_max_objects_unlimited:!1})]],bucket_quota_enabled:[!1],bucket_quota_max_size_unlimited:[!0],bucket_quota_max_size:[null,[B.a.requiredIf({bucket_quota_enabled:!0,bucket_quota_max_size_unlimited:!1}),this.quotaMaxSizeValidator]],bucket_quota_max_objects_unlimited:[!0],bucket_quota_max_objects:[null,[d.A.min(0),B.a.requiredIf({bucket_quota_enabled:!0,bucket_quota_max_objects_unlimited:!1})]]})},l.prototype.ngOnInit=function(){var l=this;this.route.params.subscribe(function(n){if(n.hasOwnProperty("uid")){var u=decodeURIComponent(n.uid);l.loading=!0;var e=[];e.push(l.rgwUserService.get(u)),e.push(l.rgwUserService.getQuota(u)),Object(w.a)(e).subscribe(function(n){l.loading=!1;var u=c.clone(l.userForm.value),e=c.pick(n[0],c.keys(l.userForm.value));switch(e.max_buckets){case-1:e.max_buckets_mode="-1",e.max_buckets="";break;case 0:e.max_buckets_mode="0",e.max_buckets="";break;default:e.max_buckets_mode="1"}["user","bucket"].forEach(function(l){var u=n[1][l+"_quota"];e[l+"_quota_enabled"]=u.enabled,u.max_size<0?(e[l+"_quota_max_size_unlimited"]=!0,e[l+"_quota_max_size"]=null):(e[l+"_quota_max_size_unlimited"]=!1,e[l+"_quota_max_size"]=u.max_size+" B"),u.max_objects<0?(e[l+"_quota_max_objects_unlimited"]=!0,e[l+"_quota_max_objects"]=null):(e[l+"_quota_max_objects_unlimited"]=!1,e[l+"_quota_max_objects"]=u.max_objects)}),e=c.merge(u,e),l.userForm.setValue(e),l.subusers=n[0].subusers,l.s3Keys=n[0].keys,l.swiftKeys=n[0].swift_keys;var t={"read, write":"*"};n[0].caps.forEach(function(l){l.perm in t&&(l.perm=t[l.perm])}),l.capabilities=n[0].caps},function(n){l.error=n})}})},l.prototype.goToListView=function(){this.router.navigate(["/rgw/user"])},l.prototype.onSubmit=function(){var l,n=this;if(this.userForm.pristine)this.goToListView();else{var u=this.userForm.getValue("uid");if(this.editing){if(this._isGeneralDirty()){var e=this._getUpdateArgs();this.submitObservables.push(this.rgwUserService.update(u,e))}l=this.i18n('Updated Object Gateway user "{{uid}}"',{uid:u})}else e=this._getCreateArgs(),this.submitObservables.push(this.rgwUserService.create(e)),l=this.i18n('Created Object Gateway user "{{uid}}"',{uid:u});if(this._isUserQuotaDirty()){var t=this._getUserQuotaArgs();this.submitObservables.push(this.rgwUserService.updateQuota(u,t))}if(this._isBucketQuotaDirty()){var i=this._getBucketQuotaArgs();this.submitObservables.push(this.rgwUserService.updateQuota(u,i))}A.a.apply(void 0,this.submitObservables).subscribe({error:function(){n.userForm.setErrors({cdSubmitButton:!0})},complete:function(){n.notificationService.show(C.a.success,l),n.goToListView()}})}},l.prototype.quotaMaxSizeValidator=function(l){return Object(B.b)(l.value)?null:null===RegExp("^(\\d+(\\.\\d+)?)\\s*(B|K(B|iB)?|M(B|iB)?|G(B|iB)?|T(B|iB)?)?$","i").exec(l.value)?{quotaMaxSize:!0}:(new U.a).toBytes(l.value)<1024?{quotaMaxSize:!0}:null},l.prototype.setSubuser=function(l,n){var u={"full-control":"full","read-write":"readwrite"},e=this.userForm.getValue("uid");this.submitObservables.push(this.rgwUserService.createSubuser(e,{subuser:l.id,access:l.permissions in u?u[l.permissions]:l.permissions,key_type:"swift",secret_key:l.secret_key,generate_secret:l.generate_secret?"true":"false"})),c.isNumber(n)?this.subusers[n]=l:(this.subusers.push(l),this.swiftKeys.push({user:l.id,secret_key:l.generate_secret?"Apply your changes first...":l.secret_key})),this.userForm.markAsDirty()},l.prototype.deleteSubuser=function(l){var n=this.subusers[l];this.submitObservables.push(this.rgwUserService.deleteSubuser(this.userForm.getValue("uid"),n.id)),this.s3Keys=this.s3Keys.filter(function(l){return l.user!==n.id}),this.swiftKeys=this.swiftKeys.filter(function(l){return l.user!==n.id}),this.subusers.splice(l,1),this.userForm.markAsDirty()},l.prototype.setCapability=function(l,n){var u=this.userForm.getValue("uid");if(c.isNumber(n)){var e=this.capabilities[n];this.submitObservables.push(this.rgwUserService.deleteCapability(u,e.type,e.perm)),this.submitObservables.push(this.rgwUserService.addCapability(u,l.type,l.perm)),this.capabilities[n]=l}else this.submitObservables.push(this.rgwUserService.addCapability(u,l.type,l.perm)),this.capabilities.push(l);this.userForm.markAsDirty()},l.prototype.deleteCapability=function(l){var n=this.capabilities[l];this.submitObservables.push(this.rgwUserService.deleteCapability(this.userForm.getValue("uid"),n.type,n.perm)),this.capabilities.splice(l,1),this.userForm.markAsDirty()},l.prototype.hasAllCapabilities=function(){return!c.difference(M.getAll(),c.map(this.capabilities,"type")).length},l.prototype.setS3Key=function(l,n){if(c.isNumber(n));else{var u=l.user.match(/([^:]+)(:(.+))?/),e=u[1],t={subuser:u[2]?u[3]:"",generate_key:l.generate_key?"true":"false"};"false"===t.generate_key&&(c.isNil(l.access_key)||(t.access_key=l.access_key),c.isNil(l.secret_key)||(t.secret_key=l.secret_key)),this.submitObservables.push(this.rgwUserService.addS3Key(e,t)),this.s3Keys.push({user:l.user,access_key:l.generate_key?"Apply your changes first...":l.access_key,secret_key:l.generate_key?"Apply your changes first...":l.secret_key})}this.userForm.markAsDirty()},l.prototype.deleteS3Key=function(l){var n=this.s3Keys[l];this.submitObservables.push(this.rgwUserService.deleteS3Key(this.userForm.getValue("uid"),n.access_key)),this.s3Keys.splice(l,1),this.userForm.markAsDirty()},l.prototype.showSubuserModal=function(l){var n=this,u=this.userForm.getValue("uid"),e=this.bsModalService.show(K);if(c.isNumber(l)){var t=this.subusers[l];e.content.setEditing(),e.content.setValues(u,t.id,t.permissions)}else e.content.setEditing(!1),e.content.setValues(u),e.content.setSubusers(this.subusers);e.content.submitAction.subscribe(function(u){n.setSubuser(u,l)})},l.prototype.showS3KeyModal=function(l){var n=this,u=this.bsModalService.show(L);if(c.isNumber(l)){var e=this.s3Keys[l];u.content.setViewing(),u.content.setValues(e.user,e.access_key,e.secret_key)}else{var t=this._getS3KeyUserCandidates();u.content.setViewing(!1),u.content.setUserCandidates(t),u.content.submitAction.subscribe(function(l){n.setS3Key(l)})}},l.prototype.showSwiftKeyModal=function(l){var n=this.bsModalService.show($),u=this.swiftKeys[l];n.content.setValues(u.user,u.secret_key)},l.prototype.showCapabilityModal=function(l){var n=this,u=this.bsModalService.show(O);if(c.isNumber(l)){var e=this.capabilities[l];u.content.setEditing(),u.content.setValues(e.type,e.perm)}else u.content.setEditing(!1),u.content.setCapabilities(this.capabilities);u.content.submitAction.subscribe(function(u){n.setCapability(u,l)})},l.prototype._isGeneralDirty=function(){var l=this;return["display_name","email","max_buckets_mode","max_buckets","suspended"].some(function(n){return l.userForm.get(n).dirty})},l.prototype._isUserQuotaDirty=function(){var l=this;return["user_quota_enabled","user_quota_max_size_unlimited","user_quota_max_size","user_quota_max_objects_unlimited","user_quota_max_objects"].some(function(n){return l.userForm.get(n).dirty})},l.prototype._isBucketQuotaDirty=function(){var l=this;return["bucket_quota_enabled","bucket_quota_max_size_unlimited","bucket_quota_max_size","bucket_quota_max_objects_unlimited","bucket_quota_max_objects"].some(function(n){return l.userForm.get(n).dirty})},l.prototype._getCreateArgs=function(){var l={uid:this.userForm.getValue("uid"),display_name:this.userForm.getValue("display_name"),suspended:this.userForm.getValue("suspended"),email:"",max_buckets:this.userForm.getValue("max_buckets"),generate_key:this.userForm.getValue("generate_key"),access_key:"",secret_key:""},n=this.userForm.getValue("email");c.isString(n)&&n.length>0&&c.merge(l,{email:n}),this.userForm.getValue("generate_key")||c.merge(l,{generate_key:!1,access_key:this.userForm.getValue("access_key"),secret_key:this.userForm.getValue("secret_key")});var u=parseInt(this.userForm.getValue("max_buckets_mode"),10);return c.includes([-1,0],u)&&c.merge(l,{max_buckets:u}),l},l.prototype._getUpdateArgs=function(){for(var l={},n=0,u=["display_name","email","max_buckets","suspended"];n-1),l(n,22,0,u.bucket.bucket_quota.max_objects<=-1),l(n,24,0,u.bucket.bucket_quota.max_objects>-1)},function(l,n){var u=n.component,e=t["\u0275unv"](n,9,0,l(n,10,0,t["\u0275nov"](n.parent.parent.parent,1),u.bucket.bucket_quota.enabled));l(n,9,0,e)})}function Kl(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,60,"div",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,57,"table",[["class","table table-striped table-bordered"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,56,"tbody",[],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Name"])),(l()(),t["\u0275eld"](6,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](7,null,["",""])),(l()(),t["\u0275eld"](8,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["ID"])),(l()(),t["\u0275eld"](11,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](12,null,["",""])),(l()(),t["\u0275eld"](13,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](14,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Owner"])),(l()(),t["\u0275eld"](16,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](17,null,["",""])),(l()(),t["\u0275eld"](18,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](19,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Index type"])),(l()(),t["\u0275eld"](21,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](22,null,["",""])),(l()(),t["\u0275eld"](23,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](24,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Placement rule"])),(l()(),t["\u0275eld"](26,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](27,null,["",""])),(l()(),t["\u0275eld"](28,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](29,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Marker"])),(l()(),t["\u0275eld"](31,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](32,null,["",""])),(l()(),t["\u0275eld"](33,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](34,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Maximum marker"])),(l()(),t["\u0275eld"](36,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](37,null,["",""])),(l()(),t["\u0275eld"](38,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](39,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Version"])),(l()(),t["\u0275eld"](41,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](42,null,["",""])),(l()(),t["\u0275eld"](43,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](44,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Master version"])),(l()(),t["\u0275eld"](46,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](47,null,["",""])),(l()(),t["\u0275eld"](48,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](49,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Modification time"])),(l()(),t["\u0275eld"](51,0,null,null,2,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](52,null,["",""])),t["\u0275ppd"](53,1),(l()(),t["\u0275eld"](54,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](55,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Zonegroup"])),(l()(),t["\u0275eld"](57,0,null,null,1,"td",[],null,null,null,null,null)),(l()(),t["\u0275ted"](58,null,["",""])),(l()(),t["\u0275and"](16777216,null,null,1,null,Gl)),t["\u0275did"](60,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,60,0,n.component.bucket.bucket_quota)},function(l,n){var u=n.component;l(n,7,0,u.bucket.bid),l(n,12,0,u.bucket.id),l(n,17,0,u.bucket.owner),l(n,22,0,u.bucket.index_type),l(n,27,0,u.bucket.placement_rule),l(n,32,0,u.bucket.marker),l(n,37,0,u.bucket.max_marker),l(n,42,0,u.bucket.ver),l(n,47,0,u.bucket.master_ver);var e=t["\u0275unv"](n,52,0,l(n,53,0,t["\u0275nov"](n.parent.parent,0),u.bucket.mtime));l(n,52,0,e),l(n,58,0,u.bucket.zonegroup)})}function $l(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,5,"tabset",[],[[2,"tab-container",null]],null,null,kl.b,kl.a)),t["\u0275did"](1,180224,null,0,vl.d,[vl.e,t.Renderer2,t.ElementRef],null,null),(l()(),t["\u0275eld"](2,0,null,0,3,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](3,212992,null,0,vl.b,[vl.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Kl)),t["\u0275did"](5,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,3,0,"Details"),l(n,5,0,u.bucket)},function(l,n){l(n,0,0,t["\u0275nov"](n,1).clazz),l(n,2,0,t["\u0275nov"](n,3).id,t["\u0275nov"](n,3).active,t["\u0275nov"](n,3).addClass)})}function Zl(l){return t["\u0275vid"](0,[t["\u0275pid"](0,wl.a,[ql.DatePipe]),t["\u0275pid"](0,zl.a,[_l.a]),t["\u0275pid"](0,V.a,[U.a]),(l()(),t["\u0275and"](16777216,null,null,1,null,$l)),t["\u0275did"](4,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,4,0,n.component.selection.hasSingleSelection)},null)}function Ql(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-bucket-details",[],null,null,null,Zl,Bl)),t["\u0275did"](1,573440,null,0,Al,[],null,null)],null,null)}var Hl=t["\u0275ccf"]("cd-rgw-bucket-details",Al,Ql,{selection:"selection"},{},[]),Yl=u("25BL"),Xl=u("xtZt"),Jl=u("lqqz"),Wl=u("TJUb"),ln=function(){function l(l,n,u){this.rgwUserService=l,this.bsModalService=n,this.i18n=u,this.keys=[],this.keysColumns=[],this.keysSelection=new T.a}return l.prototype.ngOnInit=function(){this.keysColumns=[{name:this.i18n("Username"),prop:"username",flexGrow:1},{name:this.i18n("Type"),prop:"type",flexGrow:1}],this.maxBucketsMap={"-1":this.i18n("Disabled"),0:this.i18n("Unlimited")}},l.prototype.ngOnChanges=function(){var l=this;this.selection.hasSelection&&(this.user=this.selection.first(),this.user.subusers=c.sortBy(this.user.subusers,"id"),this.user.caps=c.sortBy(this.user.caps,"type"),this.rgwUserService.getQuota(this.user.uid).subscribe(function(n){c.extend(l.user,n)}),this.keys=[],this.user.keys&&this.user.keys.forEach(function(n){l.keys.push({id:l.keys.length+1,type:"S3",username:n.user,ref:n})}),this.user.swift_keys&&this.user.swift_keys.forEach(function(n){l.keys.push({id:l.keys.length+1,type:"Swift",username:n.user,ref:n})}),this.keys=c.sortBy(this.keys,"user"))},l.prototype.updateKeysSelection=function(l){this.keysSelection=l},l.prototype.showKeyModal=function(){var l=this.keysSelection.first(),n=this.bsModalService.show("S3"===l.type?L:$);switch(l.type){case"S3":n.content.setViewing(),n.content.setValues(l.ref.user,l.ref.access_key,l.ref.secret_key);break;case"Swift":n.content.setValues(l.ref.user,l.ref.secret_key)}},l}(),nn=u("DQlY"),un=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function en(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Email address"])),(l()(),t["\u0275eld"](3,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](4,null,["",""]))],null,function(l,n){l(n,4,0,n.component.user.email)})}function tn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"div",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," (",") "]))],null,function(l,n){l(n,1,0,n.context.$implicit.id,n.context.$implicit.permissions)})}function on(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Subusers"])),(l()(),t["\u0275eld"](3,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,tn)),t["\u0275did"](5,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){l(n,5,0,n.component.user.subusers)},null)}function an(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"div",[],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," (",") "]))],null,function(l,n){l(n,1,0,n.context.$implicit.type,n.context.$implicit.perm)})}function rn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Capabilities"])),(l()(),t["\u0275eld"](3,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,an)),t["\u0275did"](5,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){l(n,5,0,n.component.user.caps)},null)}function sn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited"]))],null,null)}function dn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," "])),t["\u0275ppd"](2,1)],null,function(l,n){var u=n.component,e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent.parent.parent.parent,2),u.user.user_quota.max_size));l(n,1,0,e)})}function cn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited"]))],null,null)}function pn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," "]))],null,function(l,n){l(n,1,0,n.component.user.user_quota.max_objects)})}function fn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,24,"div",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["User quota"])),(l()(),t["\u0275eld"](3,0,null,null,21,"table",[["class","table table-striped table-bordered"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,20,"tbody",[],null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](6,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Enabled"])),(l()(),t["\u0275eld"](8,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](9,null,["",""])),t["\u0275ppd"](10,1),(l()(),t["\u0275eld"](11,0,null,null,6,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](12,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Maximum size"])),(l()(),t["\u0275and"](16777216,null,null,1,null,sn)),t["\u0275did"](15,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,dn)),t["\u0275did"](17,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](18,0,null,null,6,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](19,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Maximum objects"])),(l()(),t["\u0275and"](16777216,null,null,1,null,cn)),t["\u0275did"](22,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,pn)),t["\u0275did"](24,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,15,0,u.user.user_quota.max_size<=-1),l(n,17,0,u.user.user_quota.max_size>-1),l(n,22,0,u.user.user_quota.max_objects<=-1),l(n,24,0,u.user.user_quota.max_objects>-1)},function(l,n){var u=n.component,e=t["\u0275unv"](n,9,0,l(n,10,0,t["\u0275nov"](n.parent.parent.parent,0),u.user.user_quota.enabled));l(n,9,0,e)})}function mn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited"]))],null,null)}function gn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," "])),t["\u0275ppd"](2,1)],null,function(l,n){var u=n.component,e=t["\u0275unv"](n,1,0,l(n,2,0,t["\u0275nov"](n.parent.parent.parent.parent,2),u.user.bucket_quota.max_size));l(n,1,0,e)})}function vn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited"]))],null,null)}function bn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](1,null,[" "," "]))],null,function(l,n){l(n,1,0,n.component.user.bucket_quota.max_objects)})}function hn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,24,"div",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Bucket quota"])),(l()(),t["\u0275eld"](3,0,null,null,21,"table",[["class","table table-striped table-bordered"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,20,"tbody",[],null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](6,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Enabled"])),(l()(),t["\u0275eld"](8,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](9,null,["",""])),t["\u0275ppd"](10,1),(l()(),t["\u0275eld"](11,0,null,null,6,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](12,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Maximum size"])),(l()(),t["\u0275and"](16777216,null,null,1,null,mn)),t["\u0275did"](15,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,gn)),t["\u0275did"](17,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](18,0,null,null,6,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](19,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Maximum objects"])),(l()(),t["\u0275and"](16777216,null,null,1,null,vn)),t["\u0275did"](22,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,bn)),t["\u0275did"](24,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,15,0,u.user.bucket_quota.max_size<=-1),l(n,17,0,u.user.bucket_quota.max_size>-1),l(n,22,0,u.user.bucket_quota.max_objects<=-1),l(n,24,0,u.user.bucket_quota.max_objects>-1)},function(l,n){var u=n.component,e=t["\u0275unv"](n,9,0,l(n,10,0,t["\u0275nov"](n.parent.parent.parent,0),u.user.bucket_quota.enabled));l(n,9,0,e)})}function yn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,40,"div",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,35,"table",[["class","table table-striped table-bordered"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,34,"tbody",[],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Username"])),(l()(),t["\u0275eld"](6,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](7,null,["",""])),(l()(),t["\u0275eld"](8,0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Full name"])),(l()(),t["\u0275eld"](11,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](12,null,["",""])),(l()(),t["\u0275and"](16777216,null,null,1,null,en)),t["\u0275did"](14,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](15,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](16,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Suspended"])),(l()(),t["\u0275eld"](18,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](19,null,["",""])),t["\u0275ppd"](20,1),(l()(),t["\u0275eld"](21,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](22,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["System"])),(l()(),t["\u0275eld"](24,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](25,null,["",""])),t["\u0275ppd"](26,1),(l()(),t["\u0275eld"](27,0,null,null,5,"tr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](28,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Maximum buckets"])),(l()(),t["\u0275eld"](30,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275ted"](31,null,["",""])),t["\u0275ppd"](32,2),(l()(),t["\u0275and"](16777216,null,null,1,null,on)),t["\u0275did"](34,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,rn)),t["\u0275did"](36,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,fn)),t["\u0275did"](38,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,hn)),t["\u0275did"](40,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,14,0,null==u.user.email?null:u.user.email.length),l(n,34,0,u.user.subusers&&u.user.subusers.length),l(n,36,0,u.user.caps&&u.user.caps.length),l(n,38,0,u.user.user_quota),l(n,40,0,u.user.bucket_quota)},function(l,n){var u=n.component;l(n,7,0,u.user.uid),l(n,12,0,u.user.display_name);var e=t["\u0275unv"](n,19,0,l(n,20,0,t["\u0275nov"](n.parent.parent,0),u.user.suspended));l(n,19,0,e);var i=t["\u0275unv"](n,25,0,l(n,26,0,t["\u0275nov"](n.parent.parent,0),"true"===u.user.system));l(n,25,0,i);var o=t["\u0275unv"](n,31,0,l(n,32,0,t["\u0275nov"](n.parent.parent,1),u.user.max_buckets,u.maxBucketsMap));l(n,31,0,o)})}function Cn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"tab",[["heading","Keys"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](1,212992,null,0,vl.b,[vl.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](2,0,null,null,9,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["selectionType","multi"]],null,[[null,"updateSelection"]],function(l,n,u){var e=!0;return"updateSelection"===n&&(e=!1!==l.component.updateKeysSelection(u)&&e),e},Yl.b,Yl.a)),t["\u0275did"](3,2867200,null,0,x.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],forceIdentifier:[3,"forceIdentifier"],selectionType:[4,"selectionType"]},{updateSelection:"updateSelection"}),(l()(),t["\u0275eld"](4,0,null,0,7,"div",[["class","table-actions"]],null,null,null,null,null)),(l()(),t["\u0275eld"](5,16777216,null,null,6,"div",[["class","btn-group"],["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),t["\u0275prd"](512,null,Xl.f,Xl.f,[]),t["\u0275did"](7,212992,null,0,Xl.c,[t.ElementRef,t.Renderer2,t.ViewContainerRef,Jl.a,Xl.a,Xl.f],null,null),(l()(),t["\u0275eld"](8,0,null,null,3,"button",[["class","btn btn-sm btn-primary"],["type","button"]],[[8,"disabled",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showKeyModal()&&e),e},null,null)),(l()(),t["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-eye"]],null,null,null,null,null)),(l()(),t["\u0275eld"](10,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Show"]))],function(l,n){var u=n.component;l(n,1,0,"Keys"),l(n,3,0,u.keys,u.keysColumns,"flex","true","multi"),l(n,7,0)},function(l,n){var u=n.component;l(n,0,0,t["\u0275nov"](n,1).id,t["\u0275nov"](n,1).active,t["\u0275nov"](n,1).addClass),l(n,5,0,t["\u0275nov"](n,7).dropup,t["\u0275nov"](n,7).isOpen,t["\u0275nov"](n,7).isOpen&&t["\u0275nov"](n,7).isBs4),l(n,8,0,!u.keysSelection.hasSingleSelection)})}function _n(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,7,"tabset",[],[[2,"tab-container",null]],null,null,kl.b,kl.a)),t["\u0275did"](1,180224,null,0,vl.d,[vl.e,t.Renderer2,t.ElementRef],null,null),(l()(),t["\u0275eld"](2,0,null,0,3,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](3,212992,null,0,vl.b,[vl.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,yn)),t["\u0275did"](5,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,0,1,null,Cn)),t["\u0275did"](7,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,3,0,"Details"),l(n,5,0,u.user),l(n,7,0,u.keys.length)},function(l,n){l(n,0,0,t["\u0275nov"](n,1).clazz),l(n,2,0,t["\u0275nov"](n,3).id,t["\u0275nov"](n,3).active,t["\u0275nov"](n,3).addClass)})}function kn(l){return t["\u0275vid"](0,[t["\u0275pid"](0,zl.a,[_l.a]),t["\u0275pid"](0,Wl.a,[]),t["\u0275pid"](0,q.a,[U.a]),t["\u0275qud"](402653184,1,{accessKeyTpl:0}),t["\u0275qud"](402653184,2,{secretKeyTpl:0}),(l()(),t["\u0275and"](16777216,null,null,1,null,_n)),t["\u0275did"](6,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,6,0,n.component.selection.hasSingleSelection)},null)}function Rn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-user-details",[],null,null,null,kn,un)),t["\u0275did"](1,638976,null,0,ln,[y.a,nn.b,_l.a],null,null)],function(l,n){l(n,1,0)},null)}var In=t["\u0275ccf"]("cd-rgw-user-details",ln,Rn,{selection:"selection"},{},[]),wn=u("8xTl"),En=u("ANnk"),xn=u("f/UV"),Tn=u("D4zM"),qn=u("OcYo"),Vn=u("SZbH"),Sn=u("KVJa"),Dn=u("Z21x"),Nn=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Fn(l){return t["\u0275vid"](0,[t["\u0275pid"](0,ql.TitleCasePipe,[]),t["\u0275pid"](0,wn.a,[]),(l()(),t["\u0275eld"](2,0,null,null,7,"div",[["class","modal-header"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,3,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),(l()(),t["\u0275ted"](4,null,[""," ",""])),t["\u0275ppd"](5,1),t["\u0275ppd"](6,1),(l()(),t["\u0275eld"](7,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.bsModalRef.hide()&&e),e},null,null)),(l()(),t["\u0275eld"](8,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["\xd7"])),(l()(),t["\u0275eld"](10,0,null,null,33,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,32,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var e=!0;return"submit"===n&&(e=!1!==t["\u0275nov"](l,13).onSubmit(u)&&e),"reset"===n&&(e=!1!==t["\u0275nov"](l,13).onReset()&&e),e},null,null)),t["\u0275did"](12,16384,null,0,d.D,[],null,null),t["\u0275did"](13,4210688,null,0,d.t,[[8,null],[8,null]],null,null),t["\u0275prd"](2048,null,d.d,null,[d.t]),t["\u0275did"](15,16384,null,0,d.s,[[4,d.d]],null,null),(l()(),t["\u0275eld"](16,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","user"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Username"])),(l()(),t["\u0275eld"](19,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](20,0,null,null,6,"input",[["class","form-control"],["id","user"],["name","user"],["type","text"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0,i=l.component;return"input"===n&&(e=!1!==t["\u0275nov"](l,22)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,22).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,22)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,22)._compositionEnd(u.target.value)&&e),"ngModelChange"===n&&(e=!1!==(i.user=u)&&e),e},null,null)),t["\u0275did"](21,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](22,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](24,671744,null,0,d.u,[[2,d.d],[8,null],[8,null],[6,d.p]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),t["\u0275prd"](2048,null,d.q,null,[d.u]),t["\u0275did"](26,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](27,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](28,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","secret_key"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Secret key"])),(l()(),t["\u0275eld"](30,0,null,null,13,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](31,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](32,0,null,null,6,"input",[["class","form-control"],["id","secret_key"],["name","secret_key"],["type","password"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0,i=l.component;return"input"===n&&(e=!1!==t["\u0275nov"](l,34)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,34).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,34)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,34)._compositionEnd(u.target.value)&&e),"ngModelChange"===n&&(e=!1!==(i.secret_key=u)&&e),e},null,null)),t["\u0275did"](33,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](34,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](36,671744,null,0,d.u,[[2,d.d],[8,null],[8,null],[6,d.p]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),t["\u0275prd"](2048,null,d.q,null,[d.u]),t["\u0275did"](38,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](39,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](40,0,null,null,1,"button",[["cdPasswordButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,41).onClick()&&e),e},null,null)),t["\u0275did"](41,81920,null,0,Tn.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](42,0,null,null,1,"button",[["cdCopy2ClipboardButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,43).onClick()&&e),e},null,null)),t["\u0275did"](43,81920,null,0,qn.a,[t.ElementRef,t.Renderer2,Vn.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275eld"](44,0,null,null,2,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](45,0,null,null,1,"cd-back-button",[],null,null,null,Sn.b,Sn.a)),t["\u0275did"](46,49152,null,0,Dn.a,[ql.Location,i.b],{back:[0,"back"]},null)],function(l,n){var u=n.component;l(n,24,0,"user",u.user),l(n,36,0,"secret_key",u.secret_key),l(n,41,0,"secret_key"),l(n,43,0,"secret_key"),l(n,46,0,u.bsModalRef.hide)},function(l,n){var u=n.component,e=t["\u0275unv"](n,4,0,l(n,5,0,t["\u0275nov"](n,0),u.action)),i=t["\u0275unv"](n,4,1,l(n,6,0,t["\u0275nov"](n,1),u.resource));l(n,4,0,e,i),l(n,11,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending),l(n,20,0,!0,t["\u0275nov"](n,26).ngClassUntouched,t["\u0275nov"](n,26).ngClassTouched,t["\u0275nov"](n,26).ngClassPristine,t["\u0275nov"](n,26).ngClassDirty,t["\u0275nov"](n,26).ngClassValid,t["\u0275nov"](n,26).ngClassInvalid,t["\u0275nov"](n,26).ngClassPending),l(n,32,0,!0,t["\u0275nov"](n,38).ngClassUntouched,t["\u0275nov"](n,38).ngClassTouched,t["\u0275nov"](n,38).ngClassPristine,t["\u0275nov"](n,38).ngClassDirty,t["\u0275nov"](n,38).ngClassValid,t["\u0275nov"](n,38).ngClassInvalid,t["\u0275nov"](n,38).ngClassPending)})}function jn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-user-swift-key-modal",[],null,null,null,Fn,Nn)),t["\u0275did"](1,49152,null,0,$,[nn.a,_l.a,i.b],null,null)],null,null)}var Pn=t["\u0275ccf"]("cd-rgw-user-swift-key-modal",$,jn,{},{},[]),zn=u("IZUe"),An=u("gp3X"),Bn=u("sb0X"),Un=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Mn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function On(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,6,"input",[["class","form-control"],["formControlName","user"],["id","user"],["type","text"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,2)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,2).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,2)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,2)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](1,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](2,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](4,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](6,16384,null,0,d.r,[[4,d.q]],null,null)],function(l,n){l(n,4,0,"user")},function(l,n){l(n,0,0,!0,t["\u0275nov"](n,6).ngClassUntouched,t["\u0275nov"](n,6).ngClassTouched,t["\u0275nov"](n,6).ngClassPristine,t["\u0275nov"](n,6).ngClassDirty,t["\u0275nov"](n,6).ngClassValid,t["\u0275nov"](n,6).ngClassInvalid,t["\u0275nov"](n,6).ngClassPending)})}function Ln(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275ted"](-1,null,["-- Select a username --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function Gn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function Kn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"select",[["autofocus",""],["class","form-control"],["formControlName","user"],["id","user"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,3).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,3).onTouched()&&e),e},null,null)),t["\u0275did"](1,4210688,null,0,zn.a,[t.ElementRef],null,null),t["\u0275did"](2,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](3,16384,null,0,d.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.z]),t["\u0275did"](5,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](7,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ln)),t["\u0275did"](9,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Gn)),t["\u0275did"](11,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var u=n.component;l(n,5,0,"user"),l(n,9,0,null!==u.userCandidates),l(n,11,0,u.userCandidates)},function(l,n){l(n,0,0,t["\u0275nov"](n,7).ngClassUntouched,t["\u0275nov"](n,7).ngClassTouched,t["\u0275nov"](n,7).ngClassPristine,t["\u0275nov"](n,7).ngClassDirty,t["\u0275nov"](n,7).ngClassValid,t["\u0275nov"](n,7).ngClassInvalid,t["\u0275nov"](n,7).ngClassPending)})}function $n(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Zn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,6,"input",[["formControlName","generate_key"],["id","generate_key"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,5).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,5).onTouched()&&e),e},null,null)),t["\u0275did"](4,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](5,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](7,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](9,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](10,0,null,null,1,"label",[["for","generate_key"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Auto-generate key"]))],function(l,n){l(n,7,0,"generate_key")},function(l,n){l(n,3,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending)})}function Qn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function Hn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Yn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,23,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","access_key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Access key"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Qn)),t["\u0275did"](7,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](8,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](10,0,null,null,6,"input",[["class","form-control"],["formControlName","access_key"],["id","access_key"],["type","password"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,12)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,12).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,12)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,12)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](11,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](12,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](14,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](16,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](17,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](18,0,null,null,1,"button",[["cdPasswordButton","access_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,19).onClick()&&e),e},null,null)),t["\u0275did"](19,81920,null,0,Tn.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](20,0,null,null,1,"button",[["cdCopy2ClipboardButton","access_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,21).onClick()&&e),e},null,null)),t["\u0275did"](21,81920,null,0,qn.a,[t.ElementRef,t.Renderer2,Vn.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Hn)),t["\u0275did"](23,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.formGroup.showError("access_key",t["\u0275nov"](n.parent,12)));l(n,1,0,"form-group",e),l(n,7,0,!u.viewing),l(n,14,0,"access_key"),l(n,19,0,"access_key"),l(n,21,0,"access_key"),l(n,23,0,u.formGroup.showError("access_key",t["\u0275nov"](n.parent,12),"required"))},function(l,n){l(n,10,0,n.component.viewing,t["\u0275nov"](n,16).ngClassUntouched,t["\u0275nov"](n,16).ngClassTouched,t["\u0275nov"](n,16).ngClassPristine,t["\u0275nov"](n,16).ngClassDirty,t["\u0275nov"](n,16).ngClassValid,t["\u0275nov"](n,16).ngClassInvalid,t["\u0275nov"](n,16).ngClassPending)})}function Xn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function Jn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Wn(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,23,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","secret_key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Secret key"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Xn)),t["\u0275did"](7,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](8,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](10,0,null,null,6,"input",[["class","form-control"],["formControlName","secret_key"],["id","secret_key"],["type","password"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,12)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,12).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,12)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,12)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](11,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](12,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](14,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](16,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](17,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](18,0,null,null,1,"button",[["cdPasswordButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,19).onClick()&&e),e},null,null)),t["\u0275did"](19,81920,null,0,Tn.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](20,0,null,null,1,"button",[["cdCopy2ClipboardButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,21).onClick()&&e),e},null,null)),t["\u0275did"](21,81920,null,0,qn.a,[t.ElementRef,t.Renderer2,Vn.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Jn)),t["\u0275did"](23,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.formGroup.showError("secret_key",t["\u0275nov"](n.parent,12)));l(n,1,0,"form-group",e),l(n,7,0,!u.viewing),l(n,14,0,"secret_key"),l(n,19,0,"secret_key"),l(n,21,0,"secret_key"),l(n,23,0,u.formGroup.showError("secret_key",t["\u0275nov"](n.parent,12),"required"))},function(l,n){l(n,10,0,n.component.viewing,t["\u0275nov"](n,16).ngClassUntouched,t["\u0275nov"](n,16).ngClassTouched,t["\u0275nov"](n,16).ngClassPristine,t["\u0275nov"](n,16).ngClassDirty,t["\u0275nov"](n,16).ngClassValid,t["\u0275nov"](n,16).ngClassInvalid,t["\u0275nov"](n,16).ngClassPending)})}function lu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,4,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,u){var e=!0;return"submitAction"===n&&(e=!1!==l.component.onSubmit()&&e),e},An.b,An.a)),t["\u0275did"](1,114688,null,0,Bn.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](2,0,[""," ",""])),t["\u0275ppd"](3,1),t["\u0275ppd"](4,1)],function(l,n){l(n,1,0,n.component.formGroup)},function(l,n){var u=n.component,e=t["\u0275unv"](n,2,0,l(n,3,0,t["\u0275nov"](n.parent,0),u.action)),i=t["\u0275unv"](n,2,1,l(n,4,0,t["\u0275nov"](n.parent,1),u.resource));l(n,2,0,e,i)})}function nu(l){return t["\u0275vid"](0,[t["\u0275pid"](0,ql.TitleCasePipe,[]),t["\u0275pid"](0,wn.a,[]),(l()(),t["\u0275eld"](2,0,null,null,7,"div",[["class","modal-header"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,3,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),(l()(),t["\u0275ted"](4,null,[""," ",""])),t["\u0275ppd"](5,1),t["\u0275ppd"](6,1),(l()(),t["\u0275eld"](7,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.bsModalRef.hide()&&e),e},null,null)),(l()(),t["\u0275eld"](8,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["\xd7"])),(l()(),t["\u0275eld"](10,0,null,null,31,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var e=!0;return"submit"===n&&(e=!1!==t["\u0275nov"](l,12).onSubmit(u)&&e),"reset"===n&&(e=!1!==t["\u0275nov"](l,12).onReset()&&e),e},null,null)),t["\u0275did"](11,16384,null,0,d.D,[],null,null),t["\u0275did"](12,540672,[["frm",4]],0,d.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,d.d,null,[d.l]),t["\u0275did"](14,16384,null,0,d.s,[[4,d.d]],null,null),(l()(),t["\u0275eld"](15,0,null,null,21,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](16,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](17,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](18,{"has-error":0}),(l()(),t["\u0275eld"](19,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","user"]],null,null,null,null,null)),(l()(),t["\u0275eld"](20,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Username"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Mn)),t["\u0275did"](23,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](24,0,null,null,6,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,On)),t["\u0275did"](26,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Kn)),t["\u0275did"](28,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,$n)),t["\u0275did"](30,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Zn)),t["\u0275did"](32,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Yn)),t["\u0275did"](34,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Wn)),t["\u0275did"](36,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](37,0,null,null,4,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,lu)),t["\u0275did"](39,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](40,0,null,null,1,"cd-back-button",[],null,null,null,Sn.b,Sn.a)),t["\u0275did"](41,49152,null,0,Dn.a,[ql.Location,i.b],{back:[0,"back"]},null)],function(l,n){var u=n.component;l(n,12,0,u.formGroup);var e=l(n,18,0,u.formGroup.showError("user",t["\u0275nov"](n,12)));l(n,17,0,"form-group",e),l(n,23,0,!u.viewing),l(n,26,0,u.viewing),l(n,28,0,!u.viewing),l(n,30,0,u.formGroup.showError("user",t["\u0275nov"](n,12),"required")),l(n,32,0,!u.viewing),l(n,34,0,!u.formGroup.getValue("generate_key")),l(n,36,0,!u.formGroup.getValue("generate_key")),l(n,39,0,!u.viewing),l(n,41,0,u.bsModalRef.hide)},function(l,n){var u=n.component,e=t["\u0275unv"](n,4,0,l(n,5,0,t["\u0275nov"](n,0),u.action)),i=t["\u0275unv"](n,4,1,l(n,6,0,t["\u0275nov"](n,1),u.resource));l(n,4,0,e,i),l(n,10,0,t["\u0275nov"](n,14).ngClassUntouched,t["\u0275nov"](n,14).ngClassTouched,t["\u0275nov"](n,14).ngClassPristine,t["\u0275nov"](n,14).ngClassDirty,t["\u0275nov"](n,14).ngClassValid,t["\u0275nov"](n,14).ngClassInvalid,t["\u0275nov"](n,14).ngClassPending)})}function uu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-user-s3-key-modal",[],null,null,null,nu,Un)),t["\u0275did"](1,49152,null,0,L,[_.a,nn.a,_l.a,i.b],null,null)],null,null)}var eu=t["\u0275ccf"]("cd-rgw-user-s3-key-modal",L,uu,{},{submitAction:"submitAction"},[]),tu=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function iu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function ou(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,6,"input",[["class","form-control"],["formControlName","type"],["id","type"],["type","text"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,2)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,2).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,2)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,2)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](1,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](2,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](4,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](6,16384,null,0,d.r,[[4,d.q]],null,null)],function(l,n){l(n,4,0,"type")},function(l,n){l(n,0,0,!0,t["\u0275nov"](n,6).ngClassUntouched,t["\u0275nov"](n,6).ngClassTouched,t["\u0275nov"](n,6).ngClassPristine,t["\u0275nov"](n,6).ngClassDirty,t["\u0275nov"](n,6).ngClassValid,t["\u0275nov"](n,6).ngClassInvalid,t["\u0275nov"](n,6).ngClassPending)})}function au(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275ted"](-1,null,["-- Select a type --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function ru(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function su(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"select",[["autofocus",""],["class","form-control"],["formControlName","type"],["id","type"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,3).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,3).onTouched()&&e),e},null,null)),t["\u0275did"](1,4210688,null,0,zn.a,[t.ElementRef],null,null),t["\u0275did"](2,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](3,16384,null,0,d.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.z]),t["\u0275did"](5,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](7,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,au)),t["\u0275did"](9,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,ru)),t["\u0275did"](11,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var u=n.component;l(n,5,0,"type"),l(n,9,0,null!==u.types),l(n,11,0,u.types)},function(l,n){l(n,0,0,t["\u0275nov"](n,7).ngClassUntouched,t["\u0275nov"](n,7).ngClassTouched,t["\u0275nov"](n,7).ngClassPristine,t["\u0275nov"](n,7).ngClassDirty,t["\u0275nov"](n,7).ngClassValid,t["\u0275nov"](n,7).ngClassInvalid,t["\u0275nov"](n,7).ngClassPending)})}function du(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function cu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function pu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function fu(l){return t["\u0275vid"](0,[t["\u0275pid"](0,ql.TitleCasePipe,[]),t["\u0275pid"](0,wn.a,[]),(l()(),t["\u0275eld"](2,0,null,null,7,"div",[["class","modal-header"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,3,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),(l()(),t["\u0275ted"](4,null,[""," ",""])),t["\u0275ppd"](5,1),t["\u0275ppd"](6,1),(l()(),t["\u0275eld"](7,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.bsModalRef.hide()&&e),e},null,null)),(l()(),t["\u0275eld"](8,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["\xd7"])),(l()(),t["\u0275eld"](10,0,null,null,52,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var e=!0;return"submit"===n&&(e=!1!==t["\u0275nov"](l,12).onSubmit(u)&&e),"reset"===n&&(e=!1!==t["\u0275nov"](l,12).onReset()&&e),e},null,null)),t["\u0275did"](11,16384,null,0,d.D,[],null,null),t["\u0275did"](12,540672,[["frm",4]],0,d.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,d.d,null,[d.l]),t["\u0275did"](14,16384,null,0,d.s,[[4,d.d]],null,null),(l()(),t["\u0275eld"](15,0,null,null,39,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](16,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](17,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](18,{"has-error":0}),(l()(),t["\u0275eld"](19,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","type"]],null,null,null,null,null)),(l()(),t["\u0275eld"](20,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Type"])),(l()(),t["\u0275and"](16777216,null,null,1,null,iu)),t["\u0275did"](23,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](24,0,null,null,6,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,ou)),t["\u0275did"](26,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,su)),t["\u0275did"](28,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,du)),t["\u0275did"](30,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](31,0,null,null,23,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](32,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](33,{"has-error":0}),(l()(),t["\u0275eld"](34,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","perm"]],null,null,null,null,null)),(l()(),t["\u0275eld"](35,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Permission"])),(l()(),t["\u0275eld"](37,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](38,0,null,null,16,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](39,0,null,null,13,"select",[["class","form-control"],["formControlName","perm"],["id","perm"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,41).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,41).onTouched()&&e),e},null,null)),t["\u0275did"](40,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](41,16384,null,0,d.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.z]),t["\u0275did"](43,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](45,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](46,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](47,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](48,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275ted"](-1,null,["-- Select a permission --"])),(l()(),t["\u0275and"](16777216,null,null,2,null,cu)),t["\u0275did"](51,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),t["\u0275pad"](52,3),(l()(),t["\u0275and"](16777216,null,null,1,null,pu)),t["\u0275did"](54,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](55,0,null,null,7,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](56,0,null,null,4,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,u){var e=!0;return"submitAction"===n&&(e=!1!==l.component.onSubmit()&&e),e},An.b,An.a)),t["\u0275did"](57,114688,null,0,Bn.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](58,0,[""," ",""])),t["\u0275ppd"](59,1),t["\u0275ppd"](60,1),(l()(),t["\u0275eld"](61,0,null,null,1,"cd-back-button",[],null,null,null,Sn.b,Sn.a)),t["\u0275did"](62,49152,null,0,Dn.a,[ql.Location,i.b],{back:[0,"back"]},null)],function(l,n){var u=n.component;l(n,12,0,u.formGroup);var e=l(n,18,0,u.formGroup.showError("type",t["\u0275nov"](n,12)));l(n,17,0,"form-group",e),l(n,23,0,!u.editing),l(n,26,0,u.editing),l(n,28,0,!u.editing),l(n,30,0,u.formGroup.showError("type",t["\u0275nov"](n,12),"required"));var i=l(n,33,0,u.formGroup.showError("perm",t["\u0275nov"](n,12)));l(n,32,0,"form-group",i),l(n,43,0,"perm"),l(n,47,0,null),l(n,48,0,null);var o=l(n,52,0,"read","write","*");l(n,51,0,o),l(n,54,0,u.formGroup.showError("perm",t["\u0275nov"](n,12),"required")),l(n,57,0,u.formGroup),l(n,62,0,u.bsModalRef.hide)},function(l,n){var u=n.component,e=t["\u0275unv"](n,4,0,l(n,5,0,t["\u0275nov"](n,0),u.action)),i=t["\u0275unv"](n,4,1,l(n,6,0,t["\u0275nov"](n,1),u.resource));l(n,4,0,e,i),l(n,10,0,t["\u0275nov"](n,14).ngClassUntouched,t["\u0275nov"](n,14).ngClassTouched,t["\u0275nov"](n,14).ngClassPristine,t["\u0275nov"](n,14).ngClassDirty,t["\u0275nov"](n,14).ngClassValid,t["\u0275nov"](n,14).ngClassInvalid,t["\u0275nov"](n,14).ngClassPending),l(n,39,0,t["\u0275nov"](n,45).ngClassUntouched,t["\u0275nov"](n,45).ngClassTouched,t["\u0275nov"](n,45).ngClassPristine,t["\u0275nov"](n,45).ngClassDirty,t["\u0275nov"](n,45).ngClassValid,t["\u0275nov"](n,45).ngClassInvalid,t["\u0275nov"](n,45).ngClassPending);var o=t["\u0275unv"](n,58,0,l(n,59,0,t["\u0275nov"](n,0),u.action)),a=t["\u0275unv"](n,58,1,l(n,60,0,t["\u0275nov"](n,1),u.resource));l(n,58,0,o,a)})}function mu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-user-capability-modal",[],null,null,null,fu,tu)),t["\u0275did"](1,49152,null,0,O,[_.a,nn.a,_l.a,i.b],null,null)],null,null)}var gu=t["\u0275ccf"]("cd-rgw-user-capability-modal",O,mu,{},{submitAction:"submitAction"},[]),vu=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function bu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function hu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function yu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The chosen subuser ID is already in use."]))],null,null)}function Cu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function _u(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function ku(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Ru(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","secret_key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Secret key"])),(l()(),t["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,6,"input",[["class","form-control"],["formControlName","secret_key"],["id","secret_key"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,11)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,11).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,11)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,11)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](10,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](11,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](13,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](15,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](16,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,1,"button",[["cdPasswordButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,18).onClick()&&e),e},null,null)),t["\u0275did"](18,81920,null,0,Tn.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](19,0,null,null,1,"button",[["cdCopy2ClipboardButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,20).onClick()&&e),e},null,null)),t["\u0275did"](20,81920,null,0,qn.a,[t.ElementRef,t.Renderer2,Vn.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,ku)),t["\u0275did"](22,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.formGroup.showError("secret_key",t["\u0275nov"](n.parent.parent,12)));l(n,1,0,"form-group",e),l(n,13,0,"secret_key"),l(n,18,0,"secret_key"),l(n,20,0,"secret_key"),l(n,22,0,u.formGroup.showError("secret_key",t["\u0275nov"](n.parent.parent,12),"required"))},function(l,n){l(n,9,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending)})}function Iu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,16,"fieldset",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Swift key"])),(l()(),t["\u0275eld"](3,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](6,0,null,null,6,"input",[["formControlName","generate_secret"],["id","generate_secret"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,8).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,8).onTouched()&&e),e},null,null)),t["\u0275did"](7,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](8,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](10,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](12,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](13,0,null,null,1,"label",[["for","generate_secret"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Auto-generate secret"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Ru)),t["\u0275did"](16,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,10,0,"generate_secret"),l(n,16,0,!u.editing&&!u.formGroup.getValue("generate_secret"))},function(l,n){l(n,6,0,t["\u0275nov"](n,12).ngClassUntouched,t["\u0275nov"](n,12).ngClassTouched,t["\u0275nov"](n,12).ngClassPristine,t["\u0275nov"](n,12).ngClassDirty,t["\u0275nov"](n,12).ngClassValid,t["\u0275nov"](n,12).ngClassInvalid,t["\u0275nov"](n,12).ngClassPending)})}function wu(l){return t["\u0275vid"](0,[t["\u0275pid"](0,ql.TitleCasePipe,[]),t["\u0275pid"](0,wn.a,[]),(l()(),t["\u0275eld"](2,0,null,null,7,"div",[["class","modal-header"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,3,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),(l()(),t["\u0275ted"](4,null,[""," ",""])),t["\u0275ppd"](5,1),t["\u0275ppd"](6,1),(l()(),t["\u0275eld"](7,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.bsModalRef.hide()&&e),e},null,null)),(l()(),t["\u0275eld"](8,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["\xd7"])),(l()(),t["\u0275eld"](10,0,null,null,81,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var e=!0;return"submit"===n&&(e=!1!==t["\u0275nov"](l,12).onSubmit(u)&&e),"reset"===n&&(e=!1!==t["\u0275nov"](l,12).onReset()&&e),e},null,null)),t["\u0275did"](11,16384,null,0,d.D,[],null,null),t["\u0275did"](12,540672,[["frm",4]],0,d.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,d.d,null,[d.l]),t["\u0275did"](14,16384,null,0,d.s,[[4,d.d]],null,null),(l()(),t["\u0275eld"](15,0,null,null,68,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](16,0,null,null,12,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](17,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](18,{"has-error":0}),(l()(),t["\u0275eld"](19,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","uid"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Username"])),(l()(),t["\u0275eld"](21,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](22,0,null,null,6,"input",[["class","form-control"],["formControlName","uid"],["id","uid"],["type","text"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,24)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,24).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,24)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,24)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](23,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](24,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](26,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](28,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](29,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](30,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](31,{"has-error":0}),(l()(),t["\u0275eld"](32,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","subuid"]],null,null,null,null,null)),(l()(),t["\u0275eld"](33,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Subuser"])),(l()(),t["\u0275and"](16777216,null,null,1,null,bu)),t["\u0275did"](36,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](37,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](38,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","subuid"],["id","subuid"],["type","text"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,41)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,41).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,41)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,41)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](39,4210688,null,0,zn.a,[t.ElementRef],null,null),t["\u0275did"](40,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](41,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](43,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](45,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,hu)),t["\u0275did"](47,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,yu)),t["\u0275did"](49,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](50,0,null,null,31,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](51,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](52,{"has-error":0}),(l()(),t["\u0275eld"](53,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","perm"]],null,null,null,null,null)),(l()(),t["\u0275eld"](54,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Permission"])),(l()(),t["\u0275eld"](56,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](57,0,null,null,24,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](58,0,null,null,21,"select",[["class","form-control"],["formControlName","perm"],["id","perm"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,60).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,60).onTouched()&&e),e},null,null)),t["\u0275did"](59,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](60,16384,null,0,d.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.z]),t["\u0275did"](62,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](64,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](65,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](66,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](67,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275ted"](-1,null,["-- Select a permission --"])),(l()(),t["\u0275and"](16777216,null,null,2,null,Cu)),t["\u0275did"](70,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),t["\u0275pad"](71,2),(l()(),t["\u0275eld"](72,0,null,null,3,"option",[["value","read-write"]],null,null,null,null,null)),t["\u0275did"](73,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](74,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](-1,null,["read, write"])),(l()(),t["\u0275eld"](76,0,null,null,3,"option",[["value","full-control"]],null,null,null,null,null)),t["\u0275did"](77,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](78,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](-1,null,["full"])),(l()(),t["\u0275and"](16777216,null,null,1,null,_u)),t["\u0275did"](81,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Iu)),t["\u0275did"](83,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](84,0,null,null,7,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](85,0,null,null,4,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,u){var e=!0;return"submitAction"===n&&(e=!1!==l.component.onSubmit()&&e),e},An.b,An.a)),t["\u0275did"](86,114688,null,0,Bn.a,[t.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](87,0,[""," ",""])),t["\u0275ppd"](88,1),t["\u0275ppd"](89,1),(l()(),t["\u0275eld"](90,0,null,null,1,"cd-back-button",[],null,null,null,Sn.b,Sn.a)),t["\u0275did"](91,49152,null,0,Dn.a,[ql.Location,i.b],{back:[0,"back"]},null)],function(l,n){var u=n.component;l(n,12,0,u.formGroup);var e=l(n,18,0,u.formGroup.showError("uid",t["\u0275nov"](n,12)));l(n,17,0,"form-group",e),l(n,26,0,"uid");var i=l(n,31,0,u.formGroup.showError("subuid",t["\u0275nov"](n,12)));l(n,30,0,"form-group",i),l(n,36,0,!u.editing),l(n,43,0,"subuid"),l(n,47,0,u.formGroup.showError("subuid",t["\u0275nov"](n,12),"required")),l(n,49,0,u.formGroup.showError("subuid",t["\u0275nov"](n,12),"subuserIdExists"));var o=l(n,52,0,u.formGroup.showError("perm",t["\u0275nov"](n,12)));l(n,51,0,"form-group",o),l(n,62,0,"perm"),l(n,66,0,null),l(n,67,0,null);var a=l(n,71,0,"read","write");l(n,70,0,a),l(n,73,0,"read-write"),l(n,74,0,"read-write"),l(n,77,0,"full-control"),l(n,78,0,"full-control"),l(n,81,0,u.formGroup.showError("perm",t["\u0275nov"](n,12),"required")),l(n,83,0,!u.editing),l(n,86,0,u.formGroup),l(n,91,0,u.bsModalRef.hide)},function(l,n){var u=n.component,e=t["\u0275unv"](n,4,0,l(n,5,0,t["\u0275nov"](n,0),u.action)),i=t["\u0275unv"](n,4,1,l(n,6,0,t["\u0275nov"](n,1),u.resource));l(n,4,0,e,i),l(n,10,0,t["\u0275nov"](n,14).ngClassUntouched,t["\u0275nov"](n,14).ngClassTouched,t["\u0275nov"](n,14).ngClassPristine,t["\u0275nov"](n,14).ngClassDirty,t["\u0275nov"](n,14).ngClassValid,t["\u0275nov"](n,14).ngClassInvalid,t["\u0275nov"](n,14).ngClassPending),l(n,22,0,!0,t["\u0275nov"](n,28).ngClassUntouched,t["\u0275nov"](n,28).ngClassTouched,t["\u0275nov"](n,28).ngClassPristine,t["\u0275nov"](n,28).ngClassDirty,t["\u0275nov"](n,28).ngClassValid,t["\u0275nov"](n,28).ngClassInvalid,t["\u0275nov"](n,28).ngClassPending),l(n,38,0,u.editing,t["\u0275nov"](n,45).ngClassUntouched,t["\u0275nov"](n,45).ngClassTouched,t["\u0275nov"](n,45).ngClassPristine,t["\u0275nov"](n,45).ngClassDirty,t["\u0275nov"](n,45).ngClassValid,t["\u0275nov"](n,45).ngClassInvalid,t["\u0275nov"](n,45).ngClassPending),l(n,58,0,t["\u0275nov"](n,64).ngClassUntouched,t["\u0275nov"](n,64).ngClassTouched,t["\u0275nov"](n,64).ngClassPristine,t["\u0275nov"](n,64).ngClassDirty,t["\u0275nov"](n,64).ngClassValid,t["\u0275nov"](n,64).ngClassInvalid,t["\u0275nov"](n,64).ngClassPending);var o=t["\u0275unv"](n,87,0,l(n,88,0,t["\u0275nov"](n,0),u.action)),a=t["\u0275unv"](n,87,1,l(n,89,0,t["\u0275nov"](n,1),u.resource));l(n,87,0,o,a)})}function Eu(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-user-subuser-modal",[],null,null,null,wu,vu)),t["\u0275did"](1,49152,null,0,K,[_.a,nn.a,_l.a,i.b],null,null)],null,null)}var xu=t["\u0275ccf"]("cd-rgw-user-subuser-modal",K,Eu,{},{submitAction:"submitAction"},[]),Tu=u("IzCI"),qu=u("Dwqy"),Vu=u("uYzU"),Su=u("uhwM"),Du=u("E2fk"),Nu=u("nSDx"),Fu=u("SB+Q"),ju=u("TYzs"),Pu=u("BQkM"),zu=u("dEH0"),Au=u("G1/K"),Bu=u("lTVp"),Uu=u("OZfm"),Mu=u("NJnL"),Ou=u("eajB"),Lu=u("FO+L"),Gu=u("nhM1"),Ku=u("BARL"),$u=u("ZYCi"),Zu=u("9Xeq"),Qu=u("xdbM"),Hu=u("yGOH"),Yu=u("V/fk"),Xu=u("F8xH"),Ju=u("ChqD"),Wu=u("PCNd"),le=u("G6Q+"),ne=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function ue(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"tab",[["heading","Overall Performance"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](1,212992,null,0,vl.b,[vl.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","two"],["uid","WAkugZpiz"]],null,null,null,bl.b,bl.a)),t["\u0275did"](3,638976,null,0,hl.a,[r.a,yl.DomSanitizer,Cl.a,a.a,_l.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(l,n){l(n,1,0,"Overall Performance"),l(n,3,0,"rgw-overview?","two","WAkugZpiz")},function(l,n){l(n,0,0,t["\u0275nov"](n,1).id,t["\u0275nov"](n,1).active,t["\u0275nov"](n,1).addClass)})}function ee(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,9,"tabset",[],[[2,"tab-container",null]],null,null,kl.b,kl.a)),t["\u0275did"](1,180224,null,0,vl.d,[vl.e,t.Renderer2,t.ElementRef],null,null),(l()(),t["\u0275eld"](2,0,null,0,5,"tab",[["heading","Daemons List"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),t["\u0275did"](3,212992,null,0,vl.b,[vl.d,t.ElementRef,t.Renderer2],{heading:[0,"heading"]},null),(l()(),t["\u0275eld"](4,0,null,null,3,"cd-table",[["columnMode","flex"],["selectionType","single"]],null,[[null,"updateSelection"],[null,"fetchData"]],function(l,n,u){var e=!0,t=l.component;return"updateSelection"===n&&(e=!1!==t.updateSelection(u)&&e),"fetchData"===n&&(e=!1!==t.getDaemonList(u)&&e),e},Yl.b,Yl.a)),t["\u0275did"](5,2867200,null,0,x.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],selectionType:[3,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(l()(),t["\u0275eld"](6,0,null,2,1,"cd-rgw-daemon-details",[["cdTableDetail",""]],null,null,null,Fl,Sl)),t["\u0275did"](7,573440,null,0,Vl,[j,S.a],{selection:[0,"selection"]},null),(l()(),t["\u0275and"](16777216,null,0,1,null,ue)),t["\u0275did"](9,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,3,0,"Daemons List"),l(n,5,0,u.daemons,u.columns,"flex","single"),l(n,7,0,u.selection),l(n,9,0,u.grafanaPermission.read)},function(l,n){l(n,0,0,t["\u0275nov"](n,1).clazz),l(n,2,0,t["\u0275nov"](n,3).id,t["\u0275nov"](n,3).active,t["\u0275nov"](n,3).addClass)})}function te(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-daemon-list",[],null,null,null,ee,ne)),t["\u0275did"](1,49152,null,0,z,[j,S.a,P.a,_l.a],null,null)],null,null)}var ie=t["\u0275ccf"]("cd-rgw-daemon-list",z,te,{},{},[]),oe=u("NUGo"),ae=u("S7zO"),re=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function se(l){return t["\u0275vid"](0,[t["\u0275qud"](402653184,1,{table:0}),(l()(),t["\u0275eld"](1,0,null,null,5,"cd-table",[["columnMode","flex"],["identifier","uid"],["selectionType","multi"]],null,[[null,"updateSelection"],[null,"fetchData"]],function(l,n,u){var e=!0,t=l.component;return"updateSelection"===n&&(e=!1!==t.updateSelection(u)&&e),"fetchData"===n&&(e=!1!==t.getUserList(u)&&e),e},Yl.b,Yl.a)),t["\u0275did"](2,2867200,[[1,4],["table",4]],0,x.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoReload:[3,"autoReload"],identifier:[4,"identifier"],selectionType:[5,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(l()(),t["\u0275eld"](3,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,oe.b,oe.a)),t["\u0275did"](4,114688,null,0,ae.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),t["\u0275eld"](5,0,null,2,1,"cd-rgw-user-details",[["cdTableDetail",""]],null,null,null,kn,un)),t["\u0275did"](6,638976,null,0,ln,[y.a,nn.b,_l.a],{selection:[0,"selection"]},null)],function(l,n){var u=n.component;l(n,2,0,u.users,u.columns,"flex",!1,"uid","multi"),l(n,4,0,u.permission,u.selection,u.tableActions),l(n,6,0,u.selection)},null)}function de(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"cd-rgw-user-list",[],null,null,null,se,re)),t["\u0275prd"](256,null,D.a,H,[]),t["\u0275did"](2,49152,null,0,Y,[S.a,y.a,nn.b,_l.a,D.a,i.b],null,null)],null,null)}var ce=t["\u0275ccf"]("cd-rgw-user-list",Y,de,{},{},[]),pe=u("QC43"),fe=u("XFyV"),me=u("M/6F"),ge=u("NDi4"),ve=u("EmSq"),be=t["\u0275crt"]({encapsulation:0,styles:[["form[_ngcontent-%COMP%] .input-group-addon[_ngcontent-%COMP%]{color:#90949c!important;background-color:transparent}"]],data:{}});function he(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"cd-loading-panel",[],null,null,null,pe.b,pe.a)),t["\u0275did"](1,49152,null,0,fe.a,[],null,null),(l()(),t["\u0275ted"](-1,0,["Loading user data..."]))],null,null)}function ye(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"cd-error-panel",[],null,[[null,"backAction"]],function(l,n,u){var e=!0;return"backAction"===n&&(e=!1!==l.component.goToListView()&&e),e},me.b,me.a)),t["\u0275did"](1,49152,null,0,ge.a,[],null,{backAction:"backAction"}),(l()(),t["\u0275ted"](-1,0,["The user data could not be loaded."]))],null,null)}function Ce(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function _e(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function ke(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The chosen user ID is already in use."]))],null,null)}function Re(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function Ie(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function we(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This is not a valid email address."]))],null,null)}function Ee(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The chosen email address is already in use."]))],null,null)}function xe(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Te(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The entered value must be >= 1."]))],null,null)}function qe(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,0,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,7,"input",[["class","form-control"],["formControlName","max_buckets"],["id","max_buckets"],["min","1"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,7)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,7).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,7)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,7)._compositionEnd(u.target.value)&&e),"change"===n&&(e=!1!==t["\u0275nov"](l,8).onChange(u.target.value)&&e),"input"===n&&(e=!1!==t["\u0275nov"](l,8).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,8).onTouched()&&e),e},null,null)),t["\u0275did"](6,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](7,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275did"](8,16384,null,0,d.C,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l,n){return[l,n]},[d.e,d.C]),t["\u0275did"](10,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](12,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,xe)),t["\u0275did"](14,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Te)),t["\u0275did"](16,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.userForm.showError("max_buckets",t["\u0275nov"](n.parent,3)));l(n,1,0,"form-group",e),l(n,10,0,"max_buckets"),l(n,14,0,u.userForm.showError("max_buckets",t["\u0275nov"](n.parent,3),"required")),l(n,16,0,u.userForm.showError("max_buckets",t["\u0275nov"](n.parent,3),"min"))},function(l,n){l(n,5,0,t["\u0275nov"](n,12).ngClassUntouched,t["\u0275nov"](n,12).ngClassTouched,t["\u0275nov"](n,12).ngClassPristine,t["\u0275nov"](n,12).ngClassDirty,t["\u0275nov"](n,12).ngClassValid,t["\u0275nov"](n,12).ngClassInvalid,t["\u0275nov"](n,12).ngClassPending)})}function Ve(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Se(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","access_key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Access key"])),(l()(),t["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,6,"input",[["class","form-control"],["formControlName","access_key"],["id","access_key"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,11)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,11).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,11)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,11)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](10,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](11,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](13,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](15,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](16,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,1,"button",[["cdPasswordButton","access_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,18).onClick()&&e),e},null,null)),t["\u0275did"](18,81920,null,0,Tn.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](19,0,null,null,1,"button",[["cdCopy2ClipboardButton","access_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,20).onClick()&&e),e},null,null)),t["\u0275did"](20,81920,null,0,qn.a,[t.ElementRef,t.Renderer2,Vn.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ve)),t["\u0275did"](22,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.userForm.showError("access_key",t["\u0275nov"](n.parent.parent,3)));l(n,1,0,"form-group",e),l(n,13,0,"access_key"),l(n,18,0,"access_key"),l(n,20,0,"access_key"),l(n,22,0,u.userForm.showError("access_key",t["\u0275nov"](n.parent.parent,3),"required"))},function(l,n){l(n,9,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending)})}function De(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Ne(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","secret_key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Secret key"])),(l()(),t["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,6,"input",[["class","form-control"],["formControlName","secret_key"],["id","secret_key"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,11)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,11).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,11)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,11)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](10,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](11,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](13,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](15,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](16,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,1,"button",[["cdPasswordButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,18).onClick()&&e),e},null,null)),t["\u0275did"](18,81920,null,0,Tn.a,[t.ElementRef,t.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),t["\u0275eld"](19,0,null,null,1,"button",[["cdCopy2ClipboardButton","secret_key"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==t["\u0275nov"](l,20).onClick()&&e),e},null,null)),t["\u0275did"](20,81920,null,0,qn.a,[t.ElementRef,t.Renderer2,Vn.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,De)),t["\u0275did"](22,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.userForm.showError("secret_key",t["\u0275nov"](n.parent.parent,3)));l(n,1,0,"form-group",e),l(n,13,0,"secret_key"),l(n,18,0,"secret_key"),l(n,20,0,"secret_key"),l(n,22,0,u.userForm.showError("secret_key",t["\u0275nov"](n.parent.parent,3),"required"))},function(l,n){l(n,9,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending)})}function Fe(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,18,"fieldset",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["S3 key"])),(l()(),t["\u0275eld"](3,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](5,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](6,0,null,null,6,"input",[["formControlName","generate_key"],["id","generate_key"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,8).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,8).onTouched()&&e),e},null,null)),t["\u0275did"](7,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](8,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](10,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](12,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](13,0,null,null,1,"label",[["for","generate_key"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Auto-generate key"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Se)),t["\u0275did"](16,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ne)),t["\u0275did"](18,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,10,0,"generate_key"),l(n,16,0,!u.editing&&!u.userForm.getValue("generate_key")),l(n,18,0,!u.editing&&!u.userForm.getValue("generate_key"))},function(l,n){l(n,6,0,t["\u0275nov"](n,12).ngClassUntouched,t["\u0275nov"](n,12).ngClassTouched,t["\u0275nov"](n,12).ngClassPristine,t["\u0275nov"](n,12).ngClassDirty,t["\u0275nov"](n,12).ngClassValid,t["\u0275nov"](n,12).ngClassInvalid,t["\u0275nov"](n,12).ngClassPending)})}function je(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[["class","form-control no-border"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["There are no subusers."]))],null,null)}function Pe(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,17,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,15,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,1,"span",[["class","input-group-addon"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,0,"i",[["class","icon-prepend fa fa-user"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"input",[["class","form-control"],["readonly",""],["type","text"]],[[8,"value",0]],null,null,null,null)),t["\u0275did"](5,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](6,0,null,null,1,"span",[["class","input-group-addon"],["style","border-left: 0; border-right: 0;"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,0,"i",[["class","icon-prepend fa fa-share-alt"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,1,"input",[["class","form-control"],["readonly",""],["type","text"]],[[8,"value",0]],null,null,null,null)),t["\u0275did"](9,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](10,0,null,null,6,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,16777216,null,null,2,"button",[["class","btn btn-default tc_showSubuserButton"],["tooltip","Edit"],["type","button"]],[[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showSubuserModal(l.context.index)&&e),e},null,null)),t["\u0275did"](12,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275eld"](13,0,null,null,0,"i",[["class","fa fa-cogs"]],null,null,null,null,null)),(l()(),t["\u0275eld"](14,16777216,null,null,2,"button",[["class","btn btn-default tc_deleteSubuserButton"],["tooltip","Delete"],["type","button"]],[[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.deleteSubuser(l.context.index)&&e),e},null,null)),t["\u0275did"](15,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275eld"](16,0,null,null,0,"i",[["class","fa fa-times"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,0,"span",[["class","help-block"]],null,null,null,null,null))],function(l,n){l(n,12,0,"Edit"),l(n,15,0,"Delete")},function(l,n){l(n,4,0,t["\u0275inlineInterpolate"](1,"",n.context.$implicit.id,"")),l(n,8,0,t["\u0275inlineInterpolate"](1,"","full-control"===n.context.$implicit.permissions?"full":n.context.$implicit.permissions,"")),l(n,11,0,t["\u0275nov"](n,12).ariaDescribedby),l(n,14,0,t["\u0275nov"](n,15).ariaDescribedby)})}function ze(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,14,"fieldset",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Subusers"])),(l()(),t["\u0275eld"](3,0,null,null,11,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,je)),t["\u0275did"](5,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Pe)),t["\u0275did"](7,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275eld"](8,0,null,null,6,"span",[["class","form-control no-border"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,0,null,null,5,"button",[["class","btn btn-sm btn-default btn-label pull-right tc_addSubuserButton"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showSubuserModal()&&e),e},null,null)),(l()(),t["\u0275eld"](10,0,null,null,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,3,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](12,null,[""," ",""])),t["\u0275ppd"](13,1),t["\u0275ppd"](14,1)],function(l,n){var u=n.component;l(n,5,0,0===u.subusers.length),l(n,7,0,u.subusers)},function(l,n){var u=n.component,e=t["\u0275unv"](n,12,0,l(n,13,0,t["\u0275nov"](n.parent.parent,0),u.actionLabels.CREATE)),i=t["\u0275unv"](n,12,1,l(n,14,0,t["\u0275nov"](n.parent.parent,1),u.subuserLabel));l(n,12,0,e,i)})}function Ae(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[["class","form-control no-border"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["There are no keys."]))],null,null)}function Be(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,13,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,11,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,1,"span",[["class","input-group-addon"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,0,"i",[["class","icon-prepend fa fa-key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"input",[["class","form-control"],["readonly",""],["type","text"]],[[8,"value",0]],null,null,null,null)),t["\u0275did"](5,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](6,0,null,null,6,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,16777216,null,null,2,"button",[["class","btn btn-default tc_showS3KeyButton"],["tooltip","Show"],["type","button"]],[[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showS3KeyModal(l.context.index)&&e),e},null,null)),t["\u0275did"](8,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-eye"]],null,null,null,null,null)),(l()(),t["\u0275eld"](10,16777216,null,null,2,"button",[["class","btn btn-default tc_deleteS3KeyButton"],["tooltip","Delete"],["type","button"]],[[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.deleteS3Key(l.context.index)&&e),e},null,null)),t["\u0275did"](11,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275eld"](12,0,null,null,0,"i",[["class","fa fa-times"]],null,null,null,null,null)),(l()(),t["\u0275eld"](13,0,null,null,0,"span",[["class","help-block"]],null,null,null,null,null))],function(l,n){l(n,8,0,"Show"),l(n,11,0,"Delete")},function(l,n){l(n,4,0,t["\u0275inlineInterpolate"](1,"",n.context.$implicit.user,"")),l(n,7,0,t["\u0275nov"](n,8).ariaDescribedby),l(n,10,0,t["\u0275nov"](n,11).ariaDescribedby)})}function Ue(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[["class","form-control no-border"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["There are no keys."]))],null,null)}function Me(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,10,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,8,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,1,"span",[["class","input-group-addon"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,0,"i",[["class","icon-prepend fa fa-key"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"input",[["class","form-control"],["readonly",""],["type","text"]],[[8,"value",0]],null,null,null,null)),t["\u0275did"](5,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](6,0,null,null,3,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,16777216,null,null,2,"button",[["class","btn btn-default tc_showSwiftKeyButton"],["tooltip","Show"],["type","button"]],[[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showSwiftKeyModal(l.context.index)&&e),e},null,null)),t["\u0275did"](8,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-eye"]],null,null,null,null,null)),(l()(),t["\u0275eld"](10,0,null,null,0,"span",[["class","help-block"]],null,null,null,null,null))],function(l,n){l(n,8,0,"Show")},function(l,n){l(n,4,0,t["\u0275inlineInterpolate"](1,"",n.context.$implicit.user,"")),l(n,7,0,t["\u0275nov"](n,8).ariaDescribedby)})}function Oe(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,24,"fieldset",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Keys"])),(l()(),t["\u0275eld"](3,0,null,null,1,"label",[["class","col-sm-3 control-label"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["S3"])),(l()(),t["\u0275eld"](5,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,Ae)),t["\u0275did"](7,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Be)),t["\u0275did"](9,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275eld"](10,0,null,null,6,"span",[["class","form-control no-border"]],null,null,null,null,null)),(l()(),t["\u0275eld"](11,0,null,null,5,"button",[["class","btn btn-sm btn-default btn-label pull-right tc_addS3KeyButton"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showS3KeyModal()&&e),e},null,null)),(l()(),t["\u0275eld"](12,0,null,null,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),t["\u0275eld"](13,0,null,null,3,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](14,null,[""," ",""])),t["\u0275ppd"](15,1),t["\u0275ppd"](16,1),(l()(),t["\u0275eld"](17,0,null,null,0,"hr",[],null,null,null,null,null)),(l()(),t["\u0275eld"](18,0,null,null,1,"label",[["class","col-sm-3 control-label"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Swift"])),(l()(),t["\u0275eld"](20,0,null,null,4,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,Ue)),t["\u0275did"](22,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Me)),t["\u0275did"](24,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var u=n.component;l(n,7,0,0===u.s3Keys.length),l(n,9,0,u.s3Keys),l(n,22,0,0===u.swiftKeys.length),l(n,24,0,u.swiftKeys)},function(l,n){var u=n.component,e=t["\u0275unv"](n,14,0,l(n,15,0,t["\u0275nov"](n.parent.parent,0),u.actionLabels.CREATE)),i=t["\u0275unv"](n,14,1,l(n,16,0,t["\u0275nov"](n.parent.parent,1),u.s3keyLabel));l(n,14,0,e,i)})}function Le(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"span",[["class","form-control no-border"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["There are no capabilities."]))],null,null)}function Ge(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,13,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,11,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,1,"span",[["class","input-group-addon"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,0,"i",[["class","icon-prepend fa fa-share-alt"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,"input",[["class","form-control"],["readonly",""],["type","text"]],[[8,"value",0]],null,null,null,null)),t["\u0275did"](5,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),(l()(),t["\u0275eld"](6,0,null,null,6,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,16777216,null,null,2,"button",[["class","btn btn-default tc_editCapButton"],["tooltip","Edit"],["type","button"]],[[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showCapabilityModal(l.context.index)&&e),e},null,null)),t["\u0275did"](8,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-cogs"]],null,null,null,null,null)),(l()(),t["\u0275eld"](10,16777216,null,null,2,"button",[["class","btn btn-default tc_deleteCapButton"],["tooltip","Delete"],["type","button"]],[[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.deleteCapability(l.context.index)&&e),e},null,null)),t["\u0275did"](11,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"]},null),(l()(),t["\u0275eld"](12,0,null,null,0,"i",[["class","fa fa-times"]],null,null,null,null,null)),(l()(),t["\u0275eld"](13,0,null,null,0,"span",[["class","help-block"]],null,null,null,null,null))],function(l,n){l(n,8,0,"Edit"),l(n,11,0,"Delete")},function(l,n){l(n,4,0,t["\u0275inlineInterpolate"](2,"",n.context.$implicit.type,":",n.context.$implicit.perm,"")),l(n,7,0,t["\u0275nov"](n,8).ariaDescribedby),l(n,10,0,t["\u0275nov"](n,11).ariaDescribedby)})}function Ke(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,15,"fieldset",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Capabilities"])),(l()(),t["\u0275eld"](3,0,null,null,12,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,Le)),t["\u0275did"](5,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ge)),t["\u0275did"](7,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275eld"](8,0,null,null,7,"span",[["class","form-control no-border"]],null,null,null,null,null)),(l()(),t["\u0275eld"](9,16777216,null,null,6,"button",[["class","btn btn-sm btn-default btn-label pull-right tc_addCapButton"],["tooltip","All capabilities are already added."],["triggers","pointerenter pointerleave"],["type","button"]],[[8,"disabled",0],[1,"aria-describedby",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.showCapabilityModal()&&e),e},null,null)),t["\u0275did"](10,212992,null,0,Ou.c,[t.ViewContainerRef,Jl.a,Ou.a,t.ElementRef,t.Renderer2,Mu.a],{tooltip:[0,"tooltip"],triggers:[1,"triggers"],isDisabled:[2,"isDisabled"]},null),(l()(),t["\u0275eld"](11,0,null,null,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),t["\u0275eld"](12,0,null,null,3,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](13,null,[""," ",""])),t["\u0275ppd"](14,1),t["\u0275ppd"](15,1)],function(l,n){var u=n.component;l(n,5,0,0===u.capabilities.length),l(n,7,0,u.capabilities),l(n,10,0,"All capabilities are already added.","pointerenter pointerleave",!u.hasAllCapabilities())},function(l,n){var u=n.component;l(n,9,0,u.hasAllCapabilities(),t["\u0275nov"](n,10).ariaDescribedby);var e=t["\u0275unv"](n,13,0,l(n,14,0,t["\u0275nov"](n.parent.parent,0),u.actionLabels.ADD)),i=t["\u0275unv"](n,13,1,l(n,15,0,t["\u0275nov"](n.parent.parent,1),u.capabilityLabel));l(n,13,0,e,i)})}function $e(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,6,"input",[["formControlName","user_quota_max_size_unlimited"],["id","user_quota_max_size_unlimited"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,5).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,5).onTouched()&&e),e},null,null)),t["\u0275did"](4,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](5,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](7,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](9,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](10,0,null,null,1,"label",[["for","user_quota_max_size_unlimited"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited size"]))],function(l,n){l(n,7,0,"user_quota_max_size_unlimited")},function(l,n){l(n,3,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending)})}function Ze(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Qe(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The value is not valid."]))],null,null)}function He(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","user_quota_max_size"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Max. size"])),(l()(),t["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,7,"input",[["cdDimlessBinary",""],["class","form-control"],["formControlName","user_quota_max_size"],["id","user_quota_max_size"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,9)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,9).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,9)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,9)._compositionEnd(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,13).onBlur(u.target.value)&&e),e},null,null)),t["\u0275did"](9,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](11,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](13,81920,null,0,ve.a,[t.ElementRef,d.q,q.a,U.a],null,null),t["\u0275did"](14,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](15,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ze)),t["\u0275did"](17,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Qe)),t["\u0275did"](19,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.userForm.showError("user_quota_max_size",t["\u0275nov"](n.parent,3)));l(n,1,0,"form-group",e),l(n,11,0,"user_quota_max_size"),l(n,13,0),l(n,17,0,u.userForm.showError("user_quota_max_size",t["\u0275nov"](n.parent,3),"required")),l(n,19,0,u.userForm.showError("user_quota_max_size",t["\u0275nov"](n.parent,3),"quotaMaxSize"))},function(l,n){l(n,8,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending)})}function Ye(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,6,"input",[["formControlName","user_quota_max_objects_unlimited"],["id","user_quota_max_objects_unlimited"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,5).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,5).onTouched()&&e),e},null,null)),t["\u0275did"](4,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](5,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](7,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](9,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](10,0,null,null,1,"label",[["for","user_quota_max_objects_unlimited"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited objects"]))],function(l,n){l(n,7,0,"user_quota_max_objects_unlimited")},function(l,n){l(n,3,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending)})}function Xe(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Je(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The entered value must be >= 0."]))],null,null)}function We(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","user_quota_max_objects"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Max. objects"])),(l()(),t["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,7,"input",[["class","form-control"],["formControlName","user_quota_max_objects"],["id","user_quota_max_objects"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,10)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,10).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,10)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,10)._compositionEnd(u.target.value)&&e),"change"===n&&(e=!1!==t["\u0275nov"](l,11).onChange(u.target.value)&&e),"input"===n&&(e=!1!==t["\u0275nov"](l,11).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,11).onTouched()&&e),e},null,null)),t["\u0275did"](9,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](10,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275did"](11,16384,null,0,d.C,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l,n){return[l,n]},[d.e,d.C]),t["\u0275did"](13,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](15,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,Xe)),t["\u0275did"](17,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Je)),t["\u0275did"](19,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.userForm.showError("user_quota_max_objects",t["\u0275nov"](n.parent,3)));l(n,1,0,"form-group",e),l(n,13,0,"user_quota_max_objects"),l(n,17,0,u.userForm.showError("user_quota_max_objects",t["\u0275nov"](n.parent,3),"required")),l(n,19,0,u.userForm.showError("user_quota_max_objects",t["\u0275nov"](n.parent,3),"min"))},function(l,n){l(n,8,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending)})}function lt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,6,"input",[["formControlName","bucket_quota_max_size_unlimited"],["id","bucket_quota_max_size_unlimited"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,5).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,5).onTouched()&&e),e},null,null)),t["\u0275did"](4,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](5,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](7,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](9,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](10,0,null,null,1,"label",[["for","bucket_quota_max_size_unlimited"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited size"]))],function(l,n){l(n,7,0,"bucket_quota_max_size_unlimited")},function(l,n){l(n,3,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending)})}function nt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function ut(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The value is not valid."]))],null,null)}function et(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","bucket_quota_max_size"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Max. size"])),(l()(),t["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,7,"input",[["cdDimlessBinary",""],["class","form-control"],["formControlName","bucket_quota_max_size"],["id","bucket_quota_max_size"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,9)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,9).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,9)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,9)._compositionEnd(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,13).onBlur(u.target.value)&&e),e},null,null)),t["\u0275did"](9,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](11,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](13,81920,null,0,ve.a,[t.ElementRef,d.q,q.a,U.a],null,null),t["\u0275did"](14,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](15,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,nt)),t["\u0275did"](17,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,ut)),t["\u0275did"](19,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.userForm.showError("bucket_quota_max_size",t["\u0275nov"](n.parent,3)));l(n,1,0,"form-group",e),l(n,11,0,"bucket_quota_max_size"),l(n,13,0),l(n,17,0,u.userForm.showError("bucket_quota_max_size",t["\u0275nov"](n.parent,3),"required")),l(n,19,0,u.userForm.showError("bucket_quota_max_size",t["\u0275nov"](n.parent,3),"quotaMaxSize"))},function(l,n){l(n,8,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending)})}function tt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](3,0,null,null,6,"input",[["formControlName","bucket_quota_max_objects_unlimited"],["id","bucket_quota_max_objects_unlimited"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,5).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,5).onTouched()&&e),e},null,null)),t["\u0275did"](4,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](5,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](7,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](9,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](10,0,null,null,1,"label",[["for","bucket_quota_max_objects_unlimited"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Unlimited objects"]))],function(l,n){l(n,7,0,"bucket_quota_max_objects_unlimited")},function(l,n){l(n,3,0,t["\u0275nov"](n,9).ngClassUntouched,t["\u0275nov"](n,9).ngClassTouched,t["\u0275nov"](n,9).ngClassPristine,t["\u0275nov"](n,9).ngClassDirty,t["\u0275nov"](n,9).ngClassValid,t["\u0275nov"](n,9).ngClassInvalid,t["\u0275nov"](n,9).ngClassPending)})}function it(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function ot(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The entered value must be >= 0."]))],null,null)}function at(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](1,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](2,{"has-error":0}),(l()(),t["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","bucket_quota_max_objects"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Max. objects"])),(l()(),t["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,7,"input",[["class","form-control"],["formControlName","bucket_quota_max_objects"],["id","bucket_quota_max_objects"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,10)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,10).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,10)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,10)._compositionEnd(u.target.value)&&e),"change"===n&&(e=!1!==t["\u0275nov"](l,11).onChange(u.target.value)&&e),"input"===n&&(e=!1!==t["\u0275nov"](l,11).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,11).onTouched()&&e),e},null,null)),t["\u0275did"](9,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](10,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275did"](11,16384,null,0,d.C,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l,n){return[l,n]},[d.e,d.C]),t["\u0275did"](13,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](15,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,it)),t["\u0275did"](17,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,ot)),t["\u0275did"](19,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,e=l(n,2,0,u.userForm.showError("bucket_quota_max_objects",t["\u0275nov"](n.parent,3)));l(n,1,0,"form-group",e),l(n,13,0,"bucket_quota_max_objects"),l(n,17,0,u.userForm.showError("bucket_quota_max_objects",t["\u0275nov"](n.parent,3),"required")),l(n,19,0,u.userForm.showError("bucket_quota_max_objects",t["\u0275nov"](n.parent,3),"min"))},function(l,n){l(n,8,0,t["\u0275nov"](n,15).ngClassUntouched,t["\u0275nov"](n,15).ngClassTouched,t["\u0275nov"](n,15).ngClassPristine,t["\u0275nov"](n,15).ngClassDirty,t["\u0275nov"](n,15).ngClassValid,t["\u0275nov"](n,15).ngClassInvalid,t["\u0275nov"](n,15).ngClassPending)})}function rt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,168,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,167,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var e=!0;return"submit"===n&&(e=!1!==t["\u0275nov"](l,3).onSubmit(u)&&e),"reset"===n&&(e=!1!==t["\u0275nov"](l,3).onReset()&&e),e},null,null)),t["\u0275did"](2,16384,null,0,d.D,[],null,null),t["\u0275did"](3,540672,[["frm",4]],0,d.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,d.d,null,[d.l]),t["\u0275did"](5,16384,null,0,d.s,[[4,d.d]],null,null),(l()(),t["\u0275eld"](6,0,null,null,162,"div",[["class","panel panel-default"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(l()(),t["\u0275ted"](9,null,[""," ",""])),t["\u0275ppd"](10,1),t["\u0275ppd"](11,1),(l()(),t["\u0275eld"](12,0,null,null,147,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),t["\u0275eld"](13,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](14,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](15,{"has-error":0}),(l()(),t["\u0275eld"](16,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","uid"]],null,null,null,null,null)),(l()(),t["\u0275eld"](17,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Username"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Ce)),t["\u0275did"](20,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](21,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](22,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","uid"],["id","uid"],["type","text"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,25)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,25).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,25)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,25)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](23,4210688,null,0,zn.a,[t.ElementRef],null,null),t["\u0275did"](24,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](25,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](27,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](29,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,_e)),t["\u0275did"](31,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,ke)),t["\u0275did"](33,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](34,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](35,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](36,{"has-error":0}),(l()(),t["\u0275eld"](37,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","display_name"]],null,null,null,null,null)),(l()(),t["\u0275eld"](38,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Full name"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Re)),t["\u0275did"](41,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](42,0,null,null,9,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](43,0,null,null,6,"input",[["class","form-control"],["formControlName","display_name"],["id","display_name"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,45)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,45).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,45)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,45)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](44,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](45,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](47,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](49,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ie)),t["\u0275did"](51,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](52,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](53,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](54,{"has-error":0}),(l()(),t["\u0275eld"](55,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","email"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Email address"])),(l()(),t["\u0275eld"](57,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](58,0,null,null,6,"input",[["class","form-control"],["formControlName","email"],["id","email"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,60)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,60).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,60)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,60)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](59,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](60,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](62,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](64,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,we)),t["\u0275did"](66,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ee)),t["\u0275did"](68,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](69,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](70,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","max_buckets_mode"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Max. buckets"])),(l()(),t["\u0275eld"](72,0,null,null,19,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](73,0,null,null,18,"select",[["class","form-control"],["formControlName","max_buckets_mode"],["id","max_buckets_mode"],["name","max_buckets_mode"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0,i=l.component;return"change"===n&&(e=!1!==t["\u0275nov"](l,75).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,75).onTouched()&&e),"change"===n&&(e=!1!==i.onMaxBucketsModeChange(u.target.value)&&e),e},null,null)),t["\u0275did"](74,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](75,16384,null,0,d.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.z]),t["\u0275did"](77,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](79,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](80,0,null,null,3,"option",[["value","-1"]],null,null,null,null,null)),t["\u0275did"](81,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](82,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](-1,null,["Disabled"])),(l()(),t["\u0275eld"](84,0,null,null,3,"option",[["value","0"]],null,null,null,null,null)),t["\u0275did"](85,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](86,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](-1,null,["Unlimited"])),(l()(),t["\u0275eld"](88,0,null,null,3,"option",[["value","1"]],null,null,null,null,null)),t["\u0275did"](89,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](90,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](-1,null,["Custom"])),(l()(),t["\u0275and"](16777216,null,null,1,null,qe)),t["\u0275did"](93,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](94,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](95,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](96,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](97,0,null,null,6,"input",[["formControlName","suspended"],["id","suspended"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,99).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,99).onTouched()&&e),e},null,null)),t["\u0275did"](98,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](99,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](101,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](103,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](104,0,null,null,1,"label",[["for","suspended"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Suspended"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Fe)),t["\u0275did"](107,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,ze)),t["\u0275did"](109,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Oe)),t["\u0275did"](111,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ke)),t["\u0275did"](113,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](114,0,null,null,22,"fieldset",[],null,null,null,null,null)),(l()(),t["\u0275eld"](115,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["User quota"])),(l()(),t["\u0275eld"](117,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](118,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](119,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](120,0,null,null,6,"input",[["formControlName","user_quota_enabled"],["id","user_quota_enabled"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,122).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,122).onTouched()&&e),e},null,null)),t["\u0275did"](121,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](122,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](124,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](126,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](127,0,null,null,1,"label",[["for","user_quota_enabled"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Enabled"])),(l()(),t["\u0275and"](16777216,null,null,1,null,$e)),t["\u0275did"](130,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,He)),t["\u0275did"](132,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ye)),t["\u0275did"](134,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,We)),t["\u0275did"](136,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](137,0,null,null,22,"fieldset",[],null,null,null,null,null)),(l()(),t["\u0275eld"](138,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Bucket quota"])),(l()(),t["\u0275eld"](140,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](141,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](142,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),t["\u0275eld"](143,0,null,null,6,"input",[["formControlName","bucket_quota_enabled"],["id","bucket_quota_enabled"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,145).onChange(u.target.checked)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,145).onTouched()&&e),e},null,null)),t["\u0275did"](144,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](145,16384,null,0,d.c,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.c]),t["\u0275did"](147,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](149,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275eld"](150,0,null,null,1,"label",[["for","bucket_quota_enabled"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Enabled"])),(l()(),t["\u0275and"](16777216,null,null,1,null,lt)),t["\u0275did"](153,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,et)),t["\u0275did"](155,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,tt)),t["\u0275did"](157,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,at)),t["\u0275did"](159,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](160,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](161,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](162,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(l,n,u){var e=!0;return"submitAction"===n&&(e=!1!==l.component.onSubmit()&&e),e},An.b,An.a)),t["\u0275did"](163,114688,null,0,Bn.a,[t.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](164,0,[""," ",""])),t["\u0275ppd"](165,1),t["\u0275ppd"](166,1),(l()(),t["\u0275eld"](167,0,null,null,1,"cd-back-button",[],null,null,null,Sn.b,Sn.a)),t["\u0275did"](168,49152,null,0,Dn.a,[ql.Location,i.b],null,null)],function(l,n){var u=n.component;l(n,3,0,u.userForm);var e=l(n,15,0,u.userForm.showError("uid",t["\u0275nov"](n,3)));l(n,14,0,"form-group",e),l(n,20,0,!u.editing),l(n,27,0,"uid"),l(n,31,0,u.userForm.showError("uid",t["\u0275nov"](n,3),"required")),l(n,33,0,u.userForm.showError("uid",t["\u0275nov"](n,3),"notUnique"));var i=l(n,36,0,u.userForm.showError("display_name",t["\u0275nov"](n,3)));l(n,35,0,"form-group",i),l(n,41,0,!u.editing),l(n,47,0,"display_name"),l(n,51,0,u.userForm.showError("display_name",t["\u0275nov"](n,3),"required"));var o=l(n,54,0,u.userForm.showError("email",t["\u0275nov"](n,3)));l(n,53,0,"form-group",o),l(n,62,0,"email"),l(n,66,0,u.userForm.showError("email",t["\u0275nov"](n,3),"email")),l(n,68,0,u.userForm.showError("email",t["\u0275nov"](n,3),"notUnique")),l(n,77,0,"max_buckets_mode"),l(n,81,0,"-1"),l(n,82,0,"-1"),l(n,85,0,"0"),l(n,86,0,"0"),l(n,89,0,"1"),l(n,90,0,"1"),l(n,93,0,1==u.userForm.get("max_buckets_mode").value),l(n,101,0,"suspended"),l(n,107,0,!u.editing),l(n,109,0,u.editing),l(n,111,0,u.editing),l(n,113,0,u.editing),l(n,124,0,"user_quota_enabled"),l(n,130,0,u.userForm.controls.user_quota_enabled.value),l(n,132,0,!u.userForm.getValue("user_quota_max_size_unlimited")),l(n,134,0,u.userForm.controls.user_quota_enabled.value),l(n,136,0,!u.userForm.getValue("user_quota_max_objects_unlimited")),l(n,147,0,"bucket_quota_enabled"),l(n,153,0,u.userForm.controls.bucket_quota_enabled.value),l(n,155,0,!u.userForm.getValue("bucket_quota_max_size_unlimited")),l(n,157,0,u.userForm.controls.bucket_quota_enabled.value),l(n,159,0,!u.userForm.getValue("bucket_quota_max_objects_unlimited")),l(n,163,0,u.userForm,"button")},function(l,n){var u=n.component;l(n,1,0,t["\u0275nov"](n,5).ngClassUntouched,t["\u0275nov"](n,5).ngClassTouched,t["\u0275nov"](n,5).ngClassPristine,t["\u0275nov"](n,5).ngClassDirty,t["\u0275nov"](n,5).ngClassValid,t["\u0275nov"](n,5).ngClassInvalid,t["\u0275nov"](n,5).ngClassPending);var e=t["\u0275unv"](n,9,0,l(n,10,0,t["\u0275nov"](n.parent,0),u.action)),i=t["\u0275unv"](n,9,1,l(n,11,0,t["\u0275nov"](n.parent,1),u.resource));l(n,9,0,e,i),l(n,22,0,u.editing,t["\u0275nov"](n,29).ngClassUntouched,t["\u0275nov"](n,29).ngClassTouched,t["\u0275nov"](n,29).ngClassPristine,t["\u0275nov"](n,29).ngClassDirty,t["\u0275nov"](n,29).ngClassValid,t["\u0275nov"](n,29).ngClassInvalid,t["\u0275nov"](n,29).ngClassPending),l(n,43,0,t["\u0275nov"](n,49).ngClassUntouched,t["\u0275nov"](n,49).ngClassTouched,t["\u0275nov"](n,49).ngClassPristine,t["\u0275nov"](n,49).ngClassDirty,t["\u0275nov"](n,49).ngClassValid,t["\u0275nov"](n,49).ngClassInvalid,t["\u0275nov"](n,49).ngClassPending),l(n,58,0,t["\u0275nov"](n,64).ngClassUntouched,t["\u0275nov"](n,64).ngClassTouched,t["\u0275nov"](n,64).ngClassPristine,t["\u0275nov"](n,64).ngClassDirty,t["\u0275nov"](n,64).ngClassValid,t["\u0275nov"](n,64).ngClassInvalid,t["\u0275nov"](n,64).ngClassPending),l(n,73,0,t["\u0275nov"](n,79).ngClassUntouched,t["\u0275nov"](n,79).ngClassTouched,t["\u0275nov"](n,79).ngClassPristine,t["\u0275nov"](n,79).ngClassDirty,t["\u0275nov"](n,79).ngClassValid,t["\u0275nov"](n,79).ngClassInvalid,t["\u0275nov"](n,79).ngClassPending),l(n,97,0,t["\u0275nov"](n,103).ngClassUntouched,t["\u0275nov"](n,103).ngClassTouched,t["\u0275nov"](n,103).ngClassPristine,t["\u0275nov"](n,103).ngClassDirty,t["\u0275nov"](n,103).ngClassValid,t["\u0275nov"](n,103).ngClassInvalid,t["\u0275nov"](n,103).ngClassPending),l(n,120,0,t["\u0275nov"](n,126).ngClassUntouched,t["\u0275nov"](n,126).ngClassTouched,t["\u0275nov"](n,126).ngClassPristine,t["\u0275nov"](n,126).ngClassDirty,t["\u0275nov"](n,126).ngClassValid,t["\u0275nov"](n,126).ngClassInvalid,t["\u0275nov"](n,126).ngClassPending),l(n,143,0,t["\u0275nov"](n,149).ngClassUntouched,t["\u0275nov"](n,149).ngClassTouched,t["\u0275nov"](n,149).ngClassPristine,t["\u0275nov"](n,149).ngClassDirty,t["\u0275nov"](n,149).ngClassValid,t["\u0275nov"](n,149).ngClassInvalid,t["\u0275nov"](n,149).ngClassPending);var o=t["\u0275unv"](n,164,0,l(n,165,0,t["\u0275nov"](n.parent,0),u.action)),a=t["\u0275unv"](n,164,1,l(n,166,0,t["\u0275nov"](n.parent,1),u.resource));l(n,164,0,o,a)})}function st(l){return t["\u0275vid"](0,[t["\u0275pid"](0,ql.TitleCasePipe,[]),t["\u0275pid"](0,wn.a,[]),(l()(),t["\u0275and"](16777216,null,null,1,null,he)),t["\u0275did"](3,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,ye)),t["\u0275did"](5,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,rt)),t["\u0275did"](7,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,3,0,u.editing&&u.loading&&!u.error),l(n,5,0,u.editing&&u.error),l(n,7,0,!u.loading&&!u.error)},null)}function dt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-user-form",[],null,null,null,st,be)),t["\u0275did"](1,114688,null,0,Z,[_.a,$u.a,$u.l,y.a,nn.b,k.a,_l.a,i.b],null,null)],function(l,n){l(n,1,0)},null)}var ct=t["\u0275ccf"]("cd-rgw-user-form",Z,dt,{},{},[]),pt=u("xSw7"),ft=u("GgAd"),mt=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function gt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-usage-bar",[],null,null,null,pt.b,pt.a)),t["\u0275did"](1,573440,null,0,ft.a,[],{total:[0,"total"],used:[1,"used"]},null)],function(l,n){l(n,1,0,n.parent.context.row.bucket_quota.max_size,n.parent.context.row.bucket_size)},null)}function vt(l){return t["\u0275vid"](0,[(l()(),t["\u0275ted"](-1,null,["No Limit"]))],null,null)}function bt(l){return t["\u0275vid"](0,[(l()(),t["\u0275and"](16777216,null,null,1,null,gt)),t["\u0275did"](1,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),t["\u0275and"](0,[["noSizeQuota",2]],null,0,null,vt))],function(l,n){l(n,1,0,n.context.row.bucket_quota.max_size>0&&n.context.row.bucket_quota.enabled,t["\u0275nov"](n,2))},null)}function ht(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-usage-bar",[],null,null,null,pt.b,pt.a)),t["\u0275did"](1,573440,null,0,ft.a,[],{total:[0,"total"],used:[1,"used"],isBinary:[2,"isBinary"]},null)],function(l,n){l(n,1,0,n.parent.context.row.bucket_quota.max_objects,n.parent.context.row.num_objects,!1)},null)}function yt(l){return t["\u0275vid"](0,[(l()(),t["\u0275ted"](-1,null,["No Limit"]))],null,null)}function Ct(l){return t["\u0275vid"](0,[(l()(),t["\u0275and"](16777216,null,null,1,null,ht)),t["\u0275did"](1,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),t["\u0275and"](0,[["noObjectQuota",2]],null,0,null,yt))],function(l,n){l(n,1,0,n.context.row.bucket_quota.max_objects>0&&n.context.row.bucket_quota.enabled,t["\u0275nov"](n,2))},null)}function _t(l){return t["\u0275vid"](0,[t["\u0275qud"](402653184,1,{table:0}),t["\u0275qud"](402653184,2,{bucketSizeTpl:0}),t["\u0275qud"](402653184,3,{bucketObjectTpl:0}),(l()(),t["\u0275eld"](3,0,null,null,5,"cd-table",[["columnMode","flex"],["identifier","bid"],["selectionType","multi"]],null,[[null,"updateSelection"],[null,"fetchData"]],function(l,n,u){var e=!0,t=l.component;return"updateSelection"===n&&(e=!1!==t.updateSelection(u)&&e),"fetchData"===n&&(e=!1!==t.getBucketList(u)&&e),e},Yl.b,Yl.a)),t["\u0275did"](4,2867200,[[1,4],["table",4]],0,x.a,[t.NgZone,t.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoReload:[3,"autoReload"],identifier:[4,"identifier"],selectionType:[5,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(l()(),t["\u0275eld"](5,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,oe.b,oe.a)),t["\u0275did"](6,114688,null,0,ae.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),t["\u0275eld"](7,0,null,2,1,"cd-rgw-bucket-details",[["cdTableDetail",""]],null,null,null,Zl,Bl)),t["\u0275did"](8,573440,null,0,Al,[],{selection:[0,"selection"]},null),(l()(),t["\u0275and"](0,[[2,2],["bucketSizeTpl",2]],null,0,null,bt)),(l()(),t["\u0275and"](0,[[3,2],["bucketObjectTpl",2]],null,0,null,Ct))],function(l,n){var u=n.component;l(n,4,0,u.buckets,u.columns,"flex",!1,"bid","multi"),l(n,6,0,u.permission,u.selection,u.tableActions),l(n,8,0,u.selection)},null)}function kt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"cd-rgw-bucket-list",[],null,null,null,_t,mt)),t["\u0275prd"](256,null,D.a,N,[]),t["\u0275did"](2,114688,null,0,F,[S.a,q.a,V.a,h,nn.b,_l.a,D.a,i.b,t.ChangeDetectorRef],null,null)],function(l,n){l(n,2,0)},null)}var Rt=t["\u0275ccf"]("cd-rgw-bucket-list",F,kt,{},{},[]),It=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function wt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"cd-loading-panel",[],null,null,null,pe.b,pe.a)),t["\u0275did"](1,49152,null,0,fe.a,[],null,null),(l()(),t["\u0275ted"](-1,0,["Loading bucket data..."]))],null,null)}function Et(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,2,"cd-error-panel",[],null,[[null,"backAction"]],function(l,n,u){var e=!0;return"backAction"===n&&(e=!1!==l.component.goToListView()&&e),e},me.b,me.a)),t["\u0275did"](1,49152,null,0,ge.a,[],null,{backAction:"backAction"}),(l()(),t["\u0275ted"](-1,0,["The bucket data could not be loaded."]))],null,null)}function xt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,1,"label",[["class","col-sm-3 control-label"],["for","id"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Id"])),(l()(),t["\u0275eld"](3,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,null,6,"input",[["class","form-control"],["formControlName","id"],["id","id"],["name","id"],["readonly",""],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,6)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,6).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,6)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,6)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](5,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](6,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](8,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](10,16384,null,0,d.r,[[4,d.q]],null,null)],function(l,n){l(n,8,0,"id")},function(l,n){l(n,4,0,t["\u0275nov"](n,10).ngClassUntouched,t["\u0275nov"](n,10).ngClassTouched,t["\u0275nov"](n,10).ngClassPristine,t["\u0275nov"](n,10).ngClassDirty,t["\u0275nov"](n,10).ngClassValid,t["\u0275nov"](n,10).ngClassInvalid,t["\u0275nov"](n,10).ngClassPending)})}function Tt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function qt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Vt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The value is not valid."]))],null,null)}function St(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["The chosen name is already in use."]))],null,null)}function Dt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function Nt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{ngValue:[0,"ngValue"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),t["\u0275ted"](-1,null,["-- Select a user --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function Ft(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),t["\u0275did"](1,147456,null,0,d.v,[t.ElementRef,t.Renderer2,[2,d.z]],{value:[0,"value"]},null),t["\u0275did"](2,147456,null,0,d.G,[t.ElementRef,t.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),t["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function jt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Pt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,69,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,68,"form",[["class","form-horizontal"],["name","bucketForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var e=!0;return"submit"===n&&(e=!1!==t["\u0275nov"](l,3).onSubmit(u)&&e),"reset"===n&&(e=!1!==t["\u0275nov"](l,3).onReset()&&e),e},null,null)),t["\u0275did"](2,16384,null,0,d.D,[],null,null),t["\u0275did"](3,540672,[["frm",4]],0,d.l,[[8,null],[8,null]],{form:[0,"form"]},null),t["\u0275prd"](2048,null,d.d,null,[d.l]),t["\u0275did"](5,16384,null,0,d.s,[[4,d.d]],null,null),(l()(),t["\u0275eld"](6,0,null,null,63,"div",[["class","panel panel-default"]],null,null,null,null,null)),(l()(),t["\u0275eld"](7,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),t["\u0275eld"](8,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(l()(),t["\u0275ted"](9,null,[""," ",""])),t["\u0275ppd"](10,1),t["\u0275ppd"](11,1),(l()(),t["\u0275eld"](12,0,null,null,48,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,xt)),t["\u0275did"](14,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](15,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](16,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](17,{"has-error":0}),(l()(),t["\u0275eld"](18,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","bid"]],null,null,null,null,null)),(l()(),t["\u0275eld"](19,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Name"])),(l()(),t["\u0275and"](16777216,null,null,1,null,Tt)),t["\u0275did"](22,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](23,0,null,null,14,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](24,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","bid"],["id","bid"],["name","bid"],["placeholder","Name..."],["type","text"]],[[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var e=!0;return"input"===n&&(e=!1!==t["\u0275nov"](l,27)._handleInput(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,27).onTouched()&&e),"compositionstart"===n&&(e=!1!==t["\u0275nov"](l,27)._compositionStart()&&e),"compositionend"===n&&(e=!1!==t["\u0275nov"](l,27)._compositionEnd(u.target.value)&&e),e},null,null)),t["\u0275did"](25,4210688,null,0,zn.a,[t.ElementRef],null,null),t["\u0275did"](26,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](27,16384,null,0,d.e,[t.Renderer2,t.ElementRef,[2,d.b]],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.e]),t["\u0275did"](29,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](31,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,qt)),t["\u0275did"](33,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Vt)),t["\u0275did"](35,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,St)),t["\u0275did"](37,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](38,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),t["\u0275did"](39,278528,null,0,ql.NgClass,[t.IterableDiffers,t.KeyValueDiffers,t.ElementRef,t.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),t["\u0275pod"](40,{"has-error":0}),(l()(),t["\u0275eld"](41,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","owner"]],null,null,null,null,null)),(l()(),t["\u0275eld"](42,0,null,null,1,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Owner"])),(l()(),t["\u0275eld"](44,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),t["\u0275eld"](45,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),t["\u0275eld"](46,0,null,null,12,"select",[["class","form-control"],["formControlName","owner"],["id","owner"],["name","owner"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==t["\u0275nov"](l,48).onChange(u.target.value)&&e),"blur"===n&&(e=!1!==t["\u0275nov"](l,48).onTouched()&&e),e},null,null)),t["\u0275did"](47,4210688,null,0,En.a,[[2,xn.a],S.a,t.ElementRef],null,null),t["\u0275did"](48,16384,null,0,d.z,[t.Renderer2,t.ElementRef],null,null),t["\u0275prd"](1024,null,d.p,function(l){return[l]},[d.z]),t["\u0275did"](50,671744,null,0,d.j,[[3,d.d],[8,null],[8,null],[6,d.p],[2,d.F]],{name:[0,"name"]},null),t["\u0275prd"](2048,null,d.q,null,[d.j]),t["\u0275did"](52,16384,null,0,d.r,[[4,d.q]],null,null),(l()(),t["\u0275and"](16777216,null,null,1,null,Dt)),t["\u0275did"](54,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Nt)),t["\u0275did"](56,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Ft)),t["\u0275did"](58,278528,null,0,ql.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,jt)),t["\u0275did"](60,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275eld"](61,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(l()(),t["\u0275eld"](62,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),t["\u0275eld"](63,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(l,n,u){var e=!0;return"submitAction"===n&&(e=!1!==l.component.submit()&&e),e},An.b,An.a)),t["\u0275did"](64,114688,null,0,Bn.a,[t.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(l()(),t["\u0275ted"](65,0,[""," ",""])),t["\u0275ppd"](66,1),t["\u0275ppd"](67,1),(l()(),t["\u0275eld"](68,0,null,null,1,"cd-back-button",[],null,null,null,Sn.b,Sn.a)),t["\u0275did"](69,49152,null,0,Dn.a,[ql.Location,i.b],null,null)],function(l,n){var u=n.component;l(n,3,0,u.bucketForm),l(n,14,0,u.editing);var e=l(n,17,0,u.bucketForm.showError("bid",t["\u0275nov"](n,3)));l(n,16,0,"form-group",e),l(n,22,0,!u.editing),l(n,29,0,"bid"),l(n,33,0,u.bucketForm.showError("bid",t["\u0275nov"](n,3),"required")),l(n,35,0,u.bucketForm.showError("bid",t["\u0275nov"](n,3),"bucketNameInvalid")),l(n,37,0,u.bucketForm.showError("bid",t["\u0275nov"](n,3),"bucketNameExists"));var i=l(n,40,0,u.bucketForm.showError("owner",t["\u0275nov"](n,3)));l(n,39,0,"form-group",i),l(n,50,0,"owner"),l(n,54,0,null===u.owners),l(n,56,0,null!==u.owners),l(n,58,0,u.owners),l(n,60,0,u.bucketForm.showError("owner",t["\u0275nov"](n,3),"required")),l(n,64,0,u.bucketForm,"button")},function(l,n){var u=n.component;l(n,1,0,t["\u0275nov"](n,5).ngClassUntouched,t["\u0275nov"](n,5).ngClassTouched,t["\u0275nov"](n,5).ngClassPristine,t["\u0275nov"](n,5).ngClassDirty,t["\u0275nov"](n,5).ngClassValid,t["\u0275nov"](n,5).ngClassInvalid,t["\u0275nov"](n,5).ngClassPending);var e=t["\u0275unv"](n,9,0,l(n,10,0,t["\u0275nov"](n.parent,0),u.action)),i=t["\u0275unv"](n,9,1,l(n,11,0,t["\u0275nov"](n.parent,1),u.resource));l(n,9,0,e,i),l(n,24,0,u.editing,t["\u0275nov"](n,31).ngClassUntouched,t["\u0275nov"](n,31).ngClassTouched,t["\u0275nov"](n,31).ngClassPristine,t["\u0275nov"](n,31).ngClassDirty,t["\u0275nov"](n,31).ngClassValid,t["\u0275nov"](n,31).ngClassInvalid,t["\u0275nov"](n,31).ngClassPending),l(n,46,0,t["\u0275nov"](n,52).ngClassUntouched,t["\u0275nov"](n,52).ngClassTouched,t["\u0275nov"](n,52).ngClassPristine,t["\u0275nov"](n,52).ngClassDirty,t["\u0275nov"](n,52).ngClassValid,t["\u0275nov"](n,52).ngClassInvalid,t["\u0275nov"](n,52).ngClassPending);var o=t["\u0275unv"](n,65,0,l(n,66,0,t["\u0275nov"](n.parent,0),u.action)),a=t["\u0275unv"](n,65,1,l(n,67,0,t["\u0275nov"](n.parent,1),u.resource));l(n,65,0,o,a)})}function zt(l){return t["\u0275vid"](0,[t["\u0275pid"](0,ql.TitleCasePipe,[]),t["\u0275pid"](0,wn.a,[]),(l()(),t["\u0275and"](16777216,null,null,1,null,wt)),t["\u0275did"](3,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Et)),t["\u0275did"](5,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),t["\u0275and"](16777216,null,null,1,null,Pt)),t["\u0275did"](7,16384,null,0,ql.NgIf,[t.ViewContainerRef,t.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,3,0,u.editing&&u.loading&&!u.error),l(n,5,0,u.editing&&u.error),l(n,7,0,!u.loading&&!u.error)},null)}function At(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-bucket-form",[],null,null,null,zt,It)),t["\u0275did"](1,114688,null,0,R,[$u.a,$u.l,_.a,h,y.a,k.a,_l.a,i.b],null,null)],function(l,n){l(n,1,0)},null)}var Bt=t["\u0275ccf"]("cd-rgw-bucket-form",R,At,{},{},[]),Ut=u("TZo1"),Mt=u("9Kw/"),Ot=t["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Lt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,8,"cd-info-panel",[],null,null,null,Ut.b,Ut.a)),t["\u0275did"](1,49152,null,0,Mt.a,[_l.a],null,null),(l()(),t["\u0275ted"](2,0,[" ",""])),(l()(),t["\u0275eld"](3,0,null,0,0,"br",[],null,null,null,null,null)),(l()(),t["\u0275eld"](4,0,null,0,4,null,null,null,null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["Please consult the "])),(l()(),t["\u0275eld"](6,0,null,null,1,"a",[["target","_blank"]],[[8,"href",4]],null,null,null,null)),(l()(),t["\u0275ted"](-1,null,["documentation"])),(l()(),t["\u0275ted"](-1,null,[" on how to configure and enable the Object Gateway management functionality."]))],null,function(l,n){var u=n.component;l(n,2,0,u.message),l(n,6,0,t["\u0275inlineInterpolate"](1,"",u.docsUrl,""))})}function Gt(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,1,"cd-rgw-501",[],null,null,null,Lt,Ot)),t["\u0275did"](1,245760,null,0,s,[$u.a,r.a,a.a],null,null)],function(l,n){l(n,1,0)},null)}var Kt=t["\u0275ccf"]("cd-rgw-501",s,Gt,{},{},[]);u.d(n,"RgwModuleNgFactory",function(){return $t}),u.d(n,"RoutedRgwModuleNgFactory",function(){return Zt});var $t=t["\u0275cmf"](X,[],function(l){return t["\u0275mod"]([t["\u0275mpd"](512,t.ComponentFactoryResolver,t["\u0275CodegenComponentFactoryResolver"],[[8,[al.a,rl.a,sl.a,dl.a,dl.b,cl.a,pl.a,fl.a,ml.a,gl.a,Pl,Hl,In,Pn,eu,gu,xu]],[3,t.ComponentFactoryResolver],t.NgModuleRef]),t["\u0275mpd"](4608,ql.NgLocalization,ql.NgLocaleLocalization,[t.LOCALE_ID,[2,ql["\u0275angular_packages_common_common_a"]]]),t["\u0275mpd"](4608,zl.a,zl.a,[_l.a]),t["\u0275mpd"](4608,ql.DatePipe,ql.DatePipe,[t.LOCALE_ID]),t["\u0275mpd"](4608,P.a,P.a,[]),t["\u0275mpd"](4608,a.a,a.a,[]),t["\u0275mpd"](4608,U.a,U.a,[]),t["\u0275mpd"](4608,q.a,q.a,[U.a]),t["\u0275mpd"](4608,Tu.a,Tu.a,[U.a]),t["\u0275mpd"](4608,V.a,V.a,[U.a]),t["\u0275mpd"](4608,qu.a,qu.a,[]),t["\u0275mpd"](4608,Vu.a,Vu.a,[]),t["\u0275mpd"](4608,Su.a,Su.a,[]),t["\u0275mpd"](4608,Du.a,Du.a,[]),t["\u0275mpd"](4608,wl.a,wl.a,[ql.DatePipe]),t["\u0275mpd"](4608,Nu.a,Nu.a,[]),t["\u0275mpd"](4608,Fu.a,Fu.a,[]),t["\u0275mpd"](4608,ju.a,ju.a,[]),t["\u0275mpd"](4608,Pu.a,Pu.a,[]),t["\u0275mpd"](4608,zu.a,zu.a,[]),t["\u0275mpd"](4608,Au.a,Au.a,[_l.a]),t["\u0275mpd"](4608,wn.a,wn.a,[]),t["\u0275mpd"](4608,Wl.a,Wl.a,[]),t["\u0275mpd"](4608,d.E,d.E,[]),t["\u0275mpd"](4608,d.h,d.h,[]),t["\u0275mpd"](4608,Bu.b,Bu.b,[]),t["\u0275mpd"](4608,Uu.a,Uu.a,[]),t["\u0275mpd"](4608,Mu.a,Mu.a,[t.RendererFactory2,t.PLATFORM_ID]),t["\u0275mpd"](4608,Jl.a,Jl.a,[t.ComponentFactoryResolver,t.NgZone,t.Injector,Mu.a,t.ApplicationRef]),t["\u0275mpd"](4608,Ou.a,Ou.a,[]),t["\u0275mpd"](4608,nn.b,nn.b,[t.RendererFactory2,Jl.a]),t["\u0275mpd"](4608,Lu.ScrollbarHelper,Lu.ScrollbarHelper,[yl.DOCUMENT]),t["\u0275mpd"](4608,Gu.DimensionsHelper,Gu.DimensionsHelper,[]),t["\u0275mpd"](4608,Ku.ColumnChangesService,Ku.ColumnChangesService,[]),t["\u0275mpd"](4608,Xl.f,Xl.f,[]),t["\u0275mpd"](4608,S.a,S.a,[]),t["\u0275mpd"](4608,o.a,o.a,[$u.l,S.a]),t["\u0275mpd"](4608,vl.e,vl.e,[]),t["\u0275mpd"](1073742336,ql.CommonModule,ql.CommonModule,[]),t["\u0275mpd"](1073742336,Zu.a,Zu.a,[]),t["\u0275mpd"](1073742336,d.B,d.B,[]),t["\u0275mpd"](1073742336,d.n,d.n,[]),t["\u0275mpd"](1073742336,d.x,d.x,[]),t["\u0275mpd"](1073742336,Bu.c,Bu.c,[]),t["\u0275mpd"](1073742336,Uu.d,Uu.d,[]),t["\u0275mpd"](1073742336,Ou.d,Ou.d,[]),t["\u0275mpd"](1073742336,Qu.ChartsModule,Qu.ChartsModule,[]),t["\u0275mpd"](1073742336,nn.e,nn.e,[]),t["\u0275mpd"](1073742336,Hu.a,Hu.a,[]),t["\u0275mpd"](1073742336,Xl.e,Xl.e,[]),t["\u0275mpd"](1073742336,Yu.a,Yu.a,[]),t["\u0275mpd"](1073742336,Xu.NgxDatatableModule,Xu.NgxDatatableModule,[]),t["\u0275mpd"](1073742336,$u.p,$u.p,[[2,$u.v],[2,$u.l]]),t["\u0275mpd"](1073742336,Ju.a,Ju.a,[]),t["\u0275mpd"](1073742336,b.a,b.a,[]),t["\u0275mpd"](1073742336,Wu.a,Wu.a,[]),t["\u0275mpd"](1073742336,le.a,le.a,[]),t["\u0275mpd"](1073742336,vl.c,vl.c,[]),t["\u0275mpd"](1073742336,X,X,[]),t["\u0275mpd"](256,t.LOCALE_ID,"en-US",[]),t["\u0275mpd"](256,Xl.a,{autoClose:!0,insideClick:!1},[]),t["\u0275mpd"](256,t.TRANSLATIONS_FORMAT,"xlf",[])])}),Zt=t["\u0275cmf"](ol,[],function(l){return t["\u0275mod"]([t["\u0275mpd"](512,t.ComponentFactoryResolver,t["\u0275CodegenComponentFactoryResolver"],[[8,[al.a,rl.a,sl.a,dl.a,dl.b,cl.a,pl.a,fl.a,ml.a,gl.a,Pl,Hl,In,Pn,eu,gu,xu,ie,ce,ct,Rt,Bt,Kt]],[3,t.ComponentFactoryResolver],t.NgModuleRef]),t["\u0275mpd"](4608,ql.NgLocalization,ql.NgLocaleLocalization,[t.LOCALE_ID,[2,ql["\u0275angular_packages_common_common_a"]]]),t["\u0275mpd"](4608,zl.a,zl.a,[_l.a]),t["\u0275mpd"](4608,ql.DatePipe,ql.DatePipe,[t.LOCALE_ID]),t["\u0275mpd"](4608,P.a,P.a,[]),t["\u0275mpd"](4608,a.a,a.a,[]),t["\u0275mpd"](4608,U.a,U.a,[]),t["\u0275mpd"](4608,q.a,q.a,[U.a]),t["\u0275mpd"](4608,Tu.a,Tu.a,[U.a]),t["\u0275mpd"](4608,V.a,V.a,[U.a]),t["\u0275mpd"](4608,qu.a,qu.a,[]),t["\u0275mpd"](4608,Vu.a,Vu.a,[]),t["\u0275mpd"](4608,Su.a,Su.a,[]),t["\u0275mpd"](4608,Du.a,Du.a,[]),t["\u0275mpd"](4608,wl.a,wl.a,[ql.DatePipe]),t["\u0275mpd"](4608,Nu.a,Nu.a,[]),t["\u0275mpd"](4608,Fu.a,Fu.a,[]),t["\u0275mpd"](4608,ju.a,ju.a,[]),t["\u0275mpd"](4608,Pu.a,Pu.a,[]),t["\u0275mpd"](4608,zu.a,zu.a,[]),t["\u0275mpd"](4608,Au.a,Au.a,[_l.a]),t["\u0275mpd"](4608,wn.a,wn.a,[]),t["\u0275mpd"](4608,Wl.a,Wl.a,[]),t["\u0275mpd"](4608,d.E,d.E,[]),t["\u0275mpd"](4608,d.h,d.h,[]),t["\u0275mpd"](4608,Bu.b,Bu.b,[]),t["\u0275mpd"](4608,Uu.a,Uu.a,[]),t["\u0275mpd"](4608,Mu.a,Mu.a,[t.RendererFactory2,t.PLATFORM_ID]),t["\u0275mpd"](4608,Jl.a,Jl.a,[t.ComponentFactoryResolver,t.NgZone,t.Injector,Mu.a,t.ApplicationRef]),t["\u0275mpd"](4608,Ou.a,Ou.a,[]),t["\u0275mpd"](4608,nn.b,nn.b,[t.RendererFactory2,Jl.a]),t["\u0275mpd"](4608,Lu.ScrollbarHelper,Lu.ScrollbarHelper,[yl.DOCUMENT]),t["\u0275mpd"](4608,Gu.DimensionsHelper,Gu.DimensionsHelper,[]),t["\u0275mpd"](4608,Ku.ColumnChangesService,Ku.ColumnChangesService,[]),t["\u0275mpd"](4608,Xl.f,Xl.f,[]),t["\u0275mpd"](4608,S.a,S.a,[]),t["\u0275mpd"](4608,o.a,o.a,[$u.l,S.a]),t["\u0275mpd"](4608,vl.e,vl.e,[]),t["\u0275mpd"](1073742336,ql.CommonModule,ql.CommonModule,[]),t["\u0275mpd"](1073742336,Zu.a,Zu.a,[]),t["\u0275mpd"](1073742336,d.B,d.B,[]),t["\u0275mpd"](1073742336,d.n,d.n,[]),t["\u0275mpd"](1073742336,d.x,d.x,[]),t["\u0275mpd"](1073742336,Bu.c,Bu.c,[]),t["\u0275mpd"](1073742336,Uu.d,Uu.d,[]),t["\u0275mpd"](1073742336,Ou.d,Ou.d,[]),t["\u0275mpd"](1073742336,Qu.ChartsModule,Qu.ChartsModule,[]),t["\u0275mpd"](1073742336,nn.e,nn.e,[]),t["\u0275mpd"](1073742336,Hu.a,Hu.a,[]),t["\u0275mpd"](1073742336,Xl.e,Xl.e,[]),t["\u0275mpd"](1073742336,Yu.a,Yu.a,[]),t["\u0275mpd"](1073742336,Xu.NgxDatatableModule,Xu.NgxDatatableModule,[]),t["\u0275mpd"](1073742336,$u.p,$u.p,[[2,$u.v],[2,$u.l]]),t["\u0275mpd"](1073742336,Ju.a,Ju.a,[]),t["\u0275mpd"](1073742336,b.a,b.a,[]),t["\u0275mpd"](1073742336,Wu.a,Wu.a,[]),t["\u0275mpd"](1073742336,le.a,le.a,[]),t["\u0275mpd"](1073742336,vl.c,vl.c,[]),t["\u0275mpd"](1073742336,X,X,[]),t["\u0275mpd"](1073742336,ol,ol,[]),t["\u0275mpd"](256,t.LOCALE_ID,"en-US",[]),t["\u0275mpd"](256,Xl.a,{autoClose:!0,insideClick:!1},[]),t["\u0275mpd"](1024,$u.j,function(){return[[{path:"",redirectTo:"daemon",pathMatch:"full"},{path:"daemon",component:z,data:J},{path:"user",data:W,children:[{path:"",component:Y},{path:"create",component:Z,data:ll},{path:"edit/:uid",component:Z,data:nl}]},{path:"bucket",data:ul,children:[{path:"",component:F},{path:"create",component:R,data:el},{path:"edit/:bid",component:R,data:tl}]},{path:"501/:message",component:s,canActivate:[o.a],data:il}]]},[]),t["\u0275mpd"](256,t.TRANSLATIONS_FORMAT,"xlf",[])])})}}]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/7.76846491986b0ea6c0bd.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/7.76846491986b0ea6c0bd.js new file mode 100644 index 00000000..61b2e446 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/7.76846491986b0ea6c0bd.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{J6Oi:function(l,n,u){"use strict";u.r(n);var e=u("CcnG"),t=u("k/xb"),a=u("MdoF"),o=u("ES0t"),i=u("Xg1U"),r=u("z5nN"),d=u("iutN"),s=u("EEJc"),c=u("PEr+"),p=u("a40w"),f=u("pMnS"),g=u("RIVN"),m=u("nP0W"),v=u("VBM6"),h=u("atuK"),b=u("JIi+"),C=u("Ur3J"),R=u("I4Qz"),I=u("0rTx"),w=u("lz+O"),T=u("u2XS"),y=u("nhAp"),k=u("l7Jr"),E=u("bUo2"),_=u("Ip0R"),x=u("iExv"),V=u("Jm/i"),N=u("85J/"),D=u("+0ag"),S=u("aXbf"),F=u("Fgil"),P=u("IzCI"),q=u("o4+5"),j=u("Dwqy"),O=u("uYzU"),A=u("uhwM"),U=u("E2fk"),$=u("a0VL"),M=u("nSDx"),z=u("SB+Q"),B=u("TYzs"),L=u("BQkM"),G=u("dEH0"),K=u("G1/K"),H=u("8xTl"),J=u("TJUb"),Z=u("gIcY"),W=u("lTVp"),Q=u("OZfm"),Y=u("NJnL"),X=u("lqqz"),ll=u("eajB"),nl=u("DQlY"),ul=u("FO+L"),el=u("ZYjt"),tl=u("nhM1"),al=u("BARL"),ol=u("xtZt"),il=u("aexS"),rl=u("Avrn"),dl=u("ZYCi"),sl=u("urB8"),cl=u("JZ5S"),pl=u("Tff5"),fl=u("YAQW"),gl=u("Da1D"),ml=u("ARl4"),vl=u("9Xeq"),hl=u("xdbM"),bl=u("yGOH"),Cl=u("V/fk"),Rl=u("F8xH"),Il=u("ChqD"),wl=u("pL04"),Tl=u("PCNd"),yl=u("STEd"),kl=u("kccj"),El=u("a278"),_l=u("insk"),xl=u("mSOc"),Vl=u("20UP"),Nl=u("pKUh"),Dl=u("C6Ij"),Sl=u("AWcq"),Fl=u("25BL"),Pl=u("uIqm"),ql=u("NUGo"),jl=u("S7zO"),Ol=u("JBea"),Al=u("VTlA"),Ul=u("ufoC"),$l=u("EgGo"),Ml=u("LvDl"),zl=u("F83c"),Bl=u("OLbh"),Ll=u("0+/T"),Gl=u("sne2"),Kl=u("x38r"),Hl=u("yJti"),Jl=u("vCyI"),Zl=u("kvvV"),Wl=u("kn/O"),Ql=u("2JDI"),Yl=u("u0yg"),Xl=new $l.a("block/rbd"),ln=function(){function l(l,n,u,e,t,a,o,i,r,d){var s=this;this.authStorageService=l,this.rbdService=n,this.dimlessBinaryPipe=u,this.dimlessPipe=e,this.modalService=t,this.taskWrapper=a,this.taskListService=o,this.i18n=i,this.urlBuilder=r,this.actionLabels=d,this.selection=new Jl.a,this.builders={"rbd/create":function(l){return s.createRbdFromTask(l.pool_name,l.image_name)},"rbd/clone":function(l){return s.createRbdFromTask(l.child_pool_name,l.child_image_name)},"rbd/copy":function(l){return s.createRbdFromTask(l.dest_pool_name,l.dest_image_name)}},this.permission=this.authStorageService.getPermissions().rbdImage;var c=function(){return s.selection.first()&&encodeURIComponent(s.selection.first().pool_name)+"/"+encodeURIComponent(s.selection.first().name)};this.tableActions=[{permission:"create",icon:"fa-plus",routerLink:function(){return s.urlBuilder.getCreate()},canBePrimary:function(l){return!l.hasSingleSelection},name:this.actionLabels.CREATE},{permission:"update",icon:"fa-pencil",routerLink:function(){return s.urlBuilder.getEdit(c())},name:this.actionLabels.EDIT},{permission:"create",canBePrimary:function(l){return l.hasSingleSelection},disable:function(l){return!l.hasSingleSelection||l.first().cdExecuting},icon:"fa-copy",routerLink:function(){return"/block/rbd/copy/"+c()},name:this.actionLabels.COPY},{permission:"update",disable:function(l){return!l.hasSingleSelection||l.first().cdExecuting||!l.first().parent},icon:"fa-chain-broken",click:function(){return s.flattenRbdModal()},name:this.actionLabels.FLATTEN},{permission:"delete",icon:"fa-times",click:function(){return s.deleteRbdModal()},name:this.actionLabels.DELETE},{permission:"delete",icon:"fa-trash-o",click:function(){return s.trashRbdModal()},name:this.actionLabels.TRASH,disable:function(l){return!l.first()||!l.hasSingleSelection||l.first().image_format===Yl.a.V1}}]}return l.prototype.createRbdFromTask=function(l,n){var u=new Yl.b;return u.id="-1",u.unique_id="-1",u.name=n,u.pool_name=l,u.image_format=Yl.a.V2,u},l.prototype.ngOnInit=function(){var l=this;this.columns=[{name:this.i18n("Name"),prop:"name",flexGrow:2,cellTransformation:Kl.a.executing},{name:this.i18n("Pool"),prop:"pool_name",flexGrow:2},{name:this.i18n("Size"),prop:"size",flexGrow:1,cellClass:"text-right",pipe:this.dimlessBinaryPipe},{name:this.i18n("Objects"),prop:"num_objs",flexGrow:1,cellClass:"text-right",pipe:this.dimlessPipe},{name:this.i18n("Object size"),prop:"obj_size",flexGrow:1,cellClass:"text-right",pipe:this.dimlessBinaryPipe},{name:this.i18n("Provisioned"),prop:"disk_usage",cellClass:"text-center",flexGrow:1,pipe:this.dimlessBinaryPipe},{name:this.i18n("Total provisioned"),prop:"total_disk_usage",cellClass:"text-center",flexGrow:1,pipe:this.dimlessBinaryPipe},{name:this.i18n("Parent"),prop:"parent",flexGrow:2,cellTemplate:this.parentTpl}],this.taskListService.init(function(){return l.rbdService.list()},function(n){return l.prepareResponse(n)},function(n){return l.images=n},function(){return l.onFetchError()},this.taskFilter,this.itemFilter,this.builders)},l.prototype.onFetchError=function(){this.table.reset(),this.viewCacheStatusList=[{status:Hl.a.ValueException}]},l.prototype.prepareResponse=function(l){var n=[],u={};l.forEach(function(l){Ml.isUndefined(u[l.status])&&(u[l.status]=[]),u[l.status].push(l.pool_name),n=n.concat(l.value)});var e=[];return Ml.forEach(u,function(l,n){e.push({status:parseInt(n,10),statusFor:(l.length>1?"pools ":"pool ")+""+l.join(", ")+""})}),this.viewCacheStatusList=e,n},l.prototype.itemFilter=function(l,n){var u,e;switch(n.name){case"rbd/copy":u="dest_pool_name",e="dest_image_name";break;case"rbd/clone":u="child_pool_name",e="child_image_name";break;default:u="pool_name",e="image_name"}return l.pool_name===n.metadata[u]&&l.name===n.metadata[e]},l.prototype.taskFilter=function(l){return["rbd/clone","rbd/copy","rbd/create","rbd/delete","rbd/edit","rbd/flatten","rbd/trash/move"].includes(l.name)},l.prototype.updateSelection=function(l){this.selection=l},l.prototype.deleteRbdModal=function(){var l=this,n=this.selection.first().pool_name,u=this.selection.first().name;this.modalRef=this.modalService.show(Ll.a,{initialState:{itemDescription:"RBD",itemNames:[n+"/"+u],submitActionObservable:function(){return l.taskWrapper.wrapTaskAroundCall({task:new Zl.a("rbd/delete",{pool_name:n,image_name:u}),call:l.rbdService.delete(n,u)})}}})},l.prototype.trashRbdModal=function(){var l={metaType:"RBD",poolName:this.selection.first().pool_name,imageName:this.selection.first().name};this.modalRef=this.modalService.show(Ql.a,{initialState:l})},l.prototype.flattenRbd=function(l,n){var u=this;this.taskWrapper.wrapTaskAroundCall({task:new Zl.a("rbd/flatten",{pool_name:l,image_name:n}),call:this.rbdService.flatten(l,n)}).subscribe(void 0,void 0,function(){u.modalRef.hide()})},l.prototype.flattenRbdModal=function(){var l=this,n=this.selection.first().pool_name,u=this.selection.first().name,e=this.selection.first().parent;this.modalRef=this.modalService.show(Bl.a,{initialState:{titleText:"RBD flatten",buttonText:"Flatten",bodyTpl:this.flattenTpl,bodyData:{parent:e.pool_name+"/"+e.image_name+"@"+e.snap_name,child:n+"/"+u},onSubmit:function(){l.flattenRbd(n,u)}}})},l}(),nn=e["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function un(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-view-cache",[],null,null,null,Dl.b,Dl.a)),e["\u0275did"](1,114688,null,0,Sl.a,[],{status:[0,"status"],statusFor:[1,"statusFor"]},null)],function(l,n){l(n,1,0,n.context.$implicit.status,n.context.$implicit.statusFor)},null)}function en(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,0,"div",[],[[8,"innerHTML",1]],null,null,null,null))],null,function(l,n){l(n,0,0,"Only available for RBD images with fast-diff enabled")})}function tn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](1,null,["","/","@",""]))],null,function(l,n){l(n,1,0,n.parent.context.value.pool_name,n.parent.context.value.image_name,n.parent.context.value.snap_name)})}function an(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["-"]))],null,null)}function on(l){return e["\u0275vid"](0,[(l()(),e["\u0275and"](16777216,null,null,1,null,tn)),e["\u0275did"](1,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,an)),e["\u0275did"](3,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,n.context.value),l(n,3,0,!n.context.value)},null)}function rn(l){return e["\u0275vid"](0,[(l()(),e["\u0275ted"](-1,null,[" You are about to flatten "])),(l()(),e["\u0275eld"](1,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),e["\u0275ted"](2,null,["",""])),(l()(),e["\u0275ted"](-1,null,[". "])),(l()(),e["\u0275eld"](4,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,[" All blocks will be copied from parent "])),(l()(),e["\u0275eld"](7,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),e["\u0275ted"](8,null,["",""])),(l()(),e["\u0275ted"](-1,null,[" to child "])),(l()(),e["\u0275eld"](10,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),e["\u0275ted"](11,null,["",""])),(l()(),e["\u0275ted"](-1,null,[".\n"]))],null,function(l,n){l(n,2,0,n.context.$implicit.child),l(n,8,0,n.context.$implicit.parent),l(n,11,0,n.context.$implicit.child)})}function dn(l){return e["\u0275vid"](0,[e["\u0275qud"](402653184,1,{table:0}),e["\u0275qud"](402653184,2,{usageTpl:0}),e["\u0275qud"](402653184,3,{parentTpl:0}),e["\u0275qud"](402653184,4,{nameTpl:0}),e["\u0275qud"](402653184,5,{flattenTpl:0}),(l()(),e["\u0275and"](16777216,null,null,1,null,un)),e["\u0275did"](6,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](7,0,null,null,5,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["identifier","unique_id"],["selectionType","single"]],null,[[null,"updateSelection"]],function(l,n,u){var e=!0;return"updateSelection"===n&&(e=!1!==l.component.updateSelection(u)&&e),e},Fl.b,Fl.a)),e["\u0275did"](8,2867200,[[1,4],["table",4]],0,Pl.a,[e.NgZone,e.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],forceIdentifier:[4,"forceIdentifier"],selectionType:[5,"selectionType"],searchableObjects:[6,"searchableObjects"]},{updateSelection:"updateSelection"}),(l()(),e["\u0275eld"](9,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,ql.b,ql.a)),e["\u0275did"](10,114688,null,0,jl.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),e["\u0275eld"](11,0,null,2,1,"cd-rbd-details",[["cdTableDetail",""]],null,null,null,b.c,b.b)),e["\u0275did"](12,573440,null,0,Ol.a,[],{selection:[0,"selection"]},null),(l()(),e["\u0275and"](0,[["usageNotAvailableTooltipTpl",2]],null,0,null,en)),(l()(),e["\u0275and"](0,[[3,2],["parentTpl",2]],null,0,null,on)),(l()(),e["\u0275and"](0,[[5,2],["flattenTpl",2]],null,0,null,rn))],function(l,n){var u=n.component;l(n,6,0,u.viewCacheStatusList),l(n,8,0,u.images,u.columns,"flex","unique_id","true","single",!0),l(n,10,0,u.permission,u.selection,u.tableActions),l(n,12,0,u.selection)},null)}var sn=u("wd/R"),cn=u("WxU5"),pn=u("2GqK"),fn=function(){function l(l,n,u,e,t,a,o,i){var r=this;this.authStorageService=l,this.rbdService=n,this.modalService=u,this.cdDatePipe=e,this.taskListService=t,this.taskWrapper=a,this.i18n=o,this.actionLabels=i,this.executingTasks=[],this.selection=new Jl.a,this.disablePurgeBtn=!0,this.permission=this.authStorageService.getPermissions().rbdImage,this.tableActions=[{permission:"update",icon:"fa-undo",click:function(){return r.restoreModal()},name:this.actionLabels.RESTORE},{permission:"delete",icon:"fa-times",click:function(){return r.deleteModal()},name:this.actionLabels.DELETE}]}return l.prototype.ngOnInit=function(){var l=this;this.columns=[{name:this.i18n("ID"),prop:"id",flexGrow:1,cellTransformation:Kl.a.executing},{name:this.i18n("Name"),prop:"name",flexGrow:1},{name:this.i18n("Pool"),prop:"pool_name",flexGrow:1},{name:this.i18n("Status"),prop:"deferment_end_time",flexGrow:1,cellTemplate:this.expiresTpl},{name:this.i18n("Deleted At"),prop:"deletion_time",flexGrow:1,pipe:this.cdDatePipe}],this.taskListService.init(function(){return l.rbdService.listTrash()},function(n){return l.prepareResponse(n)},function(n){return l.images=n},function(){return l.onFetchError()},this.taskFilter,this.itemFilter,void 0)},l.prototype.prepareResponse=function(l){var n=this,u=[],e={};l.forEach(function(l){Ml.isUndefined(e[l.status])&&(e[l.status]=[]),e[l.status].push(l.pool_name),u=u.concat(l.value),n.disablePurgeBtn=!u.length});var t=[];return Ml.forEach(e,function(l,n){t.push({status:parseInt(n,10),statusFor:(l.length>1?"pools ":"pool ")+""+l.join(", ")+""})}),this.viewCacheStatusList=t,u.forEach(function(l){l.cdIsExpired=sn().isAfter(l.deferment_end_time)}),u},l.prototype.onFetchError=function(){this.table.reset(),this.viewCacheStatusList=[{status:Hl.a.ValueException}]},l.prototype.itemFilter=function(l,n){return l.id===n.metadata.image_id},l.prototype.taskFilter=function(l){return["rbd/trash/remove","rbd/trash/restore"].includes(l.name)},l.prototype.updateSelection=function(l){this.selection=l},l.prototype.restoreModal=function(){var l={metaType:"RBD",poolName:this.selection.first().pool_name,imageName:this.selection.first().name,imageId:this.selection.first().id};this.modalRef=this.modalService.show(pn.a,{initialState:l})},l.prototype.deleteModal=function(){var l=this,n=this.selection.first().pool_name,u=this.selection.first().name,e=this.selection.first().id,t=this.selection.first().deferment_end_time;this.modalRef=this.modalService.show(Ll.a,{initialState:{itemDescription:"RBD",itemNames:[n+"/"+u],bodyTemplate:this.deleteTpl,bodyContext:{$implicit:t},submitActionObservable:function(){return l.taskWrapper.wrapTaskAroundCall({task:new Zl.a("rbd/trash/remove",{pool_name:n,image_id:e,image_name:u}),call:l.rbdService.removeTrash(n,e,u,!0)})}}})},l.prototype.isExpired=function(l){return sn().isAfter(l)},l.prototype.purgeModal=function(){this.modalService.show(cn.a)},l}(),gn=e["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function mn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-view-cache",[],null,null,null,Dl.b,Dl.a)),e["\u0275did"](1,114688,null,0,Sl.a,[],{status:[0,"status"],statusFor:[1,"statusFor"]},null)],function(l,n){l(n,1,0,n.context.$implicit.status,n.context.$implicit.statusFor)},null)}function vn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"button",[["class","btn btn-sm btn-default btn-label"],["type","button"]],[[8,"disabled",0]],[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.purgeModal()&&e),e},null,null)),(l()(),e["\u0275eld"](1,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-fw fa-times"]],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Purge Trash"]))],null,function(l,n){l(n,0,0,n.component.disablePurgeBtn)})}function hn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Expired at"]))],null,null)}function bn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Protected until"]))],null,null)}function Cn(l){return e["\u0275vid"](0,[(l()(),e["\u0275and"](16777216,null,null,1,null,hn)),e["\u0275did"](1,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,bn)),e["\u0275did"](3,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275ted"](4,null,[" ","\n"])),e["\u0275ppd"](5,1)],function(l,n){l(n,1,0,n.context.row.cdIsExpired),l(n,3,0,!n.context.row.cdIsExpired)},function(l,n){var u=e["\u0275unv"](n,4,0,l(n,5,0,e["\u0275nov"](n.parent,0),n.context.value));l(n,4,0,u)})}function Rn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,4,"p",[["class","text-danger"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,3,"strong",[],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,2,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](3,null,["This image is protected until ","."])),e["\u0275ppd"](4,1)],null,function(l,n){var u=e["\u0275unv"](n,3,0,l(n,4,0,e["\u0275nov"](n.parent.parent,0),n.parent.context.$implicit));l(n,3,0,u)})}function In(l){return e["\u0275vid"](0,[(l()(),e["\u0275and"](16777216,null,null,1,null,Rn)),e["\u0275did"](1,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,!n.component.isExpired(n.context.$implicit))},null)}function wn(l){return e["\u0275vid"](0,[e["\u0275pid"](0,$.a,[_.DatePipe]),e["\u0275qud"](402653184,1,{table:0}),e["\u0275qud"](402653184,2,{expiresTpl:0}),e["\u0275qud"](402653184,3,{deleteTpl:0}),(l()(),e["\u0275and"](16777216,null,null,1,null,mn)),e["\u0275did"](5,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](6,0,null,null,6,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["identifier","id"],["selectionType","single"]],null,[[null,"updateSelection"]],function(l,n,u){var e=!0;return"updateSelection"===n&&(e=!1!==l.component.updateSelection(u)&&e),e},Fl.b,Fl.a)),e["\u0275did"](7,2867200,[[1,4]],0,Pl.a,[e.NgZone,e.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],forceIdentifier:[4,"forceIdentifier"],selectionType:[5,"selectionType"]},{updateSelection:"updateSelection"}),(l()(),e["\u0275eld"](8,0,null,0,4,"div",[["class","table-actions btn-toolbar"]],null,null,null,null,null)),(l()(),e["\u0275eld"](9,0,null,null,1,"cd-table-actions",[["class","btn-group"]],null,null,null,ql.b,ql.a)),e["\u0275did"](10,114688,null,0,jl.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,vn)),e["\u0275did"](12,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](0,[[2,2],["expiresTpl",2]],null,0,null,Cn)),(l()(),e["\u0275and"](0,[[3,2],["deleteTpl",2]],null,0,null,In))],function(l,n){var u=n.component;l(n,5,0,u.viewCacheStatusList),l(n,7,0,u.images,u.columns,"flex","id","true","single"),l(n,10,0,u.permission,u.selection,u.tableActions),l(n,12,0,u.permission.delete)},null)}var Tn=u("wG1H"),yn=e["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function kn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"tab",[["heading","Overall Performance"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),e["\u0275did"](1,212992,null,0,fl.b,[fl.d,e.ElementRef,e.Renderer2],{heading:[0,"heading"]},null),(l()(),e["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","two"],["uid","41FrpeUiz"]],null,null,null,El.b,El.a)),e["\u0275did"](3,638976,null,0,_l.a,[xl.a,el.DomSanitizer,Vl.a,D.a,V.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(l,n){l(n,1,0,"Overall Performance"),l(n,3,0,"rbd-overview?","two","41FrpeUiz")},function(l,n){l(n,0,0,e["\u0275nov"](n,1).id,e["\u0275nov"](n,1).active,e["\u0275nov"](n,1).addClass)})}function En(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,15,"div",[],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,14,"tabset",[],[[2,"tab-container",null]],null,null,Nl.b,Nl.a)),e["\u0275did"](2,180224,null,0,fl.d,[fl.e,e.Renderer2,e.ElementRef],null,null),(l()(),e["\u0275eld"](3,0,null,0,5,"tab",[["heading","Images"],["id","tab1"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),e["\u0275did"](4,212992,null,0,fl.b,[fl.d,e.ElementRef,e.Renderer2],{heading:[0,"heading"],id:[1,"id"]},null),(l()(),e["\u0275eld"](5,0,null,null,3,"cd-rbd-list",[],null,null,null,dn,nn)),e["\u0275prd"](131584,null,Al.a,Al.a,[Ul.a,xl.a]),e["\u0275prd"](256,null,$l.a,Xl,[]),e["\u0275did"](8,114688,null,0,ln,[il.a,zl.a,F.a,q.a,nl.b,Wl.a,Al.a,V.a,$l.a,Gl.b],null,null),(l()(),e["\u0275eld"](9,0,null,0,4,"tab",[["heading","Trash"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),e["\u0275did"](10,212992,null,0,fl.b,[fl.d,e.ElementRef,e.Renderer2],{heading:[0,"heading"]},null),(l()(),e["\u0275eld"](11,0,null,null,2,"cd-rbd-trash-list",[],null,null,null,wn,gn)),e["\u0275prd"](131584,null,Al.a,Al.a,[Ul.a,xl.a]),e["\u0275did"](13,114688,null,0,fn,[il.a,zl.a,nl.b,$.a,Al.a,Wl.a,V.a,Gl.b],null,null),(l()(),e["\u0275and"](16777216,null,0,1,null,kn)),e["\u0275did"](15,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,4,0,"Images","tab1"),l(n,8,0),l(n,10,0,"Trash"),l(n,13,0),l(n,15,0,u.grafanaPermission.read)},function(l,n){l(n,1,0,e["\u0275nov"](n,2).clazz),l(n,3,0,e["\u0275nov"](n,4).id,e["\u0275nov"](n,4).active,e["\u0275nov"](n,4).addClass),l(n,9,0,e["\u0275nov"](n,10).id,e["\u0275nov"](n,10).active,e["\u0275nov"](n,10).addClass)})}function _n(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-rbd-images",[],null,null,null,En,yn)),e["\u0275did"](1,114688,null,0,Tn.a,[il.a],null,null)],function(l,n){l(n,1,0)},null)}var xn=e["\u0275ccf"]("cd-rbd-images",Tn.a,_n,{},{},[]),Vn=u("ANnk"),Nn=u("f/UV"),Dn=u("4HWh"),Sn=u("p4Cf"),Fn=u("IZUe"),Pn=u("EmSq"),qn=u("BH9v"),jn=u("rFfW"),On=u("o8EM"),An=u("gp3X"),Un=u("sb0X"),$n=u("KVJa"),Mn=u("Z21x"),zn=u("MyVl"),Bn=u("Ekvf"),Ln=e["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Gn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,12,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),e["\u0275ted"](2,null,[""," from"])),e["\u0275ppd"](3,1),(l()(),e["\u0275eld"](4,0,null,null,8,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,6,"input",[["class","form-control"],["formControlName","parent"],["id","parent"],["name","parent"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,6)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,6).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,6)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,6)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](6,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](8,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](10,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](11,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](12,0,null,null,0,"hr",[],null,null,null,null,null))],function(l,n){l(n,8,0,"parent")},function(l,n){var u=n.component,t=e["\u0275unv"](n,2,0,l(n,3,0,e["\u0275nov"](n.parent,0),u.action));l(n,2,0,t),l(n,5,0,e["\u0275nov"](n,10).ngClassUntouched,e["\u0275nov"](n,10).ngClassTouched,e["\u0275nov"](n,10).ngClassPristine,e["\u0275nov"](n,10).ngClassDirty,e["\u0275nov"](n,10).ngClassValid,e["\u0275nov"](n,10).ngClassInvalid,e["\u0275nov"](n,10).ngClassPending)})}function Kn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,2,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Hn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,2,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["'/' and '@' are not allowed."]))],null,null)}function Jn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function Zn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,6,"input",[["class","form-control"],["formControlName","pool"],["id","pool"],["name","pool"],["placeholder","Pool name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,1)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,1).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,1)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,1)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](1,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](3,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](5,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](6,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null)],function(l,n){l(n,3,0,"pool")},function(l,n){l(n,0,0,e["\u0275nov"](n,5).ngClassUntouched,e["\u0275nov"](n,5).ngClassTouched,e["\u0275nov"](n,5).ngClassPristine,e["\u0275nov"](n,5).ngClassDirty,e["\u0275nov"](n,5).ngClassValid,e["\u0275nov"](n,5).ngClassInvalid,e["\u0275nov"](n,5).ngClassPending)})}function Wn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{ngValue:[0,"ngValue"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),e["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function Qn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{ngValue:[0,"ngValue"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),e["\u0275ted"](-1,null,["-- No rbd pools available --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function Yn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{ngValue:[0,"ngValue"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),e["\u0275ted"](-1,null,["-- Select a pool --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function Xn(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{value:[0,"value"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),e["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit.pool_name),l(n,2,0,n.context.$implicit.pool_name)},function(l,n){l(n,3,0,n.context.$implicit.pool_name)})}function lu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,14,"select",[["class","form-control"],["formControlName","pool"],["id","pool"],["name","pool"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var t=!0;return"change"===n&&(t=!1!==e["\u0275nov"](l,1).onChange(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,1).onTouched()&&t),t},null,null)),e["\u0275did"](1,16384,null,0,Z.z,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.z]),e["\u0275did"](3,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](5,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](6,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,Wn)),e["\u0275did"](8,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Qn)),e["\u0275did"](10,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Yn)),e["\u0275did"](12,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Xn)),e["\u0275did"](14,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var u=n.component;l(n,3,0,"pool"),l(n,8,0,null===u.pools),l(n,10,0,null!==u.pools&&0===u.pools.length),l(n,12,0,null!==u.pools&&u.pools.length>0),l(n,14,0,u.pools)},function(l,n){l(n,0,0,e["\u0275nov"](n,5).ngClassUntouched,e["\u0275nov"](n,5).ngClassTouched,e["\u0275nov"](n,5).ngClassPristine,e["\u0275nov"](n,5).ngClassDirty,e["\u0275nov"](n,5).ngClassValid,e["\u0275nov"](n,5).ngClassInvalid,e["\u0275nov"](n,5).ngClassPending)})}function nu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function uu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function eu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,6,"input",[["class","form-control"],["formControlName","dataPool"],["id","dataPool"],["name","dataPool"],["placeholder","Data pool name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,1)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,1).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,1)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,1)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](1,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](3,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](5,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](6,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null)],function(l,n){l(n,3,0,"dataPool")},function(l,n){l(n,0,0,e["\u0275nov"](n,5).ngClassUntouched,e["\u0275nov"](n,5).ngClassTouched,e["\u0275nov"](n,5).ngClassPristine,e["\u0275nov"](n,5).ngClassDirty,e["\u0275nov"](n,5).ngClassValid,e["\u0275nov"](n,5).ngClassInvalid,e["\u0275nov"](n,5).ngClassPending)})}function tu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{ngValue:[0,"ngValue"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),e["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function au(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{ngValue:[0,"ngValue"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),e["\u0275ted"](-1,null,["-- No data pools available --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function ou(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{ngValue:[0,"ngValue"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),e["\u0275ted"](-1,null,["-- Select a data pool -- "]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function iu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{value:[0,"value"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),e["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit.pool_name),l(n,2,0,n.context.$implicit.pool_name)},function(l,n){l(n,3,0,n.context.$implicit.pool_name)})}function ru(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,14,"select",[["class","form-control"],["formControlName","dataPool"],["id","dataPool"],["name","dataPool"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var t=!0,a=l.component;return"change"===n&&(t=!1!==e["\u0275nov"](l,1).onChange(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,1).onTouched()&&t),"change"===n&&(t=!1!==a.onDataPoolChange(u.target.value)&&t),t},null,null)),e["\u0275did"](1,16384,null,0,Z.z,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.z]),e["\u0275did"](3,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](5,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](6,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,tu)),e["\u0275did"](8,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,au)),e["\u0275did"](10,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,ou)),e["\u0275did"](12,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,iu)),e["\u0275did"](14,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var u=n.component;l(n,3,0,"dataPool"),l(n,8,0,null===u.dataPools),l(n,10,0,null!==u.dataPools&&0===u.dataPools.length),l(n,12,0,null!==u.dataPools&&u.dataPools.length>0),l(n,14,0,u.dataPools)},function(l,n){l(n,0,0,e["\u0275nov"](n,5).ngClassUntouched,e["\u0275nov"](n,5).ngClassTouched,e["\u0275nov"](n,5).ngClassPristine,e["\u0275nov"](n,5).ngClassDirty,e["\u0275nov"](n,5).ngClassValid,e["\u0275nov"](n,5).ngClassInvalid,e["\u0275nov"](n,5).ngClassPending)})}function du(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function su(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](1,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](2,{"has-error":0}),(l()(),e["\u0275eld"](3,0,null,null,6,"label",[["class","control-label col-sm-3"],["for","dataPool"]],null,null,null,null,null)),(l()(),e["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Data pool"])),(l()(),e["\u0275and"](16777216,null,null,1,null,uu)),e["\u0275did"](7,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](8,0,null,null,1,"cd-helper",[["html","Dedicated pool that stores the object-data of the RBD."]],null,null,null,Dn.b,Dn.a)),e["\u0275did"](9,49152,null,0,Sn.a,[],{html:[0,"html"]},null),(l()(),e["\u0275eld"](10,0,null,null,6,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,eu)),e["\u0275did"](12,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,ru)),e["\u0275did"](14,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,du)),e["\u0275did"](16,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component,t=l(n,2,0,u.rbdForm.showError("dataPool",e["\u0275nov"](n.parent,5)));l(n,1,0,"form-group",t),l(n,7,0,"editing"!==u.mode),l(n,9,0,"Dedicated pool that stores the object-data of the RBD."),l(n,12,0,"editing"===u.mode||!u.poolPermission.read),l(n,14,0,"editing"!==u.mode&&u.poolPermission.read),l(n,16,0,u.rbdForm.showError("dataPool",e["\u0275nov"](n.parent,5),"required"))},null)}function cu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function pu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["You have to increase the size."]))],null,null)}function fu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-helper",[],null,null,null,Dn.b,Dn.a)),e["\u0275did"](1,49152,null,0,Sn.a,[],{html:[0,"html"]},null)],function(l,n){l(n,1,0,e["\u0275inlineInterpolate"](1,"",n.parent.context.$implicit.helperHtml,""))},null)}function gu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,11,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,6,"input",[["type","checkbox"]],[[8,"id",0],[8,"name",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var t=!0;return"change"===n&&(t=!1!==e["\u0275nov"](l,2).onChange(u.target.checked)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,2).onTouched()&&t),t},null,null)),e["\u0275did"](2,16384,null,0,Z.c,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.c]),e["\u0275did"](4,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](6,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](7,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](8,0,null,null,1,"label",[],[[8,"htmlFor",0]],null,null,null,null)),(l()(),e["\u0275ted"](9,null,["",""])),(l()(),e["\u0275and"](16777216,null,null,1,null,fu)),e["\u0275did"](11,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,4,0,e["\u0275inlineInterpolate"](1,"",n.context.$implicit.key,"")),l(n,11,0,n.context.$implicit.helperHtml)},function(l,n){l(n,1,0,e["\u0275inlineInterpolate"](1,"",n.context.$implicit.key,""),e["\u0275inlineInterpolate"](1,"",n.context.$implicit.key,""),e["\u0275nov"](n,6).ngClassUntouched,e["\u0275nov"](n,6).ngClassTouched,e["\u0275nov"](n,6).ngClassPristine,e["\u0275nov"](n,6).ngClassDirty,e["\u0275nov"](n,6).ngClassValid,e["\u0275nov"](n,6).ngClassInvalid,e["\u0275nov"](n,6).ngClassPending),l(n,8,0,e["\u0275inlineInterpolate"](1,"",n.context.$implicit.key,"")),l(n,9,0,n.context.$implicit.desc)})}function mu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"a",[["class","pull-right margin-right-md"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=0!=(l.component.advancedEnabled=!0)&&e),e},null,null)),(l()(),e["\u0275ted"](-1,null,["Advanced..."]))],null,null)}function vu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{value:[0,"value"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),e["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function hu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function bu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](1,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{value:[0,"value"]},null),e["\u0275did"](2,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),e["\u0275ted"](3,null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function Cu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required because stripe count is defined!"]))],null,null)}function Ru(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Stripe unit is greater than object size."]))],null,null)}function Iu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function wu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required because stripe unit is defined!"]))],null,null)}function Tu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Stripe count must be greater than 0."]))],null,null)}function yu(l){return e["\u0275vid"](0,[e["\u0275pid"](0,_.TitleCasePipe,[]),e["\u0275pid"](0,H.a,[]),(l()(),e["\u0275eld"](2,0,null,null,177,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(l()(),e["\u0275eld"](3,0,null,null,176,"form",[["class","form-horizontal"],["name","rbdForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var t=!0;return"submit"===n&&(t=!1!==e["\u0275nov"](l,5).onSubmit(u)&&t),"reset"===n&&(t=!1!==e["\u0275nov"](l,5).onReset()&&t),t},null,null)),e["\u0275did"](4,16384,null,0,Z.D,[],null,null),e["\u0275did"](5,540672,[["formDir",4]],0,Z.l,[[8,null],[8,null]],{form:[0,"form"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.l]),e["\u0275did"](7,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275eld"](8,0,null,null,171,"div",[["class","panel panel-default"]],null,null,null,null,null)),(l()(),e["\u0275eld"](9,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),e["\u0275eld"](10,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(l()(),e["\u0275ted"](11,null,[""," ",""])),e["\u0275ppd"](12,1),e["\u0275ppd"](13,1),(l()(),e["\u0275eld"](14,0,null,null,156,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Gn)),e["\u0275did"](16,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](17,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](18,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](19,{"has-error":0}),(l()(),e["\u0275eld"](20,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),e["\u0275eld"](21,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Name"])),(l()(),e["\u0275eld"](23,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),e["\u0275eld"](24,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](25,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","name"],["id","name"],["name","name"],["placeholder","Name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,26)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,26).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,26)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,26)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](26,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](28,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](30,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](31,4210688,null,0,Fn.a,[e.ElementRef],null,null),e["\u0275did"](32,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,Kn)),e["\u0275did"](34,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Hn)),e["\u0275did"](36,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](37,0,null,null,13,"div",[["class","form-group"]],null,[[null,"change"]],function(l,n,u){var e=!0;return"change"===n&&(e=!1!==l.component.onPoolChange(u.target.value)&&e),e},null,null)),e["\u0275did"](38,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](39,{"has-error":0}),(l()(),e["\u0275eld"](40,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","pool"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,[" Pool "])),(l()(),e["\u0275and"](16777216,null,null,1,null,Jn)),e["\u0275did"](43,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](44,0,null,null,6,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Zn)),e["\u0275did"](46,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,lu)),e["\u0275did"](48,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,nu)),e["\u0275did"](50,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](51,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](52,0,null,null,10,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](53,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),e["\u0275eld"](54,0,null,null,6,"input",[["formControlName","useDataPool"],["id","useDataPool"],["name","useDataPool"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var t=!0,a=l.component;return"change"===n&&(t=!1!==e["\u0275nov"](l,55).onChange(u.target.checked)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,55).onTouched()&&t),"change"===n&&(t=!1!==a.onUseDataPoolChange()&&t),t},null,null)),e["\u0275did"](55,16384,null,0,Z.c,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.c]),e["\u0275did"](57,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](59,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](60,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](61,0,null,null,1,"label",[["for","useDataPool"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Use a dedicated data pool"])),(l()(),e["\u0275and"](16777216,null,null,1,null,su)),e["\u0275did"](64,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](65,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](66,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](67,{"has-error":0}),(l()(),e["\u0275eld"](68,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","size"]],null,null,null,null,null)),(l()(),e["\u0275eld"](69,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Size"])),(l()(),e["\u0275eld"](71,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),e["\u0275eld"](72,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](73,0,null,null,7,"input",[["cdDimlessBinary",""],["class","form-control"],["defaultUnit","GiB"],["formControlName","size"],["id","size"],["name","size"],["placeholder","e.g., 10GiB"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,74)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,74).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,74)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,74)._compositionEnd(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,79).onBlur(u.target.value)&&t),t},null,null)),e["\u0275did"](74,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](76,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](78,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](79,81920,null,0,Pn.a,[e.ElementRef,Z.q,F.a,S.a],{defaultUnit:[0,"defaultUnit"]},null),e["\u0275did"](80,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,cu)),e["\u0275did"](82,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,pu)),e["\u0275did"](84,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](85,0,null,null,10,"div",[["class","form-group"],["formGroupName","features"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),e["\u0275did"](86,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](87,{"has-error":0}),e["\u0275did"](88,212992,null,0,Z.m,[[3,Z.d],[8,null],[8,null]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.m]),e["\u0275did"](90,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275eld"](91,0,null,null,1,"label",[["class","col-sm-3 control-label"],["for","features"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Features"])),(l()(),e["\u0275eld"](93,0,null,null,2,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,gu)),e["\u0275did"](95,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](96,0,null,null,3,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](97,0,null,null,2,"div",[["class","col-sm-12"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,mu)),e["\u0275did"](99,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](100,0,null,null,70,"div",[],[[8,"hidden",0]],null,null,null,null)),(l()(),e["\u0275eld"](101,0,null,null,1,"h2",[["class","page-header"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Advanced"])),(l()(),e["\u0275eld"](103,0,null,null,64,"div",[["class","section"]],null,null,null,null,null)),(l()(),e["\u0275eld"](104,0,null,null,1,"h3",[["class","page-header"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Striping"])),(l()(),e["\u0275eld"](106,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](107,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](108,{"has-error":0}),(l()(),e["\u0275eld"](109,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","size"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Object size"])),(l()(),e["\u0275eld"](111,0,null,null,9,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](112,0,null,null,8,"select",[["class","form-control"],["formControlName","obj_size"],["id","obj_size"],["name","obj_size"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var t=!0;return"change"===n&&(t=!1!==e["\u0275nov"](l,113).onChange(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,113).onTouched()&&t),t},null,null)),e["\u0275did"](113,16384,null,0,Z.z,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.z]),e["\u0275did"](115,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](117,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](118,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,vu)),e["\u0275did"](120,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](121,0,null,null,25,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](122,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](123,{"has-error":0}),(l()(),e["\u0275eld"](124,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","stripingUnit"]],null,null,null,null,null)),(l()(),e["\u0275eld"](125,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Stripe unit"])),(l()(),e["\u0275and"](16777216,null,null,1,null,hu)),e["\u0275did"](128,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](129,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](130,0,null,null,12,"select",[["class","form-control"],["formControlName","stripingUnit"],["id","stripingUnit"],["name","stripingUnit"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var t=!0;return"change"===n&&(t=!1!==e["\u0275nov"](l,131).onChange(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,131).onTouched()&&t),t},null,null)),e["\u0275did"](131,16384,null,0,Z.z,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.z]),e["\u0275did"](133,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](135,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](136,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](137,0,null,null,3,"option",[],null,null,null,null,null)),e["\u0275did"](138,147456,null,0,Z.v,[e.ElementRef,e.Renderer2,[2,Z.z]],{ngValue:[0,"ngValue"]},null),e["\u0275did"](139,147456,null,0,Z.G,[e.ElementRef,e.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),e["\u0275ted"](-1,null,["-- Select stripe unit --"])),(l()(),e["\u0275and"](16777216,null,null,1,null,bu)),e["\u0275did"](142,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Cu)),e["\u0275did"](144,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ru)),e["\u0275did"](146,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](147,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](148,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](149,{"has-error":0}),(l()(),e["\u0275eld"](150,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","stripingCount"]],null,null,null,null,null)),(l()(),e["\u0275eld"](151,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Stripe count"])),(l()(),e["\u0275and"](16777216,null,null,1,null,Iu)),e["\u0275did"](154,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](155,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](156,0,null,null,7,"input",[["class","form-control"],["formControlName","stripingCount"],["id","stripingCount"],["name","stripingCount"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,157)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,157).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,157)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,157)._compositionEnd(u.target.value)&&t),"change"===n&&(t=!1!==e["\u0275nov"](l,158).onChange(u.target.value)&&t),"input"===n&&(t=!1!==e["\u0275nov"](l,158).onChange(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,158).onTouched()&&t),t},null,null)),e["\u0275did"](157,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275did"](158,16384,null,0,Z.C,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l,n){return[l,n]},[Z.e,Z.C]),e["\u0275did"](160,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](162,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](163,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,wu)),e["\u0275did"](165,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Tu)),e["\u0275did"](167,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](168,0,null,null,2,"div",[["class","section"]],null,null,null,null,null)),(l()(),e["\u0275eld"](169,0,null,null,1,"cd-rbd-configuration-form",[],null,[[null,"changes"]],function(l,n,u){var e=!0;return"changes"===n&&(e=!1!==(l.component.getDirtyConfigurationValues=u)&&e),e},qn.b,qn.a)),e["\u0275did"](170,114688,null,0,jn.a,[S.a,On.a],{form:[0,"form"],initializeData:[1,"initializeData"]},{changes:"changes"}),(l()(),e["\u0275eld"](171,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(l()(),e["\u0275eld"](172,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),e["\u0275eld"](173,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(l,n,u){var e=!0;return"submitAction"===n&&(e=!1!==l.component.submit()&&e),e},An.b,An.a)),e["\u0275did"](174,114688,null,0,Un.a,[e.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(l()(),e["\u0275ted"](175,0,[""," ",""])),e["\u0275ppd"](176,1),e["\u0275ppd"](177,1),(l()(),e["\u0275eld"](178,0,null,null,1,"cd-back-button",[],null,null,null,$n.b,$n.a)),e["\u0275did"](179,49152,null,0,Mn.a,[_.Location,Gl.b],null,null)],function(l,n){var u=n.component;l(n,5,0,u.rbdForm),l(n,16,0,u.rbdForm.getValue("parent"));var t=l(n,19,0,u.rbdForm.showError("name",e["\u0275nov"](n,5)));l(n,18,0,"form-group",t),l(n,28,0,"name"),l(n,34,0,u.rbdForm.showError("name",e["\u0275nov"](n,5),"required")),l(n,36,0,u.rbdForm.showError("name",e["\u0275nov"](n,5),"pattern"));var a=l(n,39,0,u.rbdForm.showError("pool",e["\u0275nov"](n,5)));l(n,38,0,"form-group",a),l(n,43,0,"editing"!==u.mode),l(n,46,0,"editing"===u.mode||!u.poolPermission.read),l(n,48,0,"editing"!==u.mode&&u.poolPermission.read),l(n,50,0,u.rbdForm.showError("pool",e["\u0275nov"](n,5),"required")),l(n,57,0,"useDataPool"),l(n,64,0,u.rbdForm.getValue("useDataPool"));var o=l(n,67,0,u.rbdForm.showError("size",e["\u0275nov"](n,5)));l(n,66,0,"form-group",o),l(n,76,0,"size"),l(n,79,0,"GiB"),l(n,82,0,u.rbdForm.showError("size",e["\u0275nov"](n,5),"required")),l(n,84,0,u.rbdForm.showError("size",e["\u0275nov"](n,5),"invalidSizeObject"));var i=l(n,87,0,(e["\u0275nov"](n,5).submitted||u.rbdForm.get("features").dirty)&&u.rbdForm.get("features").invalid);l(n,86,0,"form-group",i),l(n,88,0,"features"),l(n,95,0,u.featuresList),l(n,99,0,!u.advancedEnabled);var r=l(n,108,0,u.rbdForm.showError("obj_size",e["\u0275nov"](n,5)));l(n,107,0,"form-group",r),l(n,115,0,"obj_size"),l(n,120,0,u.objectSizes);var d=l(n,123,0,u.rbdForm.showError("stripingUnit",e["\u0275nov"](n,5)));l(n,122,0,"form-group",d),l(n,128,0,u.rbdForm.getValue("stripingCount")),l(n,133,0,"stripingUnit"),l(n,138,0,null),l(n,139,0,null),l(n,142,0,u.objectSizes),l(n,144,0,u.rbdForm.showError("stripingUnit",e["\u0275nov"](n,5),"required")),l(n,146,0,u.rbdForm.showError("stripingUnit",e["\u0275nov"](n,5),"invalidStripingUnit"));var s=l(n,149,0,u.rbdForm.showError("stripingCount",e["\u0275nov"](n,5)));l(n,148,0,"form-group",s),l(n,154,0,u.rbdForm.getValue("stripingUnit")),l(n,160,0,"stripingCount"),l(n,165,0,u.rbdForm.showError("stripingCount",e["\u0275nov"](n,5),"required")),l(n,167,0,u.rbdForm.showError("stripingCount",e["\u0275nov"](n,5),"min")),l(n,170,0,u.rbdForm,u.initializeConfigData),l(n,174,0,e["\u0275nov"](n,5),"button")},function(l,n){var u=n.component;l(n,3,0,e["\u0275nov"](n,7).ngClassUntouched,e["\u0275nov"](n,7).ngClassTouched,e["\u0275nov"](n,7).ngClassPristine,e["\u0275nov"](n,7).ngClassDirty,e["\u0275nov"](n,7).ngClassValid,e["\u0275nov"](n,7).ngClassInvalid,e["\u0275nov"](n,7).ngClassPending);var t=e["\u0275unv"](n,11,0,l(n,12,0,e["\u0275nov"](n,0),u.action)),a=e["\u0275unv"](n,11,1,l(n,13,0,e["\u0275nov"](n,1),u.resource));l(n,11,0,t,a),l(n,25,0,e["\u0275nov"](n,30).ngClassUntouched,e["\u0275nov"](n,30).ngClassTouched,e["\u0275nov"](n,30).ngClassPristine,e["\u0275nov"](n,30).ngClassDirty,e["\u0275nov"](n,30).ngClassValid,e["\u0275nov"](n,30).ngClassInvalid,e["\u0275nov"](n,30).ngClassPending),l(n,54,0,e["\u0275nov"](n,59).ngClassUntouched,e["\u0275nov"](n,59).ngClassTouched,e["\u0275nov"](n,59).ngClassPristine,e["\u0275nov"](n,59).ngClassDirty,e["\u0275nov"](n,59).ngClassValid,e["\u0275nov"](n,59).ngClassInvalid,e["\u0275nov"](n,59).ngClassPending),l(n,73,0,e["\u0275nov"](n,78).ngClassUntouched,e["\u0275nov"](n,78).ngClassTouched,e["\u0275nov"](n,78).ngClassPristine,e["\u0275nov"](n,78).ngClassDirty,e["\u0275nov"](n,78).ngClassValid,e["\u0275nov"](n,78).ngClassInvalid,e["\u0275nov"](n,78).ngClassPending),l(n,85,0,e["\u0275nov"](n,90).ngClassUntouched,e["\u0275nov"](n,90).ngClassTouched,e["\u0275nov"](n,90).ngClassPristine,e["\u0275nov"](n,90).ngClassDirty,e["\u0275nov"](n,90).ngClassValid,e["\u0275nov"](n,90).ngClassInvalid,e["\u0275nov"](n,90).ngClassPending),l(n,100,0,!u.advancedEnabled),l(n,112,0,e["\u0275nov"](n,117).ngClassUntouched,e["\u0275nov"](n,117).ngClassTouched,e["\u0275nov"](n,117).ngClassPristine,e["\u0275nov"](n,117).ngClassDirty,e["\u0275nov"](n,117).ngClassValid,e["\u0275nov"](n,117).ngClassInvalid,e["\u0275nov"](n,117).ngClassPending),l(n,130,0,e["\u0275nov"](n,135).ngClassUntouched,e["\u0275nov"](n,135).ngClassTouched,e["\u0275nov"](n,135).ngClassPristine,e["\u0275nov"](n,135).ngClassDirty,e["\u0275nov"](n,135).ngClassValid,e["\u0275nov"](n,135).ngClassInvalid,e["\u0275nov"](n,135).ngClassPending),l(n,156,0,e["\u0275nov"](n,162).ngClassUntouched,e["\u0275nov"](n,162).ngClassTouched,e["\u0275nov"](n,162).ngClassPristine,e["\u0275nov"](n,162).ngClassDirty,e["\u0275nov"](n,162).ngClassValid,e["\u0275nov"](n,162).ngClassInvalid,e["\u0275nov"](n,162).ngClassPending);var o=e["\u0275unv"](n,175,0,l(n,176,0,e["\u0275nov"](n,0),u.action)),i=e["\u0275unv"](n,175,1,l(n,177,0,e["\u0275nov"](n,1),u.resource));l(n,175,0,o,i)})}function ku(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-rbd-form",[],null,null,null,yu,Ln)),e["\u0275did"](1,114688,null,0,zn.a,[il.a,dl.a,Bn.a,zl.a,S.a,Wl.a,F.a,V.a,Gl.b,dl.l],null,null)],function(l,n){l(n,1,0)},null)}var Eu=e["\u0275ccf"]("cd-rbd-form",zn.a,ku,{},{},[]),_u=u("JxMD"),xu=u("dgut"),Vu=function(){function l(l){this.router=l}return l.prototype.ngOnInit=function(){this.url=this.router.url},l.prototype.navigateTo=function(l){this.router.navigate([l])},l}(),Nu=e["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Du(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,5,"tabset",[],[[2,"tab-container",null]],null,null,Nl.b,Nl.a)),e["\u0275did"](1,180224,null,0,fl.d,[fl.e,e.Renderer2,e.ElementRef],null,null),(l()(),e["\u0275eld"](2,0,null,0,1,"tab",[["heading","Overview"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],[[null,"selectTab"]],function(l,n,u){var e=!0;return"selectTab"===n&&(e=!1!==l.component.navigateTo("/block/iscsi/overview")&&e),e},null,null)),e["\u0275did"](3,212992,null,0,fl.b,[fl.d,e.ElementRef,e.Renderer2],{heading:[0,"heading"],active:[1,"active"]},{selectTab:"selectTab"}),(l()(),e["\u0275eld"](4,0,null,0,1,"tab",[["heading","Targets"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],[[null,"selectTab"]],function(l,n,u){var e=!0;return"selectTab"===n&&(e=!1!==l.component.navigateTo("/block/iscsi/targets")&&e),e},null,null)),e["\u0275did"](5,212992,null,0,fl.b,[fl.d,e.ElementRef,e.Renderer2],{heading:[0,"heading"],active:[1,"active"]},{selectTab:"selectTab"})],function(l,n){var u=n.component;l(n,3,0,"Overview","/block/iscsi/overview"===u.url),l(n,5,0,"Targets","/block/iscsi/targets"===u.url)},function(l,n){l(n,0,0,e["\u0275nov"](n,1).clazz),l(n,2,0,e["\u0275nov"](n,3).id,e["\u0275nov"](n,3).active,e["\u0275nov"](n,3).addClass),l(n,4,0,e["\u0275nov"](n,5).id,e["\u0275nov"](n,5).active,e["\u0275nov"](n,5).addClass)})}var Su=u("roDX"),Fu=u("my5R"),Pu=e["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function qu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,3,"span",[["class","label"]],null,null,null,null,null)),e["\u0275did"](1,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](2,{"label-success":0,"label-danger":1}),(l()(),e["\u0275ted"](3,null,["",""]))],function(l,n){var u=l(n,2,0,"up"==n.context.value,"down"==n.context.value);l(n,1,0,"label",u)},function(l,n){l(n,3,0,n.context.value)})}function ju(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,1,"cd-sparkline",[],null,null,null,_u.b,_u.a)),e["\u0275did"](2,638976,null,0,xu.a,[F.a],{data:[0,"data"],isBinary:[1,"isBinary"]},null)],function(l,n){l(n,2,0,n.parent.context.value,n.parent.context.row.cdIsBinary)},null)}function Ou(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,[" n/a "]))],null,null)}function Au(l){return e["\u0275vid"](0,[(l()(),e["\u0275and"](16777216,null,null,1,null,ju)),e["\u0275did"](1,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ou)),e["\u0275did"](3,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,"user:rbd"===n.context.row.backstore),l(n,3,0,"user:rbd"!==n.context.row.backstore)},null)}function Uu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](1,null,[" "," /s "]))],null,function(l,n){l(n,1,0,n.parent.context.value)})}function $u(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,[" n/a "]))],null,null)}function Mu(l){return e["\u0275vid"](0,[(l()(),e["\u0275and"](16777216,null,null,1,null,Uu)),e["\u0275did"](1,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,$u)),e["\u0275did"](3,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,"user:rbd"===n.context.row.backstore),l(n,3,0,"user:rbd"!==n.context.row.backstore)},null)}function zu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](1,null,[" "," "])),e["\u0275ppd"](2,1)],null,function(l,n){var u=e["\u0275unv"](n,1,0,l(n,2,0,e["\u0275nov"](n.parent.parent,0),n.parent.context.value));l(n,1,0,u)})}function Bu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,[" n/a "]))],null,null)}function Lu(l){return e["\u0275vid"](0,[(l()(),e["\u0275and"](16777216,null,null,1,null,zu)),e["\u0275did"](1,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Bu)),e["\u0275did"](3,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,"user:rbd"===n.context.row.backstore),l(n,3,0,"user:rbd"!==n.context.row.backstore)},null)}function Gu(l){return e["\u0275vid"](0,[e["\u0275pid"](0,j.a,[]),e["\u0275qud"](402653184,1,{statusColorTpl:0}),e["\u0275qud"](402653184,2,{iscsiSparklineTpl:0}),e["\u0275qud"](402653184,3,{iscsiPerSecondTpl:0}),e["\u0275qud"](402653184,4,{iscsiRelativeDateTpl:0}),(l()(),e["\u0275eld"](5,0,null,null,1,"cd-iscsi-tabs",[],null,null,null,Du,Nu)),e["\u0275did"](6,114688,null,0,Vu,[dl.l],null,null),(l()(),e["\u0275eld"](7,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Gateways"])),(l()(),e["\u0275eld"](9,0,null,null,1,"cd-table",[],null,[[null,"fetchData"]],function(l,n,u){var e=!0;return"fetchData"===n&&(e=!1!==l.component.refresh()&&e),e},Fl.b,Fl.a)),e["\u0275did"](10,2867200,null,0,Pl.a,[e.NgZone,e.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"]},{fetchData:"fetchData"}),(l()(),e["\u0275eld"](11,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Images"])),(l()(),e["\u0275eld"](13,0,null,null,1,"cd-table",[],null,null,null,Fl.b,Fl.a)),e["\u0275did"](14,2867200,null,0,Pl.a,[e.NgZone,e.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"]},null),(l()(),e["\u0275and"](0,[[1,2],["statusColorTpl",2]],null,0,null,qu)),(l()(),e["\u0275and"](0,[[2,2],["iscsiSparklineTpl",2]],null,0,null,Au)),(l()(),e["\u0275and"](0,[[3,2],["iscsiPerSecondTpl",2]],null,0,null,Mu)),(l()(),e["\u0275and"](0,[[4,2],["iscsiRelativeDateTpl",2]],null,0,null,Lu))],function(l,n){var u=n.component;l(n,6,0),l(n,10,0,u.gateways,u.gatewaysColumns),l(n,14,0,u.images,u.imagesColumns)},null)}function Ku(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-iscsi",[],null,null,null,Gu,Pu)),e["\u0275did"](1,114688,null,0,Su.a,[Fu.a,q.a,O.a,V.a],null,null)],function(l,n){l(n,1,0)},null)}var Hu=e["\u0275ccf"]("cd-iscsi",Su.a,Ku,{},{},[]),Ju=u("TZo1"),Zu=u("9Kw/"),Wu=u("3ris"),Qu=u("e/kN"),Yu=e["\u0275crt"]({encapsulation:0,styles:[["tabset.tabset>ul{border-bottom:0;float:left;display:block;margin-right:20px;border-right:1px solid #ddd;padding-right:15px}"]],data:{}});function Xu(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,5,null,null,null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Available information:"])),(l()(),e["\u0275eld"](4,0,null,null,1,"pre",[],null,null,null,null,null)),(l()(),e["\u0275ted"](5,null,["",""]))],null,function(l,n){l(n,5,0,n.component.status)})}function le(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,8,"cd-info-panel",[["title","iSCSI Targets not available"]],null,null,null,Ju.b,Ju.a)),e["\u0275did"](1,49152,null,0,Zu.a,[V.a],{title:[0,"title"]},null),(l()(),e["\u0275eld"](2,0,null,0,4,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Please consult the "])),(l()(),e["\u0275eld"](4,0,null,null,1,"a",[["target","_blank"]],[[8,"href",4]],null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["documentation"])),(l()(),e["\u0275ted"](-1,null,[" on how to configure and enable the iSCSI Targets management functionality."])),(l()(),e["\u0275and"](16777216,null,0,1,null,Xu)),e["\u0275did"](8,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,1,0,"iSCSI Targets not available"),l(n,8,0,u.status)},function(l,n){l(n,4,0,e["\u0275inlineInterpolate"](1,"",n.component.docsUrl,""))})}function ne(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-iscsi-target-details",[["cdTableDetail",""]],null,null,null,T.c,T.b)),e["\u0275did"](1,638976,null,0,Wu.a,[V.a,O.a,x.a],{selection:[0,"selection"],settings:[1,"settings"],cephIscsiConfigVersion:[2,"cephIscsiConfigVersion"]},null)],function(l,n){var u=n.component;l(n,1,0,u.selection,u.settings,u.cephIscsiConfigVersion)},null)}function ue(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,10,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["identifier","target_iqn"],["selectionType","single"]],null,[[null,"updateSelection"]],function(l,n,u){var e=!0;return"updateSelection"===n&&(e=!1!==l.component.updateSelection(u)&&e),e},Fl.b,Fl.a)),e["\u0275did"](1,2867200,[[1,4],["table",4]],0,Pl.a,[e.NgZone,e.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],forceIdentifier:[4,"forceIdentifier"],selectionType:[5,"selectionType"]},{updateSelection:"updateSelection"}),(l()(),e["\u0275eld"](2,0,null,0,6,"div",[["class","table-actions btn-toolbar"]],null,null,null,null,null)),(l()(),e["\u0275eld"](3,0,null,null,1,"cd-table-actions",[["class","btn-group"]],null,null,null,ql.b,ql.a)),e["\u0275did"](4,114688,null,0,jl.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),e["\u0275eld"](5,0,null,null,3,"button",[["class","btn btn-sm btn-default btn-label"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.configureDiscoveryAuth()&&e),e},null,null)),(l()(),e["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-fw fa-key-modern"]],null,null,null,null,null)),(l()(),e["\u0275eld"](7,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Discovery authentication"])),(l()(),e["\u0275and"](16777216,null,2,1,null,ne)),e["\u0275did"](10,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,1,0,u.targets,u.columns,"flex","target_iqn","true","single"),l(n,4,0,u.permissions.iscsi,u.selection,u.tableActions),l(n,10,0,u.selection.hasSingleSelection)},null)}function ee(l){return e["\u0275vid"](0,[e["\u0275qud"](671088640,1,{table:0}),(l()(),e["\u0275eld"](1,0,null,null,1,"cd-iscsi-tabs",[],null,null,null,Du,Nu)),e["\u0275did"](2,114688,null,0,Vu,[dl.l],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,le)),e["\u0275did"](4,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,ue)),e["\u0275did"](6,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,2,0),l(n,4,0,!1===u.available),l(n,6,0,!0===u.available)},null)}function te(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,2,"cd-iscsi-target-list",[],null,null,null,ee,Yu)),e["\u0275prd"](131584,null,Al.a,Al.a,[Ul.a,xl.a]),e["\u0275did"](2,245760,null,0,Qu.a,[il.a,V.a,Fu.a,A.a,Al.a,D.a,K.a,xl.a,nl.b,Wl.a,Gl.b],null,null)],function(l,n){l(n,2,0)},null)}var ae=e["\u0275ccf"]("cd-iscsi-target-list",Qu.a,te,{},{},[]),oe=u("D4zM"),ie=u("OcYo"),re=u("SZbH"),de=u("WiuZ"),se=u("wnGv"),ce=function(){function l(l){this.ngControl=l}return l.prototype.onInput=function(l){this.setValue(l)},l.prototype.setValue=function(l){l=Ml.isString(l)?l.trim():l,this.ngControl.control.setValue(l)},l}(),pe=u("gr3l"),fe=e["\u0275crt"]({encapsulation:0,styles:[[".cd-mb[_ngcontent-%COMP%]{margin-bottom:10px}"]],data:{}});function ge(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function me(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["IQN has wrong pattern."]))],null,null)}function ve(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,8,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'"])),(l()(),e["\u0275eld"](3,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),e["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309"])),(l()(),e["\u0275eld"](6,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),e["\u0275eld"](7,0,null,null,1,"a",[["href","https://en.wikipedia.org/wiki/ISCSI#Addressing"],["target","_blank"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["More information"]))],null,null)}function he(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This target has modified advanced settings."]))],null,null)}function be(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,6,null,null,null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,5,"div",[["class","input-group cd-mb"]],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,1,"input",[["class","form-control"],["disabled",""],["type","text"]],[[8,"value",0]],null,null,null,null)),e["\u0275did"](3,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](4,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.removePortal(l.context.index,l.context.$implicit)&&e),e},null,null)),(l()(),e["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-remove fa-fw"]],null,null,null,null,null))],null,function(l,n){l(n,2,0,n.context.$implicit)})}function Ce(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](1,null,["At least "," gateways are required."]))],null,function(l,n){l(n,1,0,n.component.minimum_gateways)})}function Re(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"div",[["class","input-group-addon"]],null,null,null,null,null)),(l()(),e["\u0275ted"](1,null,["lun: ",""]))],null,function(l,n){l(n,1,0,n.component.imagesSettings[n.parent.context.$implicit].lun)})}function Ie(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,2,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](1,null,["Backstore: ",".\xa0"])),e["\u0275ppd"](2,1)],null,function(l,n){var u=n.component,t=e["\u0275unv"](n,1,0,l(n,2,0,e["\u0275nov"](n.parent.parent.parent,2),u.imagesSettings[n.parent.context.$implicit].backstore));l(n,1,0,t)})}function we(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This image has modified settings."]))],null,null)}function Te(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,15,null,null,null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,9,"div",[["class","input-group cd-mb"]],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,1,"input",[["class","form-control"],["disabled",""],["type","text"]],[[8,"value",0]],null,null,null,null)),e["\u0275did"](3,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,Re)),e["\u0275did"](5,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](6,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](7,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.imageSettingsModal(l.context.$implicit)&&e),e},null,null)),(l()(),e["\u0275eld"](8,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-cogs fa-fw"]],null,null,null,null,null)),(l()(),e["\u0275eld"](9,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.removeImage(l.context.index,l.context.$implicit)&&e),e},null,null)),(l()(),e["\u0275eld"](10,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-remove fa-fw"]],null,null,null,null,null)),(l()(),e["\u0275eld"](11,0,null,null,4,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Ie)),e["\u0275did"](13,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,we)),e["\u0275did"](15,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,5,0,u.api_version>=1),l(n,13,0,u.backstores.length>1),l(n,15,0,u.hasAdvancedSettings(u.imagesSettings[n.context.$implicit][u.imagesSettings[n.context.$implicit].backstore]))},function(l,n){l(n,2,0,n.context.$implicit)})}function ye(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Duplicated LUN numbers."]))],null,null)}function ke(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Duplicated WWN."]))],null,null)}function Ee(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function _e(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Usernames must have a length of 8 to 64 characters and can only contain letters, '.', '@', '-', '_' or ':'."]))],null,null)}function xe(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Ve(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Passwords must have a length of 12 to 16 characters and can only contain letters, '@', '-', '_' or '/'."]))],null,null)}function Ne(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function De(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Usernames must have a length of 8 to 64 characters and can only contain letters, '.', '@', '-', '_' or ':'."]))],null,null)}function Se(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Fe(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Passwords must have a length of 12 to 16 characters and can only contain letters, '@', '-', '_' or '/'."]))],null,null)}function Pe(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,87,"div",[["formGroupName","auth"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),e["\u0275did"](1,212992,null,0,Z.m,[[3,Z.d],[8,null],[8,null]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.m]),e["\u0275did"](3,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275eld"](4,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](5,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](6,{"has-error":0}),(l()(),e["\u0275eld"](7,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","target_user"]],null,null,null,null,null)),(l()(),e["\u0275eld"](8,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["User"])),(l()(),e["\u0275eld"](10,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](11,0,null,null,6,"input",[["autocomplete","off"],["class","form-control"],["formControlName","user"],["id","target_user"],["name","target_user"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,12)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,12).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,12)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,12)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](12,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](14,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](16,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](17,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ee)),e["\u0275did"](19,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,_e)),e["\u0275did"](21,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](22,0,null,null,23,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](23,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](24,{"has-error":0}),(l()(),e["\u0275eld"](25,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","target_password"]],null,null,null,null,null)),(l()(),e["\u0275eld"](26,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Password"])),(l()(),e["\u0275eld"](28,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](29,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](30,0,null,null,6,"input",[["autocomplete","new-password"],["class","form-control"],["formControlName","password"],["id","target_password"],["name","target_password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,31)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,31).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,31)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,31)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](31,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](33,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](35,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](36,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](37,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](38,0,null,null,1,"button",[["cdPasswordButton","target_password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,39).onClick()&&t),t},null,null)),e["\u0275did"](39,81920,null,0,oe.a,[e.ElementRef,e.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),e["\u0275eld"](40,0,null,null,1,"button",[["cdCopy2ClipboardButton","target_password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,41).onClick()&&t),t},null,null)),e["\u0275did"](41,81920,null,0,ie.a,[e.ElementRef,e.Renderer2,re.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,xe)),e["\u0275did"](43,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ve)),e["\u0275did"](45,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](46,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](47,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](48,{"has-error":0}),(l()(),e["\u0275eld"](49,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","target_mutual_user"]],null,null,null,null,null)),(l()(),e["\u0275eld"](50,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Mutual User"])),(l()(),e["\u0275eld"](52,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](53,0,null,null,6,"input",[["autocomplete","off"],["class","form-control"],["formControlName","mutual_user"],["id","target_mutual_user"],["name","target_mutual_user"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,54)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,54).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,54)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,54)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](54,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](56,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](58,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](59,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ne)),e["\u0275did"](61,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,De)),e["\u0275did"](63,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](64,0,null,null,23,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](65,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](66,{"has-error":0}),(l()(),e["\u0275eld"](67,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","target_mutual_password"]],null,null,null,null,null)),(l()(),e["\u0275eld"](68,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Mutual Password"])),(l()(),e["\u0275eld"](70,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](71,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](72,0,null,null,6,"input",[["autocomplete","new-password"],["class","form-control"],["formControlName","mutual_password"],["id","target_mutual_password"],["name","target_mutual_password"],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,73)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,73).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,73)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,73)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](73,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](75,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](77,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](78,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](79,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](80,0,null,null,1,"button",[["cdPasswordButton","target_mutual_password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,81).onClick()&&t),t},null,null)),e["\u0275did"](81,81920,null,0,oe.a,[e.ElementRef,e.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),e["\u0275eld"](82,0,null,null,1,"button",[["cdCopy2ClipboardButton","target_mutual_password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,83).onClick()&&t),t},null,null)),e["\u0275did"](83,81920,null,0,ie.a,[e.ElementRef,e.Renderer2,re.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Se)),e["\u0275did"](85,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Fe)),e["\u0275did"](87,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,1,0,"auth");var t=l(n,6,0,u.targetForm.showError("user",e["\u0275nov"](n.parent,2)));l(n,5,0,"form-group",t),l(n,14,0,"user"),l(n,19,0,u.targetForm.showError("user",e["\u0275nov"](n.parent,2),"required")),l(n,21,0,u.targetForm.showError("user",e["\u0275nov"](n.parent,2),"pattern"));var a=l(n,24,0,u.targetForm.showError("password",e["\u0275nov"](n.parent,2)));l(n,23,0,"form-group",a),l(n,33,0,"password"),l(n,39,0,"target_password"),l(n,41,0,"target_password"),l(n,43,0,u.targetForm.showError("password",e["\u0275nov"](n.parent,2),"required")),l(n,45,0,u.targetForm.showError("password",e["\u0275nov"](n.parent,2),"pattern"));var o=l(n,48,0,u.targetForm.showError("mutual_user",e["\u0275nov"](n.parent,2)));l(n,47,0,"form-group",o),l(n,56,0,"mutual_user"),l(n,61,0,u.targetForm.showError("mutual_user",e["\u0275nov"](n.parent,2),"required")),l(n,63,0,u.targetForm.showError("mutual_user",e["\u0275nov"](n.parent,2),"pattern"));var i=l(n,66,0,u.targetForm.showError("mutual_password",e["\u0275nov"](n.parent,2)));l(n,65,0,"form-group",i),l(n,75,0,"mutual_password"),l(n,81,0,"target_mutual_password"),l(n,83,0,"target_mutual_password"),l(n,85,0,u.targetForm.showError("mutual_password",e["\u0275nov"](n.parent,2),"required")),l(n,87,0,u.targetForm.showError("mutual_password",e["\u0275nov"](n.parent,2),"pattern"))},function(l,n){l(n,0,0,e["\u0275nov"](n,3).ngClassUntouched,e["\u0275nov"](n,3).ngClassTouched,e["\u0275nov"](n,3).ngClassPristine,e["\u0275nov"](n,3).ngClassDirty,e["\u0275nov"](n,3).ngClassValid,e["\u0275nov"](n,3).ngClassInvalid,e["\u0275nov"](n,3).ngClassPending),l(n,11,0,e["\u0275nov"](n,16).ngClassUntouched,e["\u0275nov"](n,16).ngClassTouched,e["\u0275nov"](n,16).ngClassPristine,e["\u0275nov"](n,16).ngClassDirty,e["\u0275nov"](n,16).ngClassValid,e["\u0275nov"](n,16).ngClassInvalid,e["\u0275nov"](n,16).ngClassPending),l(n,30,0,e["\u0275nov"](n,35).ngClassUntouched,e["\u0275nov"](n,35).ngClassTouched,e["\u0275nov"](n,35).ngClassPristine,e["\u0275nov"](n,35).ngClassDirty,e["\u0275nov"](n,35).ngClassValid,e["\u0275nov"](n,35).ngClassInvalid,e["\u0275nov"](n,35).ngClassPending),l(n,53,0,e["\u0275nov"](n,58).ngClassUntouched,e["\u0275nov"](n,58).ngClassTouched,e["\u0275nov"](n,58).ngClassPristine,e["\u0275nov"](n,58).ngClassDirty,e["\u0275nov"](n,58).ngClassValid,e["\u0275nov"](n,58).ngClassInvalid,e["\u0275nov"](n,58).ngClassPending),l(n,72,0,e["\u0275nov"](n,77).ngClassUntouched,e["\u0275nov"](n,77).ngClassTouched,e["\u0275nov"](n,77).ngClassPristine,e["\u0275nov"](n,77).ngClassDirty,e["\u0275nov"](n,77).ngClassValid,e["\u0275nov"](n,77).ngClassInvalid,e["\u0275nov"](n,77).ngClassPending)})}function qe(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Initiator IQN needs to be unique."]))],null,null)}function je(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Oe(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["IQN has wrong pattern."]))],null,null)}function Ae(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Ue(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Usernames must have a length of 8 to 64 characters and can only contain letters, '.', '@', '-', '_' or ':'."]))],null,null)}function $e(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Me(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Passwords must have a length of 12 to 16 characters and can only contain letters, '@', '-', '_' or '/'."]))],null,null)}function ze(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Be(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Usernames must have a length of 8 to 64 characters and can only contain letters, '.', '@', '-', '_' or ':'."]))],null,null)}function Le(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Ge(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Passwords must have a length of 12 to 16 characters and can only contain letters, '@', '-', '_' or '/'."]))],null,null)}function Ke(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,6,null,null,null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,5,"div",[["class","input-group cd-mb"]],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,1,"input",[["class","form-control"],["disabled",""],["type","text"]],[[8,"value",0]],null,null,null,null)),e["\u0275did"](3,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](4,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.removeInitiatorImage(l.parent.context.$implicit,l.context.index,l.parent.context.index,l.context.$implicit)&&e),e},null,null)),(l()(),e["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-remove fa-fw"]],null,null,null,null,null))],null,function(l,n){l(n,2,0,n.context.$implicit)})}function He(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Initiator belongs to a group. Images will be configure in the group."]))],null,null)}function Je(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,6,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,5,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,4,"cd-select",[["elemClass","btn btn-default pull-right"]],null,null,null,de.b,de.a)),e["\u0275did"](3,638976,null,0,se.a,[V.a],{elemClass:[0,"elemClass"],data:[1,"data"],options:[2,"options"],messages:[3,"messages"]},null),(l()(),e["\u0275eld"](4,0,null,0,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,0,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Add image"]))],function(l,n){var u=n.component,e=n.parent.context.$implicit.getValue("luns");l(n,3,0,"btn btn-default pull-right",e,u.imagesInitiatorSelections[n.parent.context.index],u.messages.initiatorImage)},null)}function Ze(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,129,"div",[["class","panel panel-default"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),e["\u0275did"](1,212992,null,0,Z.m,[[3,Z.d],[8,null],[8,null]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.m]),e["\u0275did"](3,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275eld"](4,0,null,null,5,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Initiator"])),(l()(),e["\u0275ted"](7,null,[": "," "])),(l()(),e["\u0275eld"](8,0,null,null,1,"button",[["class","close"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.removeInitiator(l.context.index)&&e),e},null,null)),(l()(),e["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-remove fa-fw"]],null,null,null,null,null)),(l()(),e["\u0275eld"](10,0,null,null,119,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),e["\u0275eld"](11,0,null,null,21,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](12,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](13,{"has-error":0}),(l()(),e["\u0275eld"](14,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","client_iqn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](15,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Client IQN"])),(l()(),e["\u0275eld"](17,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),e["\u0275eld"](18,0,null,null,14,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](19,0,null,null,7,"input",[["cdTrim",""],["class","form-control"],["formControlName","client_iqn"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"blur"],[null,"input"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,a=l.component;return"input"===n&&(t=!1!==e["\u0275nov"](l,20)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,20).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,20)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,20)._compositionEnd(u.target.value)&&t),"input"===n&&(t=!1!==e["\u0275nov"](l,25).onInput(u.target.value)&&t),"blur"===n&&(t=!1!==a.updatedInitiatorSelector()&&t),t},null,null)),e["\u0275did"](20,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](22,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](24,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](25,16384,null,0,ce,[Z.q],null,null),e["\u0275did"](26,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,qe)),e["\u0275did"](28,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,je)),e["\u0275did"](30,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Oe)),e["\u0275did"](32,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](33,0,null,null,84,null,null,null,null,null,null,null)),e["\u0275did"](34,212992,null,0,Z.m,[[3,Z.d],[8,null],[8,null]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.m]),e["\u0275did"](36,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275eld"](37,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](38,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](39,{"has-error":0}),(l()(),e["\u0275eld"](40,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","user"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["User"])),(l()(),e["\u0275eld"](42,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](43,0,null,null,6,"input",[["autocomplete","off"],["class","form-control"],["formControlName","user"],["type","text"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,44)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,44).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,44)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,44)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](44,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](46,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](48,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](49,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ae)),e["\u0275did"](51,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ue)),e["\u0275did"](53,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](54,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](55,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](56,{"has-error":0}),(l()(),e["\u0275eld"](57,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","password"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Password"])),(l()(),e["\u0275eld"](59,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](60,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](61,0,null,null,6,"input",[["autocomplete","new-password"],["class","form-control"],["formControlName","password"],["type","password"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,62)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,62).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,62)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,62)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](62,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](64,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](66,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](67,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](68,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](69,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,70).onClick()&&t),t},null,null)),e["\u0275did"](70,81920,null,0,oe.a,[e.ElementRef,e.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),e["\u0275eld"](71,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,72).onClick()&&t),t},null,null)),e["\u0275did"](72,81920,null,0,ie.a,[e.ElementRef,e.Renderer2,re.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,$e)),e["\u0275did"](74,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Me)),e["\u0275did"](76,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](77,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](78,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](79,{"has-error":0}),(l()(),e["\u0275eld"](80,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","mutual_user"]],null,null,null,null,null)),(l()(),e["\u0275eld"](81,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Mutual User"])),(l()(),e["\u0275eld"](83,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](84,0,null,null,6,"input",[["autocomplete","off"],["class","form-control"],["formControlName","mutual_user"],["type","text"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,85)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,85).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,85)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,85)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](85,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](87,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](89,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](90,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,ze)),e["\u0275did"](92,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Be)),e["\u0275did"](94,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](95,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](96,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](97,{"has-error":0}),(l()(),e["\u0275eld"](98,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","mutual_password"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Mutual Password"])),(l()(),e["\u0275eld"](100,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](101,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](102,0,null,null,6,"input",[["autocomplete","new-password"],["class","form-control"],["formControlName","mutual_password"],["type","password"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,103)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,103).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,103)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,103)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](103,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](105,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](107,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](108,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](109,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](110,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,111).onClick()&&t),t},null,null)),e["\u0275did"](111,81920,null,0,oe.a,[e.ElementRef,e.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),e["\u0275eld"](112,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;return"click"===n&&(t=!1!==e["\u0275nov"](l,113).onClick()&&t),t},null,null)),e["\u0275did"](113,81920,null,0,ie.a,[e.ElementRef,e.Renderer2,re.j],{cdCopy2ClipboardButton:[0,"cdCopy2ClipboardButton"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Le)),e["\u0275did"](115,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ge)),e["\u0275did"](117,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](118,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](119,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](120,{"has-error":0}),(l()(),e["\u0275eld"](121,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","luns"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Images"])),(l()(),e["\u0275eld"](123,0,null,null,6,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Ke)),e["\u0275did"](125,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,He)),e["\u0275did"](127,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Je)),e["\u0275did"](129,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,1,0,n.context.index);var u=l(n,13,0,n.context.$implicit.showError("client_iqn",e["\u0275nov"](n.parent.parent,2)));l(n,12,0,"form-group",u),l(n,22,0,"client_iqn");var t=n.context.$implicit.showError("client_iqn",e["\u0275nov"](n.parent.parent,2),"notUnique");l(n,28,0,t);var a=n.context.$implicit.showError("client_iqn",e["\u0275nov"](n.parent.parent,2),"required");l(n,30,0,a);var o=n.context.$implicit.showError("client_iqn",e["\u0275nov"](n.parent.parent,2),"pattern");l(n,32,0,o),l(n,34,0,"auth");var i=l(n,39,0,n.context.$implicit.showError("user",e["\u0275nov"](n.parent.parent,2)));l(n,38,0,"form-group",i),l(n,46,0,"user");var r=n.context.$implicit.showError("user",e["\u0275nov"](n.parent.parent,2),"required");l(n,51,0,r);var d=n.context.$implicit.showError("user",e["\u0275nov"](n.parent.parent,2),"pattern");l(n,53,0,d);var s=l(n,56,0,n.context.$implicit.showError("password",e["\u0275nov"](n.parent.parent,2)));l(n,55,0,"form-group",s),l(n,64,0,"password"),l(n,70,0,"password"+n.context.index),l(n,72,0,"password"+n.context.index);var c=n.context.$implicit.showError("password",e["\u0275nov"](n.parent.parent,2),"required");l(n,74,0,c);var p=n.context.$implicit.showError("password",e["\u0275nov"](n.parent.parent,2),"pattern");l(n,76,0,p);var f=l(n,79,0,n.context.$implicit.showError("mutual_user",e["\u0275nov"](n.parent.parent,2)));l(n,78,0,"form-group",f),l(n,87,0,"mutual_user");var g=n.context.$implicit.showError("mutual_user",e["\u0275nov"](n.parent.parent,2),"required");l(n,92,0,g);var m=n.context.$implicit.showError("mutual_user",e["\u0275nov"](n.parent.parent,2),"pattern");l(n,94,0,m);var v=l(n,97,0,n.context.$implicit.showError("mutual_password",e["\u0275nov"](n.parent.parent,2)));l(n,96,0,"form-group",v),l(n,105,0,"mutual_password"),l(n,111,0,"mutual_password"+n.context.index),l(n,113,0,"mutual_password"+n.context.index);var h=n.context.$implicit.showError("mutual_password",e["\u0275nov"](n.parent.parent,2),"required");l(n,115,0,h);var b=n.context.$implicit.showError("mutual_password",e["\u0275nov"](n.parent.parent,2),"pattern");l(n,117,0,b);var C=l(n,120,0,n.context.$implicit.showError("luns",e["\u0275nov"](n.parent.parent,2)));l(n,119,0,"form-group",C);var R=n.context.$implicit.getValue("luns");l(n,125,0,R);var I=n.context.$implicit.getValue("cdIsInGroup");l(n,127,0,I);var w=!n.context.$implicit.getValue("cdIsInGroup");l(n,129,0,w)},function(l,n){l(n,0,0,e["\u0275nov"](n,3).ngClassUntouched,e["\u0275nov"](n,3).ngClassTouched,e["\u0275nov"](n,3).ngClassPristine,e["\u0275nov"](n,3).ngClassDirty,e["\u0275nov"](n,3).ngClassValid,e["\u0275nov"](n,3).ngClassInvalid,e["\u0275nov"](n,3).ngClassPending);var u=n.context.$implicit.getValue("client_iqn");l(n,7,0,u),l(n,19,0,e["\u0275nov"](n,24).ngClassUntouched,e["\u0275nov"](n,24).ngClassTouched,e["\u0275nov"](n,24).ngClassPristine,e["\u0275nov"](n,24).ngClassDirty,e["\u0275nov"](n,24).ngClassValid,e["\u0275nov"](n,24).ngClassInvalid,e["\u0275nov"](n,24).ngClassPending),l(n,43,0,"user"+n.context.index,e["\u0275nov"](n,48).ngClassUntouched,e["\u0275nov"](n,48).ngClassTouched,e["\u0275nov"](n,48).ngClassPristine,e["\u0275nov"](n,48).ngClassDirty,e["\u0275nov"](n,48).ngClassValid,e["\u0275nov"](n,48).ngClassInvalid,e["\u0275nov"](n,48).ngClassPending),l(n,61,0,"password"+n.context.index,e["\u0275nov"](n,66).ngClassUntouched,e["\u0275nov"](n,66).ngClassTouched,e["\u0275nov"](n,66).ngClassPristine,e["\u0275nov"](n,66).ngClassDirty,e["\u0275nov"](n,66).ngClassValid,e["\u0275nov"](n,66).ngClassInvalid,e["\u0275nov"](n,66).ngClassPending),l(n,84,0,"mutual_user"+n.context.index,e["\u0275nov"](n,89).ngClassUntouched,e["\u0275nov"](n,89).ngClassTouched,e["\u0275nov"](n,89).ngClassPristine,e["\u0275nov"](n,89).ngClassDirty,e["\u0275nov"](n,89).ngClassValid,e["\u0275nov"](n,89).ngClassInvalid,e["\u0275nov"](n,89).ngClassPending),l(n,102,0,"mutual_password"+n.context.index,e["\u0275nov"](n,107).ngClassUntouched,e["\u0275nov"](n,107).ngClassTouched,e["\u0275nov"](n,107).ngClassPristine,e["\u0275nov"](n,107).ngClassDirty,e["\u0275nov"](n,107).ngClassValid,e["\u0275nov"](n,107).ngClassInvalid,e["\u0275nov"](n,107).ngClassPending)})}function We(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["No items added."]))],null,null)}function Qe(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","initiators"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Initiators"])),(l()(),e["\u0275eld"](3,0,null,null,14,"div",[["class","col-sm-9"],["formArrayName","initiators"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),e["\u0275did"](4,212992,null,0,Z.g,[[3,Z.d],[8,null],[8,null]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.g]),e["\u0275did"](6,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ze)),e["\u0275did"](8,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](9,0,null,null,7,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](10,0,null,null,6,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,We)),e["\u0275did"](12,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](13,0,null,null,3,"button",[["class","btn btn-default pull-right"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(l.component.addInitiator(),e=!1),e},null,null)),(l()(),e["\u0275eld"](14,0,null,null,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),e["\u0275eld"](15,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Add initiator"])),(l()(),e["\u0275eld"](17,0,null,null,0,"hr",[],null,null,null,null,null))],function(l,n){var u=n.component;l(n,4,0,"initiators"),l(n,8,0,u.initiators.controls),l(n,12,0,0===u.initiators.controls.length)},function(l,n){l(n,3,0,e["\u0275nov"](n,6).ngClassUntouched,e["\u0275nov"](n,6).ngClassTouched,e["\u0275nov"](n,6).ngClassPristine,e["\u0275nov"](n,6).ngClassDirty,e["\u0275nov"](n,6).ngClassValid,e["\u0275nov"](n,6).ngClassInvalid,e["\u0275nov"](n,6).ngClassPending)})}function Ye(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,6,null,null,null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,5,"div",[["class","input-group cd-mb"]],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,1,"input",[["class","form-control"],["disabled",""],["type","text"]],[[8,"value",0]],null,null,null,null)),e["\u0275did"](3,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](4,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.removeGroupInitiator(l.parent.context.$implicit,l.context.index,l.parent.context.index)&&e),e},null,null)),(l()(),e["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-remove fa-fw"]],null,null,null,null,null))],null,function(l,n){l(n,2,0,n.context.$implicit)})}function Xe(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,6,null,null,null,null,null,null,null)),(l()(),e["\u0275eld"](1,0,null,null,5,"div",[["class","input-group cd-mb"]],null,null,null,null,null)),(l()(),e["\u0275eld"](2,0,null,null,1,"input",[["class","form-control"],["disabled",""],["type","text"]],[[8,"value",0]],null,null,null,null)),e["\u0275did"](3,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](4,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.removeGroupDisk(l.parent.context.$implicit,l.context.index,l.parent.context.index)&&e),e},null,null)),(l()(),e["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-remove fa-fw"]],null,null,null,null,null))],null,function(l,n){l(n,2,0,n.context.$implicit)})}function lt(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,57,"div",[["class","panel panel-default"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),e["\u0275did"](1,212992,null,0,Z.m,[[3,Z.d],[8,null],[8,null]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.m]),e["\u0275did"](3,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275eld"](4,0,null,null,5,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),e["\u0275eld"](5,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Group"])),(l()(),e["\u0275ted"](7,null,[": "," "])),(l()(),e["\u0275eld"](8,0,null,null,1,"button",[["class","close"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.groups.removeAt(l.context.index)&&e),e},null,null)),(l()(),e["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-remove fa-fw"]],null,null,null,null,null)),(l()(),e["\u0275eld"](10,0,null,null,47,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),e["\u0275eld"](11,0,null,null,12,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](12,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","group_id"]],null,null,null,null,null)),(l()(),e["\u0275eld"](13,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Name"])),(l()(),e["\u0275eld"](15,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),e["\u0275eld"](16,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](17,0,null,null,6,"input",[["class","form-control"],["formControlName","group_id"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,18)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,18).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,18)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,18)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](18,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](20,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](22,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](23,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](24,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](25,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](26,{"has-error":0}),(l()(),e["\u0275eld"](27,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","members"]],null,null,null,null,null)),(l()(),e["\u0275eld"](28,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Initiators"])),(l()(),e["\u0275eld"](30,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Ye)),e["\u0275did"](32,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](33,0,null,null,6,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](34,0,null,null,5,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),e["\u0275eld"](35,0,null,null,4,"cd-select",[["elemClass","btn btn-default pull-right"]],null,[[null,"selection"]],function(l,n,u){var e=!0;return"selection"===n&&(e=!1!==l.component.onGroupMemberSelection(u)&&e),e},de.b,de.a)),e["\u0275did"](36,638976,null,0,se.a,[V.a],{elemClass:[0,"elemClass"],data:[1,"data"],options:[2,"options"],messages:[3,"messages"]},{selection:"selection"}),(l()(),e["\u0275eld"](37,0,null,0,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),e["\u0275eld"](38,0,null,0,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Add initiator"])),(l()(),e["\u0275eld"](40,0,null,null,0,"hr",[],null,null,null,null,null)),(l()(),e["\u0275eld"](41,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](42,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](43,{"has-error":0}),(l()(),e["\u0275eld"](44,0,null,null,2,"label",[["class","control-label col-sm-3"],["for","disks"]],null,null,null,null,null)),(l()(),e["\u0275eld"](45,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Images"])),(l()(),e["\u0275eld"](47,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Xe)),e["\u0275did"](49,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](50,0,null,null,6,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](51,0,null,null,5,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),e["\u0275eld"](52,0,null,null,4,"cd-select",[["elemClass","btn btn-default pull-right"]],null,null,null,de.b,de.a)),e["\u0275did"](53,638976,null,0,se.a,[V.a],{elemClass:[0,"elemClass"],data:[1,"data"],options:[2,"options"],messages:[3,"messages"]},null),(l()(),e["\u0275eld"](54,0,null,0,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),e["\u0275eld"](55,0,null,0,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Add image"])),(l()(),e["\u0275eld"](57,0,null,null,0,"hr",[],null,null,null,null,null))],function(l,n){var u=n.component;l(n,1,0,n.context.index),l(n,20,0,"group_id");var t=l(n,26,0,n.context.$implicit.showError("members",e["\u0275nov"](n.parent.parent,2)));l(n,25,0,"form-group",t);var a=n.context.$implicit.getValue("members");l(n,32,0,a);var o=n.context.$implicit.getValue("members");l(n,36,0,"btn btn-default pull-right",o,u.groupMembersSelections[n.context.index],u.messages.groupInitiator);var i=l(n,43,0,n.context.$implicit.showError("disks",e["\u0275nov"](n.parent.parent,2)));l(n,42,0,"form-group",i);var r=n.context.$implicit.getValue("disks");l(n,49,0,r);var d=n.context.$implicit.getValue("disks");l(n,53,0,"btn btn-default pull-right",d,u.groupDiskSelections[n.context.index],u.messages.initiatorImage)},function(l,n){l(n,0,0,e["\u0275nov"](n,3).ngClassUntouched,e["\u0275nov"](n,3).ngClassTouched,e["\u0275nov"](n,3).ngClassPristine,e["\u0275nov"](n,3).ngClassDirty,e["\u0275nov"](n,3).ngClassValid,e["\u0275nov"](n,3).ngClassInvalid,e["\u0275nov"](n,3).ngClassPending);var u=n.context.$implicit.getValue("group_id");l(n,7,0,u),l(n,17,0,e["\u0275nov"](n,22).ngClassUntouched,e["\u0275nov"](n,22).ngClassTouched,e["\u0275nov"](n,22).ngClassPristine,e["\u0275nov"](n,22).ngClassDirty,e["\u0275nov"](n,22).ngClassValid,e["\u0275nov"](n,22).ngClassInvalid,e["\u0275nov"](n,22).ngClassPending)})}function nt(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["No items added."]))],null,null)}function ut(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](1,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](2,{"has-error":0}),(l()(),e["\u0275eld"](3,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","initiators"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Groups"])),(l()(),e["\u0275eld"](5,0,null,null,13,"div",[["class","col-sm-9"],["formArrayName","groups"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),e["\u0275did"](6,212992,null,0,Z.g,[[3,Z.d],[8,null],[8,null]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.g]),e["\u0275did"](8,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,lt)),e["\u0275did"](10,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](11,0,null,null,7,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](12,0,null,null,6,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,nt)),e["\u0275did"](14,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](15,0,null,null,3,"button",[["class","btn btn-default pull-right"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(l.component.addGroup(),e=!1),e},null,null)),(l()(),e["\u0275eld"](16,0,null,null,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),e["\u0275eld"](17,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Add group"]))],function(l,n){var u=n.component,t=l(n,2,0,u.targetForm.showError("groups",e["\u0275nov"](n.parent,2)));l(n,1,0,"form-group",t),l(n,6,0,"groups"),l(n,10,0,u.groups.controls),l(n,14,0,0===u.groups.controls.length)},function(l,n){l(n,5,0,e["\u0275nov"](n,8).ngClassUntouched,e["\u0275nov"](n,8).ngClassTouched,e["\u0275nov"](n,8).ngClassPristine,e["\u0275nov"](n,8).ngClassDirty,e["\u0275nov"](n,8).ngClassValid,e["\u0275nov"](n,8).ngClassInvalid,e["\u0275nov"](n,8).ngClassPending)})}function et(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,115,"form",[["class","form-horizontal"],["name","targetForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var t=!0;return"submit"===n&&(t=!1!==e["\u0275nov"](l,2).onSubmit(u)&&t),"reset"===n&&(t=!1!==e["\u0275nov"](l,2).onReset()&&t),t},null,null)),e["\u0275did"](1,16384,null,0,Z.D,[],null,null),e["\u0275did"](2,540672,[["formDir",4]],0,Z.l,[[8,null],[8,null]],{form:[0,"form"]},null),e["\u0275prd"](2048,null,Z.d,null,[Z.l]),e["\u0275did"](4,16384,null,0,Z.s,[[4,Z.d]],null,null),(l()(),e["\u0275eld"](5,0,null,null,110,"div",[["class","panel panel-default"]],null,null,null,null,null)),(l()(),e["\u0275eld"](6,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),e["\u0275eld"](7,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(l()(),e["\u0275ted"](8,null,[""," ",""])),e["\u0275ppd"](9,1),e["\u0275ppd"](10,1),(l()(),e["\u0275eld"](11,0,null,null,95,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),e["\u0275eld"](12,0,null,null,28,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](13,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](14,{"has-error":0}),(l()(),e["\u0275eld"](15,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","target_iqn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](16,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Target IQN"])),(l()(),e["\u0275eld"](18,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),e["\u0275eld"](19,0,null,null,21,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](20,0,null,null,11,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](21,0,null,null,7,"input",[["cdTrim",""],["class","form-control"],["formControlName","target_iqn"],["id","target_iqn"],["name","target_iqn"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,22)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,22).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,22)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,22)._compositionEnd(u.target.value)&&t),"input"===n&&(t=!1!==e["\u0275nov"](l,27).onInput(u.target.value)&&t),t},null,null)),e["\u0275did"](22,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](24,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](26,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](27,16384,null,0,ce,[Z.q],null,null),e["\u0275did"](28,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](29,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),e["\u0275eld"](30,0,null,null,1,"button",[["class","btn btn-default"],["id","ecp-info-button"],["type","button"]],null,[[null,"click"]],function(l,n,u){var e=!0;return"click"===n&&(e=!1!==l.component.targetSettingsModal()&&e),e},null,null)),(l()(),e["\u0275eld"](31,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-cogs fa-fw"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,ge)),e["\u0275did"](33,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,me)),e["\u0275did"](35,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,ve)),e["\u0275did"](37,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,he)),e["\u0275did"](39,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](40,0,null,null,0,"hr",[],null,null,null,null,null)),(l()(),e["\u0275eld"](41,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](42,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](43,{"has-error":0}),(l()(),e["\u0275eld"](44,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","portals"]],null,null,null,null,null)),(l()(),e["\u0275eld"](45,0,null,null,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Portals"])),(l()(),e["\u0275eld"](47,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),e["\u0275eld"](48,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,be)),e["\u0275did"](50,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Ce)),e["\u0275did"](52,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](53,0,null,null,6,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](54,0,null,null,5,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),e["\u0275eld"](55,0,null,null,4,"cd-select",[["elemClass","btn btn-default pull-right"]],null,[[null,"selection"]],function(l,n,u){var e=!0;return"selection"===n&&(e=!1!==l.component.onPortalSelection(u)&&e),e},de.b,de.a)),e["\u0275did"](56,638976,null,0,se.a,[V.a],{elemClass:[0,"elemClass"],data:[1,"data"],options:[2,"options"],messages:[3,"messages"]},{selection:"selection"}),(l()(),e["\u0275eld"](57,0,null,0,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),e["\u0275eld"](58,0,null,0,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Add portal"])),(l()(),e["\u0275eld"](60,0,null,null,0,"hr",[],null,null,null,null,null)),(l()(),e["\u0275eld"](61,0,null,null,26,"div",[["class","form-group"]],null,null,null,null,null)),e["\u0275did"](62,278528,null,0,_.NgClass,[e.IterableDiffers,e.KeyValueDiffers,e.ElementRef,e.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),e["\u0275pod"](63,{"has-error":0}),(l()(),e["\u0275eld"](64,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","disks"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Images"])),(l()(),e["\u0275eld"](66,0,null,null,21,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Te)),e["\u0275did"](68,278528,null,0,_.NgForOf,[e.ViewContainerRef,e.TemplateRef,e.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),e["\u0275eld"](69,0,null,null,6,"input",[["class","form-control"],["formControlName","disks"],["id","disks"],["name","disks"],["type","hidden"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;return"input"===n&&(t=!1!==e["\u0275nov"](l,70)._handleInput(u.target.value)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,70).onTouched()&&t),"compositionstart"===n&&(t=!1!==e["\u0275nov"](l,70)._compositionStart()&&t),"compositionend"===n&&(t=!1!==e["\u0275nov"](l,70)._compositionEnd(u.target.value)&&t),t},null,null)),e["\u0275did"](70,16384,null,0,Z.e,[e.Renderer2,e.ElementRef,[2,Z.b]],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.e]),e["\u0275did"](72,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](74,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](75,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275and"](16777216,null,null,1,null,ye)),e["\u0275did"](77,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,ke)),e["\u0275did"](79,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](80,0,null,null,6,"div",[["class","row"]],null,null,null,null,null)),(l()(),e["\u0275eld"](81,0,null,null,5,"div",[["class","col-md-12"]],null,null,null,null,null)),(l()(),e["\u0275eld"](82,0,null,null,4,"cd-select",[["elemClass","btn btn-default pull-right"]],null,[[null,"selection"]],function(l,n,u){var e=!0;return"selection"===n&&(e=!1!==l.component.onImageSelection(u)&&e),e},de.b,de.a)),e["\u0275did"](83,638976,null,0,se.a,[V.a],{elemClass:[0,"elemClass"],data:[1,"data"],options:[2,"options"],messages:[3,"messages"]},{selection:"selection"}),(l()(),e["\u0275eld"](84,0,null,0,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(l()(),e["\u0275eld"](85,0,null,0,1,null,null,null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["Add image"])),(l()(),e["\u0275eld"](87,0,null,null,0,"hr",[],null,null,null,null,null)),(l()(),e["\u0275eld"](88,0,null,null,12,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),e["\u0275eld"](89,0,null,null,11,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),e["\u0275eld"](90,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),e["\u0275eld"](91,0,null,null,6,"input",[["formControlName","acl_enabled"],["id","acl_enabled"],["name","acl_enabled"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,u){var t=!0;return"change"===n&&(t=!1!==e["\u0275nov"](l,92).onChange(u.target.checked)&&t),"blur"===n&&(t=!1!==e["\u0275nov"](l,92).onTouched()&&t),t},null,null)),e["\u0275did"](92,16384,null,0,Z.c,[e.Renderer2,e.ElementRef],null,null),e["\u0275prd"](1024,null,Z.p,function(l){return[l]},[Z.c]),e["\u0275did"](94,671744,null,0,Z.j,[[3,Z.d],[8,null],[8,null],[6,Z.p],[2,Z.F]],{name:[0,"name"]},null),e["\u0275prd"](2048,null,Z.q,null,[Z.j]),e["\u0275did"](96,16384,null,0,Z.r,[[4,Z.q]],null,null),e["\u0275did"](97,4210688,null,0,Vn.a,[[2,Nn.a],il.a,e.ElementRef],null,null),(l()(),e["\u0275eld"](98,0,null,null,1,"label",[["for","acl_enabled"]],null,null,null,null,null)),(l()(),e["\u0275ted"](-1,null,["ACL authentication"])),(l()(),e["\u0275eld"](100,0,null,null,0,"hr",[],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,Pe)),e["\u0275did"](102,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,Qe)),e["\u0275did"](104,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275and"](16777216,null,null,1,null,ut)),e["\u0275did"](106,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),e["\u0275eld"](107,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(l()(),e["\u0275eld"](108,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),e["\u0275eld"](109,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(l,n,u){var e=!0;return"submitAction"===n&&(e=!1!==l.component.submit()&&e),e},An.b,An.a)),e["\u0275did"](110,114688,null,0,Un.a,[e.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(l()(),e["\u0275ted"](111,0,[""," ",""])),e["\u0275ppd"](112,1),e["\u0275ppd"](113,1),(l()(),e["\u0275eld"](114,0,null,null,1,"cd-back-button",[],null,null,null,$n.b,$n.a)),e["\u0275did"](115,49152,null,0,Mn.a,[_.Location,Gl.b],null,null)],function(l,n){var u=n.component;l(n,2,0,u.targetForm);var t=l(n,14,0,u.targetForm.showError("target_iqn",e["\u0275nov"](n,2)));l(n,13,0,"form-group",t),l(n,24,0,"target_iqn"),l(n,33,0,u.targetForm.showError("target_iqn",e["\u0275nov"](n,2),"required")),l(n,35,0,u.targetForm.showError("target_iqn",e["\u0275nov"](n,2),"pattern")),l(n,37,0,u.targetForm.showError("target_iqn",e["\u0275nov"](n,2),"iqn")),l(n,39,0,u.hasAdvancedSettings(u.targetForm.getValue("target_controls")));var a=l(n,43,0,u.targetForm.showError("portals",e["\u0275nov"](n,2)));l(n,42,0,"form-group",a),l(n,50,0,u.portals.value),l(n,52,0,u.targetForm.showError("portals",e["\u0275nov"](n,2),"minGateways")),l(n,56,0,"btn btn-default pull-right",u.portals.value,u.portalsSelections,u.messages.portals);var o=l(n,63,0,u.targetForm.showError("disks",e["\u0275nov"](n,2)));l(n,62,0,"form-group",o),l(n,68,0,u.targetForm.getValue("disks")),l(n,72,0,"disks"),l(n,77,0,u.targetForm.showError("disks",e["\u0275nov"](n,2),"dupLunId")),l(n,79,0,u.targetForm.showError("disks",e["\u0275nov"](n,2),"dupWwn")),l(n,83,0,"btn btn-default pull-right",u.disks.value,u.imagesSelections,u.messages.images),l(n,94,0,"acl_enabled"),l(n,102,0,u.cephIscsiConfigVersion>10&&!u.targetForm.getValue("acl_enabled")),l(n,104,0,u.targetForm.getValue("acl_enabled")),l(n,106,0,u.targetForm.getValue("acl_enabled")),l(n,110,0,e["\u0275nov"](n,2),"button")},function(l,n){var u=n.component;l(n,0,0,e["\u0275nov"](n,4).ngClassUntouched,e["\u0275nov"](n,4).ngClassTouched,e["\u0275nov"](n,4).ngClassPristine,e["\u0275nov"](n,4).ngClassDirty,e["\u0275nov"](n,4).ngClassValid,e["\u0275nov"](n,4).ngClassInvalid,e["\u0275nov"](n,4).ngClassPending);var t=e["\u0275unv"](n,8,0,l(n,9,0,e["\u0275nov"](n.parent,0),u.action)),a=e["\u0275unv"](n,8,1,l(n,10,0,e["\u0275nov"](n.parent,1),u.resource));l(n,8,0,t,a),l(n,21,0,e["\u0275nov"](n,26).ngClassUntouched,e["\u0275nov"](n,26).ngClassTouched,e["\u0275nov"](n,26).ngClassPristine,e["\u0275nov"](n,26).ngClassDirty,e["\u0275nov"](n,26).ngClassValid,e["\u0275nov"](n,26).ngClassInvalid,e["\u0275nov"](n,26).ngClassPending),l(n,69,0,e["\u0275nov"](n,74).ngClassUntouched,e["\u0275nov"](n,74).ngClassTouched,e["\u0275nov"](n,74).ngClassPristine,e["\u0275nov"](n,74).ngClassDirty,e["\u0275nov"](n,74).ngClassValid,e["\u0275nov"](n,74).ngClassInvalid,e["\u0275nov"](n,74).ngClassPending),l(n,91,0,e["\u0275nov"](n,96).ngClassUntouched,e["\u0275nov"](n,96).ngClassTouched,e["\u0275nov"](n,96).ngClassPristine,e["\u0275nov"](n,96).ngClassDirty,e["\u0275nov"](n,96).ngClassValid,e["\u0275nov"](n,96).ngClassInvalid,e["\u0275nov"](n,96).ngClassPending);var o=e["\u0275unv"](n,111,0,l(n,112,0,e["\u0275nov"](n.parent,0),u.action)),i=e["\u0275unv"](n,111,1,l(n,113,0,e["\u0275nov"](n.parent,1),u.resource));l(n,111,0,o,i)})}function tt(l){return e["\u0275vid"](0,[e["\u0275pid"](0,_.TitleCasePipe,[]),e["\u0275pid"](0,H.a,[]),e["\u0275pid"](0,O.a,[]),(l()(),e["\u0275eld"](3,0,null,null,2,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(l()(),e["\u0275and"](16777216,null,null,1,null,et)),e["\u0275did"](5,16384,null,0,_.NgIf,[e.ViewContainerRef,e.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,5,0,n.component.targetForm)},null)}function at(l){return e["\u0275vid"](0,[(l()(),e["\u0275eld"](0,0,null,null,1,"cd-iscsi-target-form",[],null,null,null,tt,fe)),e["\u0275did"](1,114688,null,0,pe.a,[Fu.a,nl.b,zl.a,dl.l,dl.a,V.a,Wl.a,Gl.b],null,null)],function(l,n){l(n,1,0)},null)}var ot=e["\u0275ccf"]("cd-iscsi-target-form",pe.a,at,{},{},[]),it=u("Vhfg"),rt=u("cxJu");u.d(n,"BlockModuleNgFactory",function(){return dt}),u.d(n,"RoutedBlockModuleNgFactory",function(){return st});var dt=e["\u0275cmf"](t.a,[],function(l){return e["\u0275mod"]([e["\u0275mpd"](512,e.ComponentFactoryResolver,e["\u0275CodegenComponentFactoryResolver"],[[8,[a.a,o.a,i.a,r.a,r.b,d.a,s.a,c.a,p.a,f.a,g.a,m.a,v.a,h.a,h.c,h.b,b.a,C.a,R.a,I.a,w.a,T.a,y.a,k.a,E.a]],[3,e.ComponentFactoryResolver],e.NgModuleRef]),e["\u0275mpd"](4608,_.NgLocalization,_.NgLocaleLocalization,[e.LOCALE_ID,[2,_["\u0275angular_packages_common_common_a"]]]),e["\u0275mpd"](4608,x.a,x.a,[V.a]),e["\u0275mpd"](4608,_.DatePipe,_.DatePipe,[e.LOCALE_ID]),e["\u0275mpd"](4608,N.a,N.a,[]),e["\u0275mpd"](4608,D.a,D.a,[]),e["\u0275mpd"](4608,S.a,S.a,[]),e["\u0275mpd"](4608,F.a,F.a,[S.a]),e["\u0275mpd"](4608,P.a,P.a,[S.a]),e["\u0275mpd"](4608,q.a,q.a,[S.a]),e["\u0275mpd"](4608,j.a,j.a,[]),e["\u0275mpd"](4608,O.a,O.a,[]),e["\u0275mpd"](4608,A.a,A.a,[]),e["\u0275mpd"](4608,U.a,U.a,[]),e["\u0275mpd"](4608,$.a,$.a,[_.DatePipe]),e["\u0275mpd"](4608,M.a,M.a,[]),e["\u0275mpd"](4608,z.a,z.a,[]),e["\u0275mpd"](4608,B.a,B.a,[]),e["\u0275mpd"](4608,L.a,L.a,[]),e["\u0275mpd"](4608,G.a,G.a,[]),e["\u0275mpd"](4608,K.a,K.a,[V.a]),e["\u0275mpd"](4608,H.a,H.a,[]),e["\u0275mpd"](4608,J.a,J.a,[]),e["\u0275mpd"](4608,Z.E,Z.E,[]),e["\u0275mpd"](4608,Z.h,Z.h,[]),e["\u0275mpd"](4608,W.b,W.b,[]),e["\u0275mpd"](4608,Q.a,Q.a,[]),e["\u0275mpd"](4608,Y.a,Y.a,[e.RendererFactory2,e.PLATFORM_ID]),e["\u0275mpd"](4608,X.a,X.a,[e.ComponentFactoryResolver,e.NgZone,e.Injector,Y.a,e.ApplicationRef]),e["\u0275mpd"](4608,ll.a,ll.a,[]),e["\u0275mpd"](4608,nl.b,nl.b,[e.RendererFactory2,X.a]),e["\u0275mpd"](4608,ul.ScrollbarHelper,ul.ScrollbarHelper,[el.DOCUMENT]),e["\u0275mpd"](4608,tl.DimensionsHelper,tl.DimensionsHelper,[]),e["\u0275mpd"](4608,al.ColumnChangesService,al.ColumnChangesService,[]),e["\u0275mpd"](4608,ol.f,ol.f,[]),e["\u0275mpd"](4608,il.a,il.a,[]),e["\u0275mpd"](4608,rl.a,rl.a,[dl.l,il.a]),e["\u0275mpd"](4608,sl.NodeDraggableService,sl.NodeDraggableService,[]),e["\u0275mpd"](4608,cl.NodeMenuService,cl.NodeMenuService,[]),e["\u0275mpd"](4608,pl.TreeService,pl.TreeService,[sl.NodeDraggableService]),e["\u0275mpd"](4608,fl.e,fl.e,[]),e["\u0275mpd"](4608,gl.c,gl.c,[]),e["\u0275mpd"](4608,ml.r,ml.r,[]),e["\u0275mpd"](4608,ml.t,ml.t,[]),e["\u0275mpd"](4608,ml.a,ml.a,[]),e["\u0275mpd"](4608,ml.h,ml.h,[]),e["\u0275mpd"](4608,ml.d,ml.d,[]),e["\u0275mpd"](4608,ml.j,ml.j,[]),e["\u0275mpd"](4608,ml.s,ml.s,[ml.t,ml.j]),e["\u0275mpd"](1073742336,_.CommonModule,_.CommonModule,[]),e["\u0275mpd"](1073742336,fl.c,fl.c,[]),e["\u0275mpd"](1073742336,vl.a,vl.a,[]),e["\u0275mpd"](1073742336,Z.B,Z.B,[]),e["\u0275mpd"](1073742336,Z.n,Z.n,[]),e["\u0275mpd"](1073742336,Z.x,Z.x,[]),e["\u0275mpd"](1073742336,W.c,W.c,[]),e["\u0275mpd"](1073742336,Q.d,Q.d,[]),e["\u0275mpd"](1073742336,ll.d,ll.d,[]),e["\u0275mpd"](1073742336,hl.ChartsModule,hl.ChartsModule,[]),e["\u0275mpd"](1073742336,nl.e,nl.e,[]),e["\u0275mpd"](1073742336,bl.a,bl.a,[]),e["\u0275mpd"](1073742336,ol.e,ol.e,[]),e["\u0275mpd"](1073742336,Cl.a,Cl.a,[]),e["\u0275mpd"](1073742336,Rl.NgxDatatableModule,Rl.NgxDatatableModule,[]),e["\u0275mpd"](1073742336,dl.p,dl.p,[[2,dl.v],[2,dl.l]]),e["\u0275mpd"](1073742336,Il.a,Il.a,[]),e["\u0275mpd"](1073742336,wl.a,wl.a,[]),e["\u0275mpd"](1073742336,Tl.a,Tl.a,[]),e["\u0275mpd"](1073742336,gl.d,gl.d,[]),e["\u0275mpd"](1073742336,yl.TreeModule,yl.TreeModule,[]),e["\u0275mpd"](1073742336,kl.a,kl.a,[]),e["\u0275mpd"](1073742336,ml.g,ml.g,[]),e["\u0275mpd"](1073742336,t.a,t.a,[]),e["\u0275mpd"](256,e.LOCALE_ID,"en-US",[]),e["\u0275mpd"](256,ol.a,{autoClose:!0,insideClick:!1},[]),e["\u0275mpd"](256,e.TRANSLATIONS_FORMAT,"xlf",[])])}),st=e["\u0275cmf"](t.b,[],function(l){return e["\u0275mod"]([e["\u0275mpd"](512,e.ComponentFactoryResolver,e["\u0275CodegenComponentFactoryResolver"],[[8,[a.a,o.a,i.a,r.a,r.b,d.a,s.a,c.a,p.a,f.a,g.a,m.a,v.a,h.a,h.c,h.b,b.a,C.a,R.a,I.a,w.a,T.a,y.a,k.a,E.a,xn,Eu,Hu,ae,ot]],[3,e.ComponentFactoryResolver],e.NgModuleRef]),e["\u0275mpd"](4608,_.NgLocalization,_.NgLocaleLocalization,[e.LOCALE_ID,[2,_["\u0275angular_packages_common_common_a"]]]),e["\u0275mpd"](4608,x.a,x.a,[V.a]),e["\u0275mpd"](4608,_.DatePipe,_.DatePipe,[e.LOCALE_ID]),e["\u0275mpd"](4608,N.a,N.a,[]),e["\u0275mpd"](4608,D.a,D.a,[]),e["\u0275mpd"](4608,S.a,S.a,[]),e["\u0275mpd"](4608,F.a,F.a,[S.a]),e["\u0275mpd"](4608,P.a,P.a,[S.a]),e["\u0275mpd"](4608,q.a,q.a,[S.a]),e["\u0275mpd"](4608,j.a,j.a,[]),e["\u0275mpd"](4608,O.a,O.a,[]),e["\u0275mpd"](4608,A.a,A.a,[]),e["\u0275mpd"](4608,U.a,U.a,[]),e["\u0275mpd"](4608,$.a,$.a,[_.DatePipe]),e["\u0275mpd"](4608,M.a,M.a,[]),e["\u0275mpd"](4608,z.a,z.a,[]),e["\u0275mpd"](4608,B.a,B.a,[]),e["\u0275mpd"](4608,L.a,L.a,[]),e["\u0275mpd"](4608,G.a,G.a,[]),e["\u0275mpd"](4608,K.a,K.a,[V.a]),e["\u0275mpd"](4608,H.a,H.a,[]),e["\u0275mpd"](4608,J.a,J.a,[]),e["\u0275mpd"](4608,Z.E,Z.E,[]),e["\u0275mpd"](4608,Z.h,Z.h,[]),e["\u0275mpd"](4608,W.b,W.b,[]),e["\u0275mpd"](4608,Q.a,Q.a,[]),e["\u0275mpd"](4608,Y.a,Y.a,[e.RendererFactory2,e.PLATFORM_ID]),e["\u0275mpd"](4608,X.a,X.a,[e.ComponentFactoryResolver,e.NgZone,e.Injector,Y.a,e.ApplicationRef]),e["\u0275mpd"](4608,ll.a,ll.a,[]),e["\u0275mpd"](4608,nl.b,nl.b,[e.RendererFactory2,X.a]),e["\u0275mpd"](4608,ul.ScrollbarHelper,ul.ScrollbarHelper,[el.DOCUMENT]),e["\u0275mpd"](4608,tl.DimensionsHelper,tl.DimensionsHelper,[]),e["\u0275mpd"](4608,al.ColumnChangesService,al.ColumnChangesService,[]),e["\u0275mpd"](4608,ol.f,ol.f,[]),e["\u0275mpd"](4608,il.a,il.a,[]),e["\u0275mpd"](4608,rl.a,rl.a,[dl.l,il.a]),e["\u0275mpd"](4608,sl.NodeDraggableService,sl.NodeDraggableService,[]),e["\u0275mpd"](4608,cl.NodeMenuService,cl.NodeMenuService,[]),e["\u0275mpd"](4608,pl.TreeService,pl.TreeService,[sl.NodeDraggableService]),e["\u0275mpd"](4608,fl.e,fl.e,[]),e["\u0275mpd"](4608,gl.c,gl.c,[]),e["\u0275mpd"](4608,ml.r,ml.r,[]),e["\u0275mpd"](4608,ml.t,ml.t,[]),e["\u0275mpd"](4608,ml.a,ml.a,[]),e["\u0275mpd"](4608,ml.h,ml.h,[]),e["\u0275mpd"](4608,ml.d,ml.d,[]),e["\u0275mpd"](4608,ml.j,ml.j,[]),e["\u0275mpd"](4608,ml.s,ml.s,[ml.t,ml.j]),e["\u0275mpd"](1073742336,_.CommonModule,_.CommonModule,[]),e["\u0275mpd"](1073742336,fl.c,fl.c,[]),e["\u0275mpd"](1073742336,vl.a,vl.a,[]),e["\u0275mpd"](1073742336,Z.B,Z.B,[]),e["\u0275mpd"](1073742336,Z.n,Z.n,[]),e["\u0275mpd"](1073742336,Z.x,Z.x,[]),e["\u0275mpd"](1073742336,W.c,W.c,[]),e["\u0275mpd"](1073742336,Q.d,Q.d,[]),e["\u0275mpd"](1073742336,ll.d,ll.d,[]),e["\u0275mpd"](1073742336,hl.ChartsModule,hl.ChartsModule,[]),e["\u0275mpd"](1073742336,nl.e,nl.e,[]),e["\u0275mpd"](1073742336,bl.a,bl.a,[]),e["\u0275mpd"](1073742336,ol.e,ol.e,[]),e["\u0275mpd"](1073742336,Cl.a,Cl.a,[]),e["\u0275mpd"](1073742336,Rl.NgxDatatableModule,Rl.NgxDatatableModule,[]),e["\u0275mpd"](1073742336,dl.p,dl.p,[[2,dl.v],[2,dl.l]]),e["\u0275mpd"](1073742336,Il.a,Il.a,[]),e["\u0275mpd"](1073742336,wl.a,wl.a,[]),e["\u0275mpd"](1073742336,Tl.a,Tl.a,[]),e["\u0275mpd"](1073742336,gl.d,gl.d,[]),e["\u0275mpd"](1073742336,yl.TreeModule,yl.TreeModule,[]),e["\u0275mpd"](1073742336,kl.a,kl.a,[]),e["\u0275mpd"](1073742336,ml.g,ml.g,[]),e["\u0275mpd"](1073742336,t.a,t.a,[]),e["\u0275mpd"](1073742336,t.b,t.b,[]),e["\u0275mpd"](256,e.LOCALE_ID,"en-US",[]),e["\u0275mpd"](256,ol.a,{autoClose:!0,insideClick:!1},[]),e["\u0275mpd"](1024,dl.j,function(){return[[{path:"",redirectTo:"rbd",pathMatch:"full"},{path:"rbd",canActivate:[it.a],data:t.c,children:[{path:"",component:Tn.a},{path:"create",component:zn.a,data:t.d},{path:"edit/:pool/:name",component:zn.a,data:t.g},{path:"clone/:pool/:name/:snap",component:zn.a,data:t.h},{path:"copy/:pool/:name",component:zn.a,data:t.i},{path:"copy/:pool/:name/:snap",component:zn.a,data:t.j}]},{path:"mirroring",component:rt.a,canActivate:[it.a],data:t.k},{path:"iscsi",canActivate:[it.a],data:t.l,children:[{path:"",redirectTo:"overview",pathMatch:"full"},{path:"overview",component:Su.a,data:t.m},{path:"targets",data:t.n,children:[{path:"",component:Qu.a},{path:"create",component:pe.a,data:t.e},{path:"edit/:target_iqn",component:pe.a,data:t.f}]}]}]]},[]),e["\u0275mpd"](256,e.TRANSLATIONS_FORMAT,"xlf",[])])})}}]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/8.7550b99d388b9ca165da.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/8.7550b99d388b9ca165da.js new file mode 100644 index 00000000..e0842db4 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/8.7550b99d388b9ca165da.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{nOaW:function(l,n,e){"use strict";e.r(n);var u=e("CcnG"),t=e("sne2"),o=e("gIcY"),i=e("LvDl"),a=e("VNr4"),r=e("t/Na"),s=e("Jm/i"),d=e("pL04"),c=function(){function l(l,n){this.http=l,this.i18n=n,this.apiPath="api/erasure_code_profile",this.formTooltips={k:this.i18n("Each object is split in data-chunks parts, each stored on a different OSD."),m:this.i18n("Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data."),plugins:{jerasure:{description:this.i18n("The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools."),technique:this.i18n("The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2."),packetSize:this.i18n("The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.")},lrc:{description:this.i18n("With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven."),l:this.i18n("Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set."),crushLocality:this.i18n("The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.")},isa:{description:this.i18n("The isa plugin encapsulates the ISA library. It only runs on Intel processors."),technique:this.i18n("The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.")},shec:{description:this.i18n("The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes."),c:this.i18n("The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.")}},crushRoot:this.i18n("The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default."),crushFailureDomain:this.i18n("Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host."),crushDeviceClass:this.i18n("Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map."),directory:this.i18n("Set the directory name from which the erasure code plugin is loaded.")}}return l.prototype.list=function(){return this.http.get(this.apiPath)},l.prototype.create=function(l){return this.http.post(this.apiPath,l,{observe:"response"})},l.prototype.update=function(l){return this.http.put(this.apiPath+"/"+l.name,l,{observe:"response"})},l.prototype.delete=function(l){return this.http.delete(this.apiPath+"/"+l,{observe:"response"})},l.prototype.get=function(l){return this.http.get(this.apiPath+"/"+l)},l.prototype.getInfo=function(){return this.http.get(this.apiPath+"/_info")},l.ngInjectableDef=u.defineInjectable({factory:function(){return new l(u.inject(r.c),u.inject(s.a))},token:l,providedIn:d.a}),l}(),p=e("Ekvf"),f=e("0+/T"),m=e("QFaf"),g=e("1Ni5"),h=e("PhyI"),v=e("kvvV"),b=e("Fgil"),C=e("aexS"),R=e("aXbf"),y=e("kn/O"),I=e("2EZI"),E=function(){return function(){}}(),V=function(){function l(l,n,e,t,o,i){this.formBuilder=l,this.bsModalRef=n,this.taskWrapper=e,this.ecpService=t,this.i18n=o,this.actionLabels=i,this.submitAction=new u.EventEmitter,this.requiredControls=[],this.devices=[],this.tooltips=this.ecpService.formTooltips,this.PLUGIN={LRC:"lrc",SHEC:"shec",JERASURE:"jerasure",ISA:"isa"},this.plugin=this.PLUGIN.JERASURE,this.action=this.actionLabels.CREATE,this.resource=this.i18n("EC Profile"),this.createForm(),this.setJerasureDefaults()}return l.prototype.createForm=function(){var l=this;this.form=this.formBuilder.group({name:[null,[o.A.required,o.A.pattern("[A-Za-z0-9_-]+"),g.a.custom("uniqueName",function(n){return l.names&&-1!==l.names.indexOf(n)})]],plugin:[this.PLUGIN.JERASURE,[o.A.required]],k:[1],m:[1],crushFailureDomain:["host"],crushRoot:["default"],crushDeviceClass:[""],directory:[""],technique:["reed_sol_van"],packetSize:[2048,[o.A.min(1)]],l:[1,[o.A.required,o.A.min(1)]],crushLocality:[""],c:[1,[o.A.required,o.A.min(1)]]}),this.form.get("plugin").valueChanges.subscribe(function(n){return l.onPluginChange(n)})},l.prototype.onPluginChange=function(l){this.plugin=l,l===this.PLUGIN.JERASURE?this.setJerasureDefaults():l===this.PLUGIN.LRC?this.setLrcDefaults():l===this.PLUGIN.ISA?this.setIsaDefaults():l===this.PLUGIN.SHEC&&this.setShecDefaults()},l.prototype.setNumberValidators=function(l,n){var e=[o.A.min(1)];n&&e.push(o.A.required),this.form.get(l).setValidators(e)},l.prototype.setKMValidators=function(l){var n=this;["k","m"].forEach(function(e){return n.setNumberValidators(e,l)})},l.prototype.setJerasureDefaults=function(){this.requiredControls=["k","m"],this.setDefaults({k:4,m:2}),this.setKMValidators(!0),this.techniques=["reed_sol_van","reed_sol_r6_op","cauchy_orig","cauchy_good","liberation","blaum_roth","liber8tion"]},l.prototype.setLrcDefaults=function(){this.requiredControls=["k","m","l"],this.setKMValidators(!0),this.setNumberValidators("l",!0),this.setDefaults({k:4,m:2,l:3})},l.prototype.setIsaDefaults=function(){this.requiredControls=[],this.setKMValidators(!1),this.setDefaults({k:7,m:3}),this.techniques=["reed_sol_van","cauchy"]},l.prototype.setShecDefaults=function(){this.requiredControls=[],this.setKMValidators(!1),this.setDefaults({k:4,m:3,c:2})},l.prototype.setDefaults=function(l){var n=this;Object.keys(l).forEach(function(e){n.form.get(e).pristine&&n.form.silentSet(e,l[e])})},l.prototype.ngOnInit=function(){var l=this;this.ecpService.getInfo().subscribe(function(n){var e=n.plugins,u=n.names,t=n.directory,o=n.devices;l.failureDomains=n.failure_domains,l.plugins=e,l.names=u,l.devices=o,l.form.silentSet("directory",t)})},l.prototype.createJson=function(){var l=this,n={technique:[this.PLUGIN.ISA,this.PLUGIN.JERASURE],packetSize:[this.PLUGIN.JERASURE],l:[this.PLUGIN.LRC],crushLocality:[this.PLUGIN.LRC],c:[this.PLUGIN.SHEC]},e=new E,u=this.form.getValue("plugin");return Object.keys(this.form.controls).filter(function(e){var t=n[e],o=l.form.get(e);return(t&&t.includes(u)||!t)&&(o.dirty||l.requiredControls.includes(e))&&l.form.getValue(e)}).forEach(function(n){l.extendJson(n,e)}),e},l.prototype.extendJson=function(l,n){n[{crushFailureDomain:"crush-failure-domain",crushRoot:"crush-root",crushDeviceClass:"crush-device-class",packetSize:"packetsize",crushLocality:"crush-locality"}[l]||l]=this.form.getValue(l)},l.prototype.onSubmit=function(){var l=this;if(this.form.invalid)this.form.setErrors({cdSubmitButton:!0});else{var n=this.createJson();this.taskWrapper.wrapTaskAroundCall({task:new v.a("ecp/create",{name:n.name}),call:this.ecpService.create(n)}).subscribe(void 0,function(){l.form.setErrors({cdSubmitButton:!0})},function(){l.bsModalRef.hide(),l.submitAction.emit(n)})}},l}(),T=e("DNAf"),w=e("a96k"),S=function(){return function(l){this.erasureInfo=!1,this.crushInfo=!1,this.pgs=1,this.poolTypes=["erasure","replicated"],this.applications={selected:[],available:[new w.a(!1,"cephfs",""),new w.a(!1,"rbd",""),new w.a(!1,"rgw","")],validators:[o.A.pattern("[A-Za-z0-9_]+"),o.A.maxLength(128)],messages:new T.a({empty:l("No applications added"),selectionLimit:{text:l("Applications limit reached"),tooltip:l("A pool can only have up to four applications definitions.")},customValidations:{pattern:l("Allowed characters '_a-zA-Z0-9'"),maxlength:l("Maximum length is 128 characters")},filter:l("Filter or add applications"),add:l("Add application")},l)}}}(),N=function(){function l(l,n,e,o,i,a,r,s,d,c,p,f){this.dimlessBinaryPipe=l,this.route=n,this.router=e,this.modalService=o,this.poolService=i,this.authStorageService=a,this.formatter=r,this.bsModalService=s,this.taskWrapper=d,this.ecpService=c,this.i18n=p,this.actionLabels=f,this.editing=!1,this.data=new S(this.i18n),this.externalPgChange=!1,this.current={rules:[]},this.initializeConfigData=new u.EventEmitter,this.currentConfigurationValues={},this.editing=this.router.url.startsWith("/pool/"+t.e.EDIT),this.action=this.editing?this.actionLabels.EDIT:this.actionLabels.CREATE,this.resource=this.i18n("pool"),this.authenticate(),this.createForm()}return l.prototype.authenticate=function(){this.permission=this.authStorageService.getPermissions().pool,(!this.permission.read||!this.permission.update&&this.editing||!this.permission.create&&!this.editing)&&this.router.navigate(["/404"])},l.prototype.createForm=function(){var l=this,n=new m.a({mode:new o.i("none"),algorithm:new o.i(""),minBlobSize:new o.i("",{updateOn:"blur"}),maxBlobSize:new o.i("",{updateOn:"blur"}),ratio:new o.i("",{updateOn:"blur"})});this.form=new m.a({name:new o.i("",{validators:[o.A.pattern(/^[.A-Za-z0-9_\/-]+$/),o.A.required]}),poolType:new o.i("",{validators:[o.A.required]}),crushRule:new o.i(null,{validators:[g.a.custom("tooFewOsds",function(n){return l.info&&n&&l.info.osd_count1&&n.disabled&&n.enable(),this.ecProfiles=l},l.prototype.initEditMode=function(){var l=this;this.disableForEdit(),this.routeParamsSubscribe=this.route.params.subscribe(function(n){return l.poolService.get(n.name).subscribe(function(n){l.data.pool=n,l.initEditFormData(n)})})},l.prototype.disableForEdit=function(){var l=this;["poolType","crushRule","size","erasureProfile","ecOverwrites"].forEach(function(n){return l.form.get(n).disable()})},l.prototype.initEditFormData=function(l){var n=this;this.initializeConfigData.emit({initialData:l.configuration,sourceType:h.a.pool});var e={name:l.pool_name,poolType:l.type,crushRule:this.info["crush_rules_"+l.type].find(function(n){return n.rule_name===l.crush_rule}),size:l.size,erasureProfile:this.ecProfiles.find(function(n){return n.name===l.erasure_code_profile}),pgNum:l.pg_num,ecOverwrites:l.flags_names.includes("ec_overwrites"),mode:l.options.compression_mode,algorithm:l.options.compression_algorithm,minBlobSize:this.dimlessBinaryPipe.transform(l.options.compression_min_blob_size),maxBlobSize:this.dimlessBinaryPipe.transform(l.options.compression_max_blob_size),ratio:l.options.compression_required_ratio};Object.keys(e).forEach(function(l){var u=e[l];i.isUndefined(u)||""===u||n.form.silentSet(l,u)}),this.data.pgs=this.form.getValue("pgNum"),this.data.applications.selected=l.application_metadata},l.prototype.listenToChanges=function(){this.listenToChangesDuringAddEdit(),this.editing||this.listenToChangesDuringAdd()},l.prototype.listenToChangesDuringAddEdit=function(){var l=this;this.form.get("pgNum").valueChanges.subscribe(function(n){var e=n-l.data.pgs;1===Math.abs(e)&&2!==n?l.doPgPowerJump(e):l.data.pgs=n})},l.prototype.doPgPowerJump=function(l){var n=this.calculatePgPower()+l;this.setPgs(-1===l?Math.round(n):Math.floor(n))},l.prototype.calculatePgPower=function(l){return void 0===l&&(l=this.form.getValue("pgNum")),Math.log(l)/Math.log(2)},l.prototype.setPgs=function(l){var n=Math.pow(2,l<0?0:l);this.data.pgs=n,this.form.silentSet("pgNum",n)},l.prototype.listenToChangesDuringAdd=function(){var l=this;this.form.get("poolType").valueChanges.subscribe(function(n){l.form.get("size").updateValueAndValidity(),l.rulesChange(),"replicated"===n&&l.replicatedRuleChange(),l.pgCalc()}),this.form.get("crushRule").valueChanges.subscribe(function(){"replicated"===l.form.getValue("poolType")&&l.replicatedRuleChange(),l.pgCalc()}),this.form.get("size").valueChanges.subscribe(function(){l.pgCalc()}),this.form.get("erasureProfile").valueChanges.subscribe(function(){l.pgCalc()}),this.form.get("mode").valueChanges.subscribe(function(){["minBlobSize","maxBlobSize","ratio"].forEach(function(n){l.form.get(n).updateValueAndValidity({emitEvent:!1})})}),this.form.get("minBlobSize").valueChanges.subscribe(function(){l.form.get("maxBlobSize").updateValueAndValidity({emitEvent:!1})}),this.form.get("maxBlobSize").valueChanges.subscribe(function(){l.form.get("minBlobSize").updateValueAndValidity({emitEvent:!1})})},l.prototype.rulesChange=function(){var l=this.form.getValue("poolType");if(l&&this.info){var n=this.info["crush_rules_"+l]||[],e=this.form.get("crushRule");1===n.length?(e.setValue(n[0]),e.disable()):(e.setValue(null),e.enable()),this.current.rules=n}else this.current.rules=[]},l.prototype.replicatedRuleChange=function(){if("replicated"===this.form.getValue("poolType")){var l=this.form.get("size"),n=this.form.getValue("size")||3,e=this.getMinSize(),u=this.getMaxSize();nu&&(n=u),n!==l.value&&this.form.silentSet("size",n)}},l.prototype.getMinSize=function(){if(this.info&&!(this.info.osd_count<1)){var l=this.form.getValue("crushRule");return l?l.min_size:1}},l.prototype.getMaxSize=function(){if(this.info&&!(this.info.osd_count<1)){var l=this.info.osd_count;if(this.form.getValue("crushRule")){var n=this.form.get("crushRule").value.max_size;if(n0)return l/e},l.prototype.erasurePgCalc=function(l){var n=this.form.get("erasureProfile"),e=n.value;if((n.valid||n.disabled)&&e)return l/(e.k+e.m)},l.prototype.alignPgs=function(l){void 0===l&&(l=this.form.getValue("pgNum")),this.setPgs(Math.round(this.calculatePgPower(l<1?1:l)))},l.prototype.setComplexValidators=function(){var l=this;this.editing?this.form.get("name").setValidators([this.form.get("name").validator,g.a.custom("uniqueName",function(n){return l.data.pool&&l.info&&-1!==l.info.pool_names.indexOf(n)&&l.info.pool_names.indexOf(n)!==l.info.pool_names.indexOf(l.data.pool.pool_name)})]):(g.a.validateIf(this.form.get("size"),function(){return"replicated"===l.form.get("poolType").value},[g.a.custom("min",function(n){return l.form.getValue("size")&&n=n)},l.prototype.hasCompressionEnabled=function(){return this.form.getValue("mode")&&"none"!==this.form.get("mode").value.toLowerCase()},l.prototype.describeCrushStep=function(l){return[l.op.replace("_"," "),l.item_name||"",l.type?l.num+" type "+l.type:""].join(" ")},l.prototype.addErasureCodeProfile=function(){var l=this;this.modalSubscription=this.modalService.onHide.subscribe(function(){return l.reloadECPs()}),this.bsModalService.show(V)},l.prototype.reloadECPs=function(){var l=this;this.ecpService.list().subscribe(function(n){return l.initEcp(n)}),this.modalSubscription.unsubscribe()},l.prototype.deleteErasureCodeProfile=function(){var l=this,n=this.form.getValue("erasureProfile");if(n){var e=n.name;this.modalSubscription=this.modalService.onHide.subscribe(function(){return l.reloadECPs()}),this.modalService.show(f.a,{initialState:{itemDescription:this.i18n("erasure code profile"),itemNames:[e],submitActionObservable:function(){return l.taskWrapper.wrapTaskAroundCall({task:new v.a("ecp/delete",{name:e}),call:l.ecpService.delete(e)})}}})}},l.prototype.submit=function(){var l=this;if(this.form.invalid)this.form.setErrors({cdSubmitButton:!0});else{var n={pool:this.form.getValue("name")};this.assignFormFields(n,[{externalFieldName:"pool_type",formControlName:"poolType"},{externalFieldName:"pg_num",formControlName:"pgNum",editable:!0},"replicated"===this.form.getValue("poolType")?{externalFieldName:"size",formControlName:"size"}:{externalFieldName:"erasure_code_profile",formControlName:"erasureProfile",attr:"name"},{externalFieldName:"rule_name",formControlName:"crushRule",attr:"rule_name"}]),this.info.is_all_bluestore&&(this.assignFormField(n,{externalFieldName:"flags",formControlName:"ecOverwrites",replaceFn:function(){return["ec_overwrites"]}}),"none"!==this.form.getValue("mode")?this.assignFormFields(n,[{externalFieldName:"compression_mode",formControlName:"mode",editable:!0,replaceFn:function(n){return l.hasCompressionEnabled()&&n}},{externalFieldName:"compression_algorithm",formControlName:"algorithm",editable:!0},{externalFieldName:"compression_min_blob_size",formControlName:"minBlobSize",replaceFn:this.formatter.toBytes,editable:!0,resetValue:0},{externalFieldName:"compression_max_blob_size",formControlName:"maxBlobSize",replaceFn:this.formatter.toBytes,editable:!0,resetValue:0},{externalFieldName:"compression_required_ratio",formControlName:"ratio",editable:!0,resetValue:0}]):this.editing&&this.assignFormFields(n,[{externalFieldName:"compression_mode",formControlName:"mode",editable:!0,replaceFn:function(){return"unset"}},{externalFieldName:"srcpool",formControlName:"name",editable:!0,replaceFn:function(){return l.data.pool.pool_name}}]));var e=this.data.applications.selected;(e.length>0||this.editing)&&(n.application_metadata=e),"replicated"!==this.form.get("poolType").value||i.isEmpty(this.currentConfigurationValues)||(n.configuration=this.currentConfigurationValues),this.triggerApiTask(n)}},l.prototype.assignFormFields=function(l,n){var e=this;n.forEach(function(n){return e.assignFormField(l,n)})},l.prototype.assignFormField=function(l,n){var e=n.externalFieldName,u=n.formControlName,t=n.attr,o=n.replaceFn,a=n.editable,r=n.resetValue;if(!this.editing||a&&!this.form.get(u).pristine){var s=this.form.getValue(u),d=o?o(s):t?i.get(s,t):s;if(!s||!d){if(!a||i.isUndefined(r))return;d=r}l[e]=d}},l.prototype.triggerApiTask=function(l){var n=this;this.taskWrapper.wrapTaskAroundCall({task:new v.a("pool/"+(this.editing?t.e.EDIT:t.e.CREATE),{pool_name:l.hasOwnProperty("srcpool")?l.srcpool:l.pool}),call:this.poolService[this.editing?t.e.UPDATE:t.e.CREATE](l)}).subscribe(void 0,function(l){i.isObject(l.error)&&"34"===l.error.code&&n.form.get("pgNum").setErrors({34:!0}),n.form.setErrors({cdSubmitButton:!0})},function(){return n.router.navigate(["/pool"])})},l.prototype.appSelection=function(){this.form.updateValueAndValidity({emitEvent:!1,onlySelf:!0})},l}(),_=e("MuvH"),D=e("uIqm"),P=e("x38r"),k=e("yJti"),z=e("vCyI"),x=e("o4+5"),F=e("VTlA"),q=e("EgGo"),A=e("d+Og"),O=function(){return function(l){this.pool_name=l}}(),L=new q.a("pool"),j=function(){function l(l,n,e,u,t,o,a,r,s,d,c){var p=this;this.poolService=l,this.taskWrapper=n,this.authStorageService=e,this.taskListService=u,this.modalService=t,this.i18n=o,this.pgCategoryService=a,this.dimlessPipe=r,this.urlBuilder=s,this.configurationService=d,this.actionLabels=c,this.pools=[],this.selection=new z.a,this.executingTasks=[],this.selectionCacheTiers=[],this.monAllowPoolDelete=!1,this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{permission:"create",icon:"fa-plus",routerLink:function(){return p.urlBuilder.getCreate()},name:this.actionLabels.CREATE},{permission:"update",icon:"fa-pencil",routerLink:function(){return p.urlBuilder.getEdit(encodeURIComponent(p.selection.first().pool_name))},name:this.actionLabels.EDIT},{permission:"delete",icon:"fa-trash-o",click:function(){return p.deletePoolModal()},name:this.actionLabels.DELETE,disable:function(){return!p.selection.first()||!p.monAllowPoolDelete},disableDesc:function(){return p.getDisableDesc()}}],this.permissions.configOpt.read&&this.configurationService.get("mon_allow_pool_delete").subscribe(function(l){if(i.has(l,"value")){var n=i.find(l.value,function(l){return"mon"===l.section})||{value:!1};p.monAllowPoolDelete="true"===n.value}})}return l.prototype.ngOnInit=function(){var l=this,n=function(l,n,e){return i.get(n,l)>i.get(e,l)?1:-1};this.columns=[{prop:"pool_name",name:this.i18n("Name"),flexGrow:4,cellTransformation:P.a.executing},{prop:"type",name:this.i18n("Type"),flexGrow:2},{prop:"application_metadata",name:this.i18n("Applications"),flexGrow:3},{prop:"pg_status",name:this.i18n("PG Status"),flexGrow:3,cellClass:function(n){return l.getPgStatusCellClass(n.row,n.column,n.value)}},{prop:"size",name:this.i18n("Replica Size"),flexGrow:2,cellClass:"text-right"},{prop:"last_change",name:this.i18n("Last Change"),flexGrow:2,cellClass:"text-right"},{prop:"erasure_code_profile",name:this.i18n("Erasure Coded Profile"),flexGrow:2},{prop:"crush_rule",name:this.i18n("Crush Ruleset"),flexGrow:3},{name:this.i18n("Usage"),prop:"usage",cellTemplate:this.poolUsageTpl,flexGrow:3},{prop:"stats.rd_bytes.rates",name:this.i18n("Read bytes"),comparator:function(l,e,u,t){return n("stats.rd_bytes.latest",u,t)},cellTransformation:P.a.sparkline,flexGrow:3},{prop:"stats.wr_bytes.rates",name:this.i18n("Write bytes"),comparator:function(l,e,u,t){return n("stats.wr_bytes.latest",u,t)},cellTransformation:P.a.sparkline,flexGrow:3},{prop:"stats.rd.rate",name:this.i18n("Read ops"),flexGrow:1,pipe:this.dimlessPipe,cellTransformation:P.a.perSecond},{prop:"stats.wr.rate",name:this.i18n("Write ops"),flexGrow:1,pipe:this.dimlessPipe,cellTransformation:P.a.perSecond}],this.taskListService.init(function(){return l.poolService.getList()},void 0,function(n){return l.pools=l.transformPoolsData(n)},function(){l.table.reset(),l.viewCacheStatusList=[{status:k.a.ValueException}]},function(l){return l.name.startsWith("pool/")},function(l,n){return n.metadata.pool_name===l.pool_name},{default:function(l){return new O(l.metadata.pool_name)}})},l.prototype.updateSelection=function(l){this.selection=l,this.getSelectionTiers()},l.prototype.deletePoolModal=function(){var l=this,n=this.selection.first().pool_name;this.modalRef=this.modalService.show(f.a,{initialState:{itemDescription:"Pool",itemNames:[n],submitActionObservable:function(){return l.taskWrapper.wrapTaskAroundCall({task:new v.a("pool/"+t.e.DELETE,{pool_name:n}),call:l.poolService.delete(n)})}}})},l.prototype.getPgStatusCellClass=function(l,n,e){var u;return(u={"text-right":!0})["pg-"+this.pgCategoryService.getTypeByStates(e)]=!0,u},l.prototype.transformPoolsData=function(l){var n=this,e=["bytes_used","max_avail","avail_raw","percent_used","rd_bytes","wr_bytes","rd","wr"],u={latest:0,rate:0,rates:[]};return i.forEach(l,function(l){l.pg_status=n.transformPgStatus(l.pg_status);var t={};i.forEach(e,function(n){t[n]=l.stats&&l.stats[n]?l.stats[n]:u}),l.stats=t,l.usage=t.percent_used.latest,l.cdExecuting||l.pg_num+l.pg_placement_num===l.pg_num_target+l.pg_placement_num_target||(l.cdExecuting="Updating"),["rd_bytes","wr_bytes"].forEach(function(n){l.stats[n].rates=l.stats[n].rates.map(function(l){return l[1]})}),l.cdIsBinary=!0}),l},l.prototype.transformPgStatus=function(l){var n=[];return i.forEach(l,function(l,e){n.push(l+" "+e)}),n.join(", ")},l.prototype.getSelectionTiers=function(){var l=this.selection.hasSingleSelection?this.selection.first().tiers:[];this.selectionCacheTiers=this.pools.filter(function(n){return l.includes(n.pool)})},l.prototype.getDisableDesc=function(){if(!this.monAllowPoolDelete)return this.i18n("Pool deletion is disabled by the mon_allow_pool_delete configuration setting.")},l}(),M=function(){return function(){}}(),U={breadcrumbs:t.a.CREATE},B={breadcrumbs:t.a.EDIT},G=function(){return function(){}}(),K=e("ES0t"),$=e("MdoF"),J=e("Xg1U"),H=e("z5nN"),W=e("iutN"),Z=e("EEJc"),Y=e("PEr+"),X=e("a40w"),Q=e("pMnS"),ll=e("RIVN"),nl=e("nP0W"),el=e("VBM6"),ul=e("atuK"),tl=e("JIi+"),ol=e("Ur3J"),il=e("I4Qz"),al=e("0rTx"),rl=e("lz+O"),sl=e("u2XS"),dl=e("nhAp"),cl=e("l7Jr"),pl=e("bUo2"),fl=e("Ip0R"),ml=e("4HWh"),gl=e("p4Cf"),hl=e("ANnk"),vl=e("f/UV"),bl=e("8xTl"),Cl=e("IZUe"),Rl=e("gp3X"),yl=e("sb0X"),Il=e("KVJa"),El=e("Z21x"),Vl=e("DQlY"),Tl=u["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function wl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function Sl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["The name can only consist of alphanumeric characters, dashes and underscores."]))],null,null)}function Nl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["The chosen erasure code profile name is already in use."]))],null,null)}function _l(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,""),l(n,2,0,"")},null)}function Dl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function Pl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function kl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function zl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function xl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Must be equal to or greater than 2."]))],null,null)}function Fl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function ql(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function Al(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Must be equal to or greater than 1."]))],null,null)}function Ol(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Must be equal to or greater than 1."]))],null,null)}function Ll(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](1,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](2,{"has-error":0}),(l()(),u["\u0275eld"](3,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","c"]],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Durability estimator (c)"])),(l()(),u["\u0275eld"](6,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](7,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](8,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](9,0,null,null,7,"input",[["class","form-control"],["formControlName","c"],["id","c"],["name","c"],["placeholder","Coding chunks..."],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,11)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,11).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,11)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,11)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,12).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,12).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,12).onTouched()&&t),t},null,null)),u["\u0275did"](10,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](11,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](12,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](14,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](16,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Ol)),u["\u0275did"](18,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,2,0,e.form.showError("c",u["\u0275nov"](n.parent,12)));l(n,1,0,"form-group",t),l(n,7,0,e.tooltips.plugins.shec.c),l(n,14,0,"c"),l(n,18,0,e.form.showError("c",u["\u0275nov"](n.parent,12),"min"))},function(l,n){l(n,9,0,u["\u0275nov"](n,16).ngClassUntouched,u["\u0275nov"](n,16).ngClassTouched,u["\u0275nov"](n,16).ngClassPristine,u["\u0275nov"](n,16).ngClassDirty,u["\u0275nov"](n,16).ngClassValid,u["\u0275nov"](n,16).ngClassInvalid,u["\u0275nov"](n,16).ngClassPending)})}function jl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function Ml(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Must be equal to or greater than 1."]))],null,null)}function Ul(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,21,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](1,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](2,{"has-error":0}),(l()(),u["\u0275eld"](3,0,null,null,5,"label",[["class","control-label col-sm-3"],["for","l"]],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Locality (l)"])),(l()(),u["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](8,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](9,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](10,0,null,null,7,"input",[["class","form-control"],["formControlName","l"],["id","l"],["name","l"],["placeholder","Coding chunks..."],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,12)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,12).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,12)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,12)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,13).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,13).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,13).onTouched()&&t),t},null,null)),u["\u0275did"](11,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](12,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](13,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](15,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](17,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,jl)),u["\u0275did"](19,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Ml)),u["\u0275did"](21,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,2,0,e.form.showError("l",u["\u0275nov"](n.parent,12)));l(n,1,0,"form-group",t),l(n,8,0,e.tooltips.plugins.lrc.l),l(n,15,0,"l"),l(n,19,0,e.form.showError("l",u["\u0275nov"](n.parent,12),"required")),l(n,21,0,e.form.showError("l",u["\u0275nov"](n.parent,12),"min"))},function(l,n){l(n,10,0,u["\u0275nov"](n,17).ngClassUntouched,u["\u0275nov"](n,17).ngClassTouched,u["\u0275nov"](n,17).ngClassPristine,u["\u0275nov"](n,17).ngClassDirty,u["\u0275nov"](n,17).ngClassValid,u["\u0275nov"](n,17).ngClassInvalid,u["\u0275nov"](n,17).ngClassPending)})}function Bl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,""),l(n,2,0,"")},null)}function Gl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function Kl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,""),l(n,2,0,"")},null)}function $l(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["None"]))],function(l,n){l(n,1,0,""),l(n,2,0,"")},null)}function Jl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function Hl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","crushLocality"]],null,null,null,null,null)),(l()(),u["\u0275eld"](2,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Crush Locality"])),(l()(),u["\u0275eld"](4,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](5,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](6,0,null,null,13,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,12,"select",[["class","form-control"],["formControlName","crushLocality"],["id","crushLocality"],["name","crushLocality"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,9).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,9).onTouched()&&t),t},null,null)),u["\u0275did"](8,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](9,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](11,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](13,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Kl)),u["\u0275did"](15,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,$l)),u["\u0275did"](17,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Jl)),u["\u0275did"](19,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component;l(n,5,0,e.tooltips.plugins.lrc.crushLocality),l(n,11,0,"crushLocality"),l(n,15,0,!e.failureDomains),l(n,17,0,e.failureDomains&&e.failureDomains.length>0),l(n,19,0,e.failureDomains)},function(l,n){l(n,7,0,u["\u0275nov"](n,13).ngClassUntouched,u["\u0275nov"](n,13).ngClassTouched,u["\u0275nov"](n,13).ngClassPristine,u["\u0275nov"](n,13).ngClassDirty,u["\u0275nov"](n,13).ngClassValid,u["\u0275nov"](n,13).ngClassInvalid,u["\u0275nov"](n,13).ngClassPending)})}function Wl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function Zl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,15,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","technique"]],null,null,null,null,null)),(l()(),u["\u0275eld"](2,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Technique"])),(l()(),u["\u0275eld"](4,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](5,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](6,0,null,null,9,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,8,"select",[["class","form-control"],["formControlName","technique"],["id","technique"],["name","technique"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,9).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,9).onTouched()&&t),t},null,null)),u["\u0275did"](8,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](9,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](11,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](13,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Wl)),u["\u0275did"](15,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component;l(n,5,0,e.tooltips.plugins[e.plugin].technique),l(n,11,0,"technique"),l(n,15,0,e.techniques)},function(l,n){l(n,7,0,u["\u0275nov"](n,13).ngClassUntouched,u["\u0275nov"](n,13).ngClassTouched,u["\u0275nov"](n,13).ngClassPristine,u["\u0275nov"](n,13).ngClassDirty,u["\u0275nov"](n,13).ngClassValid,u["\u0275nov"](n,13).ngClassInvalid,u["\u0275nov"](n,13).ngClassPending)})}function Yl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Must be equal to or greater than 1."]))],null,null)}function Xl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](1,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](2,{"has-error":0}),(l()(),u["\u0275eld"](3,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","packetSize"]],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Packetsize"])),(l()(),u["\u0275eld"](6,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](7,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](8,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](9,0,null,null,7,"input",[["class","form-control"],["formControlName","packetSize"],["id","packetSize"],["name","packetSize"],["placeholder","Packetsize..."],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,11)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,11).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,11)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,11)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,12).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,12).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,12).onTouched()&&t),t},null,null)),u["\u0275did"](10,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](11,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](12,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](14,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](16,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Yl)),u["\u0275did"](18,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,2,0,e.form.showError("packetSize",u["\u0275nov"](n.parent,12)));l(n,1,0,"form-group",t),l(n,7,0,e.tooltips.plugins.jerasure.packetSize),l(n,14,0,"packetSize"),l(n,18,0,e.form.showError("packetSize",u["\u0275nov"](n.parent,12),"min"))},function(l,n){l(n,9,0,u["\u0275nov"](n,16).ngClassUntouched,u["\u0275nov"](n,16).ngClassTouched,u["\u0275nov"](n,16).ngClassPristine,u["\u0275nov"](n,16).ngClassDirty,u["\u0275nov"](n,16).ngClassValid,u["\u0275nov"](n,16).ngClassInvalid,u["\u0275nov"](n,16).ngClassPending)})}function Ql(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function ln(l){return u["\u0275vid"](0,[u["\u0275pid"](0,fl.TitleCasePipe,[]),u["\u0275pid"](0,bl.a,[]),(l()(),u["\u0275eld"](2,0,null,null,7,"div",[["class","modal-header"]],null,null,null,null,null)),(l()(),u["\u0275eld"](3,0,null,null,3,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),(l()(),u["\u0275ted"](4,null,[""," ",""])),u["\u0275ppd"](5,1),u["\u0275ppd"](6,1),(l()(),u["\u0275eld"](7,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==l.component.bsModalRef.hide()&&u),u},null,null)),(l()(),u["\u0275eld"](8,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["\xd7"])),(l()(),u["\u0275eld"](10,0,null,null,181,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var t=!0;return"submit"===n&&(t=!1!==u["\u0275nov"](l,12).onSubmit(e)&&t),"reset"===n&&(t=!1!==u["\u0275nov"](l,12).onReset()&&t),t},null,null)),u["\u0275did"](11,16384,null,0,o.D,[],null,null),u["\u0275did"](12,540672,[["frm",4]],0,o.l,[[8,null],[8,null]],{form:[0,"form"]},null),u["\u0275prd"](2048,null,o.d,null,[o.l]),u["\u0275did"](14,16384,null,0,o.s,[[4,o.d]],null,null),(l()(),u["\u0275eld"](15,0,null,null,168,"div",[["class","modal-body"]],null,null,null,null,null)),(l()(),u["\u0275eld"](16,0,null,null,21,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](17,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](18,{"has-error":0}),(l()(),u["\u0275eld"](19,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),u["\u0275eld"](20,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Name"])),(l()(),u["\u0275eld"](22,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),u["\u0275eld"](23,0,null,null,14,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](24,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","name"],["id","name"],["name","name"],["placeholder","Name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,27)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,27).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,27)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,27)._compositionEnd(e.target.value)&&t),t},null,null)),u["\u0275did"](25,4210688,null,0,Cl.a,[u.ElementRef],null,null),u["\u0275did"](26,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](27,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),u["\u0275did"](29,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](31,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,wl)),u["\u0275did"](33,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Sl)),u["\u0275did"](35,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Nl)),u["\u0275did"](37,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](38,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](39,0,null,null,5,"label",[["class","control-label col-sm-3"],["for","plugin"]],null,null,null,null,null)),(l()(),u["\u0275eld"](40,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Plugin"])),(l()(),u["\u0275eld"](42,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),u["\u0275eld"](43,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](44,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](45,0,null,null,13,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](46,0,null,null,10,"select",[["class","form-control"],["formControlName","plugin"],["id","plugin"],["name","plugin"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,48).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,48).onTouched()&&t),t},null,null)),u["\u0275did"](47,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](48,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](50,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](52,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,_l)),u["\u0275did"](54,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Dl)),u["\u0275did"](56,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Pl)),u["\u0275did"](58,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](59,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](60,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](61,{"has-error":0}),(l()(),u["\u0275eld"](62,0,null,null,6,"label",[["class","control-label col-sm-3"],["for","k"]],null,null,null,null,null)),(l()(),u["\u0275eld"](63,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Data chunks (k)"])),(l()(),u["\u0275and"](16777216,null,null,1,null,kl)),u["\u0275did"](66,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](67,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](68,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](69,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](70,0,null,null,7,"input",[["class","form-control"],["formControlName","k"],["id","k"],["name","k"],["ng-model","$ctrl.erasureCodeProfile.k"],["placeholder","Data chunks..."],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,72)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,72).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,72)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,72)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,73).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,73).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,73).onTouched()&&t),t},null,null)),u["\u0275did"](71,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](72,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](73,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](75,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](77,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,zl)),u["\u0275did"](79,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,xl)),u["\u0275did"](81,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](82,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](83,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](84,{"has-error":0}),(l()(),u["\u0275eld"](85,0,null,null,6,"label",[["class","control-label col-sm-3"],["for","m"]],null,null,null,null,null)),(l()(),u["\u0275eld"](86,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Coding chunks (m)"])),(l()(),u["\u0275and"](16777216,null,null,1,null,Fl)),u["\u0275did"](89,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](90,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](91,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](92,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](93,0,null,null,7,"input",[["class","form-control"],["formControlName","m"],["id","m"],["name","m"],["placeholder","Coding chunks..."],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,95)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,95).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,95)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,95)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,96).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,96).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,96).onTouched()&&t),t},null,null)),u["\u0275did"](94,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](95,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](96,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](98,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](100,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,ql)),u["\u0275did"](102,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Al)),u["\u0275did"](104,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Ll)),u["\u0275did"](106,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Ul)),u["\u0275did"](108,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](109,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](110,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","crushFailureDomain"]],null,null,null,null,null)),(l()(),u["\u0275eld"](111,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Crush failure domain"])),(l()(),u["\u0275eld"](113,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](114,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](115,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](116,0,null,null,10,"select",[["class","form-control"],["formControlName","crushFailureDomain"],["id","crushFailureDomain"],["name","crushFailureDomain"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,118).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,118).onTouched()&&t),t},null,null)),u["\u0275did"](117,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](118,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](120,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](122,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Bl)),u["\u0275did"](124,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Gl)),u["\u0275did"](126,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Hl)),u["\u0275did"](128,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,2,null,Zl)),u["\u0275did"](130,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),u["\u0275pad"](131,2),(l()(),u["\u0275and"](16777216,null,null,1,null,Xl)),u["\u0275did"](133,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](134,0,null,null,15,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](135,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](136,{"has-error":0}),(l()(),u["\u0275eld"](137,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","crushRoot"]],null,null,null,null,null)),(l()(),u["\u0275eld"](138,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Crush root"])),(l()(),u["\u0275eld"](140,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](141,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](142,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](143,0,null,null,6,"input",[["class","form-control"],["formControlName","crushRoot"],["id","crushRoot"],["name","crushRoot"],["placeholder","root..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,145)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,145).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,145)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,145)._compositionEnd(e.target.value)&&t),t},null,null)),u["\u0275did"](144,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](145,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),u["\u0275did"](147,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](149,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275eld"](150,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](151,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","crushDeviceClass"]],null,null,null,null,null)),(l()(),u["\u0275eld"](152,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Crush device class"])),(l()(),u["\u0275eld"](154,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](155,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](156,0,null,null,13,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](157,0,null,null,12,"select",[["class","form-control"],["formControlName","crushDeviceClass"],["id","crushDeviceClass"],["name","crushDeviceClass"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,159).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,159).onTouched()&&t),t},null,null)),u["\u0275did"](158,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](159,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](161,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](163,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275eld"](164,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](165,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](166,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["any"])),(l()(),u["\u0275and"](16777216,null,null,1,null,Ql)),u["\u0275did"](169,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275eld"](170,0,null,null,13,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](171,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","directory"]],null,null,null,null,null)),(l()(),u["\u0275eld"](172,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Directory"])),(l()(),u["\u0275eld"](174,0,null,null,1,"cd-helper",[],null,null,null,ml.b,ml.a)),u["\u0275did"](175,49152,null,0,gl.a,[],{html:[0,"html"]},null),(l()(),u["\u0275eld"](176,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](177,0,null,null,6,"input",[["class","form-control"],["formControlName","directory"],["id","directory"],["name","directory"],["placeholder","Path..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,179)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,179).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,179)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,179)._compositionEnd(e.target.value)&&t),t},null,null)),u["\u0275did"](178,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](179,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),u["\u0275did"](181,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](183,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275eld"](184,0,null,null,7,"div",[["class","modal-footer"]],null,null,null,null,null)),(l()(),u["\u0275eld"](185,0,null,null,4,"cd-submit-button",[],null,[[null,"submitAction"]],function(l,n,e){var u=!0;return"submitAction"===n&&(u=!1!==l.component.onSubmit()&&u),u},Rl.b,Rl.a)),u["\u0275did"](186,114688,null,0,yl.a,[u.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(l()(),u["\u0275ted"](187,0,[""," ",""])),u["\u0275ppd"](188,1),u["\u0275ppd"](189,1),(l()(),u["\u0275eld"](190,0,null,null,1,"cd-back-button",[],null,null,null,Il.b,Il.a)),u["\u0275did"](191,49152,null,0,El.a,[fl.Location,t.b],{back:[0,"back"]},null)],function(l,n){var e=n.component;l(n,12,0,e.form);var t=l(n,18,0,e.form.showError("name",u["\u0275nov"](n,12)));l(n,17,0,"form-group",t),l(n,29,0,"name"),l(n,33,0,e.form.showError("name",u["\u0275nov"](n,12),"required")),l(n,35,0,e.form.showError("name",u["\u0275nov"](n,12),"pattern")),l(n,37,0,e.form.showError("name",u["\u0275nov"](n,12),"uniqueName")),l(n,44,0,e.tooltips.plugins[e.plugin].description),l(n,50,0,"plugin"),l(n,54,0,!e.plugins),l(n,56,0,e.plugins),l(n,58,0,e.form.showError("name",u["\u0275nov"](n,12),"required"));var o=l(n,61,0,e.form.showError("k",u["\u0275nov"](n,12)));l(n,60,0,"form-group",o),l(n,66,0,e.requiredControls.includes("k")),l(n,68,0,e.tooltips.k),l(n,75,0,"k"),l(n,79,0,e.form.showError("k",u["\u0275nov"](n,12),"required")),l(n,81,0,e.form.showError("k",u["\u0275nov"](n,12),"min"));var i=l(n,84,0,e.form.showError("m",u["\u0275nov"](n,12)));l(n,83,0,"form-group",i),l(n,89,0,e.requiredControls.includes("m")),l(n,91,0,e.tooltips.m),l(n,98,0,"m"),l(n,102,0,e.form.showError("m",u["\u0275nov"](n,12),"required")),l(n,104,0,e.form.showError("m",u["\u0275nov"](n,12),"min")),l(n,106,0,"shec"===e.plugin),l(n,108,0,e.plugin===e.PLUGIN.LRC),l(n,114,0,e.tooltips.crushFailureDomain),l(n,120,0,"crushFailureDomain"),l(n,124,0,!e.failureDomains),l(n,126,0,e.failureDomains),l(n,128,0,e.plugin===e.PLUGIN.LRC);var a=l(n,131,0,e.PLUGIN.JERASURE,e.PLUGIN.ISA).includes(e.plugin);l(n,130,0,a),l(n,133,0,e.plugin===e.PLUGIN.JERASURE);var r=l(n,136,0,e.form.showError("crushRoot",u["\u0275nov"](n,12)));l(n,135,0,"form-group",r),l(n,141,0,e.tooltips.crushRoot),l(n,147,0,"crushRoot"),l(n,155,0,e.tooltips.crushDeviceClass),l(n,161,0,"crushDeviceClass"),l(n,165,0,""),l(n,166,0,""),l(n,169,0,e.devices),l(n,175,0,e.tooltips.directory),l(n,181,0,"directory"),l(n,186,0,u["\u0275nov"](n,12)),l(n,191,0,e.bsModalRef.hide)},function(l,n){var e=n.component,t=u["\u0275unv"](n,4,0,l(n,5,0,u["\u0275nov"](n,0),e.action)),o=u["\u0275unv"](n,4,1,l(n,6,0,u["\u0275nov"](n,1),e.resource));l(n,4,0,t,o),l(n,10,0,u["\u0275nov"](n,14).ngClassUntouched,u["\u0275nov"](n,14).ngClassTouched,u["\u0275nov"](n,14).ngClassPristine,u["\u0275nov"](n,14).ngClassDirty,u["\u0275nov"](n,14).ngClassValid,u["\u0275nov"](n,14).ngClassInvalid,u["\u0275nov"](n,14).ngClassPending),l(n,24,0,u["\u0275nov"](n,31).ngClassUntouched,u["\u0275nov"](n,31).ngClassTouched,u["\u0275nov"](n,31).ngClassPristine,u["\u0275nov"](n,31).ngClassDirty,u["\u0275nov"](n,31).ngClassValid,u["\u0275nov"](n,31).ngClassInvalid,u["\u0275nov"](n,31).ngClassPending),l(n,46,0,u["\u0275nov"](n,52).ngClassUntouched,u["\u0275nov"](n,52).ngClassTouched,u["\u0275nov"](n,52).ngClassPristine,u["\u0275nov"](n,52).ngClassDirty,u["\u0275nov"](n,52).ngClassValid,u["\u0275nov"](n,52).ngClassInvalid,u["\u0275nov"](n,52).ngClassPending),l(n,70,0,u["\u0275nov"](n,77).ngClassUntouched,u["\u0275nov"](n,77).ngClassTouched,u["\u0275nov"](n,77).ngClassPristine,u["\u0275nov"](n,77).ngClassDirty,u["\u0275nov"](n,77).ngClassValid,u["\u0275nov"](n,77).ngClassInvalid,u["\u0275nov"](n,77).ngClassPending),l(n,93,0,u["\u0275nov"](n,100).ngClassUntouched,u["\u0275nov"](n,100).ngClassTouched,u["\u0275nov"](n,100).ngClassPristine,u["\u0275nov"](n,100).ngClassDirty,u["\u0275nov"](n,100).ngClassValid,u["\u0275nov"](n,100).ngClassInvalid,u["\u0275nov"](n,100).ngClassPending),l(n,116,0,u["\u0275nov"](n,122).ngClassUntouched,u["\u0275nov"](n,122).ngClassTouched,u["\u0275nov"](n,122).ngClassPristine,u["\u0275nov"](n,122).ngClassDirty,u["\u0275nov"](n,122).ngClassValid,u["\u0275nov"](n,122).ngClassInvalid,u["\u0275nov"](n,122).ngClassPending),l(n,143,0,u["\u0275nov"](n,149).ngClassUntouched,u["\u0275nov"](n,149).ngClassTouched,u["\u0275nov"](n,149).ngClassPristine,u["\u0275nov"](n,149).ngClassDirty,u["\u0275nov"](n,149).ngClassValid,u["\u0275nov"](n,149).ngClassInvalid,u["\u0275nov"](n,149).ngClassPending),l(n,157,0,u["\u0275nov"](n,163).ngClassUntouched,u["\u0275nov"](n,163).ngClassTouched,u["\u0275nov"](n,163).ngClassPristine,u["\u0275nov"](n,163).ngClassDirty,u["\u0275nov"](n,163).ngClassValid,u["\u0275nov"](n,163).ngClassInvalid,u["\u0275nov"](n,163).ngClassPending),l(n,177,0,u["\u0275nov"](n,183).ngClassUntouched,u["\u0275nov"](n,183).ngClassTouched,u["\u0275nov"](n,183).ngClassPristine,u["\u0275nov"](n,183).ngClassDirty,u["\u0275nov"](n,183).ngClassValid,u["\u0275nov"](n,183).ngClassInvalid,u["\u0275nov"](n,183).ngClassPending);var i=u["\u0275unv"](n,187,0,l(n,188,0,u["\u0275nov"](n,0),e.action)),a=u["\u0275unv"](n,187,1,l(n,189,0,u["\u0275nov"](n,1),e.resource));l(n,187,0,i,a)})}function nn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"cd-erasure-code-profile-form",[],null,null,null,ln,Tl)),u["\u0275did"](1,114688,null,0,V,[I.a,Vl.a,y.a,c,s.a,t.b],null,null)],function(l,n){l(n,1,0)},null)}var en=u["\u0275ccf"]("cd-erasure-code-profile-form",V,nn,{},{submitAction:"submitAction"},[]),un=e("iExv"),tn=e("85J/"),on=e("+0ag"),an=e("IzCI"),rn=e("Dwqy"),sn=e("uYzU"),dn=e("uhwM"),cn=e("E2fk"),pn=e("a0VL"),fn=e("nSDx"),mn=e("SB+Q"),gn=e("TYzs"),hn=e("BQkM"),vn=e("dEH0"),bn=e("G1/K"),Cn=e("TJUb"),Rn=e("lTVp"),yn=e("OZfm"),In=e("NJnL"),En=e("lqqz"),Vn=e("eajB"),Tn=e("FO+L"),wn=e("ZYjt"),Sn=e("nhM1"),Nn=e("BARL"),_n=e("xtZt"),Dn=e("Avrn"),Pn=e("ZYCi"),kn=e("urB8"),zn=e("JZ5S"),xn=e("Tff5"),Fn=e("YAQW"),qn=e("Da1D"),An=e("ARl4"),On=e("kJI8"),Ln=e("9Xeq"),jn=e("xdbM"),Mn=e("yGOH"),Un=e("V/fk"),Bn=e("F8xH"),Gn=e("ChqD"),Kn=e("PCNd"),$n=e("STEd"),Jn=e("kccj"),Hn=e("k/xb"),Wn=e("C6Ij"),Zn=e("AWcq"),Yn=e("xSw7"),Xn=e("GgAd"),Qn=e("a278"),le=e("insk"),ne=e("mSOc"),ee=e("20UP"),ue=e("pKUh"),te=e("25BL"),oe=e("NUGo"),ie=e("S7zO"),ae=e("EFGL"),re=e("aAWM"),se=e("o8EM"),de=e("sLuX"),ce=e("FSuO"),pe=(e("jKX/"),function(){function l(l,n){this.i18n=l,this.poolService=n,this.cacheTierColumns=[],this.cacheTierColumns=[{prop:"pool_name",name:this.i18n("Name"),flexGrow:3},{prop:"cache_mode",name:this.i18n("Cache Mode"),flexGrow:2},{prop:"cache_min_evict_age",name:this.i18n("Min Evict Age"),flexGrow:2},{prop:"cache_min_flush_age",name:this.i18n("Min Flush Age"),flexGrow:2},{prop:"target_max_bytes",name:this.i18n("Target Max Bytes"),flexGrow:2},{prop:"target_max_objects",name:this.i18n("Target Max Objects"),flexGrow:2}]}return l.prototype.ngOnChanges=function(){var l=this;this.selection.hasSingleSelection&&this.poolService.getConfiguration(this.selection.first().pool_name).subscribe(function(n){l.selectedPoolConfiguration=n})},l.prototype.filterNonPoolData=function(l){return i.omit(l,["cdExecuting","cdIsBinary"])},l}()),fe=u["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function me(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"tab",[["heading","Performance Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](1,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","one"],["uid","-xyV8KCiz"]],null,null,null,Qn.b,Qn.a)),u["\u0275did"](3,638976,null,0,le.a,[ne.a,wn.DomSanitizer,ee.a,on.a,s.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(l,n){var e=n.component;l(n,1,0,"Performance Details"),l(n,3,0,"ceph-pool-detail?var-pool_name="+e.selection.first().pool_name,"one","-xyV8KCiz")},function(l,n){l(n,0,0,u["\u0275nov"](n,1).id,u["\u0275nov"](n,1).active,u["\u0275nov"](n,1).addClass)})}function ge(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"tab",[["heading","Configuration"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](1,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](2,0,null,null,1,"cd-rbd-configuration-table",[],null,null,null,ae.b,ae.a)),u["\u0275did"](3,638976,null,0,re.a,[R.a,se.a,s.a],{data:[0,"data"]},null)],function(l,n){var e=n.component;l(n,1,0,"Configuration"),l(n,3,0,e.selectedPoolConfiguration)},function(l,n){l(n,0,0,u["\u0275nov"](n,1).id,u["\u0275nov"](n,1).active,u["\u0275nov"](n,1).addClass)})}function he(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"tab",[["heading","Cache Tiers Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](1,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](2,0,null,null,1,"cd-table",[["columnMode","flex"]],null,null,null,te.b,te.a)),u["\u0275did"](3,2867200,null,0,D.a,[u.NgZone,u.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoSave:[3,"autoSave"]},null)],function(l,n){var e=n.component;l(n,1,0,"Cache Tiers Details"),l(n,3,0,e.cacheTiers,e.cacheTierColumns,"flex",!1)},function(l,n){l(n,0,0,u["\u0275nov"](n,1).id,u["\u0275nov"](n,1).active,u["\u0275nov"](n,1).addClass)})}function ve(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,11,"tabset",[["cdTableDetail",""]],[[2,"tab-container",null]],null,null,ue.b,ue.a)),u["\u0275did"](1,180224,[[1,4],["tabsetChild",4]],0,Fn.d,[Fn.e,u.Renderer2,u.ElementRef],null,null),(l()(),u["\u0275eld"](2,0,null,0,3,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](3,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](4,0,null,null,1,"cd-table-key-value",[],null,null,null,de.b,de.a)),u["\u0275did"](5,638976,null,0,ce.a,[pn.a],{data:[0,"data"],autoReload:[1,"autoReload"],renderObjects:[2,"renderObjects"]},null),(l()(),u["\u0275and"](16777216,null,0,1,null,me)),u["\u0275did"](7,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,0,1,null,ge)),u["\u0275did"](9,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,0,1,null,he)),u["\u0275did"](11,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,3,0,"Details"),l(n,5,0,e.filterNonPoolData(e.selection.first()),!1,!0),l(n,7,0,e.permissions.grafana.read),l(n,9,0,"replicated"===e.selection.first().type),l(n,11,0,e.selection.first().tiers.length>0)},function(l,n){l(n,0,0,u["\u0275nov"](n,1).clazz),l(n,2,0,u["\u0275nov"](n,3).id,u["\u0275nov"](n,3).active,u["\u0275nov"](n,3).addClass)})}function be(l){return u["\u0275vid"](0,[u["\u0275qud"](671088640,1,{tabsetChild:0}),(l()(),u["\u0275and"](16777216,null,null,1,null,ve)),u["\u0275did"](2,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,2,0,n.component.selection.hasSingleSelection)},null)}var Ce=e("ufoC"),Re=u["\u0275crt"]({encapsulation:0,styles:[[".pg-clean{color:#0b0} .pg-working{color:#2b99a8} .pg-warning{color:#ffc200} .pg-unknown{color:red}"]],data:{}});function ye(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"cd-view-cache",[],null,null,null,Wn.b,Wn.a)),u["\u0275did"](1,114688,null,0,Zn.a,[],{status:[0,"status"],statusFor:[1,"statusFor"]},null)],function(l,n){l(n,1,0,n.context.$implicit.status,n.context.$implicit.statusFor)},null)}function Ie(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"cd-usage-bar",[["decimals","2"]],null,null,null,Yn.b,Yn.a)),u["\u0275did"](1,573440,null,0,Xn.a,[],{total:[0,"total"],used:[1,"used"],decimals:[2,"decimals"]},null)],function(l,n){l(n,1,0,n.parent.context.row.stats.bytes_used.latest+n.parent.context.row.stats.avail_raw.latest,n.parent.context.row.stats.bytes_used.latest,"2")},null)}function Ee(l){return u["\u0275vid"](0,[(l()(),u["\u0275and"](16777216,null,null,1,null,Ie)),u["\u0275did"](1,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,null==n.context.row.stats?null:null==n.context.row.stats.avail_raw?null:n.context.row.stats.avail_raw.latest)},null)}function Ve(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"tab",[["heading","Overall Performance"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](1,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","two"],["uid","z99hzWtmk"]],null,null,null,Qn.b,Qn.a)),u["\u0275did"](3,638976,null,0,le.a,[ne.a,wn.DomSanitizer,ee.a,on.a,s.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(l,n){l(n,1,0,"Overall Performance"),l(n,3,0,"ceph-pools-overview?","two","z99hzWtmk")},function(l,n){l(n,0,0,u["\u0275nov"](n,1).id,u["\u0275nov"](n,1).active,u["\u0275nov"](n,1).addClass)})}function Te(l){return u["\u0275vid"](0,[u["\u0275qud"](402653184,1,{table:0}),u["\u0275qud"](402653184,2,{poolUsageTpl:0}),u["\u0275qud"](402653184,3,{poolConfigurationSourceTpl:0}),(l()(),u["\u0275eld"](3,0,null,null,14,"tabset",[],[[2,"tab-container",null]],null,null,ue.b,ue.a)),u["\u0275did"](4,180224,null,0,Fn.d,[Fn.e,u.Renderer2,u.ElementRef],null,null),(l()(),u["\u0275eld"](5,0,null,0,10,"tab",[["heading","Pools List"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](6,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,ye)),u["\u0275did"](8,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275eld"](9,0,null,null,5,"cd-table",[["selectionType","single"]],null,[[null,"updateSelection"]],function(l,n,e){var u=!0;return"updateSelection"===n&&(u=!1!==l.component.updateSelection(e)&&u),u},te.b,te.a)),u["\u0275did"](10,2867200,[[1,4],["table",4]],0,D.a,[u.NgZone,u.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],selectionType:[2,"selectionType"]},{updateSelection:"updateSelection"}),(l()(),u["\u0275eld"](11,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,oe.b,oe.a)),u["\u0275did"](12,114688,null,0,ie.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),u["\u0275eld"](13,0,null,2,1,"cd-pool-details",[["cdTableDetail",""]],null,null,null,be,fe)),u["\u0275did"](14,573440,null,0,pe,[s.a,p.a],{selection:[0,"selection"],permissions:[1,"permissions"],cacheTiers:[2,"cacheTiers"]},null),(l()(),u["\u0275and"](0,[[2,2],["poolUsageTpl",2]],null,0,null,Ee)),(l()(),u["\u0275and"](16777216,null,0,1,null,Ve)),u["\u0275did"](17,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,6,0,"Pools List"),l(n,8,0,e.viewCacheStatusList),l(n,10,0,e.pools,e.columns,"single"),l(n,12,0,e.permissions.pool,e.selection,e.tableActions),l(n,14,0,e.selection,e.permissions,e.selectionCacheTiers),l(n,17,0,e.permissions.grafana.read)},function(l,n){l(n,3,0,u["\u0275nov"](n,4).clazz),l(n,5,0,u["\u0275nov"](n,6).id,u["\u0275nov"](n,6).active,u["\u0275nov"](n,6).addClass)})}function we(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"cd-pool-list",[],null,null,null,Te,Re)),u["\u0275prd"](131584,null,F.a,F.a,[Ce.a,ne.a]),u["\u0275prd"](256,null,q.a,L,[]),u["\u0275did"](3,114688,null,0,j,[p.a,y.a,C.a,F.a,Vl.b,s.a,A.a,x.a,q.a,_.a,t.b],null,null)],function(l,n){l(n,3,0)},null)}var Se=u["\u0275ccf"]("cd-pool-list",j,we,{},{},[]),Ne=e("EmSq"),_e=e("pYKc"),De=e("ppaS"),Pe=e("BH9v"),ke=e("rFfW"),ze=u["\u0275crt"]({encapsulation:0,styles:[[".crush-rule-steps[_ngcontent-%COMP%]{margin-top:10px}"]],data:{}});function xe(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"h1",[["class","jumbotron"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,0,"i",[["class","fa fa-lg fa-pulse fa-spinner text-primary"]],null,null,null,null,null)),(l()(),u["\u0275eld"](2,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Loading..."]))],null,null)}function Fe(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function qe(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["The chosen Ceph pool name is already in use."]))],null,null)}function Ae(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{value:[0,"value"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function Oe(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function Le(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function je(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["At least one placement group is needed!"]))],null,null)}function Me(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Your cluster can't handle this many PGs. Please recalculate the PG amount needed."]))],null,null)}function Ue(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["The current PGs settings were calculated for you, you should make sure the values suit your needs before submit."]))],null,null)}function Be(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit.rule_name)})}function Ge(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"li",[],null,null,null,null,null)),(l()(),u["\u0275ted"](1,null,[" "," "]))],null,function(l,n){l(n,1,0,n.component.describeCrushStep(n.context.$implicit))})}function Ke(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,11,"span",[["class","help-block"],["id","crush-info-block"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,10,"tabset",[],[[2,"tab-container",null]],null,null,ue.b,ue.a)),u["\u0275did"](2,180224,null,0,Fn.d,[Fn.e,u.Renderer2,u.ElementRef],null,null),(l()(),u["\u0275eld"](3,0,null,0,3,"tab",[["class","crush-rule-info"],["heading","Crush rule"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](4,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](5,0,null,null,1,"cd-table-key-value",[],null,null,null,de.b,de.a)),u["\u0275did"](6,638976,null,0,ce.a,[pn.a],{data:[0,"data"],autoReload:[1,"autoReload"],renderObjects:[2,"renderObjects"]},null),(l()(),u["\u0275eld"](7,0,null,0,4,"tab",[["class","crush-rule-steps"],["heading","Crush steps"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](8,212992,null,0,Fn.b,[Fn.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](9,0,null,null,2,"ol",[],null,null,null,null,null)),(l()(),u["\u0275and"](16777216,null,null,1,null,Ge)),u["\u0275did"](11,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component;l(n,4,0,"Crush rule"),l(n,6,0,e.form.getValue("crushRule"),!1,!0),l(n,8,0,"Crush steps"),l(n,11,0,e.form.get("crushRule").value.steps)},function(l,n){l(n,1,0,u["\u0275nov"](n,2).clazz),l(n,3,0,u["\u0275nov"](n,4).id,u["\u0275nov"](n,4).active,u["\u0275nov"](n,4).addClass),l(n,7,0,u["\u0275nov"](n,8).id,u["\u0275nov"](n,8).active,u["\u0275nov"](n,8).addClass)})}function $e(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["The rule can't be used in the current cluster as it has to few OSDs to meet the minimum required OSD by this rule."]))],null,null)}function Je(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,28,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](1,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](2,{"has-error":0}),(l()(),u["\u0275eld"](3,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","crushRule"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Crush ruleset"])),(l()(),u["\u0275eld"](5,0,null,null,23,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](6,0,null,null,18,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,12,"select",[["class","form-control"],["formControlName","crushRule"],["id","crushRule"],["name","crushSet"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,9).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,9).onTouched()&&t),t},null,null)),u["\u0275did"](8,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](9,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](11,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](13,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275eld"](14,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](15,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](16,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["-- Select a crush rule --"])),(l()(),u["\u0275and"](16777216,null,null,1,null,Be)),u["\u0275did"](19,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275eld"](20,0,null,null,4,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),u["\u0275eld"](21,0,null,null,3,"button",[["class","btn btn-default"],["id","crush-info-button"],["type","button"]],null,[[null,"click"]],function(l,n,e){var u=!0,t=l.component;return"click"===n&&(u=0!=(t.data.crushInfo=!t.data.crushInfo)&&u),u},null,null)),u["\u0275did"](22,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](23,{active:0}),(l()(),u["\u0275eld"](24,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-question-circle"]],null,null,null,null,null)),(l()(),u["\u0275and"](16777216,null,null,1,null,Ke)),u["\u0275did"](26,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,$e)),u["\u0275did"](28,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,2,0,e.form.showError("crushRule",u["\u0275nov"](n.parent.parent,2)));l(n,1,0,"form-group",t),l(n,11,0,"crushRule"),l(n,15,0,null),l(n,16,0,null),l(n,19,0,e.current.rules);var o=l(n,23,0,e.data.crushInfo);l(n,22,0,"btn btn-default",o),l(n,26,0,e.data.crushInfo&&e.form.getValue("crushRule")),l(n,28,0,e.form.showError("crushRule",u["\u0275nov"](n.parent.parent,2),"tooFewOsds"))},function(l,n){l(n,7,0,u["\u0275nov"](n,13).ngClassUntouched,u["\u0275nov"](n,13).ngClassTouched,u["\u0275nov"](n,13).ngClassPristine,u["\u0275nov"](n,13).ngClassDirty,u["\u0275nov"](n,13).ngClassValid,u["\u0275nov"](n,13).ngClassInvalid,u["\u0275nov"](n,13).ngClassPending)})}function He(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,5,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,4,"ul",[["class","list-inline"]],null,null,null,null,null)),(l()(),u["\u0275eld"](2,0,null,null,1,"li",[],null,null,null,null,null)),(l()(),u["\u0275ted"](3,null,["Minimum: ",""])),(l()(),u["\u0275eld"](4,0,null,null,1,"li",[],null,null,null,null,null)),(l()(),u["\u0275ted"](5,null,["Maximum: ",""]))],null,function(l,n){var e=n.component;l(n,3,0,e.getMinSize()),l(n,5,0,e.getMaxSize())})}function We(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](1,null,["The size specified is out of range. A value from "," to "," is valid."]))],null,function(l,n){var e=n.component;l(n,1,0,e.getMinSize(),e.getMaxSize())})}function Ze(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](1,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](2,{"has-error":0}),(l()(),u["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","size"]],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Replicated size"])),(l()(),u["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](8,0,null,null,7,"input",[["class","form-control"],["formControlName","size"],["id","size"],["name","size"],["type","number"]],[[8,"max",0],[8,"min",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,10)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,10).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,10)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,10)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,11).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,11).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,11).onTouched()&&t),t},null,null)),u["\u0275did"](9,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](10,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](11,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](13,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](15,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,He)),u["\u0275did"](17,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,We)),u["\u0275did"](19,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,2,0,e.form.showError("size",u["\u0275nov"](n.parent.parent,2)));l(n,1,0,"form-group",t),l(n,13,0,"size"),l(n,17,0,e.form.showError("size",u["\u0275nov"](n.parent.parent,2))),l(n,19,0,e.form.showError("size",u["\u0275nov"](n.parent.parent,2)))},function(l,n){var e=n.component;l(n,8,0,e.getMaxSize(),e.getMinSize(),u["\u0275nov"](n,15).ngClassUntouched,u["\u0275nov"](n,15).ngClassTouched,u["\u0275nov"](n,15).ngClassPristine,u["\u0275nov"](n,15).ngClassDirty,u["\u0275nov"](n,15).ngClassValid,u["\u0275nov"](n,15).ngClassInvalid,u["\u0275nov"](n,15).ngClassPending)})}function Ye(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,""),l(n,2,0,"")},null)}function Xe(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["-- No erasure code profile available --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function Qe(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["-- Select an erasure code profile --"]))],function(l,n){l(n,1,0,null),l(n,2,0,null)},null)}function lu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit.name)})}function nu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,2,"span",[["class","help-block"],["id","ecp-info-block"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"cd-table-key-value",[],null,null,null,de.b,de.a)),u["\u0275did"](2,638976,null,0,ce.a,[pn.a],{data:[0,"data"],autoReload:[1,"autoReload"],renderObjects:[2,"renderObjects"]},null)],function(l,n){l(n,2,0,n.component.form.getValue("erasureProfile"),!1,!0)},null)}function eu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,30,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","erasureProfile"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Erasure code profile"])),(l()(),u["\u0275eld"](3,0,null,null,27,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,24,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](5,0,null,null,14,"select",[["class","form-control"],["formControlName","erasureProfile"],["id","erasureProfile"],["name","erasureProfile"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,7).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,7).onTouched()&&t),t},null,null)),u["\u0275did"](6,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](7,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](9,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](11,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Ye)),u["\u0275did"](13,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Xe)),u["\u0275did"](15,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Qe)),u["\u0275did"](17,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,lu)),u["\u0275did"](19,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275eld"](20,0,null,null,8,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),u["\u0275eld"](21,0,null,null,3,"button",[["class","btn btn-default"],["id","ecp-info-button"],["type","button"]],null,[[null,"click"]],function(l,n,e){var u=!0,t=l.component;return"click"===n&&(u=0!=(t.data.erasureInfo=!t.data.erasureInfo)&&u),u},null,null)),u["\u0275did"](22,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](23,{active:0}),(l()(),u["\u0275eld"](24,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-question-circle"]],null,null,null,null,null)),(l()(),u["\u0275eld"](25,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],[[8,"disabled",0]],[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==l.component.addErasureCodeProfile()&&u),u},null,null)),(l()(),u["\u0275eld"](26,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-plus"]],null,null,null,null,null)),(l()(),u["\u0275eld"](27,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],[[8,"disabled",0]],[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==l.component.deleteErasureCodeProfile()&&u),u},null,null)),(l()(),u["\u0275eld"](28,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-trash-o"]],null,null,null,null,null)),(l()(),u["\u0275and"](16777216,null,null,1,null,nu)),u["\u0275did"](30,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,9,0,"erasureProfile"),l(n,13,0,!e.ecProfiles),l(n,15,0,e.ecProfiles&&0===e.ecProfiles.length),l(n,17,0,e.ecProfiles&&e.ecProfiles.length>0),l(n,19,0,e.ecProfiles);var u=l(n,23,0,e.data.erasureInfo);l(n,22,0,"btn btn-default",u),l(n,30,0,e.data.erasureInfo&&e.form.getValue("erasureProfile"))},function(l,n){var e=n.component;l(n,5,0,u["\u0275nov"](n,11).ngClassUntouched,u["\u0275nov"](n,11).ngClassTouched,u["\u0275nov"](n,11).ngClassPristine,u["\u0275nov"](n,11).ngClassDirty,u["\u0275nov"](n,11).ngClassValid,u["\u0275nov"](n,11).ngClassInvalid,u["\u0275nov"](n,11).ngClassPending),l(n,25,0,e.editing),l(n,27,0,e.editing||e.ecProfiles.length<1)})}function uu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Flags"])),(l()(),u["\u0275eld"](3,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,10,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](5,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),u["\u0275eld"](6,0,null,null,6,"input",[["formControlName","ecOverwrites"],["id","ec-overwrites"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,8).onChange(e.target.checked)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,8).onTouched()&&t),t},null,null)),u["\u0275did"](7,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](8,16384,null,0,o.c,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.c]),u["\u0275did"](10,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](12,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275eld"](13,0,null,null,1,"label",[["for","ec-overwrites"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["EC Overwrites"]))],function(l,n){l(n,10,0,"ecOverwrites")},function(l,n){l(n,6,0,u["\u0275nov"](n,12).ngClassUntouched,u["\u0275nov"](n,12).ngClassTouched,u["\u0275nov"](n,12).ngClassPristine,u["\u0275nov"](n,12).ngClassDirty,u["\u0275nov"](n,12).ngClassValid,u["\u0275nov"](n,12).ngClassInvalid,u["\u0275nov"](n,12).ngClassPending)})}function tu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,37,"div",[],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,28,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](2,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](3,{"has-error":0}),(l()(),u["\u0275eld"](4,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","pgNum"]],null,null,null,null,null)),(l()(),u["\u0275eld"](5,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Placement groups"])),(l()(),u["\u0275eld"](7,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),u["\u0275eld"](8,0,null,null,21,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](9,0,null,null,9,"input",[["class","form-control"],["formControlName","pgNum"],["id","pgNum"],["min","1"],["name","pgNum"],["required",""],["type","number"]],[[1,"required",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"focus"],[null,"blur"],[null,"input"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0,o=l.component;return"input"===n&&(t=!1!==u["\u0275nov"](l,11)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,11).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,11)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,11)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,12).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,12).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,12).onTouched()&&t),"focus"===n&&(t=0!=(o.externalPgChange=!1)&&t),"blur"===n&&(t=!1!==o.alignPgs()&&t),t},null,null)),u["\u0275did"](10,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](11,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](12,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275did"](13,16384,null,0,o.y,[],{required:[0,"required"]},null),u["\u0275prd"](1024,null,o.o,function(l){return[l]},[o.y]),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](16,671744,null,0,o.j,[[3,o.d],[6,o.o],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](18,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Le)),u["\u0275did"](20,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,je)),u["\u0275did"](22,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Me)),u["\u0275did"](24,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](25,0,null,null,2,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275eld"](26,0,null,null,1,"a",[["href","http://ceph.com/pgcalc"],["target","_blank"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Calculation help"])),(l()(),u["\u0275and"](16777216,null,null,1,null,Ue)),u["\u0275did"](29,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Je)),u["\u0275did"](31,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Ze)),u["\u0275did"](33,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,eu)),u["\u0275did"](35,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,uu)),u["\u0275did"](37,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,3,0,e.form.showError("pgNum",u["\u0275nov"](n.parent,2)));l(n,2,0,"form-group",t),l(n,13,0,""),l(n,16,0,"pgNum"),l(n,20,0,e.form.showError("pgNum",u["\u0275nov"](n.parent,2),"required")),l(n,22,0,e.form.showError("pgNum",u["\u0275nov"](n.parent,2),"min")),l(n,24,0,e.form.showError("pgNum",u["\u0275nov"](n.parent,2),"34")),l(n,29,0,e.externalPgChange),l(n,31,0,e.form.getValue("poolType")&&e.current.rules.length>0),l(n,33,0,"replicated"===e.form.getValue("poolType")),l(n,35,0,"erasure"===e.form.getValue("poolType")),l(n,37,0,e.info.is_all_bluestore&&"erasure"===e.form.getValue("poolType"))},function(l,n){l(n,9,0,u["\u0275nov"](n,13).required?"":null,u["\u0275nov"](n,18).ngClassUntouched,u["\u0275nov"](n,18).ngClassTouched,u["\u0275nov"](n,18).ngClassPristine,u["\u0275nov"](n,18).ngClassDirty,u["\u0275nov"](n,18).ngClassValid,u["\u0275nov"](n,18).ngClassInvalid,u["\u0275nov"](n,18).ngClassPending)})}function ou(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{value:[0,"value"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function iu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["Loading..."]))],function(l,n){l(n,1,0,""),l(n,2,0,"")},null)}function au(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["-- No erasure compression algorithm available --"]))],function(l,n){l(n,1,0,""),l(n,2,0,"")},null)}function ru(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),u["\u0275did"](1,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{value:[0,"value"]},null),u["\u0275did"](2,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{value:[0,"value"]},null),(l()(),u["\u0275ted"](3,null,[" "," "]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.context.$implicit)})}function su(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Value should be greater than 0"]))],null,null)}function du(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Value should be less than the maximum blob size"]))],null,null)}function cu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Value should be greater than 0"]))],null,null)}function pu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Value should be greater than the minimum blob size"]))],null,null)}function fu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Value should be between 0.0 and 1.0"]))],null,null)}function mu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,71,"div",[],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](2,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](3,{"has-error":0}),(l()(),u["\u0275eld"](4,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","algorithm"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Algorithm"])),(l()(),u["\u0275eld"](6,0,null,null,13,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,12,"select",[["class","form-control"],["formControlName","algorithm"],["id","algorithm"],["name","algorithm"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,9).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,9).onTouched()&&t),t},null,null)),u["\u0275did"](8,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](9,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](11,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](13,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,iu)),u["\u0275did"](15,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,au)),u["\u0275did"](17,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,ru)),u["\u0275did"](19,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275eld"](20,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](21,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](22,{"has-error":0}),(l()(),u["\u0275eld"](23,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","minBlobSize"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Minimum blob size"])),(l()(),u["\u0275eld"](25,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](26,0,null,null,7,"input",[["cdDimlessBinary",""],["class","form-control"],["defaultUnit","KiB"],["formControlName","minBlobSize"],["id","minBlobSize"],["min","0"],["name","minBlobSize"],["placeholder","e.g., 128KiB"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,27)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,27).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,27)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,27)._compositionEnd(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,31).onBlur(e.target.value)&&t),t},null,null)),u["\u0275did"](27,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),u["\u0275did"](29,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](31,81920,null,0,Ne.a,[u.ElementRef,o.q,b.a,R.a],{defaultUnit:[0,"defaultUnit"]},null),u["\u0275did"](32,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](33,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,su)),u["\u0275did"](35,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,du)),u["\u0275did"](37,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](38,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](39,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](40,{"has-error":0}),(l()(),u["\u0275eld"](41,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","maxBlobSize"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Maximum blob size"])),(l()(),u["\u0275eld"](43,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](44,0,null,null,7,"input",[["cdDimlessBinary",""],["class","form-control"],["defaultUnit","KiB"],["formControlName","maxBlobSize"],["id","maxBlobSize"],["min","0"],["placeholder","e.g., 512KiB"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,45)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,45).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,45)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,45)._compositionEnd(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,49).onBlur(e.target.value)&&t),t},null,null)),u["\u0275did"](45,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),u["\u0275did"](47,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](49,81920,null,0,Ne.a,[u.ElementRef,o.q,b.a,R.a],{defaultUnit:[0,"defaultUnit"]},null),u["\u0275did"](50,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](51,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,cu)),u["\u0275did"](53,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,pu)),u["\u0275did"](55,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](56,0,null,null,15,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](57,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](58,{"has-error":0}),(l()(),u["\u0275eld"](59,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","ratio"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Ratio"])),(l()(),u["\u0275eld"](61,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](62,0,null,null,7,"input",[["class","form-control"],["formControlName","ratio"],["id","ratio"],["max","1"],["min","0"],["name","ratio"],["placeholder","Compression ratio"],["step","0.1"],["type","number"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,64)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,64).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,64)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,64)._compositionEnd(e.target.value)&&t),"change"===n&&(t=!1!==u["\u0275nov"](l,65).onChange(e.target.value)&&t),"input"===n&&(t=!1!==u["\u0275nov"](l,65).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,65).onTouched()&&t),t},null,null)),u["\u0275did"](63,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](64,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275did"](65,16384,null,0,o.C,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l,n){return[l,n]},[o.e,o.C]),u["\u0275did"](67,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](69,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,fu)),u["\u0275did"](71,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component,t=l(n,3,0,e.form.showError("algorithm",u["\u0275nov"](n.parent.parent,2)));l(n,2,0,"form-group",t),l(n,11,0,"algorithm"),l(n,15,0,!e.info.compression_algorithms),l(n,17,0,e.info.compression_algorithms&&0===e.info.compression_algorithms.length),l(n,19,0,e.info.compression_algorithms);var o=l(n,22,0,e.form.showError("minBlobSize",u["\u0275nov"](n.parent.parent,2)));l(n,21,0,"form-group",o),l(n,29,0,"minBlobSize"),l(n,31,0,"KiB"),l(n,35,0,e.form.showError("minBlobSize",u["\u0275nov"](n.parent.parent,2),"min")),l(n,37,0,e.form.showError("minBlobSize",u["\u0275nov"](n.parent.parent,2),"maximum"));var i=l(n,40,0,e.form.showError("maxBlobSize",u["\u0275nov"](n.parent.parent,2)));l(n,39,0,"form-group",i),l(n,47,0,"maxBlobSize"),l(n,49,0,"KiB"),l(n,53,0,e.form.showError("maxBlobSize",u["\u0275nov"](n.parent.parent,2),"min")),l(n,55,0,e.form.showError("maxBlobSize",u["\u0275nov"](n.parent.parent,2),"minimum"));var a=l(n,58,0,e.form.showError("ratio",u["\u0275nov"](n.parent.parent,2)));l(n,57,0,"form-group",a),l(n,67,0,"ratio"),l(n,71,0,e.form.showError("ratio",u["\u0275nov"](n.parent.parent,2),"min")||e.form.showError("ratio",u["\u0275nov"](n.parent.parent,2),"max"))},function(l,n){l(n,7,0,u["\u0275nov"](n,13).ngClassUntouched,u["\u0275nov"](n,13).ngClassTouched,u["\u0275nov"](n,13).ngClassPristine,u["\u0275nov"](n,13).ngClassDirty,u["\u0275nov"](n,13).ngClassValid,u["\u0275nov"](n,13).ngClassInvalid,u["\u0275nov"](n,13).ngClassPending),l(n,26,0,u["\u0275nov"](n,33).ngClassUntouched,u["\u0275nov"](n,33).ngClassTouched,u["\u0275nov"](n,33).ngClassPristine,u["\u0275nov"](n,33).ngClassDirty,u["\u0275nov"](n,33).ngClassValid,u["\u0275nov"](n,33).ngClassInvalid,u["\u0275nov"](n,33).ngClassPending),l(n,44,0,u["\u0275nov"](n,51).ngClassUntouched,u["\u0275nov"](n,51).ngClassTouched,u["\u0275nov"](n,51).ngClassPristine,u["\u0275nov"](n,51).ngClassDirty,u["\u0275nov"](n,51).ngClassValid,u["\u0275nov"](n,51).ngClassInvalid,u["\u0275nov"](n,51).ngClassPending),l(n,62,0,u["\u0275nov"](n,69).ngClassUntouched,u["\u0275nov"](n,69).ngClassTouched,u["\u0275nov"](n,69).ngClassPristine,u["\u0275nov"](n,69).ngClassDirty,u["\u0275nov"](n,69).ngClassValid,u["\u0275nov"](n,69).ngClassInvalid,u["\u0275nov"](n,69).ngClassPending)})}function gu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,20,"div",[["formGroupName","compression"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),u["\u0275did"](1,212992,null,0,o.m,[[3,o.d],[8,null],[8,null]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.d,null,[o.m]),u["\u0275did"](3,16384,null,0,o.s,[[4,o.d]],null,null),(l()(),u["\u0275eld"](4,0,null,null,1,"legend",[],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Compression"])),(l()(),u["\u0275eld"](6,0,null,null,12,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","mode"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Mode"])),(l()(),u["\u0275eld"](9,0,null,null,9,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](10,0,null,null,8,"select",[["class","form-control"],["formControlName","mode"],["id","mode"],["name","mode"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,12).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,12).onTouched()&&t),t},null,null)),u["\u0275did"](11,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](12,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](14,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](16,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,ou)),u["\u0275did"](18,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,mu)),u["\u0275did"](20,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,1,0,"compression"),l(n,14,0,"mode"),l(n,18,0,e.info.compression_modes),l(n,20,0,e.hasCompressionEnabled())},function(l,n){l(n,0,0,u["\u0275nov"](n,3).ngClassUntouched,u["\u0275nov"](n,3).ngClassTouched,u["\u0275nov"](n,3).ngClassPristine,u["\u0275nov"](n,3).ngClassDirty,u["\u0275nov"](n,3).ngClassValid,u["\u0275nov"](n,3).ngClassInvalid,u["\u0275nov"](n,3).ngClassPending),l(n,10,0,u["\u0275nov"](n,16).ngClassUntouched,u["\u0275nov"](n,16).ngClassTouched,u["\u0275nov"](n,16).ngClassPristine,u["\u0275nov"](n,16).ngClassDirty,u["\u0275nov"](n,16).ngClassValid,u["\u0275nov"](n,16).ngClassInvalid,u["\u0275nov"](n,16).ngClassPending)})}function hu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,5,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),u["\u0275eld"](2,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["It's not possible to create an RBD pool with '/' in the name."])),(l()(),u["\u0275eld"](4,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Please change the name or remove 'rbd' from the applications list."]))],null,null)}function vu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,80,"form",[["class","form-horizontal"],["name","form"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var t=!0;return"submit"===n&&(t=!1!==u["\u0275nov"](l,2).onSubmit(e)&&t),"reset"===n&&(t=!1!==u["\u0275nov"](l,2).onReset()&&t),t},null,null)),u["\u0275did"](1,16384,null,0,o.D,[],null,null),u["\u0275did"](2,540672,[["formDir",4]],0,o.l,[[8,null],[8,null]],{form:[0,"form"]},null),u["\u0275prd"](2048,null,o.d,null,[o.l]),u["\u0275did"](4,16384,null,0,o.s,[[4,o.d]],null,null),(l()(),u["\u0275eld"](5,0,null,null,75,"div",[["class","panel panel-default"]],null,null,null,null,null)),(l()(),u["\u0275eld"](6,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),u["\u0275eld"](7,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(l()(),u["\u0275ted"](8,null,[""," ",""])),u["\u0275ppd"](9,1),u["\u0275ppd"](10,1),(l()(),u["\u0275eld"](11,0,null,null,60,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),u["\u0275eld"](12,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](13,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](14,{"has-error":0}),(l()(),u["\u0275eld"](15,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),u["\u0275eld"](16,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Name"])),(l()(),u["\u0275eld"](18,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),u["\u0275eld"](19,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](20,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","name"],["id","name"],["name","name"],["placeholder","Name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var t=!0;return"input"===n&&(t=!1!==u["\u0275nov"](l,23)._handleInput(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,23).onTouched()&&t),"compositionstart"===n&&(t=!1!==u["\u0275nov"](l,23)._compositionStart()&&t),"compositionend"===n&&(t=!1!==u["\u0275nov"](l,23)._compositionEnd(e.target.value)&&t),t},null,null)),u["\u0275did"](21,4210688,null,0,Cl.a,[u.ElementRef],null,null),u["\u0275did"](22,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](23,16384,null,0,o.e,[u.Renderer2,u.ElementRef,[2,o.b]],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.e]),u["\u0275did"](25,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](27,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Fe)),u["\u0275did"](29,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,qe)),u["\u0275did"](31,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](32,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](33,278528,null,0,fl.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](34,{"has-error":0}),(l()(),u["\u0275eld"](35,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","poolType"]],null,null,null,null,null)),(l()(),u["\u0275eld"](36,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Pool type"])),(l()(),u["\u0275eld"](38,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(l()(),u["\u0275eld"](39,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](40,0,null,null,12,"select",[["class","form-control"],["formControlName","poolType"],["id","poolType"],["name","poolType"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(l,n,e){var t=!0;return"change"===n&&(t=!1!==u["\u0275nov"](l,42).onChange(e.target.value)&&t),"blur"===n&&(t=!1!==u["\u0275nov"](l,42).onTouched()&&t),t},null,null)),u["\u0275did"](41,4210688,null,0,hl.a,[[2,vl.a],C.a,u.ElementRef],null,null),u["\u0275did"](42,16384,null,0,o.z,[u.Renderer2,u.ElementRef],null,null),u["\u0275prd"](1024,null,o.p,function(l){return[l]},[o.z]),u["\u0275did"](44,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,o.q,null,[o.j]),u["\u0275did"](46,16384,null,0,o.r,[[4,o.q]],null,null),(l()(),u["\u0275eld"](47,0,null,null,3,"option",[["ngValue",""]],null,null,null,null,null)),u["\u0275did"](48,147456,null,0,o.v,[u.ElementRef,u.Renderer2,[2,o.z]],{ngValue:[0,"ngValue"]},null),u["\u0275did"](49,147456,null,0,o.G,[u.ElementRef,u.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(l()(),u["\u0275ted"](-1,null,["-- Select a pool type --"])),(l()(),u["\u0275and"](16777216,null,null,1,null,Ae)),u["\u0275did"](52,278528,null,0,fl.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Oe)),u["\u0275did"](54,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,tu)),u["\u0275did"](56,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](57,0,null,null,6,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](58,0,null,null,1,"label",[["class","col-sm-3 control-label"],["for","applications"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Applications"])),(l()(),u["\u0275eld"](60,0,null,null,3,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](61,0,null,null,2,"span",[["class","form-control no-border full-height"]],null,null,null,null,null)),(l()(),u["\u0275eld"](62,0,null,null,1,"cd-select-badges",[["id","applications"]],null,[[null,"selection"]],function(l,n,e){var u=!0;return"selection"===n&&(u=!1!==l.component.appSelection()&&u),u},_e.b,_e.a)),u["\u0275did"](63,49152,null,0,De.a,[s.a],{data:[0,"data"],options:[1,"options"],messages:[2,"messages"],selectionLimit:[3,"selectionLimit"],customBadges:[4,"customBadges"],customBadgeValidators:[5,"customBadgeValidators"]},{selection:"selection"}),(l()(),u["\u0275and"](16777216,null,null,1,null,gu)),u["\u0275did"](65,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](66,0,null,null,2,"div",[],[[8,"hidden",0]],null,null,null,null)),(l()(),u["\u0275eld"](67,0,null,null,1,"cd-rbd-configuration-form",[],null,[[null,"changes"]],function(l,n,e){var u=!0;return"changes"===n&&(u=!1!==(l.component.currentConfigurationValues=e())&&u),u},Pe.b,Pe.a)),u["\u0275did"](68,114688,null,0,ke.a,[R.a,se.a],{form:[0,"form"],initializeData:[1,"initializeData"]},{changes:"changes"}),(l()(),u["\u0275eld"](69,0,null,null,2,"div",[["class","form-group has-error"]],null,null,null,null,null)),(l()(),u["\u0275and"](16777216,null,null,1,null,hu)),u["\u0275did"](71,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](72,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(l()(),u["\u0275eld"](73,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),u["\u0275eld"](74,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(l,n,e){var u=!0;return"submitAction"===n&&(u=!1!==l.component.submit()&&u),u},Rl.b,Rl.a)),u["\u0275did"](75,114688,null,0,yl.a,[u.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(l()(),u["\u0275ted"](76,0,[""," ",""])),u["\u0275ppd"](77,1),u["\u0275ppd"](78,1),(l()(),u["\u0275eld"](79,0,null,null,1,"cd-back-button",[],null,null,null,Il.b,Il.a)),u["\u0275did"](80,49152,null,0,El.a,[fl.Location,t.b],null,null)],function(l,n){var e=n.component;l(n,2,0,e.form);var t=l(n,14,0,e.form.showError("name",u["\u0275nov"](n,2)));l(n,13,0,"form-group",t),l(n,25,0,"name"),l(n,29,0,e.form.showError("name",u["\u0275nov"](n,2),"required")),l(n,31,0,e.form.showError("name",u["\u0275nov"](n,2),"uniqueName"));var o=l(n,34,0,e.form.showError("poolType",u["\u0275nov"](n,2)));l(n,33,0,"form-group",o),l(n,44,0,"poolType"),l(n,48,0,""),l(n,49,0,""),l(n,52,0,e.data.poolTypes),l(n,54,0,e.form.showError("poolType",u["\u0275nov"](n,2),"required")),l(n,56,0,e.form.getValue("poolType")),l(n,63,0,e.data.applications.selected,e.data.applications.available,e.data.applications.messages,4,!0,e.data.applications.validators),l(n,65,0,e.info.is_all_bluestore),l(n,68,0,e.form,e.initializeConfigData),l(n,71,0,e.form.hasError("rbdPool")),l(n,75,0,u["\u0275nov"](n,2),"button")},function(l,n){var e=n.component;l(n,0,0,u["\u0275nov"](n,4).ngClassUntouched,u["\u0275nov"](n,4).ngClassTouched,u["\u0275nov"](n,4).ngClassPristine,u["\u0275nov"](n,4).ngClassDirty,u["\u0275nov"](n,4).ngClassValid,u["\u0275nov"](n,4).ngClassInvalid,u["\u0275nov"](n,4).ngClassPending);var t=u["\u0275unv"](n,8,0,l(n,9,0,u["\u0275nov"](n.parent,0),e.action)),o=u["\u0275unv"](n,8,1,l(n,10,0,u["\u0275nov"](n.parent,1),e.resource));l(n,8,0,t,o),l(n,20,0,u["\u0275nov"](n,27).ngClassUntouched,u["\u0275nov"](n,27).ngClassTouched,u["\u0275nov"](n,27).ngClassPristine,u["\u0275nov"](n,27).ngClassDirty,u["\u0275nov"](n,27).ngClassValid,u["\u0275nov"](n,27).ngClassInvalid,u["\u0275nov"](n,27).ngClassPending),l(n,40,0,u["\u0275nov"](n,46).ngClassUntouched,u["\u0275nov"](n,46).ngClassTouched,u["\u0275nov"](n,46).ngClassPristine,u["\u0275nov"](n,46).ngClassDirty,u["\u0275nov"](n,46).ngClassValid,u["\u0275nov"](n,46).ngClassInvalid,u["\u0275nov"](n,46).ngClassPending),l(n,66,0,"replicated"!==e.form.get("poolType").value||-1===e.data.applications.selected.indexOf("rbd"));var i=u["\u0275unv"](n,76,0,l(n,77,0,u["\u0275nov"](n.parent,0),e.action)),a=u["\u0275unv"](n,76,1,l(n,78,0,u["\u0275nov"](n.parent,1),e.resource));l(n,76,0,i,a)})}function bu(l){return u["\u0275vid"](0,[u["\u0275pid"](0,fl.TitleCasePipe,[]),u["\u0275pid"](0,bl.a,[]),(l()(),u["\u0275eld"](2,0,null,null,4,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(l()(),u["\u0275and"](16777216,null,null,1,null,xe)),u["\u0275did"](4,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,vu)),u["\u0275did"](6,16384,null,0,fl.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,4,0,!(e.info&&e.ecProfiles)),l(n,6,0,e.info&&e.ecProfiles)},null)}function Cu(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"cd-pool-form",[],null,null,null,bu,ze)),u["\u0275did"](1,114688,null,0,N,[b.a,Pn.a,Pn.l,Vl.b,p.a,C.a,R.a,Vl.b,y.a,c,s.a,t.b],null,null)],function(l,n){l(n,1,0)},null)}var Ru=u["\u0275ccf"]("cd-pool-form",N,Cu,{},{},[]);e.d(n,"PoolModuleNgFactory",function(){return yu}),e.d(n,"RoutedPoolModuleNgFactory",function(){return Iu});var yu=u["\u0275cmf"](M,[],function(l){return u["\u0275mod"]([u["\u0275mpd"](512,u.ComponentFactoryResolver,u["\u0275CodegenComponentFactoryResolver"],[[8,[K.a,$.a,J.a,H.a,H.b,W.a,Z.a,Y.a,X.a,Q.a,ll.a,nl.a,el.a,ul.a,ul.c,ul.b,tl.a,ol.a,il.a,al.a,rl.a,sl.a,dl.a,cl.a,pl.a,en]],[3,u.ComponentFactoryResolver],u.NgModuleRef]),u["\u0275mpd"](4608,fl.NgLocalization,fl.NgLocaleLocalization,[u.LOCALE_ID,[2,fl["\u0275angular_packages_common_common_a"]]]),u["\u0275mpd"](4608,un.a,un.a,[s.a]),u["\u0275mpd"](4608,fl.DatePipe,fl.DatePipe,[u.LOCALE_ID]),u["\u0275mpd"](4608,tn.a,tn.a,[]),u["\u0275mpd"](4608,on.a,on.a,[]),u["\u0275mpd"](4608,R.a,R.a,[]),u["\u0275mpd"](4608,b.a,b.a,[R.a]),u["\u0275mpd"](4608,an.a,an.a,[R.a]),u["\u0275mpd"](4608,x.a,x.a,[R.a]),u["\u0275mpd"](4608,rn.a,rn.a,[]),u["\u0275mpd"](4608,sn.a,sn.a,[]),u["\u0275mpd"](4608,dn.a,dn.a,[]),u["\u0275mpd"](4608,cn.a,cn.a,[]),u["\u0275mpd"](4608,pn.a,pn.a,[fl.DatePipe]),u["\u0275mpd"](4608,fn.a,fn.a,[]),u["\u0275mpd"](4608,mn.a,mn.a,[]),u["\u0275mpd"](4608,gn.a,gn.a,[]),u["\u0275mpd"](4608,hn.a,hn.a,[]),u["\u0275mpd"](4608,vn.a,vn.a,[]),u["\u0275mpd"](4608,bn.a,bn.a,[s.a]),u["\u0275mpd"](4608,bl.a,bl.a,[]),u["\u0275mpd"](4608,Cn.a,Cn.a,[]),u["\u0275mpd"](4608,o.E,o.E,[]),u["\u0275mpd"](4608,o.h,o.h,[]),u["\u0275mpd"](4608,Rn.b,Rn.b,[]),u["\u0275mpd"](4608,yn.a,yn.a,[]),u["\u0275mpd"](4608,In.a,In.a,[u.RendererFactory2,u.PLATFORM_ID]),u["\u0275mpd"](4608,En.a,En.a,[u.ComponentFactoryResolver,u.NgZone,u.Injector,In.a,u.ApplicationRef]),u["\u0275mpd"](4608,Vn.a,Vn.a,[]),u["\u0275mpd"](4608,Vl.b,Vl.b,[u.RendererFactory2,En.a]),u["\u0275mpd"](4608,Tn.ScrollbarHelper,Tn.ScrollbarHelper,[wn.DOCUMENT]),u["\u0275mpd"](4608,Sn.DimensionsHelper,Sn.DimensionsHelper,[]),u["\u0275mpd"](4608,Nn.ColumnChangesService,Nn.ColumnChangesService,[]),u["\u0275mpd"](4608,_n.f,_n.f,[]),u["\u0275mpd"](4608,C.a,C.a,[]),u["\u0275mpd"](4608,Dn.a,Dn.a,[Pn.l,C.a]),u["\u0275mpd"](4608,kn.NodeDraggableService,kn.NodeDraggableService,[]),u["\u0275mpd"](4608,zn.NodeMenuService,zn.NodeMenuService,[]),u["\u0275mpd"](4608,xn.TreeService,xn.TreeService,[kn.NodeDraggableService]),u["\u0275mpd"](4608,Fn.e,Fn.e,[]),u["\u0275mpd"](4608,qn.c,qn.c,[]),u["\u0275mpd"](4608,An.r,An.r,[]),u["\u0275mpd"](4608,An.t,An.t,[]),u["\u0275mpd"](4608,An.a,An.a,[]),u["\u0275mpd"](4608,An.h,An.h,[]),u["\u0275mpd"](4608,An.d,An.d,[]),u["\u0275mpd"](4608,An.j,An.j,[]),u["\u0275mpd"](4608,An.s,An.s,[An.t,An.j]),u["\u0275mpd"](1073742336,fl.CommonModule,fl.CommonModule,[]),u["\u0275mpd"](1073742336,On.a,On.a,[]),u["\u0275mpd"](1073742336,Fn.c,Fn.c,[]),u["\u0275mpd"](1073742336,yn.d,yn.d,[]),u["\u0275mpd"](1073742336,Ln.a,Ln.a,[]),u["\u0275mpd"](1073742336,o.B,o.B,[]),u["\u0275mpd"](1073742336,o.n,o.n,[]),u["\u0275mpd"](1073742336,o.x,o.x,[]),u["\u0275mpd"](1073742336,Rn.c,Rn.c,[]),u["\u0275mpd"](1073742336,Vn.d,Vn.d,[]),u["\u0275mpd"](1073742336,jn.ChartsModule,jn.ChartsModule,[]),u["\u0275mpd"](1073742336,Vl.e,Vl.e,[]),u["\u0275mpd"](1073742336,Mn.a,Mn.a,[]),u["\u0275mpd"](1073742336,_n.e,_n.e,[]),u["\u0275mpd"](1073742336,Un.a,Un.a,[]),u["\u0275mpd"](1073742336,Bn.NgxDatatableModule,Bn.NgxDatatableModule,[]),u["\u0275mpd"](1073742336,Pn.p,Pn.p,[[2,Pn.v],[2,Pn.l]]),u["\u0275mpd"](1073742336,Gn.a,Gn.a,[]),u["\u0275mpd"](1073742336,d.a,d.a,[]),u["\u0275mpd"](1073742336,Kn.a,Kn.a,[]),u["\u0275mpd"](1073742336,qn.d,qn.d,[]),u["\u0275mpd"](1073742336,$n.TreeModule,$n.TreeModule,[]),u["\u0275mpd"](1073742336,Jn.a,Jn.a,[]),u["\u0275mpd"](1073742336,An.g,An.g,[]),u["\u0275mpd"](1073742336,Hn.a,Hn.a,[]),u["\u0275mpd"](1073742336,M,M,[]),u["\u0275mpd"](256,u.LOCALE_ID,"en-US",[]),u["\u0275mpd"](256,_n.a,{autoClose:!0,insideClick:!1},[]),u["\u0275mpd"](256,u.TRANSLATIONS_FORMAT,"xlf",[])])}),Iu=u["\u0275cmf"](G,[],function(l){return u["\u0275mod"]([u["\u0275mpd"](512,u.ComponentFactoryResolver,u["\u0275CodegenComponentFactoryResolver"],[[8,[K.a,$.a,J.a,H.a,H.b,W.a,Z.a,Y.a,X.a,Q.a,ll.a,nl.a,el.a,ul.a,ul.c,ul.b,tl.a,ol.a,il.a,al.a,rl.a,sl.a,dl.a,cl.a,pl.a,en,Se,Ru]],[3,u.ComponentFactoryResolver],u.NgModuleRef]),u["\u0275mpd"](4608,fl.NgLocalization,fl.NgLocaleLocalization,[u.LOCALE_ID,[2,fl["\u0275angular_packages_common_common_a"]]]),u["\u0275mpd"](4608,un.a,un.a,[s.a]),u["\u0275mpd"](4608,fl.DatePipe,fl.DatePipe,[u.LOCALE_ID]),u["\u0275mpd"](4608,tn.a,tn.a,[]),u["\u0275mpd"](4608,on.a,on.a,[]),u["\u0275mpd"](4608,R.a,R.a,[]),u["\u0275mpd"](4608,b.a,b.a,[R.a]),u["\u0275mpd"](4608,an.a,an.a,[R.a]),u["\u0275mpd"](4608,x.a,x.a,[R.a]),u["\u0275mpd"](4608,rn.a,rn.a,[]),u["\u0275mpd"](4608,sn.a,sn.a,[]),u["\u0275mpd"](4608,dn.a,dn.a,[]),u["\u0275mpd"](4608,cn.a,cn.a,[]),u["\u0275mpd"](4608,pn.a,pn.a,[fl.DatePipe]),u["\u0275mpd"](4608,fn.a,fn.a,[]),u["\u0275mpd"](4608,mn.a,mn.a,[]),u["\u0275mpd"](4608,gn.a,gn.a,[]),u["\u0275mpd"](4608,hn.a,hn.a,[]),u["\u0275mpd"](4608,vn.a,vn.a,[]),u["\u0275mpd"](4608,bn.a,bn.a,[s.a]),u["\u0275mpd"](4608,bl.a,bl.a,[]),u["\u0275mpd"](4608,Cn.a,Cn.a,[]),u["\u0275mpd"](4608,o.E,o.E,[]),u["\u0275mpd"](4608,o.h,o.h,[]),u["\u0275mpd"](4608,Rn.b,Rn.b,[]),u["\u0275mpd"](4608,yn.a,yn.a,[]),u["\u0275mpd"](4608,In.a,In.a,[u.RendererFactory2,u.PLATFORM_ID]),u["\u0275mpd"](4608,En.a,En.a,[u.ComponentFactoryResolver,u.NgZone,u.Injector,In.a,u.ApplicationRef]),u["\u0275mpd"](4608,Vn.a,Vn.a,[]),u["\u0275mpd"](4608,Vl.b,Vl.b,[u.RendererFactory2,En.a]),u["\u0275mpd"](4608,Tn.ScrollbarHelper,Tn.ScrollbarHelper,[wn.DOCUMENT]),u["\u0275mpd"](4608,Sn.DimensionsHelper,Sn.DimensionsHelper,[]),u["\u0275mpd"](4608,Nn.ColumnChangesService,Nn.ColumnChangesService,[]),u["\u0275mpd"](4608,_n.f,_n.f,[]),u["\u0275mpd"](4608,C.a,C.a,[]),u["\u0275mpd"](4608,Dn.a,Dn.a,[Pn.l,C.a]),u["\u0275mpd"](4608,kn.NodeDraggableService,kn.NodeDraggableService,[]),u["\u0275mpd"](4608,zn.NodeMenuService,zn.NodeMenuService,[]),u["\u0275mpd"](4608,xn.TreeService,xn.TreeService,[kn.NodeDraggableService]),u["\u0275mpd"](4608,Fn.e,Fn.e,[]),u["\u0275mpd"](4608,qn.c,qn.c,[]),u["\u0275mpd"](4608,An.r,An.r,[]),u["\u0275mpd"](4608,An.t,An.t,[]),u["\u0275mpd"](4608,An.a,An.a,[]),u["\u0275mpd"](4608,An.h,An.h,[]),u["\u0275mpd"](4608,An.d,An.d,[]),u["\u0275mpd"](4608,An.j,An.j,[]),u["\u0275mpd"](4608,An.s,An.s,[An.t,An.j]),u["\u0275mpd"](1073742336,fl.CommonModule,fl.CommonModule,[]),u["\u0275mpd"](1073742336,On.a,On.a,[]),u["\u0275mpd"](1073742336,Fn.c,Fn.c,[]),u["\u0275mpd"](1073742336,yn.d,yn.d,[]),u["\u0275mpd"](1073742336,Ln.a,Ln.a,[]),u["\u0275mpd"](1073742336,o.B,o.B,[]),u["\u0275mpd"](1073742336,o.n,o.n,[]),u["\u0275mpd"](1073742336,o.x,o.x,[]),u["\u0275mpd"](1073742336,Rn.c,Rn.c,[]),u["\u0275mpd"](1073742336,Vn.d,Vn.d,[]),u["\u0275mpd"](1073742336,jn.ChartsModule,jn.ChartsModule,[]),u["\u0275mpd"](1073742336,Vl.e,Vl.e,[]),u["\u0275mpd"](1073742336,Mn.a,Mn.a,[]),u["\u0275mpd"](1073742336,_n.e,_n.e,[]),u["\u0275mpd"](1073742336,Un.a,Un.a,[]),u["\u0275mpd"](1073742336,Bn.NgxDatatableModule,Bn.NgxDatatableModule,[]),u["\u0275mpd"](1073742336,Pn.p,Pn.p,[[2,Pn.v],[2,Pn.l]]),u["\u0275mpd"](1073742336,Gn.a,Gn.a,[]),u["\u0275mpd"](1073742336,d.a,d.a,[]),u["\u0275mpd"](1073742336,Kn.a,Kn.a,[]),u["\u0275mpd"](1073742336,qn.d,qn.d,[]),u["\u0275mpd"](1073742336,$n.TreeModule,$n.TreeModule,[]),u["\u0275mpd"](1073742336,Jn.a,Jn.a,[]),u["\u0275mpd"](1073742336,An.g,An.g,[]),u["\u0275mpd"](1073742336,Hn.a,Hn.a,[]),u["\u0275mpd"](1073742336,M,M,[]),u["\u0275mpd"](1073742336,G,G,[]),u["\u0275mpd"](256,u.LOCALE_ID,"en-US",[]),u["\u0275mpd"](256,_n.a,{autoClose:!0,insideClick:!1},[]),u["\u0275mpd"](1024,Pn.j,function(){return[[{path:"",component:j},{path:"create",component:N,data:U},{path:"edit/:name",component:N,data:B}]]},[]),u["\u0275mpd"](256,u.TRANSLATIONS_FORMAT,"xlf",[])])})}}]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/9.b19f6391d5c667b85d12.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/9.b19f6391d5c667b85d12.js new file mode 100644 index 00000000..b4cb12f4 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/9.b19f6391d5c667b85d12.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[9],{DY6s:function(l,n,e){"use strict";e.r(n);var u=e("CcnG"),o=e("LceX"),a=e("iutN"),t=e("ES0t"),d=e("MdoF"),s=e("Xg1U"),r=e("z5nN"),i=e("EEJc"),c=e("PEr+"),p=e("a40w"),m=e("pMnS"),f=e("Ip0R"),v=e("gIcY"),g=e("iExv"),h=e("Jm/i"),b=e("85J/"),C=e("+0ag"),R=e("aXbf"),I=e("Fgil"),y=e("IzCI"),T=e("o4+5"),w=e("Dwqy"),D=e("uYzU"),x=e("uhwM"),E=e("E2fk"),k=e("a0VL"),N=e("nSDx"),F=e("SB+Q"),S=e("TYzs"),_=e("BQkM"),P=e("dEH0"),M=e("G1/K"),A=e("8xTl"),q=e("TJUb"),V=e("lTVp"),L=e("OZfm"),U=e("NJnL"),O=e("lqqz"),j=e("eajB"),z=e("DQlY"),H=e("FO+L"),B=e("ZYjt"),Z=e("nhM1"),G=e("BARL"),K=e("xtZt"),Y=e("aexS"),J=e("Avrn"),X=e("ZYCi"),Q=e("YAQW"),W=e("9Xeq"),$=e("xdbM"),ll=e("yGOH"),nl=e("V/fk"),el=e("F8xH"),ul=e("ChqD"),ol=e("pL04"),al=e("PCNd"),tl=e("pKUh"),dl=function(){function l(l){this.router=l}return l.prototype.ngOnInit=function(){this.url=this.router.url},l.prototype.navigateTo=function(l){this.router.navigate([l])},l}(),sl=u["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function rl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,5,"tabset",[],[[2,"tab-container",null]],null,null,tl.b,tl.a)),u["\u0275did"](1,180224,null,0,Q.d,[Q.e,u.Renderer2,u.ElementRef],null,null),(l()(),u["\u0275eld"](2,0,null,0,1,"tab",[["heading","Users"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],[[null,"selectTab"]],function(l,n,e){var u=!0;return"selectTab"===n&&(u=!1!==l.component.navigateTo("/user-management/users")&&u),u},null,null)),u["\u0275did"](3,212992,null,0,Q.b,[Q.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"],active:[1,"active"]},{selectTab:"selectTab"}),(l()(),u["\u0275eld"](4,0,null,0,1,"tab",[["heading","Roles"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],[[null,"selectTab"]],function(l,n,e){var u=!0;return"selectTab"===n&&(u=!1!==l.component.navigateTo("/user-management/roles")&&u),u},null,null)),u["\u0275did"](5,212992,null,0,Q.b,[Q.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"],active:[1,"active"]},{selectTab:"selectTab"})],function(l,n){var e=n.component;l(n,3,0,"Users","/user-management/users"===e.url),l(n,5,0,"Roles","/user-management/roles"===e.url)},function(l,n){l(n,0,0,u["\u0275nov"](n,1).clazz),l(n,2,0,u["\u0275nov"](n,3).id,u["\u0275nov"](n,3).active,u["\u0275nov"](n,3).addClass),l(n,4,0,u["\u0275nov"](n,5).id,u["\u0275nov"](n,5).active,u["\u0275nov"](n,5).addClass)})}var il=e("25BL"),cl=e("uIqm"),pl=e("NUGo"),ml=e("S7zO"),fl=e("EgGo"),vl=e("ZEkX"),gl=e("Mxhz"),hl=e("9nlD"),bl=e("sne2"),Cl=u["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Rl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(l()(),u["\u0275ted"](1,null,[" ",""," "]))],null,function(l,n){l(n,1,0,n.context.$implicit,n.context.last?"":", ")})}function Il(l){return u["\u0275vid"](0,[(l()(),u["\u0275and"](16777216,null,null,1,null,Rl)),u["\u0275did"](1,278528,null,0,f.NgForOf,[u.ViewContainerRef,u.TemplateRef,u.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(l()(),u["\u0275and"](0,null,null,0))],function(l,n){l(n,1,0,n.context.value)},null)}function yl(l){return u["\u0275vid"](0,[u["\u0275qud"](402653184,1,{userRolesTpl:0}),(l()(),u["\u0275eld"](1,0,null,null,1,"cd-user-tabs",[],null,null,null,rl,sl)),u["\u0275did"](2,114688,null,0,dl,[X.l],null,null),(l()(),u["\u0275eld"](3,0,null,null,3,"cd-table",[["columnMode","flex"],["identifier","username"],["selectionType","single"]],null,[[null,"fetchData"],[null,"updateSelection"]],function(l,n,e){var u=!0,o=l.component;return"fetchData"===n&&(u=!1!==o.getUsers()&&u),"updateSelection"===n&&(u=!1!==o.updateSelection(e)&&u),u},il.b,il.a)),u["\u0275did"](4,2867200,null,0,cl.a,[u.NgZone,u.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],selectionType:[4,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(l()(),u["\u0275eld"](5,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,pl.b,pl.a)),u["\u0275did"](6,114688,null,0,ml.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),u["\u0275and"](0,[[1,2],["userRolesTpl",2]],null,0,null,Il))],function(l,n){var e=n.component;l(n,2,0),l(n,4,0,e.users,e.columns,"flex","username","single"),l(n,6,0,e.permission,e.selection,e.tableActions)},null)}function Tl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,2,"cd-user-list",[],null,null,null,yl,Cl)),u["\u0275prd"](256,null,fl.a,vl.b,[]),u["\u0275did"](2,114688,null,0,vl.a,[gl.a,N.a,z.b,hl.a,Y.a,h.a,fl.a,bl.b],null,null)],function(l,n){l(n,2,0)},null)}var wl=u["\u0275ccf"]("cd-user-list",vl.a,Tl,{},{},[]),Dl=e("pYKc"),xl=e("ppaS"),El=e("IZUe"),kl=e("ANnk"),Nl=e("f/UV"),Fl=e("D4zM"),Sl=e("gp3X"),_l=e("sb0X"),Pl=e("KVJa"),Ml=e("Z21x"),Al=e("V3my"),ql=e("DSvg"),Vl=e("SgmB"),Ll=u["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Ul(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function Ol(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required."]))],null,null)}function jl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required."]))],null,null)}function zl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Hl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Password confirmation doesn't match the password."]))],null,null)}function Bl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Invalid email."]))],null,null)}function Zl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,2,"span",[["class","form-control no-border full-height"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"cd-select-badges",[],null,null,null,Dl.b,Dl.a)),u["\u0275did"](2,49152,null,0,xl.a,[h.a],{data:[0,"data"],options:[1,"options"],messages:[2,"messages"]},null)],function(l,n){var e=n.component;l(n,2,0,e.userForm.controls.roles.value,e.allRoles,e.messages)},null)}function Gl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,2,"p",[],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"strong",[],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,['You are about to remove "user read / update" permissions from your own user.'])),(l()(),u["\u0275eld"](3,0,null,null,0,"br",[],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,1,"p",[],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["If you continue, you will no longer be able to add or remove roles from any user."])),(l()(),u["\u0275eld"](6,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Are you sure you want to continue?"]))],null,null)}function Kl(l){return u["\u0275vid"](0,[u["\u0275pid"](0,f.TitleCasePipe,[]),u["\u0275pid"](0,A.a,[]),u["\u0275qud"](402653184,1,{removeSelfUserReadUpdatePermissionTpl:0}),(l()(),u["\u0275eld"](3,0,null,null,111,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(l()(),u["\u0275eld"](4,0,null,null,110,"form",[["class","form-horizontal"],["name","userForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var o=!0;return"submit"===n&&(o=!1!==u["\u0275nov"](l,6).onSubmit(e)&&o),"reset"===n&&(o=!1!==u["\u0275nov"](l,6).onReset()&&o),o},null,null)),u["\u0275did"](5,16384,null,0,v.D,[],null,null),u["\u0275did"](6,540672,[["formDir",4]],0,v.l,[[8,null],[8,null]],{form:[0,"form"]},null),u["\u0275prd"](2048,null,v.d,null,[v.l]),u["\u0275did"](8,16384,null,0,v.s,[[4,v.d]],null,null),(l()(),u["\u0275eld"](9,0,null,null,105,"div",[["class","panel panel-default"]],null,null,null,null,null)),(l()(),u["\u0275eld"](10,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),u["\u0275eld"](11,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(l()(),u["\u0275ted"](12,null,[""," ",""])),u["\u0275ppd"](13,1),u["\u0275ppd"](14,1),(l()(),u["\u0275eld"](15,0,null,null,90,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),u["\u0275eld"](16,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](17,278528,null,0,f.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](18,{"has-error":0}),(l()(),u["\u0275eld"](19,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),u["\u0275eld"](20,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Username"])),(l()(),u["\u0275and"](16777216,null,null,1,null,Ul)),u["\u0275did"](23,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](24,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](25,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","username"],["id","username"],["name","username"],["placeholder","Username..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var o=!0;return"input"===n&&(o=!1!==u["\u0275nov"](l,26)._handleInput(e.target.value)&&o),"blur"===n&&(o=!1!==u["\u0275nov"](l,26).onTouched()&&o),"compositionstart"===n&&(o=!1!==u["\u0275nov"](l,26)._compositionStart()&&o),"compositionend"===n&&(o=!1!==u["\u0275nov"](l,26)._compositionEnd(e.target.value)&&o),o},null,null)),u["\u0275did"](26,16384,null,0,v.e,[u.Renderer2,u.ElementRef,[2,v.b]],null,null),u["\u0275prd"](1024,null,v.p,function(l){return[l]},[v.e]),u["\u0275did"](28,671744,null,0,v.j,[[3,v.d],[8,null],[8,null],[6,v.p],[2,v.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,v.q,null,[v.j]),u["\u0275did"](30,16384,null,0,v.r,[[4,v.q]],null,null),u["\u0275did"](31,4210688,null,0,El.a,[u.ElementRef],null,null),u["\u0275did"](32,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Ol)),u["\u0275did"](34,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](35,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](36,278528,null,0,f.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](37,{"has-error":0}),(l()(),u["\u0275eld"](38,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Password"])),(l()(),u["\u0275eld"](40,0,null,null,13,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](41,0,null,null,10,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](42,0,null,null,6,"input",[["autocomplete","new-password"],["class","form-control"],["formControlName","password"],["id","password"],["name","password"],["placeholder","Password..."],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var o=!0;return"input"===n&&(o=!1!==u["\u0275nov"](l,43)._handleInput(e.target.value)&&o),"blur"===n&&(o=!1!==u["\u0275nov"](l,43).onTouched()&&o),"compositionstart"===n&&(o=!1!==u["\u0275nov"](l,43)._compositionStart()&&o),"compositionend"===n&&(o=!1!==u["\u0275nov"](l,43)._compositionEnd(e.target.value)&&o),o},null,null)),u["\u0275did"](43,16384,null,0,v.e,[u.Renderer2,u.ElementRef,[2,v.b]],null,null),u["\u0275prd"](1024,null,v.p,function(l){return[l]},[v.e]),u["\u0275did"](45,671744,null,0,v.j,[[3,v.d],[8,null],[8,null],[6,v.p],[2,v.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,v.q,null,[v.j]),u["\u0275did"](47,16384,null,0,v.r,[[4,v.q]],null,null),u["\u0275did"](48,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275eld"](49,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),u["\u0275eld"](50,0,null,null,1,"button",[["cdPasswordButton","password"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,e){var o=!0;return"click"===n&&(o=!1!==u["\u0275nov"](l,51).onClick()&&o),o},null,null)),u["\u0275did"](51,81920,null,0,Fl.a,[u.ElementRef,u.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,jl)),u["\u0275did"](53,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](54,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](55,278528,null,0,f.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](56,{"has-error":0}),(l()(),u["\u0275eld"](57,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Confirm password"])),(l()(),u["\u0275eld"](59,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](60,0,null,null,10,"div",[["class","input-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](61,0,null,null,6,"input",[["class","form-control"],["formControlName","confirmpassword"],["id","confirmpassword"],["name","confirmpassword"],["placeholder","Confirm password..."],["type","password"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var o=!0;return"input"===n&&(o=!1!==u["\u0275nov"](l,62)._handleInput(e.target.value)&&o),"blur"===n&&(o=!1!==u["\u0275nov"](l,62).onTouched()&&o),"compositionstart"===n&&(o=!1!==u["\u0275nov"](l,62)._compositionStart()&&o),"compositionend"===n&&(o=!1!==u["\u0275nov"](l,62)._compositionEnd(e.target.value)&&o),o},null,null)),u["\u0275did"](62,16384,null,0,v.e,[u.Renderer2,u.ElementRef,[2,v.b]],null,null),u["\u0275prd"](1024,null,v.p,function(l){return[l]},[v.e]),u["\u0275did"](64,671744,null,0,v.j,[[3,v.d],[8,null],[8,null],[6,v.p],[2,v.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,v.q,null,[v.j]),u["\u0275did"](66,16384,null,0,v.r,[[4,v.q]],null,null),u["\u0275did"](67,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275eld"](68,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(l()(),u["\u0275eld"](69,0,null,null,1,"button",[["cdPasswordButton","confirmpassword"],["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(l,n,e){var o=!0;return"click"===n&&(o=!1!==u["\u0275nov"](l,70).onClick()&&o),o},null,null)),u["\u0275did"](70,81920,null,0,Fl.a,[u.ElementRef,u.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,zl)),u["\u0275did"](72,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,Hl)),u["\u0275did"](74,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](75,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](76,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Full name"])),(l()(),u["\u0275eld"](78,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](79,0,null,null,6,"input",[["class","form-control"],["formControlName","name"],["id","name"],["name","name"],["placeholder","Full name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var o=!0;return"input"===n&&(o=!1!==u["\u0275nov"](l,80)._handleInput(e.target.value)&&o),"blur"===n&&(o=!1!==u["\u0275nov"](l,80).onTouched()&&o),"compositionstart"===n&&(o=!1!==u["\u0275nov"](l,80)._compositionStart()&&o),"compositionend"===n&&(o=!1!==u["\u0275nov"](l,80)._compositionEnd(e.target.value)&&o),o},null,null)),u["\u0275did"](80,16384,null,0,v.e,[u.Renderer2,u.ElementRef,[2,v.b]],null,null),u["\u0275prd"](1024,null,v.p,function(l){return[l]},[v.e]),u["\u0275did"](82,671744,null,0,v.j,[[3,v.d],[8,null],[8,null],[6,v.p],[2,v.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,v.q,null,[v.j]),u["\u0275did"](84,16384,null,0,v.r,[[4,v.q]],null,null),u["\u0275did"](85,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275eld"](86,0,null,null,14,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](87,278528,null,0,f.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](88,{"has-error":0}),(l()(),u["\u0275eld"](89,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","email"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Email"])),(l()(),u["\u0275eld"](91,0,null,null,9,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](92,0,null,null,6,"input",[["class","form-control"],["formControlName","email"],["id","email"],["name","email"],["placeholder","Email..."],["type","email"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var o=!0;return"input"===n&&(o=!1!==u["\u0275nov"](l,93)._handleInput(e.target.value)&&o),"blur"===n&&(o=!1!==u["\u0275nov"](l,93).onTouched()&&o),"compositionstart"===n&&(o=!1!==u["\u0275nov"](l,93)._compositionStart()&&o),"compositionend"===n&&(o=!1!==u["\u0275nov"](l,93)._compositionEnd(e.target.value)&&o),o},null,null)),u["\u0275did"](93,16384,null,0,v.e,[u.Renderer2,u.ElementRef,[2,v.b]],null,null),u["\u0275prd"](1024,null,v.p,function(l){return[l]},[v.e]),u["\u0275did"](95,671744,null,0,v.j,[[3,v.d],[8,null],[8,null],[6,v.p],[2,v.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,v.q,null,[v.j]),u["\u0275did"](97,16384,null,0,v.r,[[4,v.q]],null,null),u["\u0275did"](98,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,Bl)),u["\u0275did"](100,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](101,0,null,null,1,"label",[["class","col-sm-3 control-label"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Roles"])),(l()(),u["\u0275eld"](103,0,null,null,2,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275and"](16777216,null,null,1,null,Zl)),u["\u0275did"](105,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](106,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(l()(),u["\u0275eld"](107,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),u["\u0275eld"](108,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(l,n,e){var u=!0;return"submitAction"===n&&(u=!1!==l.component.submit()&&u),u},Sl.b,Sl.a)),u["\u0275did"](109,114688,null,0,_l.a,[u.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(l()(),u["\u0275ted"](110,0,[""," ",""])),u["\u0275ppd"](111,1),u["\u0275ppd"](112,1),(l()(),u["\u0275eld"](113,0,null,null,1,"cd-back-button",[],null,null,null,Pl.b,Pl.a)),u["\u0275did"](114,49152,null,0,Ml.a,[f.Location,bl.b],null,null),(l()(),u["\u0275and"](0,[[1,2],["removeSelfUserReadUpdatePermissionTpl",2]],null,0,null,Gl))],function(l,n){var e=n.component;l(n,6,0,e.userForm);var o=l(n,18,0,e.userForm.showError("username",u["\u0275nov"](n,6)));l(n,17,0,"form-group",o),l(n,23,0,e.mode!==e.userFormMode.editing),l(n,28,0,"username"),l(n,34,0,e.userForm.showError("username",u["\u0275nov"](n,6),"required"));var a=l(n,37,0,e.userForm.showError("password",u["\u0275nov"](n,6)));l(n,36,0,"form-group",a),l(n,45,0,"password"),l(n,51,0,"password"),l(n,53,0,e.userForm.showError("password",u["\u0275nov"](n,6),"required"));var t=l(n,56,0,e.userForm.showError("confirmpassword",u["\u0275nov"](n,6)));l(n,55,0,"form-group",t),l(n,64,0,"confirmpassword"),l(n,70,0,"confirmpassword"),l(n,72,0,e.userForm.showError("confirmpassword",u["\u0275nov"](n,6),"required")),l(n,74,0,e.userForm.showError("confirmpassword",u["\u0275nov"](n,6),"match")),l(n,82,0,"name");var d=l(n,88,0,e.userForm.showError("email",u["\u0275nov"](n,6)));l(n,87,0,"form-group",d),l(n,95,0,"email"),l(n,100,0,e.userForm.showError("email",u["\u0275nov"](n,6),"email")),l(n,105,0,e.allRoles),l(n,109,0,u["\u0275nov"](n,6),"button")},function(l,n){var e=n.component;l(n,4,0,u["\u0275nov"](n,8).ngClassUntouched,u["\u0275nov"](n,8).ngClassTouched,u["\u0275nov"](n,8).ngClassPristine,u["\u0275nov"](n,8).ngClassDirty,u["\u0275nov"](n,8).ngClassValid,u["\u0275nov"](n,8).ngClassInvalid,u["\u0275nov"](n,8).ngClassPending);var o=u["\u0275unv"](n,12,0,l(n,13,0,u["\u0275nov"](n,0),e.action)),a=u["\u0275unv"](n,12,1,l(n,14,0,u["\u0275nov"](n,1),e.resource));l(n,12,0,o,a),l(n,25,0,u["\u0275nov"](n,30).ngClassUntouched,u["\u0275nov"](n,30).ngClassTouched,u["\u0275nov"](n,30).ngClassPristine,u["\u0275nov"](n,30).ngClassDirty,u["\u0275nov"](n,30).ngClassValid,u["\u0275nov"](n,30).ngClassInvalid,u["\u0275nov"](n,30).ngClassPending),l(n,42,0,u["\u0275nov"](n,47).ngClassUntouched,u["\u0275nov"](n,47).ngClassTouched,u["\u0275nov"](n,47).ngClassPristine,u["\u0275nov"](n,47).ngClassDirty,u["\u0275nov"](n,47).ngClassValid,u["\u0275nov"](n,47).ngClassInvalid,u["\u0275nov"](n,47).ngClassPending),l(n,61,0,u["\u0275nov"](n,66).ngClassUntouched,u["\u0275nov"](n,66).ngClassTouched,u["\u0275nov"](n,66).ngClassPristine,u["\u0275nov"](n,66).ngClassDirty,u["\u0275nov"](n,66).ngClassValid,u["\u0275nov"](n,66).ngClassInvalid,u["\u0275nov"](n,66).ngClassPending),l(n,79,0,u["\u0275nov"](n,84).ngClassUntouched,u["\u0275nov"](n,84).ngClassTouched,u["\u0275nov"](n,84).ngClassPristine,u["\u0275nov"](n,84).ngClassDirty,u["\u0275nov"](n,84).ngClassValid,u["\u0275nov"](n,84).ngClassInvalid,u["\u0275nov"](n,84).ngClassPending),l(n,92,0,u["\u0275nov"](n,97).ngClassUntouched,u["\u0275nov"](n,97).ngClassTouched,u["\u0275nov"](n,97).ngClassPristine,u["\u0275nov"](n,97).ngClassDirty,u["\u0275nov"](n,97).ngClassValid,u["\u0275nov"](n,97).ngClassInvalid,u["\u0275nov"](n,97).ngClassPending);var t=u["\u0275unv"](n,110,0,l(n,111,0,u["\u0275nov"](n,0),e.action)),d=u["\u0275unv"](n,110,1,l(n,112,0,u["\u0275nov"](n,1),e.resource));l(n,110,0,t,d)})}function Yl(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"cd-user-form",[],null,null,null,Kl,Ll)),u["\u0275did"](1,114688,null,0,Al.a,[ql.a,Y.a,X.a,X.l,z.b,Vl.a,gl.a,hl.a,h.a,bl.b],null,null)],function(l,n){l(n,1,0)},null)}var Jl=u["\u0275ccf"]("cd-user-form",Al.a,Yl,{},{},[]),Xl=e("LvDl"),Ql=e("x38r"),Wl=(e("vCyI"),function(){function l(l){this.i18n=l,this.scopes_permissions=[]}return l.prototype.ngOnInit=function(){this.columns=[{prop:"scope",name:this.i18n("Scope"),flexGrow:2},{prop:"read",name:this.i18n("Read"),flexGrow:1,cellClass:"text-center",cellTransformation:Ql.a.checkIcon},{prop:"create",name:this.i18n("Create"),flexGrow:1,cellClass:"text-center",cellTransformation:Ql.a.checkIcon},{prop:"update",name:this.i18n("Update"),flexGrow:1,cellClass:"text-center",cellTransformation:Ql.a.checkIcon},{prop:"delete",name:this.i18n("Delete"),flexGrow:1,cellClass:"text-center",cellTransformation:Ql.a.checkIcon}]},l.prototype.ngOnChanges=function(){var l=this;if(this.selection.hasSelection){this.selectedItem=this.selection.first();var n=[];Xl.each(this.scopes,function(e){var u={read:!1,create:!1,update:!1,delete:!1};u.scope=e,e in l.selectedItem.scopes_permissions&&Xl.each(l.selectedItem.scopes_permissions[e],function(l){u[l]=!0}),n.push(u)}),this.scopes_permissions=n}},l}()),$l=u["\u0275crt"]({encapsulation:0,styles:[["thead[_ngcontent-%COMP%]{background-color:#f5f5f5}.fa[_ngcontent-%COMP%]{font-size:large}.fa.fa-square-o[_ngcontent-%COMP%]{color:#d1d1d1}"]],data:{}});function ln(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,5,"tabset",[],[[2,"tab-container",null]],null,null,tl.b,tl.a)),u["\u0275did"](1,180224,null,0,Q.d,[Q.e,u.Renderer2,u.ElementRef],null,null),(l()(),u["\u0275eld"](2,0,null,0,3,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),u["\u0275did"](3,212992,null,0,Q.b,[Q.d,u.ElementRef,u.Renderer2],{heading:[0,"heading"]},null),(l()(),u["\u0275eld"](4,0,null,null,1,"cd-table",[["columnMode","flex"]],null,null,null,il.b,il.a)),u["\u0275did"](5,2867200,null,0,cl.a,[u.NgZone,u.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],toolHeader:[3,"toolHeader"],footer:[4,"footer"],limit:[5,"limit"],autoReload:[6,"autoReload"],autoSave:[7,"autoSave"]},null)],function(l,n){var e=n.component;l(n,3,0,"Details"),l(n,5,0,e.scopes_permissions,e.columns,"flex",!1,!1,0,!1,!1)},function(l,n){l(n,0,0,u["\u0275nov"](n,1).clazz),l(n,2,0,u["\u0275nov"](n,3).id,u["\u0275nov"](n,3).active,u["\u0275nov"](n,3).addClass)})}function nn(l){return u["\u0275vid"](0,[(l()(),u["\u0275and"](16777216,null,null,1,null,ln)),u["\u0275did"](1,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(l,n){var e=n.component;l(n,1,0,null==e.selection?null:e.selection.hasSingleSelection)},null)}var en=e("n/D3"),un=e("ZDA6"),on=u["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function an(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"cd-user-tabs",[],null,null,null,rl,sl)),u["\u0275did"](1,114688,null,0,dl,[X.l],null,null),(l()(),u["\u0275eld"](2,0,null,null,5,"cd-table",[["columnMode","flex"],["identifier","name"],["selectionType","single"]],null,[[null,"fetchData"],[null,"updateSelection"]],function(l,n,e){var u=!0,o=l.component;return"fetchData"===n&&(u=!1!==o.getRoles()&&u),"updateSelection"===n&&(u=!1!==o.updateSelection(e)&&u),u},il.b,il.a)),u["\u0275did"](3,2867200,null,0,cl.a,[u.NgZone,u.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],selectionType:[4,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(l()(),u["\u0275eld"](4,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,pl.b,pl.a)),u["\u0275did"](5,114688,null,0,ml.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(l()(),u["\u0275eld"](6,0,null,2,1,"cd-role-details",[["cdTableDetail",""]],null,null,null,nn,$l)),u["\u0275did"](7,638976,null,0,Wl,[h.a],{selection:[0,"selection"],scopes:[1,"scopes"]},null)],function(l,n){var e=n.component;l(n,1,0),l(n,3,0,e.roles,e.columns,"flex","name","single"),l(n,5,0,e.permission,e.selection,e.tableActions),l(n,7,0,e.selection,e.scopes)},null)}function tn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,2,"cd-role-list",[],null,null,null,an,on)),u["\u0275prd"](256,null,fl.a,en.b,[]),u["\u0275did"](2,114688,null,0,en.a,[Vl.a,un.a,N.a,Y.a,z.b,hl.a,h.a,fl.a,bl.b],null,null)],function(l,n){l(n,2,0)},null)}var dn=u["\u0275ccf"]("cd-role-list",en.a,tn,{},{},[]),sn=e("eTJe"),rn=u["\u0275crt"]({encapsulation:0,styles:[[".datatable-permissions-header-cell-label[_ngcontent-%COMP%], .datatable-permissions-scope-cell-label[_ngcontent-%COMP%]{font-weight:700}"]],data:{}});function cn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function pn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["This field is required."]))],null,null)}function mn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["The chosen name is already in use."]))],null,null)}function fn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,4,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"input",[["type","checkbox"]],[[8,"id",0],[8,"checked",0]],[[null,"change"]],function(l,n,e){var u=!0;return"change"===n&&(u=!1!==l.component.onClickCellCheckbox(l.context.row.scope,l.context.column.prop,e)&&u),u},null,null)),u["\u0275did"](2,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275eld"](3,0,null,null,1,"label",[["class","datatable-permissions-scope-cell-label"]],[[8,"htmlFor",0]],null,null,null,null)),(l()(),u["\u0275ted"](4,null,["",""]))],null,function(l,n){var e=n.component;l(n,1,0,u["\u0275inlineInterpolate"](1,"scope_",n.context.row.scope,""),e.isRowChecked(n.context.row.scope)),l(n,3,0,u["\u0275inlineInterpolate"](1,"scope_",n.context.row.scope,"")),l(n,4,0,n.context.value)})}function vn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,3,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"input",[["type","checkbox"]],[[8,"checked",0]],[[null,"change"]],function(l,n,e){var u=!0;return"change"===n&&(u=!1!==l.component.onClickCellCheckbox(l.context.row.scope,l.context.column.prop,e)&&u),u},null,null)),u["\u0275did"](2,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275eld"](3,0,null,null,0,"label",[],null,null,null,null,null))],null,function(l,n){l(n,1,0,n.context.value)})}function gn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,4,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(l()(),u["\u0275eld"](1,0,null,null,1,"input",[["type","checkbox"]],[[8,"id",0],[8,"checked",0]],[[null,"change"]],function(l,n,e){var u=!0;return"change"===n&&(u=!1!==l.component.onClickHeaderCheckbox(l.context.column.prop,e)&&u),u},null,null)),u["\u0275did"](2,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275eld"](3,0,null,null,1,"label",[["class","datatable-permissions-header-cell-label"]],[[8,"htmlFor",0]],null,null,null,null)),(l()(),u["\u0275ted"](4,null,["",""]))],null,function(l,n){var e=n.component;l(n,1,0,u["\u0275inlineInterpolate"](1,"header_",n.context.column.prop,""),e.isHeaderChecked(n.context.column.prop)),l(n,3,0,u["\u0275inlineInterpolate"](1,"header_",n.context.column.prop,"")),l(n,4,0,n.context.column.name)})}function hn(l){return u["\u0275vid"](0,[u["\u0275pid"](0,f.TitleCasePipe,[]),u["\u0275pid"](0,A.a,[]),u["\u0275qud"](402653184,1,{headerPermissionCheckboxTpl:0}),u["\u0275qud"](402653184,2,{cellScopeCheckboxTpl:0}),u["\u0275qud"](402653184,3,{cellPermissionCheckboxTpl:0}),(l()(),u["\u0275eld"](5,0,null,null,61,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(l()(),u["\u0275eld"](6,0,null,null,60,"form",[["class","form-horizontal"],["name","roleForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,e){var o=!0;return"submit"===n&&(o=!1!==u["\u0275nov"](l,8).onSubmit(e)&&o),"reset"===n&&(o=!1!==u["\u0275nov"](l,8).onReset()&&o),o},null,null)),u["\u0275did"](7,16384,null,0,v.D,[],null,null),u["\u0275did"](8,540672,[["formDir",4]],0,v.l,[[8,null],[8,null]],{form:[0,"form"]},null),u["\u0275prd"](2048,null,v.d,null,[v.l]),u["\u0275did"](10,16384,null,0,v.s,[[4,v.d]],null,null),(l()(),u["\u0275eld"](11,0,null,null,55,"div",[["class","panel panel-default"]],null,null,null,null,null)),(l()(),u["\u0275eld"](12,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(l()(),u["\u0275eld"](13,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(l()(),u["\u0275ted"](14,null,[""," ",""])),u["\u0275ppd"](15,1),u["\u0275ppd"](16,1),(l()(),u["\u0275eld"](17,0,null,null,40,"div",[["class","panel-body"]],null,null,null,null,null)),(l()(),u["\u0275eld"](18,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](19,278528,null,0,f.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](20,{"has-error":0}),(l()(),u["\u0275eld"](21,0,null,null,4,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(l()(),u["\u0275eld"](22,0,null,null,1,null,null,null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Name"])),(l()(),u["\u0275and"](16777216,null,null,1,null,cn)),u["\u0275did"](25,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](26,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](27,0,null,null,7,"input",[["autofocus",""],["class","form-control"],["formControlName","name"],["id","name"],["name","name"],["placeholder","Name..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var o=!0;return"input"===n&&(o=!1!==u["\u0275nov"](l,28)._handleInput(e.target.value)&&o),"blur"===n&&(o=!1!==u["\u0275nov"](l,28).onTouched()&&o),"compositionstart"===n&&(o=!1!==u["\u0275nov"](l,28)._compositionStart()&&o),"compositionend"===n&&(o=!1!==u["\u0275nov"](l,28)._compositionEnd(e.target.value)&&o),o},null,null)),u["\u0275did"](28,16384,null,0,v.e,[u.Renderer2,u.ElementRef,[2,v.b]],null,null),u["\u0275prd"](1024,null,v.p,function(l){return[l]},[v.e]),u["\u0275did"](30,671744,null,0,v.j,[[3,v.d],[8,null],[8,null],[6,v.p],[2,v.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,v.q,null,[v.j]),u["\u0275did"](32,16384,null,0,v.r,[[4,v.q]],null,null),u["\u0275did"](33,4210688,null,0,El.a,[u.ElementRef],null,null),u["\u0275did"](34,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275and"](16777216,null,null,1,null,pn)),u["\u0275did"](36,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275and"](16777216,null,null,1,null,mn)),u["\u0275did"](38,16384,null,0,f.NgIf,[u.ViewContainerRef,u.TemplateRef],{ngIf:[0,"ngIf"]},null),(l()(),u["\u0275eld"](39,0,null,null,12,"div",[["class","form-group"]],null,null,null,null,null)),u["\u0275did"](40,278528,null,0,f.NgClass,[u.IterableDiffers,u.KeyValueDiffers,u.ElementRef,u.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),u["\u0275pod"](41,{"has-error":0}),(l()(),u["\u0275eld"](42,0,null,null,1,"label",[["class","control-label col-sm-3"],["for","description"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Description"])),(l()(),u["\u0275eld"](44,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](45,0,null,null,6,"input",[["class","form-control"],["formControlName","description"],["id","description"],["name","description"],["placeholder","Description..."],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,e){var o=!0;return"input"===n&&(o=!1!==u["\u0275nov"](l,46)._handleInput(e.target.value)&&o),"blur"===n&&(o=!1!==u["\u0275nov"](l,46).onTouched()&&o),"compositionstart"===n&&(o=!1!==u["\u0275nov"](l,46)._compositionStart()&&o),"compositionend"===n&&(o=!1!==u["\u0275nov"](l,46)._compositionEnd(e.target.value)&&o),o},null,null)),u["\u0275did"](46,16384,null,0,v.e,[u.Renderer2,u.ElementRef,[2,v.b]],null,null),u["\u0275prd"](1024,null,v.p,function(l){return[l]},[v.e]),u["\u0275did"](48,671744,null,0,v.j,[[3,v.d],[8,null],[8,null],[6,v.p],[2,v.F]],{name:[0,"name"]},null),u["\u0275prd"](2048,null,v.q,null,[v.j]),u["\u0275did"](50,16384,null,0,v.r,[[4,v.q]],null,null),u["\u0275did"](51,4210688,null,0,kl.a,[[2,Nl.a],Y.a,u.ElementRef],null,null),(l()(),u["\u0275eld"](52,0,null,null,5,"div",[["class","form-group"]],null,null,null,null,null)),(l()(),u["\u0275eld"](53,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(l()(),u["\u0275ted"](-1,null,["Permissions"])),(l()(),u["\u0275eld"](55,0,null,null,2,"div",[["class","col-sm-9"]],null,null,null,null,null)),(l()(),u["\u0275eld"](56,0,null,null,1,"cd-table",[["columnMode","flex"]],null,null,null,il.b,il.a)),u["\u0275did"](57,2867200,null,0,cl.a,[u.NgZone,u.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],toolHeader:[3,"toolHeader"],footer:[4,"footer"],limit:[5,"limit"],autoReload:[6,"autoReload"],autoSave:[7,"autoSave"]},null),(l()(),u["\u0275eld"](58,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(l()(),u["\u0275eld"](59,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(l()(),u["\u0275eld"](60,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(l,n,e){var u=!0;return"submitAction"===n&&(u=!1!==l.component.submit()&&u),u},Sl.b,Sl.a)),u["\u0275did"](61,114688,null,0,_l.a,[u.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(l()(),u["\u0275ted"](62,0,[""," ",""])),u["\u0275ppd"](63,1),u["\u0275ppd"](64,1),(l()(),u["\u0275eld"](65,0,null,null,1,"cd-back-button",[],null,null,null,Pl.b,Pl.a)),u["\u0275did"](66,49152,null,0,Ml.a,[f.Location,bl.b],null,null),(l()(),u["\u0275and"](0,[[2,2],["cellScopeCheckboxTpl",2]],null,0,null,fn)),(l()(),u["\u0275and"](0,[[3,2],["cellPermissionCheckboxTpl",2]],null,0,null,vn)),(l()(),u["\u0275and"](0,[[1,2],["headerPermissionCheckboxTpl",2]],null,0,null,gn))],function(l,n){var e=n.component;l(n,8,0,e.roleForm);var o=l(n,20,0,e.roleForm.showError("name",u["\u0275nov"](n,8)));l(n,19,0,"form-group",o),l(n,25,0,e.mode!==e.roleFormMode.editing),l(n,30,0,"name"),l(n,36,0,e.roleForm.showError("name",u["\u0275nov"](n,8),"required")),l(n,38,0,e.roleForm.showError("name",u["\u0275nov"](n,8),"notUnique"));var a=l(n,41,0,e.roleForm.showError("description",u["\u0275nov"](n,8)));l(n,40,0,"form-group",a),l(n,48,0,"description"),l(n,57,0,e.scopes_permissions,e.columns,"flex",!1,!1,0,!1,!1),l(n,61,0,u["\u0275nov"](n,8),"button")},function(l,n){var e=n.component;l(n,6,0,u["\u0275nov"](n,10).ngClassUntouched,u["\u0275nov"](n,10).ngClassTouched,u["\u0275nov"](n,10).ngClassPristine,u["\u0275nov"](n,10).ngClassDirty,u["\u0275nov"](n,10).ngClassValid,u["\u0275nov"](n,10).ngClassInvalid,u["\u0275nov"](n,10).ngClassPending);var o=u["\u0275unv"](n,14,0,l(n,15,0,u["\u0275nov"](n,0),e.action)),a=u["\u0275unv"](n,14,1,l(n,16,0,u["\u0275nov"](n,1),e.resource));l(n,14,0,o,a),l(n,27,0,u["\u0275nov"](n,32).ngClassUntouched,u["\u0275nov"](n,32).ngClassTouched,u["\u0275nov"](n,32).ngClassPristine,u["\u0275nov"](n,32).ngClassDirty,u["\u0275nov"](n,32).ngClassValid,u["\u0275nov"](n,32).ngClassInvalid,u["\u0275nov"](n,32).ngClassPending),l(n,45,0,u["\u0275nov"](n,50).ngClassUntouched,u["\u0275nov"](n,50).ngClassTouched,u["\u0275nov"](n,50).ngClassPristine,u["\u0275nov"](n,50).ngClassDirty,u["\u0275nov"](n,50).ngClassValid,u["\u0275nov"](n,50).ngClassInvalid,u["\u0275nov"](n,50).ngClassPending);var t=u["\u0275unv"](n,62,0,l(n,63,0,u["\u0275nov"](n,0),e.action)),d=u["\u0275unv"](n,62,1,l(n,64,0,u["\u0275nov"](n,1),e.resource));l(n,62,0,t,d)})}function bn(l){return u["\u0275vid"](0,[(l()(),u["\u0275eld"](0,0,null,null,1,"cd-role-form",[],null,null,null,hn,rn)),u["\u0275did"](1,114688,null,0,sn.a,[X.a,X.l,Vl.a,un.a,hl.a,h.a,bl.b],null,null)],function(l,n){l(n,1,0)},null)}var Cn=u["\u0275ccf"]("cd-role-form",sn.a,bn,{},{},[]);e.d(n,"AuthModuleNgFactory",function(){return Rn}),e.d(n,"RoutedAuthModuleNgFactory",function(){return In});var Rn=u["\u0275cmf"](o.a,[],function(l){return u["\u0275mod"]([u["\u0275mpd"](512,u.ComponentFactoryResolver,u["\u0275CodegenComponentFactoryResolver"],[[8,[a.a,t.a,d.a,s.a,r.a,r.b,i.a,c.a,p.a,m.a]],[3,u.ComponentFactoryResolver],u.NgModuleRef]),u["\u0275mpd"](4608,f.NgLocalization,f.NgLocaleLocalization,[u.LOCALE_ID,[2,f["\u0275angular_packages_common_common_a"]]]),u["\u0275mpd"](4608,v.E,v.E,[]),u["\u0275mpd"](4608,v.h,v.h,[]),u["\u0275mpd"](4608,g.a,g.a,[h.a]),u["\u0275mpd"](4608,f.DatePipe,f.DatePipe,[u.LOCALE_ID]),u["\u0275mpd"](4608,b.a,b.a,[]),u["\u0275mpd"](4608,C.a,C.a,[]),u["\u0275mpd"](4608,R.a,R.a,[]),u["\u0275mpd"](4608,I.a,I.a,[R.a]),u["\u0275mpd"](4608,y.a,y.a,[R.a]),u["\u0275mpd"](4608,T.a,T.a,[R.a]),u["\u0275mpd"](4608,w.a,w.a,[]),u["\u0275mpd"](4608,D.a,D.a,[]),u["\u0275mpd"](4608,x.a,x.a,[]),u["\u0275mpd"](4608,E.a,E.a,[]),u["\u0275mpd"](4608,k.a,k.a,[f.DatePipe]),u["\u0275mpd"](4608,N.a,N.a,[]),u["\u0275mpd"](4608,F.a,F.a,[]),u["\u0275mpd"](4608,S.a,S.a,[]),u["\u0275mpd"](4608,_.a,_.a,[]),u["\u0275mpd"](4608,P.a,P.a,[]),u["\u0275mpd"](4608,M.a,M.a,[h.a]),u["\u0275mpd"](4608,A.a,A.a,[]),u["\u0275mpd"](4608,q.a,q.a,[]),u["\u0275mpd"](4608,V.b,V.b,[]),u["\u0275mpd"](4608,L.a,L.a,[]),u["\u0275mpd"](4608,U.a,U.a,[u.RendererFactory2,u.PLATFORM_ID]),u["\u0275mpd"](4608,O.a,O.a,[u.ComponentFactoryResolver,u.NgZone,u.Injector,U.a,u.ApplicationRef]),u["\u0275mpd"](4608,j.a,j.a,[]),u["\u0275mpd"](4608,z.b,z.b,[u.RendererFactory2,O.a]),u["\u0275mpd"](4608,H.ScrollbarHelper,H.ScrollbarHelper,[B.DOCUMENT]),u["\u0275mpd"](4608,Z.DimensionsHelper,Z.DimensionsHelper,[]),u["\u0275mpd"](4608,G.ColumnChangesService,G.ColumnChangesService,[]),u["\u0275mpd"](4608,K.f,K.f,[]),u["\u0275mpd"](4608,Y.a,Y.a,[]),u["\u0275mpd"](4608,J.a,J.a,[X.l,Y.a]),u["\u0275mpd"](4608,Q.e,Q.e,[]),u["\u0275mpd"](1073742336,K.e,K.e,[]),u["\u0275mpd"](1073742336,f.CommonModule,f.CommonModule,[]),u["\u0275mpd"](1073742336,v.B,v.B,[]),u["\u0275mpd"](1073742336,v.n,v.n,[]),u["\u0275mpd"](1073742336,L.d,L.d,[]),u["\u0275mpd"](1073742336,v.x,v.x,[]),u["\u0275mpd"](1073742336,W.a,W.a,[]),u["\u0275mpd"](1073742336,V.c,V.c,[]),u["\u0275mpd"](1073742336,j.d,j.d,[]),u["\u0275mpd"](1073742336,$.ChartsModule,$.ChartsModule,[]),u["\u0275mpd"](1073742336,z.e,z.e,[]),u["\u0275mpd"](1073742336,ll.a,ll.a,[]),u["\u0275mpd"](1073742336,nl.a,nl.a,[]),u["\u0275mpd"](1073742336,el.NgxDatatableModule,el.NgxDatatableModule,[]),u["\u0275mpd"](1073742336,X.p,X.p,[[2,X.v],[2,X.l]]),u["\u0275mpd"](1073742336,ul.a,ul.a,[]),u["\u0275mpd"](1073742336,ol.a,ol.a,[]),u["\u0275mpd"](1073742336,al.a,al.a,[]),u["\u0275mpd"](1073742336,Q.c,Q.c,[]),u["\u0275mpd"](1073742336,o.a,o.a,[]),u["\u0275mpd"](256,u.LOCALE_ID,"en-US",[]),u["\u0275mpd"](256,K.a,{autoClose:!0,insideClick:!1},[]),u["\u0275mpd"](256,u.TRANSLATIONS_FORMAT,"xlf",[])])}),In=u["\u0275cmf"](o.b,[],function(l){return u["\u0275mod"]([u["\u0275mpd"](512,u.ComponentFactoryResolver,u["\u0275CodegenComponentFactoryResolver"],[[8,[a.a,t.a,d.a,s.a,r.a,r.b,i.a,c.a,p.a,m.a,wl,Jl,dn,Cn]],[3,u.ComponentFactoryResolver],u.NgModuleRef]),u["\u0275mpd"](4608,f.NgLocalization,f.NgLocaleLocalization,[u.LOCALE_ID,[2,f["\u0275angular_packages_common_common_a"]]]),u["\u0275mpd"](4608,v.E,v.E,[]),u["\u0275mpd"](4608,v.h,v.h,[]),u["\u0275mpd"](4608,g.a,g.a,[h.a]),u["\u0275mpd"](4608,f.DatePipe,f.DatePipe,[u.LOCALE_ID]),u["\u0275mpd"](4608,b.a,b.a,[]),u["\u0275mpd"](4608,C.a,C.a,[]),u["\u0275mpd"](4608,R.a,R.a,[]),u["\u0275mpd"](4608,I.a,I.a,[R.a]),u["\u0275mpd"](4608,y.a,y.a,[R.a]),u["\u0275mpd"](4608,T.a,T.a,[R.a]),u["\u0275mpd"](4608,w.a,w.a,[]),u["\u0275mpd"](4608,D.a,D.a,[]),u["\u0275mpd"](4608,x.a,x.a,[]),u["\u0275mpd"](4608,E.a,E.a,[]),u["\u0275mpd"](4608,k.a,k.a,[f.DatePipe]),u["\u0275mpd"](4608,N.a,N.a,[]),u["\u0275mpd"](4608,F.a,F.a,[]),u["\u0275mpd"](4608,S.a,S.a,[]),u["\u0275mpd"](4608,_.a,_.a,[]),u["\u0275mpd"](4608,P.a,P.a,[]),u["\u0275mpd"](4608,M.a,M.a,[h.a]),u["\u0275mpd"](4608,A.a,A.a,[]),u["\u0275mpd"](4608,q.a,q.a,[]),u["\u0275mpd"](4608,V.b,V.b,[]),u["\u0275mpd"](4608,L.a,L.a,[]),u["\u0275mpd"](4608,U.a,U.a,[u.RendererFactory2,u.PLATFORM_ID]),u["\u0275mpd"](4608,O.a,O.a,[u.ComponentFactoryResolver,u.NgZone,u.Injector,U.a,u.ApplicationRef]),u["\u0275mpd"](4608,j.a,j.a,[]),u["\u0275mpd"](4608,z.b,z.b,[u.RendererFactory2,O.a]),u["\u0275mpd"](4608,H.ScrollbarHelper,H.ScrollbarHelper,[B.DOCUMENT]),u["\u0275mpd"](4608,Z.DimensionsHelper,Z.DimensionsHelper,[]),u["\u0275mpd"](4608,G.ColumnChangesService,G.ColumnChangesService,[]),u["\u0275mpd"](4608,K.f,K.f,[]),u["\u0275mpd"](4608,Y.a,Y.a,[]),u["\u0275mpd"](4608,J.a,J.a,[X.l,Y.a]),u["\u0275mpd"](4608,Q.e,Q.e,[]),u["\u0275mpd"](1073742336,K.e,K.e,[]),u["\u0275mpd"](1073742336,f.CommonModule,f.CommonModule,[]),u["\u0275mpd"](1073742336,v.B,v.B,[]),u["\u0275mpd"](1073742336,v.n,v.n,[]),u["\u0275mpd"](1073742336,L.d,L.d,[]),u["\u0275mpd"](1073742336,v.x,v.x,[]),u["\u0275mpd"](1073742336,W.a,W.a,[]),u["\u0275mpd"](1073742336,V.c,V.c,[]),u["\u0275mpd"](1073742336,j.d,j.d,[]),u["\u0275mpd"](1073742336,$.ChartsModule,$.ChartsModule,[]),u["\u0275mpd"](1073742336,z.e,z.e,[]),u["\u0275mpd"](1073742336,ll.a,ll.a,[]),u["\u0275mpd"](1073742336,nl.a,nl.a,[]),u["\u0275mpd"](1073742336,el.NgxDatatableModule,el.NgxDatatableModule,[]),u["\u0275mpd"](1073742336,X.p,X.p,[[2,X.v],[2,X.l]]),u["\u0275mpd"](1073742336,ul.a,ul.a,[]),u["\u0275mpd"](1073742336,ol.a,ol.a,[]),u["\u0275mpd"](1073742336,al.a,al.a,[]),u["\u0275mpd"](1073742336,Q.c,Q.c,[]),u["\u0275mpd"](1073742336,o.a,o.a,[]),u["\u0275mpd"](1073742336,o.b,o.b,[]),u["\u0275mpd"](256,u.LOCALE_ID,"en-US",[]),u["\u0275mpd"](256,K.a,{autoClose:!0,insideClick:!1},[]),u["\u0275mpd"](1024,X.j,function(){return[[{path:"",redirectTo:"users",pathMatch:"full"},{path:"users",data:o.c,children:[{path:"",component:vl.a},{path:"create",component:Al.a,data:o.d},{path:"edit/:username",component:Al.a,data:o.e}]},{path:"roles",data:o.f,children:[{path:"",component:en.a},{path:"create",component:sn.a,data:o.g},{path:"edit/:name",component:sn.a,data:o.h}]}]]},[]),u["\u0275mpd"](256,u.TRANSLATIONS_FORMAT,"xlf",[])])})}}]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo_Stacked_RGB_120411_fa_228x228.1ed169ccc35367a2dab2.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo_Stacked_RGB_120411_fa_228x228.1ed169ccc35367a2dab2.png new file mode 100644 index 00000000..79064dc0 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/Ceph_Logo_Stacked_RGB_120411_fa_228x228.1ed169ccc35367a2dab2.png differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Mimic_Octopus2.jpg b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Mimic_Octopus2.jpg new file mode 100644 index 00000000..f8cf2a8d Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Mimic_Octopus2.jpg differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Nautilus_Octopus.jpg b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Nautilus_Octopus.jpg new file mode 100644 index 00000000..1f0776fb Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/1280px-Nautilus_Octopus.jpg differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_228x228.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_228x228.png new file mode 100644 index 00000000..79064dc0 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_228x228.png differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_348x348.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_348x348.png new file mode 100644 index 00000000..d46bd73f Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_120411_fa_348x348.png differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_White_120411_fa_256x256.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_White_120411_fa_256x256.png new file mode 100644 index 00000000..26d602be Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Stacked_RGB_White_120411_fa_256x256.png differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Standard_RGB_White_120411_fa.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Standard_RGB_White_120411_fa.png new file mode 100644 index 00000000..0f07b83e Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/Ceph_Logo_Standard_RGB_White_120411_fa.png differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gif b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gif new file mode 100644 index 00000000..8fb88dea Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/loading.gif differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.png new file mode 100644 index 00000000..b3446a89 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/logo-mini.png differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/notification-icons.png b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/notification-icons.png new file mode 100644 index 00000000..d609a7c8 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/notification-icons.png differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg new file mode 100644 index 00000000..5c51f66d --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/assets/prometheus_logo.svg @@ -0,0 +1,50 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/common.8a53d98b04768bd15706.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/common.8a53d98b04768bd15706.js new file mode 100644 index 00000000..85fd813e --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/common.8a53d98b04768bd15706.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{pYKc:function(l,n,e){"use strict";var t=e("CcnG"),u=e("WiuZ"),i=e("wnGv"),s=e("Jm/i"),a=e("Ip0R");e("ppaS"),e.d(n,"a",function(){return c}),e.d(n,"b",function(){return r});var c=t["\u0275crt"]({encapsulation:0,styles:[[".select-menu-edit{margin-left:-20px}.badge-remove[_ngcontent-%COMP%]{color:#fff}"]],data:{}});function o(l){return t["\u0275vid"](0,[(l()(),t["\u0275eld"](0,0,null,null,5,"span",[],null,null,null,null,null)),(l()(),t["\u0275eld"](1,0,null,null,4,"span",[["class","badge badge-pill badge-primary margin-right-sm"]],null,null,null,null,null)),(l()(),t["\u0275eld"](2,0,null,null,1,"span",[["class","margin-right-sm"]],null,null,null,null,null)),(l()(),t["\u0275ted"](3,null,["",""])),(l()(),t["\u0275eld"](4,0,null,null,1,"a",[["class","badge-remove"]],null,[[null,"click"]],function(l,n,e){var u=!0;return"click"===n&&(u=!1!==t["\u0275nov"](l.parent,2).removeItem(l.context.$implicit)&&u),u},null,null)),(l()(),t["\u0275eld"](5,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-times"]],null,null,null,null,null))],null,function(l,n){l(n,3,0,n.context.$implicit)})}function r(l){return t["\u0275vid"](0,[t["\u0275qud"](402653184,1,{cdSelect:0}),(l()(),t["\u0275eld"](1,0,null,null,2,"cd-select",[["elemClass","margin-right-sm select-menu-edit"]],null,[[null,"selection"]],function(l,n,e){var t=!0;return"selection"===n&&(t=!1!==l.component.selection.emit(e)&&t),t},u.b,u.a)),t["\u0275did"](2,638976,[[1,4],["cdSelect",4]],0,i.a,[s.a],{elemClass:[0,"elemClass"],data:[1,"data"],options:[2,"options"],messages:[3,"messages"],selectionLimit:[4,"selectionLimit"],customBadges:[5,"customBadges"],customBadgeValidators:[6,"customBadgeValidators"]},{selection:"selection"}),(l()(),t["\u0275eld"](3,0,null,0,0,"i",[["class","fa fa-fw fa-pencil"]],null,null,null,null,null)),(l()(),t["\u0275and"](16777216,null,null,1,null,o)),t["\u0275did"](5,278528,null,0,a.NgForOf,[t.ViewContainerRef,t.TemplateRef,t.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(l,n){var e=n.component;l(n,2,0,"margin-right-sm select-menu-edit",e.data,e.options,e.messages,e.selectionLimit,e.customBadges,e.customBadgeValidators),l(n,5,0,e.data)},null)}},ppaS:function(l,n,e){"use strict";e.d(n,"a",function(){return i});var t=e("CcnG"),u=e("DNAf"),i=function(){return function(l){this.i18n=l,this.data=[],this.options=[],this.messages=new u.a({},this.i18n),this.customBadges=!1,this.customBadgeValidators=[],this.selection=new t.EventEmitter}}()}}]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.ico b/src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.ico new file mode 100644 index 00000000..90e538ba Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/favicon.ico differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.35e77a38ca9d85c4e897.eot b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.35e77a38ca9d85c4e897.eot new file mode 100644 index 00000000..b96d208f Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.35e77a38ca9d85c4e897.eot differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.3a9e014c2469ffa65a0e.woff2 b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.3a9e014c2469ffa65a0e.woff2 new file mode 100644 index 00000000..f3520b53 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.3a9e014c2469ffa65a0e.woff2 differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.44bbdbbfb5a10ba2d1ce.woff b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.44bbdbbfb5a10ba2d1ce.woff new file mode 100644 index 00000000..477da445 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.44bbdbbfb5a10ba2d1ce.woff differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.78dcc9c4999659b8026a.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.78dcc9c4999659b8026a.svg new file mode 100644 index 00000000..e9972045 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.78dcc9c4999659b8026a.svg @@ -0,0 +1,2849 @@ + + + + + +Created by FontForge 20180321 at Mon Feb 18 18:29:30 2019 + By Julien Deswaef +The Fork Awesome font is licensed under the SIL OFL 1.1 (http://scripts.sil.org/OFL). Fork Awesome is a fork based of off Font Awesome 4.7.0 by Dave Gandy. More info on licenses at https://forkawesome.github.io + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.fc46f3dae03b2b2e1cee.ttf b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.fc46f3dae03b2b2e1cee.ttf new file mode 100644 index 00000000..6cf62efb Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/forkawesome-webfont.fc46f3dae03b2b2e1cee.ttf differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.448c34a56d699c29117a.woff2 b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.448c34a56d699c29117a.woff2 new file mode 100644 index 00000000..64539b54 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.448c34a56d699c29117a.woff2 differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.89889688147bd7575d63.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.89889688147bd7575d63.svg new file mode 100644 index 00000000..94fb5490 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.89889688147bd7575d63.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf new file mode 100644 index 00000000..1413fc60 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.f4769f9bdb7466be6508.eot b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.f4769f9bdb7466be6508.eot new file mode 100644 index 00000000..b93a4953 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.f4769f9bdb7466be6508.eot differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.fa2772327f55d8198301.woff b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.fa2772327f55d8198301.woff new file mode 100644 index 00000000..9e612858 Binary files /dev/null and b/src/pybind/mgr/dashboard/frontend/dist/en-US/glyphicons-halflings-regular.fa2772327f55d8198301.woff differ diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/index.html b/src/pybind/mgr/dashboard/frontend/dist/en-US/index.html new file mode 100644 index 00000000..c8c823f7 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/index.html @@ -0,0 +1,28 @@ + + + + + Ceph + + + + + + + + + + + + diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/main.a8acf27ca1415ab0d94b.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/main.a8acf27ca1415ab0d94b.js new file mode 100644 index 00000000..8cf068e1 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/main.a8acf27ca1415ab0d94b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{"+0ag":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){}return t.prototype.transform=function(t){var e=/ceph version\s+[^ ]+\s+\(.+\)\s+(.+)\s+\((.+)\)/.exec(t);return e?"dev"===e[2]?"master":e[1]:t},t}()},"+s0g":function(t,e,n){!function(t){"use strict";var e="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),n="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),a=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],r=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;t.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(t,a){return t?/-MMM-/.test(a)?n[t.month()]:e[t.month()]:e},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:a,longMonthsParse:a,shortMonthsParse:a,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(t){return t+(1===t||8===t||t>=20?"ste":"de")},week:{dow:1,doy:4}})}(n("wd/R"))},"+tJ4":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(t){return function(e){for(var n=0,a=t.length;n=0}},"/6aS":function(t,e){t.exports='\n \n \n \n Toggle navigation\n Rozwi\u0144\n \n \n Dashboard\n Pulpit\n \n \n Cluster\n Klaster\n \n \n Hosts\n Hosty\n \n \n Monitors\n Monitory\n \n \n OSDs\n OSD-ki\n \n \n Configuration\n Konfiguracja\n \n \n CRUSH map\n CRUSH mapa\n \n \n Manager modules\n Zarz\u0105dca modu\u0142\xf3w\n \n \n Logs\n Logi\n \n \n Alerts\n Powiadomienia\n \n \n Silences\n Silences\n \n \n Pools\n Pule\n \n \n Block\n Dost\u0119p blokowy\n \n \n Images\n Obrazy\n \n \n Mirroring\n Kopia lustrzana\n \n \n iSCSI\n iSCSI\n \n \n NFS\n Sieciowy system plik\xf3w NFS\n \n \n Filesystems\n Systemy plik\xf3w\n \n \n Object Gateway\n Dost\u0119p obiektowy\n \n \n Daemons\n Demony\n \n \n Users\n U\u017cytkownicy\n \n \n Buckets\n Wiadra\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Trwa pobieranie danych \n dla \n \n \n . Czekaj...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Wy\u015bwietlanie wcze\u015bniej buforowanych danych \n \ndla \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Nie mo\u017cna za\u0142adowa\u0107 danych \n dla\n \n \n . Sprawd\u017a prosz\u0119 zdrowie klastra. \n \n \n \n Back\n Wstecz\n \n \n Select a Language\n Wybierz j\u0119zyk\n \n \n Loading panel data...\n Trwa \u0142adowanie danych...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Sprawd\u017a prosz\u0119 \n dokumentacj\u0119\n jak\nskonfigurowa\u0107 i uruchomi\u0107 funkcje monitoringu.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Pulpit Grafany nie istnieje. Sprawd\u017a prosz\u0119 \n dokumentacj\u0119 \n jak\ndodaj pulpity do Grafany.\n \n \n \n Grafana Time Picker\n Wyb\xf3r czasu Grafana\n \n \n Reset Settings\n Zresetuj ustawienia\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n B\u0142\u0105d wczytywania danych.\n \n \n selected\n Wybrane\n X selected\n \n \n found\n Znaleziono\n X found\n \n \n total\n Razem\n X total\n \n \n Edit\n Edytuj\n \n \n Name\n Nazwa\n \n \n Description\n Opis\n \n \n Long description\n D\u0142ugi opis\n \n \n Default\n Domy\u015blna\n \n \n Daemon default\n Domy\u015blny demon\n \n \n Services\n Us\u0142ugi\n \n \n Values\n Warto\u015bci\n \n \n The entered value is too high! It must not be greater than \n .\n \n Podana warto\u015b\u0107 jest za wysoka. Nie mo\u017ce by\u0107 wi\u0119ksza ni\u017c \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Podana warto\u015b\u0107 jest za ma\u0142a. Nie mo\u017ce by\u0107 mniejsza od \n .\n \n \n \n Save\n Zapisz\n \n \n CRUSH map viewer\n widok CRUSH mapy\n \n \n Hosts List\n Lista host\xf3w\n \n \n Overall Performance\n Ca\u0142kowita wydajno\u015b\u0107\n \n \n No entries found\n Nie znaleziono wej\u015b\u0107\n \n \n Cluster Logs\n Logi z klastra \n \n \n Audit Logs\n Audyt log\xf3w\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n \u0141adowanie konfiguracji.\n \n \n The configuration could not be loaded.\n Nie mo\u017cna za\u0142adowa\u0107 konfiguracji\n \n \n Edit Manager module\n Edytuj modu\u0142 zarz\u0105dzania\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n Wpisana warto\u015b\u0107 nie jest poprawnym UUID, np. 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n Wpisana warto\u015b\u0107 musi by\u0107 poprawnym adresem IP\n \n \n This field is required.\n Pole jest wymagane.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n Podana warto\u015b\u0107 jest za wysoka! Musi by\u0107 mniejsza b\u0105d\u017a r\xf3wna \n .\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n Podana warto\u015b\u0107 jest za niska! Musi by\u0107 wi\u0119ksza b\u0105d\u017a r\xf3wna \n .\n \n \n \n The entered value needs to be a number.\n Podana warto\u015b\u0107 musi by\u0107 liczb\u0105\n \n \n The entered value needs to be a number or decimal.\n Podana warto\u015b\u0107 musi by\u0107 liczb\u0105 albo dziesi\u0119tn\u0105.\n \n \n Update\n Zaktualizuj\n \n \n Status\n Status\n \n \n Cluster ID\n Klaster ID\n \n \n monmap modified\n Zmodyfikowana monmapa\n \n \n monmap epoch\n epoka monmap\n \n \n quorum con\n kworum con\n \n \n quorum mon\n kworum mon\n \n \n required con\n wymagany con\n \n \n required mon\n Wymagane mon \n \n \n In Quorum\n W kworum\n \n \n Not In Quorum\n Nie w kworum\n \n \n Cancel\n Anuluj\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n Jeste\u015b pewny, \u017ce chcesz \n \xa0 wybrany \n ? \n \n \n \n Yes, I am sure.\n Tak, jestem pewny.\n \n \n Cluster-wide OSD Flags\n Flagi OSD w ca\u0142ym klastrze\n \n \n Submit\n Zatwierd\u017a\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Zaawansowane...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n Priorytet odzyskiwania OSD\n \n \n Priority\n Priorytet\n \n \n Customize priority values\n Dostosuj warto\u015bci priorytetowe\n \n \n This field is required!\n To pole jest wymagane.\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n Podana warto\u015b\u0107 jest za wysoka. Nie mo\u017ce by\u0107 wi\u0119ksza ni\u017c \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Podana warto\u015b\u0107 jest za ma\u0142a! Nie mo\u017ce by\u0107 mniejsza od \n .\n \n \n \n Reweight OSD\n Ponowne wa\u017cenie OSD\n \n \n The value needs to be between 0 and 1.\n Warto\u015b\u0107 powinna by\u0107 pomi\u0119dzy 0 a 1. \n \n \n Reweight\n Ponowne wa\u017cenie\n \n \n OSDs \n Scrub\n \n Szoruj\n OSD-ki\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, wybierz, 1 {G\u0142\u0119boko\u015b\u0107} }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Zamierzasz zaaplikowa\u0107 \n szorowanie na OSD \n \n \n .\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, wybierz, 1 {g\u0142\u0119boko\u015b\u0107} }\n \n \n OSDs List\n Lista OSD-k\xf3w \n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n Je\u015bli kontynuujesz \n OSD \n \n b\u0119dzie zaznaczony\n \n \n .\n \n \n \n The OSD is not safe to destroy!\n Nie mo\u017cna bezpiecznie zniszczy\u0107 tego OSD.\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n Je\u015bli kontyuujesz \n OSD \n \n b\u0119dzie \n \n \n .\n \n \n \n Details\n Szczeg\xf3\u0142y\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Warto\u015b\u0107\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Zamknij\n \n \n Delete\n Usu\u0144\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Zdrowie\n \n \n Statistics\n Statystyki\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Sprawd\u017a prosz\u0119 \n dokumentacj\u0119 \n \xa0\njak nale\u017cy skonfigurowa\u0107 i uruchomi\u0107 zarz\u0105dzanie funkcjami NFS Ganeshy \n \n \n \n Clients\n Klienci\n \n \n Any client can access\n Ka\u017cdy klient ma dost\u0119p\n \n \n Addresses\n Adresy\n \n \n Required field\n Obowi\u0105zkowe pole\n \n \n Must contain one or more comma-separated values\n Musi zawiera\u0107 jedn\u0105 albo wi\u0119cej ,rozdzielonych przecinkiem, warto\u015bci \n \n \n For example:\n Na przyk\u0142ad: \n \n \n Access Type\n Typ dost\u0119pu\n \n \n Squash\n Squash\n \n \n Add clients\n Dodaj klient\xf3w \n \n \n Loading...\n \u0141adowanie...\n \n \n -- No cluster available --\n -- Brak dost\u0119pnego klastra -- \n \n \n -- Select the cluster --\n -- Wybierz klaster --\n \n \n Add daemon\n Dodaj demona\n \n \n Storage Backend\n Pami\u0119\u0107 Podr\u0119czna\n \n \n -- No data pools available --\n -- Brak danych puli -- \n \n \n -- Select the storage backend --\n -- Wybierz pami\u0119\u0107 podr\u0119czn\u0105 -- \n \n \n Object Gateway User\n U\u017cytkownik dost\u0119pu obiektowego\n \n \n -- No users available --\n -- Brak dost\u0119pnych u\u017cytkownik\xf3w -- \n \n \n -- Select the object gateway user --\n -- Wybierz u\u017cytkownika dost\u0119pu obiektowego -- \n \n \n CephFS User ID\n CephFS U\u017cytkownik ID\n \n \n -- No clients available --\n -- Brak dost\u0119pnych klient\xf3w -- \n \n \n -- Select the cephx client --\n -- Wybierz klienta cephx -- \n \n \n CephFS Name\n Nazwa CephFS\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n Etykieta bezpiecze\u0144stwa\n \n \n Enable security label\n Uruchom etykiet\u0119 bezpiecze\u0144stwa\n \n \n CephFS Path\n \u015acie\u017cka CephFS \n \n \n Path need to start with a \'/\' and can be followed by a word\n \u015acie\u017cka powinna zaczyna\u0107 si\u0119 z \'/\' i nast\u0119pne mo\u017ce by\u0107 s\u0142owo\n \n \n New directory will be created\n Nowy katalog b\u0119dzie stworzony. \n \n \n Path\n \u015acie\u017cka\n \n \n Path can only be a single \'/\' or a word\n \u015acie\u017ck\u0105 mo\u017ce by\u0107 tylko \'/\' albo s\u0142owo\n \n \n New bucket will be created\n Nowe wiadro b\u0119dzie stworzone \n \n \n NFS Protocol\n Protok\xf3\u0142 NFS\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n Tag NFS\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Alternatywny dost\u0119p do \n NFS v3\n \xa0montuje ( nie musi mie\u0107 poprzedzaj\u0105cego \'/\' )\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n Klient mo\u017ce nie montowa\u0107 podkatalog\xf3w ( np. je\u015bli Tag = foo, klient mo\u017ce nie montowa\u0107 foo/baz) \n \n \n By using different Tag options, the same Path may be exported multiple times.\n U\u017cywaj\u0105c r\xf3\u017cnych opcji Tagu, ta sama \u015acie\u017cka mo\u017ce by\u0107 wyeksportowana kilka razy.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n Pozycja, kt\xf3r\u0105 \n NFS v4\n eksport zajmuje \nw \n Pseudo FS\n (musi by\u0107 unikatowa). \n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n U\u017cywaj\u0105c r\xf3\u017cnych opcji Pseudo, ta sama \u015acie\u017cka mo\u017ce by\u0107 wyeksportowana kilka razy.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- Brak dost\u0119pnych typ\xf3w dost\u0119pu --\n \n \n -- Select the access type --\n -- Wybierz typ dost\u0119pu --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n - Brak squasha -\n \n \n --Select what kind of user id squashing is performed --\n -- Wybierz, jakiego rodzaju identyfikacja u\u017cytkownika ma by\u0107 przeprowadzana --\n \n \n Transport Protocol\n Protok\xf3\u0142 Transportu \n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Witamy w Cephie! \n The welcome message on the login page\n \n \n Username is required\n Nazwa u\u017cytkownika jest wymagana\n \n \n Password is required\n Has\u0142o jest wymagane.\n \n \n Login\n Zaloguj\n \n \n Sorry, the user does not exist in Ceph.\n Przepraszam, u\u017cytkownik nie istnieje w Ceph.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Powr\xf3t do \n Strony Logowania\n . Zostaniesz wylogowany z Dostastcy To\u017csamo\u015bci , kiedy spr\xf3bujesz si\u0119 zalgowa\u0107. \n \n \n \n Forbidden\n Zakazany\n \n \n Sorry, you are not allowed to see what you were looking for.\n Przepraszam, nie masz dost\u0119pu do tego czego szukasz. \n \n \n Sorry, we could not find what you were looking for\n Przepraszam, nie mo\u017cemy znale\u017a\u0107 tego czego szukasz.\n \n \n Remove all\n Usu\u0144 wszystko\n \n \n Recent Notifications\n Ostatnie powiadomienia\n \n \n There are no background tasks.\n Brak zada\u0144 w tle.\n \n \n Background Tasks\n Zagadnienia w tle \n \n \n Help\n Pomoc\n \n \n Documentation\n Dokumentacja\n \n \n API\n Interfejs API\n \n \n About\n O\n \n \n Dashboard Settings\n Ustawienia Pulpitu\n \n \n User management\n Zarz\u0105dzanie u\u017cytkownikami\n \n \n Logged in user\n Zalogowany u\u017cytkownik\n \n \n Signed in as\n \n \n \n \n Zalogowany jako \n \n \n \n \n \n \n Sign out\n Wyloguj\n \n \n Name...\n Nazwa...\n \n \n The chosen name is already in use.\n Wybrana nazwa ju\u017c jest u\u017cyta.\n \n \n Description...\n Opis...\n \n \n Permissions\n Pozwolenia\n \n \n Roles\n Role\n \n \n Username\n Nazwa u\u017cytkownika\n \n \n Password\n Has\u0142o\n \n \n Confirm password\n Potwierd\u017a has\u0142o\n \n \n Password confirmation doesn\'t match the password.\n Potwierdzaj\u0105ce has\u0142o nie pokrywa si\u0119 z has\u0142em.\n \n \n Full name\n Pe\u0142ne imi\u0119 \n \n \n Email\n Email\n \n \n Invalid email.\n Niepoprawny email.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Zamierzasz usun\u0105\u0107 uprawnienia \u201eodczytu / aktualizacji u\u017cytkownika\u201d od w\u0142asnego u\u017cytkownika.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Je\u015bli kontynuujesz, nie b\u0119dziesz m\xf3g\u0142 dodawa\u0107 albo usuwa\u0107 role od u\u017cytkownik\xf3w.\n \n \n Are you sure you want to continue?\n Jeste\u015b pewny, \u017ce chcesz kontynuowa\u0107? \n \n \n Performance counters not available\n Liczniki wydajno\u015bci nie s\u0105 dost\u0119pne\n \n \n Attributes (OSD map)\n Atrybuty (mapa OSD-k\xf3w)\n \n \n Metadata not available\n Niedost\u0119pne metadane\n \n \n Metadata\n Metadane\n \n \n Performance counter\n Licznik wydajno\u015bci\n \n \n Histogram not available: \n \n \n Histogram niedost\u0119pny: \n \n \n \n \n Writes\n Pisze\n \n \n Reads\n Czyta\n \n \n Histogram\n Histogram\n \n \n Performance Details\n Szczeg\xf3\u0142y wydajno\u015bci\n \n \n Current values\n Obecne warto\u015bci \n \n \n Type\n Typ\n \n \n Min\n Min\n \n \n Max\n Max\n \n \n Flags\n Flagi\n \n \n Source\n \u0179r\xf3d\u0142o \n \n \n Level\n Poziom\n \n \n Can be updated at runtime (editable)\n Mo\u017ce by\u0107 aktualizowany w czasie wykonywania (edytowalny)\n \n \n Tags\n Tagi\n \n \n Enum values\n Warto\u015bci enumerowane \n \n \n See also\n Zobacz tak\u017ce \n \n \n Cluster Status\n Status klastra\n \n \n Manager Daemons\n Zarz\u0105dzanie demonami\n \n \n Object Gateways\n Obiekty bram \n \n \n Metadata Servers\n Serwery metadanych\n \n \n iSCSI Gateways\n Bramy iSCSI\n \n \n Client IOPS\n Klient IOPS\n \n \n Client Throughput\n Przepustowo\u015b\u0107 klienta\n \n \n Client Read/Write\n Odczyt/Zapis klienta\n \n \n Recovery Throughput\n Przepustowo\u015b\u0107 odzyskiwania\n \n \n Scrub\n Szoruj\n \n \n Performance\n Wydajno\u015b\u0107\n \n \n Raw Capacity\n Pojemno\u015b\u0107 rz\u0119du\n \n \n Objects\n Obiekty\n \n \n PGs per OSD\n PG-y na OSD\n \n \n PG Status\n Status PG\n \n \n Capacity\n Pojemno\u015b\u0107\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n zobacz\n logi\n , \u017ceby mie\u0107 wi\u0119cej szczeg\xf3\u0142\xf3w. \n \n \n \n Ranks\n Szeregi\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Klienci: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n Przenie\u015b obraz do kosza\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n \u017beby przenie\u015b\u0107 \n \n /\n \n do kosza, kliknij \n Przenie\u015b obraz\n . Opcjonalnie, mo\u017cesz wybra\u0107 dat\u0119 wa\u017cno\u015bci.\n \n \n \n Protection expires at\n Zabezpieczenie wygasa w \n \n \n NOT PROTECTED\n NIEZABEZPIECZONY \n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Z\u0142y format daty. Prosz\u0119 u\u017cywa\u0107 "RRRR-MM-DD GG:mm:ss".\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n Ochrona ju\u017c wygas\u0142a. Prosz\u0119 wybra\u0107 przysz\u0142\u0105 dat\u0119 lub zostawi\u0107 pust\u0105.\n \n \n Move Image\n Przenie\u015b obraz\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n Przegl\u0105d\n \n \n Targets\n Obiekty docelowe\n \n \n Discovery Authentication\n Uwierzytelnianie wykrywania\n \n \n User\n U\u017cytkownik\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Nazwy u\u017cytkownik\xf3w musz\u0105 mie\u0107 d\u0142ugo\u015b\u0107 od 8 do 64 znak\xf3w i \nmog\u0105 zawiera\u0107 jedynie litery, \'.\', \'@\', \'-\', \'_\' lub \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n Wsp\xf3lny u\u017cytkownik \n \n \n Mutual Password\n Wsp\xf3lne has\u0142o\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Sprawd\u017a prosz\u0119 \n dokumentacj\u0119 \n \xa0\njak skonfigurowa\u0107 i uruchomi\u0107 zarz\u0105dzanie funkcjonalno\u015bciami obiektami docelowymi iSCSI\n \n \n \n Available information:\n Dost\u0119pne informacje: \n \n \n iSCSI Targets not available\n obiekty docelowe iSCSI niedost\u0119pne \n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n Dost\u0119pne tylko dla obraz\xf3w RBD z \n szybk\u0105 r\xf3\u017cnic\u0105 \n w\u0142\u0105czone\n \n \n \n Pool\n Pul\n \n \n Data Pool\n Dane pula\n \n \n Created\n Utworzony\n \n \n Size\n Rozmiar\n \n \n Object size\n Rozmiar obiektu\n \n \n Features\n Funkcje\n \n \n Provisioned\n Zaopatrzony\n \n \n N/A\n Niedost\u0119pny\n \n \n Total provisioned\n Ca\u0142kowite rezerwy\n \n \n Striping unit\n Jednostka maskowana\n \n \n Striping count\n Licznik maskowania\n \n \n Parent\n Rodzic\n \n \n Block name prefix\n Prefiks nazwy bloku\n \n \n Order\n Zam\xf3wienie\n \n \n Snapshots\n Migawki\n \n \n Image\n Obraz\n \n \n This setting overrides the global value\n To ustawienie zast\u0119puj\u0119 warto\u015b\u0107 globaln\u0105.\n \n \n Global\n Globalne\n \n \n This is the global value. No value for this option has been set for this image.\n To jest globalna warto\u015b\u0107. Dla tego obrazu nie ustawiono \u017cadnej warto\u015bci dla tej opcji.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \'/\' and \'@\' nie s\u0105 dozwolone.\n \n \n -- No rbd pools available --\n -- Brak dost\u0119pnych rbd puli -- \n \n \n -- Select a pool --\n -- Wybierz pul --\n \n \n Use a dedicated data pool\n U\u017cyj dedykowanych danych pul \n \n \n Data pool\n Dane pul\n \n \n Dedicated pool that stores the object-data of the RBD.\n Dedykowany pul, kt\xf3ry przechowuje dane obiektowe z RBD\n \n \n e.g., 10GiB\n np. 10 GiB\n \n \n You have to increase the size.\n Musisz zwi\u0119kszy\u0107 rozmiar.\n \n \n Advanced\n Zaawansowane\n \n \n Striping\n Maskowanie\n \n \n Stripe unit\n Jednostka pask\xf3w\n \n \n -- Select stripe unit --\n -- Wybierz jednostk\u0119 pask\xf3w -- \n \n \n This field is required because stripe count is defined!\n Pole jest wymagane, poniewa\u017c licznik pask\xf3w jest zdefiniowany. \n \n \n Stripe unit is greater than object size.\n Jednostka pask\xf3w jest wi\u0119ksza ni\u017c rozmiar obiektu.\n \n \n Stripe count\n Licznik pask\xf3w \n \n \n This field is required because stripe unit is defined!\n Pole jest wymagane, poniewa\u017c jednostka pask\xf3w jest zdefiniowana! \n \n \n Stripe count must be greater than 0.\n Licznik pask\xf3w musi by\u0107 wi\u0119kszy od 0.\n \n \n \n RBD Snapshot\n \n \n migawka RBD\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, wybierz, prawda {Zmie\u0144 nazwe} inaczej{Utw\xf3rz} }\n \n \n \n Snapshot\n \n \n Migawka\n \n \n \n PROTECTED\n ZABEZPIECZONE\n \n \n UNPROTECTED\n NIEZABEZPIECZONY \n \n \n You are about to rollback\n Zaraz si\u0119 wycofasz. \n \n \n Purge Trash\n Usu\u0144 \u015amieci\n \n \n To purge, select one or All images and click\n Aby usun\u0105\u0107, wybierz jeden albo wszystkie obrazy i kliknij \n \n \n Pool:\n Pul:\n \n \n Pool name...\n Nazwa pula\n \n \n All\n Wszystkie\n \n \n Restore Image\n Przywr\xf3\u0107 obraz\n \n \n To restore\n Przywr\xf3\u0107\n \n \n type the image\'s new name and click\n Wpisz nazwe nowego obrazu i kliknij. \n \n \n New Name\n Nowa Nazwa\n \n \n Expired at\n Wygas\u0142y w\n \n \n Protected until\n Zabezpieczony do\n \n \n This image is protected until \n .\n \n Ten obraz jest chroniony do \n .\xa0\n \n \n \n Trash\n Kosz\n \n \n iSCSI Topology\n Topologia iSCSI\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n Zmiana tych parametr\xf3w z domy\u015blnych warto\u015bci przewa\u017cnie nie jest potrzebna.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Ustawienia\n \n \n Backstore\n Tylny koniec przechowywania\n \n \n Confirm\n Potwierd\u017a\n \n \n Advanced Settings\n Ustawienia zaawansowane\n \n \n Target IQN\n Nazwa IQN obiektu docelowego iSCSI\n \n \n IQN has wrong pattern.\n B\u0142\u0119dna sk\u0142adnia nazwy IQN.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n IQN ma nast\u0119puj\u0105c\u0105 notacj\u0119 \u201eiqn. $ Rok-$ miesi\u0105c. $ odwr\xf3conyAdres: $ zdefiniowanaNazwa\u201d\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Na przyk\u0142ad: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n Wi\u0119cej informacji\n \n \n This target has modified advanced settings.\n Ten obiekt docelowy zmodyfikowa\u0142 zaawansowane ustawienia.\n \n \n Portals\n Portale\n \n \n At least \n gateways are required.\n \n Wymagane s\u0105 przynajmniej \n bramy.\n \n \n \n Add portal\n Dodaj portal\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Ten obraz zmodyfikowa\u0142 ustawienia. \n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n Dodaj obraz.\n \n \n ACL authentication\n Uwierzytelnianie ACL\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Inicjatory iSCSI\n \n \n Initiator\n Inicjator iSCSI\n \n \n Client IQN\n Klient IQN\n \n \n Initiator IQN needs to be unique.\n Inicjator IQN powinien by\u0107 unikalny.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Nazwy u\u017cytkownik\xf3w musz\u0105 mie\u0107 d\u0142ugo\u015b\u0107 od 8 do 64 znak\xf3w i mog\u0105 zawiera\u0107 jedynie litery, \'.\', \'@\', \'-\', \'_\' lub \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n Inicjator iSCSI nale\u017c\u0105 do grupy. Obrazy b\u0119d\u0105 skonfigurowane w grupie. \n \n \n No items added.\n Brak dodanych pozycji.\n \n \n Add initiator\n Dodaj inicjator iSCSI\n \n \n Groups\n Grupy\n \n \n Group\n Grupa\n \n \n Add group\n Dodaj grup\u0119\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n Konfiguracja RBD\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Usu\u0144 warto\u015b\u0107 konfiguracji lokalnej. Warto\u015b\u0107 konfiguracji rodzica b\u0119dzie odziedziczona i zostanie u\u017cyta zamiast tej.\n \n \n The mininum value is 0\n Minimalna warto\u015b\u0107 wynosi 0.\n \n \n Issues\n Zagadnienia\n \n \n Syncing\n Synchronizacja\n \n \n Ready\n Gotowy\n \n \n Edit pool mirror mode\n Tryb edycji lustrzanego pula\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n Aby edytowa\u0107 tryb lustrzanydla pula\n \n \n , wybierz tryb z listy i kliknij\n Zaktualizuj\n .\n \n \n \n Mode\n Tryb\n \n \n Peer clusters must be removed prior to disabling mirror.\n Sparowany klaster musi by\u0107 usuni\u0119ty przed wy\u0142\u0105czeniem lustra. \n \n \n \n \n pool mirror peer\n \n \n sparowany pul lustrzany\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, wybierz, edytuj{Edytuj} inaczej {Dodaj} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n pul \nlustra sparowanych atrybut\xf3w dla pula \n \n \n i kliknij \n Zatwierd\u017a\n .\n \n \n \n Cluster Name\n Nazwa Klastra\n \n \n The cluster name is not valid.\n Nazwa klastra jest niepoprawna \n \n \n CephX ID\n CephX ID\n \n \n CephX ID...\n CephX ID...\n \n \n The CephX ID is not valid.\n ID CephX nie jest poprawne.\n \n \n Monitor Addresses\n Adres monitora \n \n \n Comma-delimited addresses...\n Adresy rozdzielane przecinkami... \n \n \n The monitory address is not valid.\n Adres monitora nie jest poprawny.\n \n \n CephX Key\n Klucz CephX\n \n \n Base64-encoded key...\n Klucz zakodowany w Base64...\n \n \n CephX key must be base64 encoded.\n Klucz CephX musi by\u0107 zakodowany w Base64/\n \n \n Pools List\n Lista puli\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n Nazwa mo\u017ce sk\u0142ada\u0107 si\u0119 z alfanumerycznych znak\xf3w, kresek i podkre\u015ble\u0144.\n \n \n The chosen erasure code profile name is already in use.\n Wybrana nazwa profilu kodu kasowania jest ju\u017c u\u017cywana.\n \n \n Plugin\n Wtyczka\n \n \n Data chunks (k)\n Ramka danych (k)\n \n \n Must be equal to or greater than 2.\n Musi by\u0107 wi\u0119ksza b\u0105d\u017a r\xf3wna 2.\n \n \n Coding chunks (m)\n Kodowanie kawa\u0142ka (m)\n \n \n Must be equal to or greater than 1.\n Musi by\u0107 wi\u0119ksza b\u0105d\u017a r\xf3wna 1.\n \n \n Durability estimator (c)\n Estymator trwa\u0142o\u015bci (c)\n \n \n Locality (l)\n Lokalno\u015b\u0107 (l)\n \n \n Crush failure domain\n Domena niepowodzenia Crush\n \n \n Crush Locality\n Lokalno\u015b\u0107 Crusha\n \n \n None\n Nic\n \n \n Technique\n Technika\n \n \n Packetsize\n Rozmiar pakietu\n \n \n Crush root\n korze\u0144 Crusha\n \n \n Crush device class\n urz\u0105dzenie klasy Crush\n \n \n any\n kt\xf3rykolwiek\n \n \n Directory\n Katalog\n \n \n The chosen Ceph pool name is already in use.\n Wybrana nazwa Ceph pula jest ju\u017c u\u017cyta.\n \n \n Pool type\n Typ pula\n \n \n -- Select a pool type --\n -- Wybierz typ pula --\n \n \n Placement groups\n Grupa umieszczenia\n \n \n At least one placement group is needed!\n Przynajmniej jedna grupa umieszczenia jest wymagana\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n Tw\xf3j klaster nie obs\u0142uguje tylu PG. Skalkuluj prosz\u0119 potrzebn\u0105 ilo\u015b\u0107 PG.\n \n \n Calculation help\n Pomoc obliczeniowa\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n Obecne ustawienia PG zosta\u0142y policzone dla Ciebie, \npowiniene\u015b upewni\u0107 si\u0119 czy te warto\u015bci Ci odpowiadaj\u0105 przed zatwierdzeniem.\n \n \n Crush ruleset\n zbi\xf3r zasad Crush\n \n \n -- Select a crush rule --\n -- Wybierz zasad\u0119 Crush --\n \n \n Crush rule\n zasada Crush\n \n \n Crush steps\n Kroki Crush\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n Zasada nie mo\u017ce by\u0107 u\u017cyta w obecnym klastrze, gdy\u017c ma\nzbyt ma\u0142o OSD-k\xf3w, \u017ceby spe\u0142ni\u0107 minimum OSD-k\xf3w wymaganych przez t\u0119 zasad\u0119.\n \n \n Replicated size\n Replikowany rozmiar\n \n \n Minimum: \n \n \n Minimum: \n \n \n \n \n Maximum: \n \n \n Maximum: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n Sprecyzowany rozmiar jest poza zakresem. Warto\u015b\u0107 od \n do \n jest poprawna.\n \n \n \n Erasure code profile\n Skasuj profil kodu.\n \n \n -- No erasure code profile available --\n -- Brak profilu kasowania --\n \n \n -- Select an erasure code profile --\n -- Wybierz profil kodu wymazywania --\n \n \n EC Overwrites\n EC Nadpisuje\n \n \n Applications\n Zastosowania\n \n \n Compression\n Kompresja\n \n \n Algorithm\n Algorytm\n \n \n -- No erasure compression algorithm available --\n -- Brak algorytmu kompresji wymazywania --\n \n \n Minimum blob size\n Minimalny rozmiar blob\n \n \n e.g., 128KiB\n np. 128 KB\n \n \n Value should be greater than 0\n Warto\u015b\u0107 powinna by\u0107 wi\u0119ksza ni\u017c 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Maksymalny rozmiar blob\n \n \n e.g., 512KiB\n np. 512 KB\n \n \n Value should be greater than the minimum blob size\n Warto\u015b\u0107 powinna by\u0107 wi\u0119ksza ni\u017c minimalny rozmiar blob\n \n \n Ratio\n Stosunek\n \n \n Compression ratio\n Skompresowany stosunek\n \n \n Value should be between 0.0 and 1.0\n Warto\u015b\u0107 powinna by\u0107 pomi\u0119dzy 0.0, a 1.0\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n Nie mo\u017cna stworzy\u0107 pula RBD z \'/\' w nazwie.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n Prosz\u0119 zmieni\u0107 nazw\u0119 albo usun\u0105\u0107 \'rbd\' z listy zastosowa\u0144.\n \n \n Cache Tiers Details\n Szczeg\xf3\u0142y poziom\xf3w pami\u0119ci podr\u0119cznej\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Sprawd\u017a prosz\u0119 \n dokumentacj\u0119 \n \xa0\njak skonfigurowa\u0107 i i uruchomi\u0107 zarz\u0105dzanie funkcjami Dost\u0119pu obiektowego\n \n \n \n Daemons List\n Lista demon\xf3w\n \n \n Performance Counters\n Liczniki wydajno\u015bci\n \n \n Loading bucket data...\n \u0141adowanie wiadra danych\n \n \n The bucket data could not be loaded.\n Nie mo\u017cna za\u0142adowa\u0107 wiadra danych.\n \n \n Id\n Number ID\n \n \n The value is not valid.\n Warto\u015b\u0107 nie jest poprawna.\n \n \n Owner\n W\u0142a\u015bciciel\n \n \n -- Select a user --\n -- Wybierz u\u017cytkownika -- \n \n \n ID\n ID\n \n \n Index type\n Typ indeksu\n \n \n Placement rule\n Zasada umieszczania\n \n \n Marker\n Znacznik\n \n \n Maximum marker\n Maksymalny znacznik\n \n \n Version\n Wersja\n \n \n Master version\n G\u0142\xf3wna wersja\n \n \n Modification time\n Czas modyfikacji\n \n \n Zonegroup\n Strefa \n \n \n Bucket quota\n kontyngent wiadra\n \n \n Enabled\n Uaktywniony\n \n \n Maximum size\n Maksymalny rozmiar\n \n \n Unlimited\n Nielimitowany\n \n \n Maximum objects\n Maksimum obiekt\xf3w\n \n \n -- Select a username --\n -- Wybierz nazw\u0119 u\u017cytkownika -- \n \n \n Auto-generate key\n Auto-generowany klucz\n \n \n Access key\n Klucz dost\u0119pu\n \n \n Secret key\n Tajny klucz \n \n \n Email address\n Adres email\n \n \n Suspended\n Zawieszony\n \n \n System\n System\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, wybierz, 0 {Nie} 1{Tak} }\n \n \n Maximum buckets\n Maksimum wiader\n \n \n Subusers\n pod-u\u017cytkownicy\n \n \n Capabilities\n Zdolno\u015bci\n \n \n User quota\n Limit u\u017cytkownika\n \n \n Show\n Poka\u017c\n \n \n Keys\n Klucze\n \n \n -- Select a type --\n -- wybierz typ --\n \n \n Permission\n Pozwolenie \n \n \n -- Select a permission --\n -- Wybierz pozwolenie --\n \n \n Subuser\n pod-u\u017cytkownik\n \n \n The chosen subuser ID is already in use.\n Wybrane ID pod-u\u017cytkownika jest ju\u017c u\u017cyte.\n \n \n read, write\n odczyt, zapis\n \n \n full\n pe\u0142ny\n \n \n Swift key\n Szybki klucz\n \n \n Auto-generate secret\n Auto-generowany sekret\n \n \n Loading user data...\n \u0141adowanie danych u\u017cytkownika...\n \n \n The user data could not be loaded.\n Nie mo\u017cna za\u0142adowa\u0107 danych u\u017cytkownika.\n \n \n The chosen user ID is already in use.\n Wybrane ID u\u017cytkownika jest ju\u017c u\u017cyte.\n \n \n This is not a valid email address.\n Ten adres email nie jest poprawny.\n \n \n The chosen email address is already in use.\n Wybrany adres email jest ju\u017c u\u017cyty.\n \n \n Max. buckets\n Max. wiader \n \n \n The entered value must be >= 0.\n Podana warto\u015b\u0107 musi by\u0107 >= 0\n \n \n S3 key\n klucz S3\n \n \n There are no subusers.\n Nie ma pod-u\u017cytkownik\xf3w.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3 (prosty serwis przechowywania) \n \n \n There are no keys.\n Nie ma kluczy.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Szybki\n \n \n There are no capabilities.\n Nie ma zdolno\u015bci. \n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Nielimitowany rozmiar\n \n \n Max. size\n Max. rozmiar\n \n \n Unlimited objects\n Nielimitowane obiekty\n \n \n Max. objects\n Max. obiekt\xf3w\n \n \n Current\n Obecny\n \n \n Updated discovery authentication\n Zaktualizowane uwierzytelnianie wykrywania\n \n \n There are no portals available.\n Brak dost\u0119pnych portali.\n \n \n There are no images available.\n Nie ma dost\u0119pnych obraz\xf3w. \n \n \n There are no images available. Please make sure you add an image to the target.\n Nie ma dost\u0119pnych obraz\xf3w. Prosz\u0119 si\u0119 upewni\u0107, \u017ce dodajesz obraz do obiektu docelowego. \n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n Nie ma dost\u0119pnych inicjator\xf3w iSCSI. Prosz\u0119 upewni\u0107 si\u0119, \u017ce dodajesz inicjator iSCSI do obiektu docelowego.\n \n \n target\n target\n \n \n Target\n obiekt docelowy iSCSI\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n Stan\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Odczyt bajt\xf3w \n \n \n Write Bytes\n Zapis bajt\xf3w\n \n \n Read Ops\n Odczyt Ops\n \n \n Write Ops\n Zapis Ops\n \n \n A/O Since\n A/O Od\n \n \n Instance\n Instancja\n \n \n Hostname\n Nazwa hosta\n \n \n Issue\n Zagadnienie \n \n \n Progress\n Progres\n \n \n Disabled\n Wy\u0142\u0105czony\n \n \n Edit Mode\n Tryb Edycji\n \n \n Add Peer\n Dodaj parowanie \n \n \n Edit Peer\n Edytuj parowanie\n \n \n Delete Peer\n Usu\u0144 parowanie\n \n \n Leader\n Lider\n \n \n # Local\n # Lokalny\n \n \n # Remote\n # Zdalny\n \n \n mirror peer\n lustrzane parowanie\n \n \n Key\n Klucz\n \n \n RBD\n RBD\n \n \n Deep flatten\n G\u0142\u0119bokie sp\u0142aszczenie\n \n \n Layering\n Warstwowanie \n \n \n Exclusive lock\n Wy\u0142\u0105czna blokada\n \n \n Object map (requires exclusive-lock)\n Mapa obiekt\xf3w (wymaga wy\u0142\u0105cznej blokady)\n \n \n Journaling (requires exclusive-lock)\n Kronikowanie (wymaga wy\u0142\u0105cznej blokady)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Wycofywanie migawek RBD\n \n \n Rollback\n Wycofanie\n \n \n RBD snapshot\n migawka RBD\n \n \n Deleted At\n Usuni\u0119ty o \n \n \n id\n id\n \n \n type\n typ\n \n \n state\n stan\n \n \n version\n wersja\n \n \n Host\n Host\n \n \n root\n administrator\n \n \n Rank\n Ranga\n \n \n Daemon\n Demon\n \n \n Activity\n Aktywno\u015b\u0107\n \n \n Dentries\n centrale\n \n \n Inodes\n i-w\u0119z\u0142y\n \n \n Usage\n U\u017cycie\n \n \n Standby daemons\n Czuwanie demona \n \n \n The value can be updated at runtime.\n Warto\u015b\u0107 mo\u017ce by\u0107 zaktualizowana w czasie wykonywania . \n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n Demony/klienci nie pobieraj\u0105 tej warto\u015bci z\nbazy danych skonfigurowanego monitora. Nie zezwalamy na ustawienie tej opcji przez \'konfiguracje ceph\nustaw.. \'. Ta opcja powinna by\u0107 skonfigurowana przez ceph.conf albo przez\nterminal.\n \n \n Option takes effect only during daemon startup.\n Opcja dzia\u0142a tylko podczas startu demona.\n \n \n Option only affects cluster creation.\n Opcja dotyczy tylko tworzenia klastra.\n \n \n Option only affects daemon creation.\n Opcja tylko wp\u0142ywa na tworzenie demona.\n \n \n Updated config option \n \n \n Zaktualizowana opcja konfiguracji \n \n \n \n \n Service\n Us\u0142uga\n \n \n Current value\n Obecna warto\u015b\u0107\n \n \n Editable\n Edytowalny\n \n \n Updated options for module "\n ".\n \n Zaktualizowane opcje dla modu\u0142u &quot;\n &quot;.\n \n \n \n Enable\n W\u0142\u0105czy\u0107\n \n \n Disable\n Wy\u0142\u0105czy\u0107\n \n \n Reconnecting, please wait ...\n Ponowne \u0142\u0105czenie, prosz\u0119 czeka\u0107\n \n \n Public Address\n Adres publiczny\n \n \n Open Sessions\n Otwarte sesje\n \n \n No In\n Nie w \n \n \n OSDs that were previously marked out will not be marked back in when they start\n OSD-ki, kt\xf3re zosta\u0142y oznaczone jako poza, nie b\u0119d\u0105 oznaczone ponownie jako w gdy zostan\u0105 uruchomion\n \n \n No Out\n Nie poza\n \n \n OSDs will not automatically be marked out after the configured interval\n OSD-ki nie b\u0119d\u0105 automatycznie oznaczone jako poza po konfiguracji interwa\u0142u\n \n \n No Up\n Nie powsta\u0142y \n \n \n OSDs are not allowed to start\n OSD-ki nie mog\u0105 startowa\u0107\n \n \n No Down\n Nie upad\u0142y\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n Raport z niepowodzenia OSD jest ignorowany, tak\u017ce monitory nie oznacz\u0105 OSD jako upad\u0142ego. \n \n \n Pause\n Pauza \n \n \n Pauses reads and writes\n Pauzuje czytanie i zapisywanie\n \n \n No Scrub\n Nie szoruj\n \n \n Scrubbing is disabled\n Szorowanie jest wy\u0142\u0105czone\n \n \n No Deep Scrub\n Nie ma g\u0142\u0119bokiego szorowania\n \n \n Deep Scrubbing is disabled\n G\u0142\u0119bokie szorowanie jest wy\u0142\u0105czone\n \n \n No Backfill\n Brak zasypywania\n \n \n Backfilling of PGs is suspended\n Zasypywanie PG jest zawieszone\n \n \n No Recover\n Nie przywr\xf3cono\n \n \n Recovery of PGs is suspended\n Przywr\xf3cenie PGy jest zawieszone \n \n \n Bitwise Sort\n Sortuj bitowo\n \n \n Use bitwise sort\n U\u017cyj sortowania bitowego\n \n \n Purged Snapdirs\n Usu\u0144 snap katalogi\n \n \n OSDs have converted snapsets\n OSD-ki zmieni\u0142y snapsety\n \n \n Recovery Deletes\n Odzyskaj usuni\u0119te\n \n \n Deletes performed during recovery instead of peering\n Podczas zdrowienia zastosowano usuni\u0119cie zamiast parowania\n \n \n PG Log Hard Limit\n Twardy limit log\xf3w PG\n \n \n Puts a hard limit on pg log length\n Ustawia twardy limit na d\u0142ugo\u015b\u0107 log\xf3w PG\n \n \n Updated OSD Flags\n Zaktualizowane flagi OSD-k\xf3w\n \n \n out\n poza\n \n \n in\n w\n \n \n down\n upad\u0142y\n \n \n Mark\n Zaznacz\n \n \n OSD lost\n Stracony OSD\n \n \n marked lost\n Zaznaczony jako stracony\n \n \n Purge\n Czy\u015b\u0107\n \n \n OSD\n OSD-ik\n \n \n purged\n Oczyszczony\n \n \n destroy\n Zniszcz\n \n \n destroyed\n Zniszczony\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n PG-y\n \n \n Read bytes\n Czytanie bajt\xf3w\n \n \n Writes bytes\n Zapis bajt\xf3w\n \n \n Read ops\n Czytanie ops\n \n \n Write ops\n Zapis ops\n \n \n Mark OSD \n \n \n Zaznacz OSD \n \n \n \n \n Mark \n \n \n Zaznacz \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n Max zasypywanie\n \n \n Recovery Max Active\n Max aktywno\u015b\u0107 wyzdrowienia\n \n \n Recovery Max Single Start\n Max pojedynczy start wyzdrowienia\n \n \n Recovery Sleep\n U\u015bpienie wyzdrowienia\n \n \n Custom\n Zwyczaj\n \n \n Updated OSD recovery speed priority "\n "\n \n Zaktualizowano pr\u0119dko\u015b\u0107 wyzdrowienia OSD priorytet &quot;\n &quot;\n \n \n \n \n was initialized in the following OSD: \n \n \n \n zosta\u0142 zainicjalizowany w nast\u0119puj\u0105cym OSD: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n Praca\n \n \n Severity\n surowo\u015b\u0107\n \n \n Started\n Wystartowany\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Zaktualizowany\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n U\u017cyty\n \n \n Avail.\n Dost\u0119pny\n \n \n Clean\n Czy\u015b\u0107\n \n \n Working\n Dzia\u0142aj\u0105cy\n \n \n Warning\n Ostrze\u017cenie \n \n \n Unknown\n Nieznany\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n Podniesiony\n \n \n no filesystems\n brak system\xf3w plik\xf3w\n \n \n active\n aktywny\n \n \n standby\n Rezerwa\n \n \n n/a\n niedost\u0119pny\n \n \n active daemon\n aktywny demon\n \n \n quorum\n kworum\n \n \n The NFS Ganesha service is not configured.\n Us\u0142uga NFS Ganesha nie jest skonfigurowana\n \n \n Transport\n Transport\n \n \n CephFS User\n U\u017cytkownik CephFS\n \n \n CephFS Filesystem\n system plik\xf3w CephFS \n \n \n (inherited from global config)\n (Odziedziczy\u0142o z globalnej konfiguracji)\n \n \n inherited from global config\n Odziedziczy\u0142o z globalnej konfiguracji\n \n \n -- Select what kind of user id squashing is performed --\n -- Wybierz, jakiego rodzaju identyfikacja u\u017cytkownika ma by\u0107 przeprowadzana -- \n \n \n There are no daemons available.\n Brak dost\u0119pnym demon\xf3w\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Tryb pami\u0119ci podr\u0119cznej\n \n \n Min Evict Age\n Min wiek eksmisji\n \n \n Min Flush Age\n Min wiek wyr\xf3wnania \n \n \n Target Max Bytes\n Max bajt\xf3w obiektu docelowego \n \n \n Target Max Objects\n Max obiekt\xf3w docelowych\n \n \n No applications added\n Nie dodano \u017cadnego zastosowania\n \n \n Applications limit reached\n Osi\u0105gni\u0119to limit zastosowa\u0144 \n \n \n A pool can only have up to four applications definitions.\n Pul mo\u017ce mie\u0107 maksymalnie 4 definicje aplikacji. \n \n \n Allowed characters \'_a-zA-Z0-9\'\n Dozwolone znaki \'_a-zA-Z0-9\'\n \n \n Maximum length is 128 characters\n Maksymalna d\u0142ugo\u015b\u0107 wynosi 128 znak\xf3w\n \n \n Filter or add applications\n Filtruj lub dodaj zastosowanie\n \n \n Add application\n Dodaj zastosowanie\n \n \n pool\n pool\n \n \n erasure code profile\n skasuj profil kodu\n \n \n Replica Size\n Rozmiar repliki\n \n \n Last Change\n Ostatnia zmiana\n \n \n Erasure Coded Profile\n Skasuj profil zakodowany\n \n \n Crush Ruleset\n Zbi\xf3r zasad Crush\n \n \n Write bytes\n Zapis bajt\xf3w \n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n wiadro\n \n \n Updated Object Gateway bucket "\n "\n \n Zaktualizowano wiadro dost\u0119pu obiektowego &quot;\n &quot;\n \n \n \n Created Object Gateway bucket "\n "\n \n Stworzono wiadro dost\u0119pu obiektowego &quot;\n &quot;\n \n \n \n buckets\n Wiadra\n \n \n capability\n capability\n \n \n user\n u\u017cytkownik\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Zaktualizowano u\u017cytkownika dost\u0119pu obiektowego &quot;\n &quot;\n \n \n \n Created Object Gateway user "\n "\n \n Stworzono u\u017cytkownika dost\u0119pu obiektowego&quot;\n &quot;\n \n \n \n users\n u\u017cytkownicy\n \n \n Swift Key\n Swift Key\n \n \n Scope\n Zakres\n \n \n Read\n Czytaj\n \n \n Create\n Stw\xf3rz\n \n \n role\n role\n \n \n Created role \'\n \'\n \n Utw\xf3rz rol\u0119 \'\n \'\n \n \n \n Updated role \'\n \'\n \n Zaktualizuj rol\u0119 \'\n \'\n \n \n \n System Role\n System roli \n \n \n Deleted role \'\n \'\n \n Usu\u0144 rol\u0119 \'\n \'\n \n \n \n Created user "\n "\n \n Stw\xf3rz u\u017cytkownika &quot;\n &quot;\n \n \n \n Update user\n Zaktualizuj u\u017cytkownika\n \n \n Continue\n Kontynuuj \n \n \n You were automatically logged out because your roles have been changed.\n Zosta\u0142e\u015b automatycznie wylogowany, poniewa\u017c zosta\u0142y zmienione twoje role.\n \n \n Updated user "\n "\n \n Zaktualizowano u\u017cytkownika &quot;\n &quot;\n \n \n \n Deleted user "\n "\n \n Usuni\u0119to u\u017cytkownika &quot;\n &quot;\n \n \n \n Failed to delete user "\n "\n \n Nie uda\u0142o si\u0119 usun\u0105\u0107 u\u017cytkownika &quot;\n &quot;\n \n \n \n You are currently logged in as "\n ".\n \n Jeste\u015b obecnie zalogowany jako&quot;\n &quot;.\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Ka\u017cdy obiekt jest podzielony na cz\u0119\u015bci fragment\xf3w danych, ka\u017cdy jest przechowywany na innym OSD.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Oblicz porcje kodu dla ka\u017cdego obiektu i przechowuj je na r\xf3\u017cnych OSD.\n Liczba fragment\xf3w koduj\u0105cych to r\xf3wnie\u017c liczba OSD, kt\xf3re mog\u0105 zosta\u0107 wy\u0142\u0105czone bez utraty danych.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Wtyczka jerasure jest najbardziej uniwersaln\u0105 i elastyczn\u0105 wtyczk\u0105,\n jest to r\xf3wnie\u017c domy\u015blne ustawienie dla pui kodowanych przez Ceph.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n Bardziej elastyczn\u0105 technik\u0105 jest reed_sol_van: wystarczy ustawi\u0107 k\n oraz m. Technika cauchy_good mo\u017ce by\u0107 szybsza, ale musisz wybra\u0107 rozmiar pakietu\n ostro\u017cnie. Wszystkie reed_sol_r6_op, liberation, blaum_roth, liber8tion s\u0105 odpowiednikami RAID6\n w tym sensie, \u017ce mog\u0105 by\u0107 skonfigurowane tylko z m = 2.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n Kodowanie b\u0119dzie wykonywane na pakietach o rozmiarze bajt\xf3w naraz.\n Wyb\xf3r odpowiedniego rozmiaru pakietu jest trudny.\n Dokumentacja jerasure zawiera obszerne informacje na ten temat.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n Z wtyczk\u0105 jerasure, gdy obiekt zakodowany przy u\u017cyciu skasowania jest przechowywany na \n wielu OSD-kach, odzyskiwanie po utracie jednego OSD wymaga odczytu ze wszystkich pozosta\u0142ych.\n Na przyk\u0142ad, je\u015bli konfiguracja skryptu ma warto\u015b\u0107 k = 8 ,m = 4 i l=4, utrata jednego OSD wymaga odczytu\n od jedenastu innych do naprawy.\n\n Wtyczka kodu wymazywania lrc tworzy fragmenty o parzysto\u015bci lokalnej, aby m\xf3c je odzyska\u0107\n mniej OSD. Na przyk\u0142ad, je\u015bli lrc jest skonfigurowane z k = 8, m = 4 i l = 4, zostanie utworzony\n dodatkowy fragment parzysto\u015bci na ka\u017cde cztery OSD. Gdy jeden OSD zostanie utracone, mo\u017ce to by\u0107\n odzyskane tylko z czterema OSD zamiast jedenastu.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Grupuj fragmenty kodu i danych w zestawy lokalizacji wielko\u015bci. Na przyk\u0142ad,\n dla k = 4 i m = 2, gdy lokalno\u015b\u0107 = 3 tworzone s\u0105 dwie grupy po trzy. Ka\u017cdy zestaw mo\u017ce\n odzyska\u0107 bez czytania kawa\u0142k\xf3w z innego zestawu.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n Typ wiadra CRUSH, w kt\xf3rym zdefiniowano ka\u017cdy zestaw porcji\n przez l zostan\u0105 zapisane. Na przyk\u0142ad, je\u015bli jest ustawiony na rack, ka\u017cda grupa l porcji b\u0119dzie\n umieszczona w innym raku. S\u0142u\u017cy do utworzenia kroku regu\u0142y CRUSH, takiego jak krok wyboru\n racka. Je\u015bli nie jest ustawiony, nie ma takiego grupowania.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n Wtyczka isa zawiera bibliotek\u0119 ISA. Dzia\u0142a tylko na procesorach Intel.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n Wtyczka ISA jest dost\u0119pna w dw\xf3ch formach Reed Solomon.\n Je\u015bli ustawiono reed_sol_van, jest to Vandermonde, je\u015bli ustawiono cauchy, to jest to Cauchy.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n Wtyczka shec zawiera wiele bibliotek SHEC.\n Pozwala ceph odzyska\u0107 dane bardziej efektywnie ni\u017c kody Reeda Solomona.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n Liczba kawa\u0142k\xf3w parzysto\u015bci, z kt\xf3rych ka\u017cdy zawiera ka\u017cd\u0105 porcj\u0119 danych w swoim zakresie oblicze\u0144. Liczba jest u\u017cywana jako estymator trwa\u0142o\u015bci. Na przyk\u0142ad, je\u015bli c = 2,\n 2 OSD mo\u017cna wy\u0142\u0105czy\u0107 bez utraty danych.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n Nazwa wiadra crush jest u\u017cyte do pierwszego kroku regu\u0142y CRUSH.\nNa przyk\u0142ad krok jest domy\u015blny.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n Upewnij si\u0119, \u017ce \u017cadne dwie porcje nie znajduj\u0105 si\u0119 w wiadrze z t\u0105 sam\u0105 awari\u0105\n domeny. Na przyk\u0142ad, je\u015bli domena awarii jest hostem, nie zostan\u0105 na niej zapisane dwie porcje\n hosta. S\u0142u\u017cy do utworzenia kroku regu\u0142y CRUSH, takiego jak krok wyboru hosta.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Ogranicz umieszczanie do urz\u0105dze\u0144 okre\u015blonej klasy\n (np. ssd lub hdd), u\u017cywaj\u0105c nazw klas urz\u0105dze\u0144 zgniataj\u0105cych na mapie CRUSH.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n Ustaw nazw\u0119 katalogu, z kt\xf3rego \u0142adowana jest wtyczka kodu kasowania.\n \n \n Allows all operations\n Dozwolone s\u0105 wszystkie operacje\n \n \n Allows only operations that do not modify the server\n Dozwolone s\u0105 operacje, kt\xf3re nie modyfikuj\u0105 serweru\n \n \n Does not allow read or write operations, but allows any other operation\n Operacje odczytu i zapisu s\u0105 zakazane, wszystkie inne dozwolone\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n Operacje odczytu i zapisu, oraz wszystkie operacje modyfikuj\u0105ce atrybuty albo katalogi s\u0105 zakazane\xa0\n \n \n Allows no access at all\n Brak dost\u0119pu w og\xf3le\n \n \n -- Select the priority --\n -- wybierz priorytet -- \n \n \n Low\n Niski\n \n \n High\n Wysoki\n \n \n Last 5 minutes\n Ostatnie 5 minut\n \n \n Last 15 minutes\n Ostatnie 15 minut\n \n \n Last 30 minutes\n Ostatnie 30 minut\n \n \n Last 1 hour (Default)\n Ostatnia 1 godzina (domy\u015blnie)\n \n \n Last 3 hours\n Ostatnie 3 godziny\n \n \n Last 6 hours\n Ostatnie 6 godzin\n \n \n Last 12 hours\n Ostatnie 12 godzin\n \n \n Last 24 hours\n Ostatnie 24 godziny\n \n \n Yesterday\n Wczoraj\n \n \n Today\n Dzisiaj\n \n \n Today so far\n Do tej pory dzisiaj\n \n \n Day before yesterday\n Przedwczoraj\n \n \n Last 2 days\n Ostatnie 2 dni\n \n \n This day last week\n Tego dnia tydzie\u0144 temu\n \n \n Previous week\n Poprzedni tydzie\u0144\n \n \n This week\n Ten tydzie\u0144 \n \n \n This week so far\n Do tej pory w tym tygodniu\n \n \n Last 7 days\n Ostatnie 7 dni\n \n \n Previous month\n Poprzedniego miesi\u0105ca\n \n \n This month\n ten miesi\u0105c\n \n \n This month so far\n Do tej pory w tym miesi\u0105cu\n \n \n Last 30 days\n Ostatnie 30 dni\n \n \n Last 90 days\n Ostatnie 90 dni\n \n \n Last 6 months\n Ostatnie 6 miesi\u0119cy\n \n \n Last 1 year\n Ostatni 1 rok\n \n \n Previous year\n Poprzedniego roku\n \n \n This year\n Bie\u017c\u0105cego roku\n \n \n This year so far\n Do tej pory bie\u017c\u0105cego roku\n \n \n Last 2 years\n Ostatnie 2 lata\n \n \n Last 5 years\n Ostatnie 5 lat\n \n \n Information\n Informacja\n \n \n No items selected.\n Nie wybrano \u017cadnej pozycji\n \n \n Deselect item to select again\n Odznacz pozycj\u0119, \u017ceby wybra\u0107 ponownie\n \n \n Selection limit reached\n Osi\u0105gni\u0119to limit wyboru. \n \n \n Filter tags\n Filtr tag\xf3w.\n \n \n Add badge\n Dodaj odznak\u0119\n \n \n There are no items available.\n Brak dost\u0119pnych pozycji.\n \n \n Add\n Dodaj\n \n \n Remove\n Remove\n \n \n Clone\n Sklonuj\n \n \n Copy\n Kopia\n \n \n Deep Scrub\n Szoruj g\u0142\u0119boko\n \n \n Destroy\n Zniszcz\n \n \n Flatten\n Sp\u0142aszcz\n \n \n Mark Down\n zaznacz jako upad\u0142y\n \n \n Mark In\n Zaznacz jako w \n \n \n Mark Lost\n Zaznacz jako stracony\n \n \n Mark Out\n Zaznacz jako poza\n \n \n Protect\n Zabezpiecz\n \n \n Rename\n Zmie\u0144 nazw\u0119\n \n \n Restore\n Przywr\xf3\u0107\n \n \n Move to Trash\n Przenie\u015b do kosza\n \n \n Unprotect\n Odbezpiecz \n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Usuni\u0119ty\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Sklonowano\n \n \n Copied\n Skopiowano \n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n Tak\n \n \n No\n Nie\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Jako\u015b\u0107 serwisu\n \n \n BPS Limit\n Limit BPS\n \n \n The desired limit of IO bytes per second.\n Po\u017c\u0105dany limit IO bajt\xf3w na sekund\u0119.\n \n \n IOPS Limit\n Limit IOPS\n \n \n The desired limit of IO operations per second.\n Po\u017c\u0105dany limit operacji IO na sekund\u0119.\n \n \n Read BPS Limit\n limit odczytu BPS\n \n \n The desired limit of read bytes per second.\n Po\u017c\u0105dany limit odczytu bajt\xf3w na sekund\u0119.\n \n \n Read IOPS Limit\n limit odczytu IOPS\n \n \n The desired limit of read operations per second.\n Po\u017c\u0105dany limit operacji odczytu na sekund\u0119.\n \n \n Write BPS Limit\n Limit zapisu BPS\n \n \n The desired limit of write bytes per second.\n Po\u017c\u0105dany limit zapisu bajt\xf3w na sekund\u0119.\n \n \n Write IOPS Limit\n Limit zapisu IOPS\n \n \n The desired limit of write operations per second.\n Po\u017c\u0105dany limit operacji zapisu na sekund\u0119.\n \n \n BPS Burst\n Wi\u0105zka BPS\n \n \n The desired burst limit of IO bytes.\n \u017b\u0105dana granica serii IO bajt\xf3w.\n \n \n IOPS Burst\n Wi\u0105zka IOPS\n \n \n The desired burst limit of IO operations.\n \u017b\u0105dana granica serii operacji IO.\n \n \n Read BPS Burst\n Odczyt wi\u0105zki BPS\n \n \n The desired burst limit of read bytes.\n \u017b\u0105dana granica serii odczytanych bajt\xf3w.\n \n \n Read IOPS Burst\n Odczyt wi\u0105zki IOPS\n \n \n The desired burst limit of read operations.\n \u017b\u0105dana granica serii operacji odczytu.\n \n \n Write BPS Burst\n Zapis wi\u0105zki BPS\n \n \n The desired burst limit of write bytes.\n \u017b\u0105dana granica serii bajt\xf3w zapisu.\n \n \n Write IOPS Burst\n Zapis wi\u0105zki IOPS\n \n \n The desired burst limit of write operations.\n \u017b\u0105dana granica serii operacji zapisu.\n \n \n Failed to \n \n \n \n Nie powiod\u0142o si\u0119 \n \n \n \n \n \n Executing\n Wykonywanie \n \n \n execute\n Wykonaj\n \n \n Executed\n Wykonany\n \n \n unknown task\n Nieznane zadanie\n \n \n Creating\n Tworzenie\n \n \n create\n Utw\xf3rz\n \n \n Updating\n Aktualizowanie \n \n \n update\n Zaktualizuj\n \n \n Deleting\n Usuwanie\n \n \n delete\n Usu\u0144\n \n \n RBD \'\n \'\n \n urz\u0105dzenie blokowe Rados\xa0\'\n \'\xa0\n \n \n \n RBD snapshot \'\n \'\n \n migawka RBD \'\n \'\xa0\n \n \n \n mirror mode for pool \'\n \'\n \n tryb lustrzany dla pula \'\n \'\n \n \n \n mirror peer for pool \'\n \'\n \n Lustrzane parowanie dla pula \'\n \'\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n Nazwa jest ju\u017c u\u017cyta przez \n .\n \n \n \n Name is already used by \n .\n \n Nazwa jest ju\u017c u\u017cywana przez \n .\n \n \n \n Name is already used by \n .\n \n Nazwa jest ju\u017c u\u017cywana przez \n .\n \n \n \n \n contains snapshots.\n \n \n zawiera migawk\u0119.\n \n \n \n Cloning\n Klonowanie\n \n \n clone\n Sklonuj \n \n \n Snapshot of \n must be protected.\n \n Migawka \n \xa0 musi by\u0107 zabezpieczona.\n \n \n \n Copying\n Kopiowanie \n \n \n copy\n Kopiuj\n \n \n Flattening\n Sp\u0142aszczanie\n \n \n flatten\n Sp\u0142aszcz\n \n \n Flattened\n Sp\u0142aszczony\n \n \n Name is already used by \n .\n \n Nazwa ju\u017c jest u\u017cywana przez \n .\n \n \n \n Cannot unprotect \n because it contains child images.\n \n Nie mo\u017cna zdj\u0105\u0107 zabezpieczenia \n , poniewa\u017c zawiera pokrewne obrazy.\n \n \n \n Cannot delete \n because it\'s protected.\n \n Nie mo\u017cna usun\u0105\u0107 \n , poniewa\u017c jest zabezpieczony.\n \n \n \n Rolling back\n Wycofywanie \n \n \n rollback\n Wycofanie\n \n \n Rolled back\n Wycofaj\n \n \n Moving\n Przenoszenie\n \n \n move\n Przenie\u015b\n \n \n Moved\n Przeniesiono\n \n \n image \'\n \' to trash\n \n Obraz \'\n \' przenie\u015b do kosza\n \n \n \n Could not find image.\n Nie znaleziono obrazu.\n \n \n Restoring\n Przywracanie\n \n \n restore\n Przywr\xf3\u0107 \n \n \n Restored\n Przywr\xf3cony\n \n \n image \'\n \' into \'\n \'\n \n Obraz \'\n \' w \'\n \' \n \n \n \n Image name \'\n \' is already in use.\n \n Nazwa obrazu \'\n \' jest ju\u017c u\u017cywana. \n \n \n \n image \'\n \'\n \n Obraz \'\n \'\xa0\n \n \n \n Purging\n oczyszcza\u0107\n \n \n purge\n oczy\u015b\u0107\n \n \n Purged\n Oczyszczony\n \n \n all pools\n Wszystkie pule\n \n \n images from \n \n \n Obraz z \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n Nie mo\u017cna wy\u0142\u0105czy\u0107 lustrzenia poniewa\u017c zawiera parowanie.\n \n \n pool \'\n \'\n \n pul \'\n \'\n \n \n \n erasure code profile \'\n \'\n \n skasuj profil kodu \'\n \'\n \n \n \n target \'\n \'\n \n docelowy \'\n \'\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},"/TVo":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("CcnG"),r=(n("urB8"),n("0M9P"));n("xZld"),e.NodeDraggableDirective=function(){function t(t,e,n){this.element=t,this.nodeDraggableService=e,this.renderer=n,this.disposersForDragListeners=[],this.nodeNativeElement=t.nativeElement}return t.prototype.ngOnInit=function(){this.tree.isStatic()||(this.renderer.setAttribute(this.nodeNativeElement,"draggable","true"),this.disposersForDragListeners.push(this.renderer.listen(this.nodeNativeElement,"dragenter",this.handleDragEnter.bind(this))),this.disposersForDragListeners.push(this.renderer.listen(this.nodeNativeElement,"dragover",this.handleDragOver.bind(this))),this.disposersForDragListeners.push(this.renderer.listen(this.nodeNativeElement,"dragstart",this.handleDragStart.bind(this))),this.disposersForDragListeners.push(this.renderer.listen(this.nodeNativeElement,"dragleave",this.handleDragLeave.bind(this))),this.disposersForDragListeners.push(this.renderer.listen(this.nodeNativeElement,"drop",this.handleDrop.bind(this))),this.disposersForDragListeners.push(this.renderer.listen(this.nodeNativeElement,"dragend",this.handleDragEnd.bind(this))))},t.prototype.ngOnDestroy=function(){this.disposersForDragListeners.forEach(function(t){return t()})},t.prototype.handleDragStart=function(e){e.stopPropagation&&e.stopPropagation(),this.nodeDraggableService.captureNode(new r.CapturedNode(this.nodeDraggable,this.tree)),e.dataTransfer.setData("text",t.DATA_TRANSFER_STUB_DATA),e.dataTransfer.effectAllowed="move"},t.prototype.handleDragOver=function(t){t.preventDefault(),t.dataTransfer.dropEffect="move"},t.prototype.handleDragEnter=function(t){t.preventDefault(),this.containsElementAt(t)&&this.addClass("over-drop-target")},t.prototype.handleDragLeave=function(t){this.containsElementAt(t)||this.removeClass("over-drop-target")},t.prototype.handleDrop=function(t){return t.preventDefault(),t.stopPropagation&&t.stopPropagation(),this.removeClass("over-drop-target"),!!this.isDropPossible(t)&&(this.nodeDraggableService.getCapturedNode()?this.notifyThatNodeWasDropped():void 0)},t.prototype.isDropPossible=function(t){var e=this.nodeDraggableService.getCapturedNode();return e&&e.canBeDroppedAt(this.nodeDraggable)&&this.containsElementAt(t)},t.prototype.handleDragEnd=function(t){this.removeClass("over-drop-target"),this.nodeDraggableService.releaseCapturedNode()},t.prototype.containsElementAt=function(t){var e=t.x,n=t.y;return this.nodeNativeElement.contains(document.elementFromPoint(void 0===e?t.clientX:e,void 0===n?t.clientY:n))},t.prototype.addClass=function(t){this.nodeNativeElement.classList.add(t)},t.prototype.removeClass=function(t){this.nodeNativeElement.classList.remove(t)},t.prototype.notifyThatNodeWasDropped=function(){this.nodeDraggableService.fireNodeDragged(this.nodeDraggableService.getCapturedNode(),this.nodeDraggable)},t.DATA_TRANSFER_STUB_DATA="some browsers enable drag-n-drop only when dataTransfer has data",t.decorators=[{type:a.Directive,args:[{selector:"[nodeDraggable]"}]}],t.propDecorators={nodeDraggable:[{type:a.Input}],tree:[{type:a.Input}]},t}()},"/WYv":function(t,e,n){"use strict";function a(t){return!!t&&"function"!=typeof t.subscribe&&"function"==typeof t.then}n.d(e,"a",function(){return a})},"/X5v":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("x-pseudo",{months:"J~\xe1\xf1\xfa\xe1~r\xfd_F~\xe9br\xfa~\xe1r\xfd_~M\xe1rc~h_\xc1p~r\xedl_~M\xe1\xfd_~J\xfa\xf1\xe9~_J\xfal~\xfd_\xc1\xfa~g\xfast~_S\xe9p~t\xe9mb~\xe9r_\xd3~ct\xf3b~\xe9r_\xd1~\xf3v\xe9m~b\xe9r_~D\xe9c\xe9~mb\xe9r".split("_"),monthsShort:"J~\xe1\xf1_~F\xe9b_~M\xe1r_~\xc1pr_~M\xe1\xfd_~J\xfa\xf1_~J\xfal_~\xc1\xfag_~S\xe9p_~\xd3ct_~\xd1\xf3v_~D\xe9c".split("_"),monthsParseExact:!0,weekdays:"S~\xfa\xf1d\xe1~\xfd_M\xf3~\xf1d\xe1\xfd~_T\xfa\xe9~sd\xe1\xfd~_W\xe9d~\xf1\xe9sd~\xe1\xfd_T~h\xfars~d\xe1\xfd_~Fr\xedd~\xe1\xfd_S~\xe1t\xfar~d\xe1\xfd".split("_"),weekdaysShort:"S~\xfa\xf1_~M\xf3\xf1_~T\xfa\xe9_~W\xe9d_~Th\xfa_~Fr\xed_~S\xe1t".split("_"),weekdaysMin:"S~\xfa_M\xf3~_T\xfa_~W\xe9_T~h_Fr~_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[T~\xf3d\xe1~\xfd \xe1t] LT",nextDay:"[T~\xf3m\xf3~rr\xf3~w \xe1t] LT",nextWeek:"dddd [\xe1t] LT",lastDay:"[\xdd~\xe9st~\xe9rd\xe1~\xfd \xe1t] LT",lastWeek:"[L~\xe1st] dddd [\xe1t] LT",sameElse:"L"},relativeTime:{future:"\xed~\xf1 %s",past:"%s \xe1~g\xf3",s:"\xe1 ~f\xe9w ~s\xe9c\xf3~\xf1ds",ss:"%d s~\xe9c\xf3\xf1~ds",m:"\xe1 ~m\xed\xf1~\xfat\xe9",mm:"%d m~\xed\xf1\xfa~t\xe9s",h:"\xe1~\xf1 h\xf3~\xfar",hh:"%d h~\xf3\xfars",d:"\xe1 ~d\xe1\xfd",dd:"%d d~\xe1\xfds",M:"\xe1 ~m\xf3\xf1~th",MM:"%d m~\xf3\xf1t~hs",y:"\xe1 ~\xfd\xe9\xe1r",yy:"%d \xfd~\xe9\xe1rs"},dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")},week:{dow:1,doy:4}})}()},0:function(t,e,n){t.exports=n("zUnb")},"0+/T":function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("gIcY"),r=n("QFaf"),i=(n("sb0X"),function(){function t(t){this.modalRef=t,this.actionDescription="delete"}return t.prototype.ngOnInit=function(){if(this.deletionForm=new r.a({confirmation:new a.i(!1,[a.A.requiredTrue])}),!this.submitAction&&!this.submitActionObservable)throw new Error("No submit action defined")},t.prototype.callSubmitAction=function(){this.submitActionObservable?this.submitActionObservable().subscribe(null,this.stopLoadingSpinner.bind(this),this.hideModal.bind(this)):this.submitAction()},t.prototype.hideModal=function(){this.modalRef.hide()},t.prototype.stopLoadingSpinner=function(){this.deletionForm.setErrors({cdSubmitButton:!0})},t}())},"0/uQ":function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("6blF"),r=n("Fxb1"),i=n("i4X3");function s(t,e){return e?Object(i.a)(t,e):t instanceof a.a?t:new a.a(Object(r.a)(t))}},"0M9P":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.CapturedNode=function(){function t(t,e){this.anElement=t,this.aTree=e}return t.prototype.canBeDroppedAt=function(t){return!this.sameAs(t)&&!this.contains(t)},t.prototype.contains=function(t){return this.element.nativeElement.contains(t.nativeElement)},t.prototype.sameAs=function(t){return this.element===t},Object.defineProperty(t.prototype,"element",{get:function(){return this.anElement},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"tree",{get:function(){return this.aTree},enumerable:!0,configurable:!0}),t}()},"0MID":function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("qwkt"),o=n("5tze");n("czA5"),e.DataTableHeaderCellComponent=function(){function t(t){this.cd=t,this.sort=new i.EventEmitter,this.select=new i.EventEmitter,this.columnContextmenu=new i.EventEmitter(!1),this.sortFn=this.onSort.bind(this),this.selectFn=this.select.emit.bind(this.select),this.cellContext={column:this.column,sortDir:this.sortDir,sortFn:this.sortFn,allRowsSelected:this.allRowsSelected,selectFn:this.selectFn}}return Object.defineProperty(t.prototype,"allRowsSelected",{get:function(){return this._allRowsSelected},set:function(t){this._allRowsSelected=t,this.cellContext.allRowsSelected=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"column",{get:function(){return this._column},set:function(t){this._column=t,this.cellContext.column=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"sorts",{get:function(){return this._sorts},set:function(t){this._sorts=t,this.sortDir=this.calcSortDir(t),this.cellContext.sortDir=this.sortDir,this.sortClass=this.calcSortClass(this.sortDir),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columnCssClasses",{get:function(){var t="datatable-header-cell";if(this.column.sortable&&(t+=" sortable"),this.column.resizeable&&(t+=" resizeable"),this.column.headerClass)if("string"==typeof this.column.headerClass)t+=" "+this.column.headerClass;else if("function"==typeof this.column.headerClass){var e=this.column.headerClass({column:this.column});if("string"==typeof e)t+=e;else if("object"==typeof e)for(var n=0,a=Object.keys(e);n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',host:{class:"datatable-header-cell"},changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},"0mo+":function(t,e,n){!function(t){"use strict";var e={1:"\u0f21",2:"\u0f22",3:"\u0f23",4:"\u0f24",5:"\u0f25",6:"\u0f26",7:"\u0f27",8:"\u0f28",9:"\u0f29",0:"\u0f20"},n={"\u0f21":"1","\u0f22":"2","\u0f23":"3","\u0f24":"4","\u0f25":"5","\u0f26":"6","\u0f27":"7","\u0f28":"8","\u0f29":"9","\u0f20":"0"};t.defineLocale("bo",{months:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54".split("_"),monthsShort:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54".split("_"),weekdays:"\u0f42\u0f5f\u0f60\u0f0b\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f42\u0f5f\u0f60\u0f0b\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f42\u0f5f\u0f60\u0f0b\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysShort:"\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),weekdaysMin:"\u0f49\u0f72\u0f0b\u0f58\u0f0b_\u0f5f\u0fb3\u0f0b\u0f56\u0f0b_\u0f58\u0f72\u0f42\u0f0b\u0f51\u0f58\u0f62\u0f0b_\u0f63\u0fb7\u0f42\u0f0b\u0f54\u0f0b_\u0f55\u0f74\u0f62\u0f0b\u0f56\u0f74_\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b_\u0f66\u0fa4\u0f7a\u0f53\u0f0b\u0f54\u0f0b".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0f51\u0f72\u0f0b\u0f62\u0f72\u0f44] LT",nextDay:"[\u0f66\u0f44\u0f0b\u0f49\u0f72\u0f53] LT",nextWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f62\u0f97\u0f7a\u0f66\u0f0b\u0f58], LT",lastDay:"[\u0f41\u0f0b\u0f66\u0f44] LT",lastWeek:"[\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f55\u0fb2\u0f42\u0f0b\u0f58\u0f50\u0f60\u0f0b\u0f58] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0f63\u0f0b",past:"%s \u0f66\u0f94\u0f53\u0f0b\u0f63",s:"\u0f63\u0f58\u0f0b\u0f66\u0f44",ss:"%d \u0f66\u0f90\u0f62\u0f0b\u0f46\u0f0d",m:"\u0f66\u0f90\u0f62\u0f0b\u0f58\u0f0b\u0f42\u0f45\u0f72\u0f42",mm:"%d \u0f66\u0f90\u0f62\u0f0b\u0f58",h:"\u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51\u0f0b\u0f42\u0f45\u0f72\u0f42",hh:"%d \u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51",d:"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f45\u0f72\u0f42",dd:"%d \u0f49\u0f72\u0f53\u0f0b",M:"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f45\u0f72\u0f42",MM:"%d \u0f5f\u0fb3\u0f0b\u0f56",y:"\u0f63\u0f7c\u0f0b\u0f42\u0f45\u0f72\u0f42",yy:"%d \u0f63\u0f7c"},preparse:function(t){return t.replace(/[\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u0f20]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c|\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66|\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44|\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42|\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"===e&&t>=4||"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44"===e&&t<5||"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42"===e?t+12:t},meridiem:function(t,e,n){return t<4?"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c":t<10?"\u0f5e\u0f7c\u0f42\u0f66\u0f0b\u0f40\u0f66":t<17?"\u0f49\u0f72\u0f53\u0f0b\u0f42\u0f74\u0f44":t<20?"\u0f51\u0f42\u0f7c\u0f44\u0f0b\u0f51\u0f42":"\u0f58\u0f5a\u0f53\u0f0b\u0f58\u0f7c"},week:{dow:0,doy:6}})}(n("wd/R"))},"0tRk":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("pt-br",{months:"Janeiro_Fevereiro_Mar\xe7o_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [\xe0s] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [\xe0s] HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"poucos segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba"})}()},"15JJ":function(t,e,n){"use strict";n.d(e,"a",function(){return c});var a=n("mrSG"),r=n("MGBS"),i=n("rPjj"),s=n("zotm"),o=n("67Y/"),u=n("0/uQ");function c(t,e){return"function"==typeof e?function(n){return n.pipe(c(function(n,a){return Object(u.a)(t(n,a)).pipe(Object(o.a)(function(t,r){return e(n,t,a,r)}))}))}:function(e){return e.lift(new l(t))}}var l=function(){function t(t){this.project=t}return t.prototype.call=function(t,e){return e.subscribe(new d(t,this.project))},t}(),d=function(t){function e(e,n){var a=t.call(this,e)||this;return a.project=n,a.index=0,a}return a.__extends(e,t),e.prototype._next=function(t){var e,n=this.index++;try{e=this.project(t,n)}catch(a){return void this.destination.error(a)}this._innerSub(e,t,n)},e.prototype._innerSub=function(t,e,n){var a=this.innerSubscription;a&&a.unsubscribe();var r=new i.a(this,void 0,void 0);this.destination.add(r),this.innerSubscription=Object(s.a)(this,t,e,n,r)},e.prototype._complete=function(){var e=this.innerSubscription;e&&!e.closed||t.prototype._complete.call(this),this.unsubscribe()},e.prototype._unsubscribe=function(){this.innerSubscription=null},e.prototype.notifyComplete=function(e){this.destination.remove(e),this.innerSubscription=null,this.isStopped&&t.prototype._complete.call(this)},e.prototype.notifyNext=function(t,e,n,a,r){this.destination.next(e)},e}(r.a)},"1HVU":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("rdkg"),r=n("CVuo"),i="undefined"!=typeof window?a.getVendorPrefixedName("transform"):void 0,s="undefined"!=typeof window?a.getVendorPrefixedName("backfaceVisibility"):void 0,o="undefined"!=typeof window?!!a.getVendorPrefixedName("transform"):void 0,u="undefined"!=typeof window?!!a.getVendorPrefixedName("perspective"):void 0,c="undefined"!=typeof window?window.navigator.userAgent:"Chrome",l=/Safari\//.test(c)&&!/Chrome\//.test(c);e.translateXY=function(t,e,n){void 0!==i&&o?!l&&u?(t[i]="translate3d("+e+"px, "+n+"px, 0)",t[s]="hidden"):t[r.camelCase(i)]="translate("+e+"px, "+n+"px)":(t.top=n+"px",t.left=e+"px")}},"1Ni5":function(t,e,n){"use strict";n.d(e,"b",function(){return l}),n.d(e,"a",function(){return d});var a=n("gIcY"),r=n("LvDl"),i=n("F/XL"),s=n("gI3B"),o=n("zQHH"),u=n("67Y/"),c=n("t9fZ");function l(t){return null==t||0===t.length}var d=function(){function t(){}return t.email=function(t){return l(t.value)?null:a.A.email(t)},t.ip=function(t){void 0===t&&(t=0);var e=/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i,n=/^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i;return a.A.pattern(4===t?e:6===t?n:new RegExp(e.source+"|"+n.source))},t.number=function(t){return void 0===t&&(t=!0),a.A.pattern(t?/^-?[0-9]+$/i:/^[0-9]+$/i)},t.decimalNumber=function(t){return void 0===t&&(t=!0),a.A.pattern(t?/^-?[0-9]+(.[0-9]+)?$/i:/^[0-9]+(.[0-9]+)?$/i)},t.requiredIf=function(t,e){var n=!1;return function(a){return!n&&a.parent&&(Object.keys(t).forEach(function(t){a.parent.get(t).valueChanges.subscribe(function(){a.updateValueAndValidity({emitEvent:!1})})}),n=!0),Object.keys(t).every(function(e){return a.parent&&a.parent.get(e).value===t[e]})&&(r.isFunction(e)?e.call(e,a.value):l(a.value))?{required:!0}:null}},t.custom=function(t,e){var n=this;return function(a){var r,i=e.call(n,a.value);return i?((r={})[t]=i,r):null}},t.validateIf=function(t,e,n,r,i){var s=this;void 0===r&&(r=[]),void 0===i&&(i=[]),n=n.concat(r),t.setValidators(function(t){return e.call(s)?a.A.compose(n)(t):r.length>0?a.A.compose(r)(t):null}),i.forEach(function(e){e.valueChanges.subscribe(function(){t.updateValueAndValidity({emitEvent:!1})})})},t.match=function(t,e){return function(n){var a=n.get(t),i=n.get(e);if(a.value!==i.value)i.setErrors({match:!0});else if(i.hasError("match")){var s=i.errors;r.unset(s,"match"),i.setErrors(r.isEmpty(r.keys(s))?null:s)}return null}},t.unique=function(t,e,n){return void 0===e&&(e=null),void 0===n&&(n=500),function(a){return a.pristine||l(a.value)?Object(i.a)(null):Object(s.a)(n).pipe(Object(o.a)(t.call(e,a.value)),Object(u.a)(function(t){return t?{notUnique:!0}:null}),Object(c.a)(1))}},t.uuid=function(t){void 0===t&&(t=!1);var e=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return function(n){return n.pristine&&n.untouched?null:t||n.value?e.test(n.value)?null:{invalidUuid:"This is not a valid UUID"}:null}},t}()},"1PfE":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.NodeEditableEventAction=function(t){return t[t.Cancel=0]="Cancel",t}(e.NodeEditableEventAction||{})},"1fDf":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("FFOo");function r(t){for(;t;){var e=t.destination;if(t.closed||t.isStopped)return!1;t=e&&e instanceof a.a?e:null}return!0}},"1rYy":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("hy-am",{months:{format:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580\u056b_\u0583\u0565\u057f\u0580\u057e\u0561\u0580\u056b_\u0574\u0561\u0580\u057f\u056b_\u0561\u057a\u0580\u056b\u056c\u056b_\u0574\u0561\u0575\u056b\u057d\u056b_\u0570\u0578\u0582\u0576\u056b\u057d\u056b_\u0570\u0578\u0582\u056c\u056b\u057d\u056b_\u0585\u0563\u0578\u057d\u057f\u0578\u057d\u056b_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580\u056b_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580\u056b".split("_"),standalone:"\u0570\u0578\u0582\u0576\u057e\u0561\u0580_\u0583\u0565\u057f\u0580\u057e\u0561\u0580_\u0574\u0561\u0580\u057f_\u0561\u057a\u0580\u056b\u056c_\u0574\u0561\u0575\u056b\u057d_\u0570\u0578\u0582\u0576\u056b\u057d_\u0570\u0578\u0582\u056c\u056b\u057d_\u0585\u0563\u0578\u057d\u057f\u0578\u057d_\u057d\u0565\u057a\u057f\u0565\u0574\u0562\u0565\u0580_\u0570\u0578\u056f\u057f\u0565\u0574\u0562\u0565\u0580_\u0576\u0578\u0575\u0565\u0574\u0562\u0565\u0580_\u0564\u0565\u056f\u057f\u0565\u0574\u0562\u0565\u0580".split("_")},monthsShort:"\u0570\u0576\u057e_\u0583\u057f\u0580_\u0574\u0580\u057f_\u0561\u057a\u0580_\u0574\u0575\u057d_\u0570\u0576\u057d_\u0570\u056c\u057d_\u0585\u0563\u057d_\u057d\u057a\u057f_\u0570\u056f\u057f_\u0576\u0574\u0562_\u0564\u056f\u057f".split("_"),weekdays:"\u056f\u056b\u0580\u0561\u056f\u056b_\u0565\u0580\u056f\u0578\u0582\u0577\u0561\u0562\u0569\u056b_\u0565\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0579\u0578\u0580\u0565\u0584\u0577\u0561\u0562\u0569\u056b_\u0570\u056b\u0576\u0563\u0577\u0561\u0562\u0569\u056b_\u0578\u0582\u0580\u0562\u0561\u0569_\u0577\u0561\u0562\u0561\u0569".split("_"),weekdaysShort:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),weekdaysMin:"\u056f\u0580\u056f_\u0565\u0580\u056f_\u0565\u0580\u0584_\u0579\u0580\u0584_\u0570\u0576\u0563_\u0578\u0582\u0580\u0562_\u0577\u0562\u0569".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0569.",LLL:"D MMMM YYYY \u0569., HH:mm",LLLL:"dddd, D MMMM YYYY \u0569., HH:mm"},calendar:{sameDay:"[\u0561\u0575\u057d\u0585\u0580] LT",nextDay:"[\u057e\u0561\u0572\u0568] LT",lastDay:"[\u0565\u0580\u0565\u056f] LT",nextWeek:function(){return"dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},lastWeek:function(){return"[\u0561\u0576\u0581\u0561\u056e] dddd [\u0585\u0580\u0568 \u056a\u0561\u0574\u0568] LT"},sameElse:"L"},relativeTime:{future:"%s \u0570\u0565\u057f\u0578",past:"%s \u0561\u057c\u0561\u057b",s:"\u0574\u056b \u0584\u0561\u0576\u056b \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",ss:"%d \u057e\u0561\u0575\u0580\u056f\u0575\u0561\u0576",m:"\u0580\u0578\u057a\u0565",mm:"%d \u0580\u0578\u057a\u0565",h:"\u056a\u0561\u0574",hh:"%d \u056a\u0561\u0574",d:"\u0585\u0580",dd:"%d \u0585\u0580",M:"\u0561\u0574\u056b\u057d",MM:"%d \u0561\u0574\u056b\u057d",y:"\u057f\u0561\u0580\u056b",yy:"%d \u057f\u0561\u0580\u056b"},meridiemParse:/\u0563\u056b\u0577\u0565\u0580\u057e\u0561|\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561|\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576/,isPM:function(t){return/^(\u0581\u0565\u0580\u0565\u056f\u057e\u0561|\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576)$/.test(t)},meridiem:function(t){return t<4?"\u0563\u056b\u0577\u0565\u0580\u057e\u0561":t<12?"\u0561\u057c\u0561\u057e\u0578\u057f\u057e\u0561":t<17?"\u0581\u0565\u0580\u0565\u056f\u057e\u0561":"\u0565\u0580\u0565\u056f\u0578\u0575\u0561\u0576"},dayOfMonthOrdinalParse:/\d{1,2}|\d{1,2}-(\u056b\u0576|\u0580\u0564)/,ordinal:function(t,e){switch(e){case"DDD":case"w":case"W":case"DDDo":return 1===t?t+"-\u056b\u0576":t+"-\u0580\u0564";default:return t}},week:{dow:1,doy:7}})}()},"1xZ4":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("ca",{months:{standalone:"gener_febrer_mar\xe7_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),format:"de gener_de febrer_de mar\xe7_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._mar\xe7_abr._maig_juny_jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dt_dc_dj_dv_ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a les] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a les] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[dem\xe0 a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"d'aqu\xed %s",past:"fa %s",s:"uns segons",ss:"%d segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|\xe8|a)/,ordinal:function(t,e){var n=1===t?"r":2===t?"n":3===t?"r":4===t?"t":"\xe8";return"w"!==e&&"W"!==e||(n="a"),t+n},week:{dow:1,doy:4}})}()},"20UP":function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("CcnG"),r=n("t/Na"),i=n("pL04"),s=function(){function t(t){this.http=t,this.settings={}}return t.prototype.ifSettingConfigured=function(t,e,n){var a=this,r=this.settings[t];void 0===r?this.http.get(t).subscribe(function(r){a.settings[t]=a.getSettingsValue(r),a.ifSettingConfigured(t,e,n)},function(e){401!==e.status&&(a.settings[t]="")}):""!==r?e(r):n&&n()},t.prototype.disableSetting=function(t){this.settings[t]=""},t.prototype.getSettingsValue=function(t){return t.value||t.instance||""},t.prototype.validateGrafanaDashboardUrl=function(t){return this.http.get("api/grafana/validation/"+t)},t.ngInjectableDef=a.defineInjectable({factory:function(){return new t(a.inject(r.c))},token:t,providedIn:i.a}),t}()},"25BL":function(t,e,n){"use strict";var a=n("CcnG"),r=n("M/6F"),i=n("NDi4"),s=n("Ip0R"),o=n("gIcY"),u=n("xtZt"),c=n("lqqz"),l=n("fhFe"),d=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function f(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"li",[["class","pages"],["role","button"]],[[1,"aria-label",0],[2,"active",null]],null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"a",[["href","javascript:void(0)"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.selectPage(t.context.$implicit.number)&&a),a},null,null)),(t()(),a["\u0275ted"](2,null,[" "," "]))],null,function(t,e){t(e,0,0,"page "+e.context.$implicit.number,e.context.$implicit.number===e.component.page),t(e,2,0,e.context.$implicit.text)})}function p(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,14,"ul",[["class","pager"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,2,"li",[],[[2,"disabled",null]],null,null,null,null)),(t()(),a["\u0275eld"](2,0,null,null,1,"a",[["aria-label","go to first page"],["href","javascript:void(0)"],["role","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.selectPage(1)&&a),a},null,null)),(t()(),a["\u0275eld"](3,0,null,null,0,"i",[],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275eld"](4,0,null,null,2,"li",[],[[2,"disabled",null]],null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,1,"a",[["aria-label","go to previous page"],["href","javascript:void(0)"],["role","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.prevPage()&&a),a},null,null)),(t()(),a["\u0275eld"](6,0,null,null,0,"i",[],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,f)),a["\u0275did"](8,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),a["\u0275eld"](9,0,null,null,2,"li",[],[[2,"disabled",null]],null,null,null,null)),(t()(),a["\u0275eld"](10,0,null,null,1,"a",[["aria-label","go to next page"],["href","javascript:void(0)"],["role","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.nextPage()&&a),a},null,null)),(t()(),a["\u0275eld"](11,0,null,null,0,"i",[],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275eld"](12,0,null,null,2,"li",[],[[2,"disabled",null]],null,null,null,null)),(t()(),a["\u0275eld"](13,0,null,null,1,"a",[["aria-label","go to last page"],["href","javascript:void(0)"],["role","button"]],null,[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.selectPage(r.totalPages)&&a),a},null,null)),(t()(),a["\u0275eld"](14,0,null,null,0,"i",[],[[8,"className",0]],null,null,null,null))],function(t,e){t(e,8,0,e.component.pages)},function(t,e){var n=e.component;t(e,1,0,!n.canPrevious()),t(e,3,0,a["\u0275inlineInterpolate"](1,"",n.pagerPreviousIcon,"")),t(e,4,0,!n.canPrevious()),t(e,6,0,a["\u0275inlineInterpolate"](1,"",n.pagerLeftArrowIcon,"")),t(e,9,0,!n.canNext()),t(e,11,0,a["\u0275inlineInterpolate"](1,"",n.pagerRightArrowIcon,"")),t(e,12,0,!n.canNext()),t(e,14,0,a["\u0275inlineInterpolate"](1,"",n.pagerNextIcon,""))})}var h=n("JxMD"),g=n("dgut"),b=n("Fgil"),m=n("ZYCi"),y=n("o4+5"),v=n("aXbf"),_=n("TJUb"),x=n("0MID"),T=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function w(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function S(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,w)),a["\u0275did"](1,540672,null,0,s.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,1,0,n.targetMarkerContext,n.targetMarkerTemplate)},null)}function O(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"label",[["class","datatable-checkbox"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,0,"input",[["type","checkbox"]],[[8,"checked",0]],[[null,"change"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==r.select.emit(!r.allRowsSelected)&&a),a},null,null))],null,function(t,e){t(e,1,0,e.component.allRowsSelected)})}function I(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"span",[["class","datatable-header-cell-wrapper"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,0,"span",[["class","datatable-header-cell-label draggable"]],[[8,"innerHTML",1]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.onSort()&&a),a},null,null))],null,function(t,e){t(e,1,0,e.component.name)})}function C(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function k(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,C)),a["\u0275did"](1,540672,null,0,s.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,1,0,n.cellContext,n.column.headerTemplate)},null)}function N(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,9,"div",[["class","datatable-header-cell-template-wrap"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,S)),a["\u0275did"](2,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,O)),a["\u0275did"](4,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,I)),a["\u0275did"](6,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,k)),a["\u0275did"](8,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](9,0,null,null,0,"span",[],[[8,"className",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.onSort()&&a),a},null,null))],function(t,e){var n=e.component;t(e,2,0,n.isTarget),t(e,4,0,n.isCheckboxable),t(e,6,0,!n.column.headerTemplate),t(e,8,0,n.column.headerTemplate)},function(t,e){t(e,9,0,e.component.sortClass)})}var R=n("3MdB"),A=n("M9eX"),D=n("Cc8h"),E=n("ylLw"),L=n("ZYjt"),P=n("tFKq"),M=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function q(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"datatable-header-cell",[["class","datatable-header-cell"],["draggable",""],["long-press",""],["resizeable",""]],[[2,"resizeable",null],[2,"press",null],[2,"longpress",null],[4,"height","px"],[8,"className",0],[1,"title",0],[4,"minWidth","px"],[4,"maxWidth","px"],[4,"width","px"]],[[null,"resize"],[null,"longPressStart"],[null,"longPressEnd"],[null,"sort"],[null,"select"],[null,"columnContextmenu"],[null,"mousedown"],[null,"contextmenu"]],function(t,e,n){var r=!0,i=t.component;return"mousedown"===e&&(r=!1!==a["\u0275nov"](t,2).onMousedown(n)&&r),"mousedown"===e&&(r=!1!==a["\u0275nov"](t,3).onMouseDown(n)&&r),"contextmenu"===e&&(r=!1!==a["\u0275nov"](t,4).onContextmenu(n)&&r),"resize"===e&&(r=!1!==i.onColumnResized(n,t.context.$implicit)&&r),"longPressStart"===e&&(r=!1!==i.onLongPressStart(n)&&r),"longPressEnd"===e&&(r=!1!==i.onLongPressEnd(n)&&r),"sort"===e&&(r=!1!==i.onSort(n)&&r),"select"===e&&(r=!1!==i.select.emit(n)&&r),"columnContextmenu"===e&&(r=!1!==i.columnContextmenu.emit(n)&&r),r},N,T)),a["\u0275did"](1,671744,[[1,4]],0,R.DraggableDirective,[a.ElementRef],{dragEventTarget:[0,"dragEventTarget"],dragModel:[1,"dragModel"],dragX:[2,"dragX"],dragY:[3,"dragY"]},null),a["\u0275did"](2,4341760,null,0,A.ResizeableDirective,[a.ElementRef,a.Renderer2],{resizeEnabled:[0,"resizeEnabled"]},{resize:"resize"}),a["\u0275did"](3,147456,null,0,D.LongPressDirective,[],{pressEnabled:[0,"pressEnabled"],pressModel:[1,"pressModel"]},{longPressStart:"longPressStart",longPressEnd:"longPressEnd"}),a["\u0275did"](4,49152,null,0,x.DataTableHeaderCellComponent,[a.ChangeDetectorRef],{sortType:[0,"sortType"],sortAscendingIcon:[1,"sortAscendingIcon"],sortDescendingIcon:[2,"sortDescendingIcon"],isTarget:[3,"isTarget"],targetMarkerTemplate:[4,"targetMarkerTemplate"],targetMarkerContext:[5,"targetMarkerContext"],allRowsSelected:[6,"allRowsSelected"],selectionType:[7,"selectionType"],column:[8,"column"],headerHeight:[9,"headerHeight"],sorts:[10,"sorts"]},{sort:"sort",select:"select",columnContextmenu:"columnContextmenu"})],function(t,e){var n=e.component;t(e,1,0,n.dragEventTarget,e.context.$implicit,n.reorderable&&e.context.$implicit.draggable&&e.context.$implicit.dragging,!1),t(e,2,0,e.context.$implicit.resizeable),t(e,3,0,n.reorderable&&e.context.$implicit.draggable,e.context.$implicit),t(e,4,1,[n.sortType,n.sortAscendingIcon,n.sortDescendingIcon,e.context.$implicit.isTarget,n.targetMarkerTemplate,e.context.$implicit.targetMarkerContext,n.allRowsSelected,n.selectionType,e.context.$implicit,n.headerHeight,n.sorts])},function(t,e){t(e,0,0,a["\u0275nov"](e,2).resizeEnabled,a["\u0275nov"](e,3).press,a["\u0275nov"](e,3).isLongPress,a["\u0275nov"](e,4).headerHeight,a["\u0275nov"](e,4).columnCssClasses,a["\u0275nov"](e,4).name,a["\u0275nov"](e,4).minWidth,a["\u0275nov"](e,4).maxWidth,a["\u0275nov"](e,4).width)})}function j(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[],[[8,"className",0]],null,null,null,null)),a["\u0275did"](1,278528,null,0,s.NgStyle,[a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngStyle:[0,"ngStyle"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,q)),a["\u0275did"](3,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null)],function(t,e){var n=e.component;t(e,1,0,n._styleByGroup[e.context.$implicit.type]),t(e,3,0,e.context.$implicit.columns,n.columnTrackingFn)},function(t,e){t(e,0,0,"datatable-row-"+e.context.$implicit.type)})}function F(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,4,"div",[["class","datatable-header-inner"],["orderable",""]],[[4,"width","px"]],[[null,"reorder"],[null,"targetChanged"]],function(t,e,n){var a=!0,r=t.component;return"reorder"===e&&(a=!1!==r.onColumnReordered(n)&&a),"targetChanged"===e&&(a=!1!==r.onTargetChanged(n)&&a),a},null,null)),a["\u0275did"](1,1196032,null,1,E.OrderableDirective,[a.KeyValueDiffers,L.DOCUMENT],null,{reorder:"reorder",targetChanged:"targetChanged"}),a["\u0275qud"](603979776,1,{draggables:1}),(t()(),a["\u0275and"](16777216,null,null,1,null,j)),a["\u0275did"](4,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null)],function(t,e){var n=e.component;t(e,4,0,n._columnsByPin,n.trackByGroups)},function(t,e){t(e,0,0,e.component._columnGroupWidths.total)})}var z=n("Ahxa"),G=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function Y(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function V(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,2,null,Y)),a["\u0275did"](1,540672,null,0,s.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),a["\u0275pod"](2,{rowCount:0,pageSize:1,selectedCount:2,curPage:3,offset:4}),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component,a=t(e,2,0,n.rowCount,n.pageSize,n.selectedCount,n.curPage,n.offset);t(e,1,0,a,n.footerTemplate.template)},null)}function H(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,[" "," "," / "]))],null,function(t,e){var n=e.component;t(e,1,0,null==n.selectedCount?null:n.selectedCount.toLocaleString(),n.selectedMessage)})}function B(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","page-count"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,H)),a["\u0275did"](2,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275ted"](3,null,[" "," "," "]))],function(t,e){t(e,2,0,e.component.selectedMessage)},function(t,e){var n=e.component;t(e,3,0,null==n.rowCount?null:n.rowCount.toLocaleString(),n.totalMessage)})}function U(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-pager",[["class","datatable-pager"]],[[8,"hidden",0]],[[null,"change"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==t.component.page.emit(n)&&a),a},p,d)),a["\u0275did"](1,49152,null,0,l.DataTablePagerComponent,[],{pagerLeftArrowIcon:[0,"pagerLeftArrowIcon"],pagerRightArrowIcon:[1,"pagerRightArrowIcon"],pagerPreviousIcon:[2,"pagerPreviousIcon"],pagerNextIcon:[3,"pagerNextIcon"],size:[4,"size"],count:[5,"count"],page:[6,"page"]},{change:"change"})],function(t,e){var n=e.component;t(e,1,0,n.pagerLeftArrowIcon,n.pagerRightArrowIcon,n.pagerPreviousIcon,n.pagerNextIcon,n.pageSize,n.rowCount,n.curPage)},function(t,e){t(e,0,0,!e.component.isVisible)})}function W(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,8,"div",[["class","datatable-footer-inner"]],[[4,"height","px"]],null,null,null,null)),a["\u0275did"](1,278528,null,0,s.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a["\u0275pod"](2,{"selected-count":0}),(t()(),a["\u0275and"](16777216,null,null,1,null,V)),a["\u0275did"](4,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,B)),a["\u0275did"](6,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,U)),a["\u0275did"](8,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.selectedMessage);t(e,1,0,"datatable-footer-inner",a),t(e,4,0,n.footerTemplate),t(e,6,0,!n.footerTemplate),t(e,8,0,!n.footerTemplate)},function(t,e){t(e,0,0,e.component.footerHeight)})}var K=n("uKs4"),$=n("PNOi"),Z=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function X(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["class","progress-linear"],["role","progressbar"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"div",[["class","container"]],null,null,null,null,null)),(t()(),a["\u0275eld"](2,0,null,null,0,"div",[["class","bar"]],null,null,null,null,null))],null,null)}var J=n("YVFZ"),Q=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function tt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"label",[["class","datatable-checkbox"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,0,"input",[["type","checkbox"]],[[8,"checked",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.onCheckboxChange(n)&&a),a},null,null))],null,function(t,e){t(e,1,0,e.component.isSelected)})}function et(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"i",[["class","icon datatable-icon-collapse"]],null,null,null,null,null))],null,null)}function nt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"i",[["class","icon datatable-icon-up"]],null,null,null,null,null))],null,null)}function at(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"i",[["class","icon datatable-icon-down"]],null,null,null,null,null))],null,null)}function rt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,7,"button",[["class","datatable-tree-button"]],[[8,"disabled",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.onTreeAction()&&a),a},null,null)),(t()(),a["\u0275eld"](1,0,null,null,6,"span",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,et)),a["\u0275did"](3,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,nt)),a["\u0275did"](5,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,at)),a["\u0275did"](7,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,"loading"===n.treeStatus),t(e,5,0,"collapsed"===n.treeStatus),t(e,7,0,"expanded"===n.treeStatus||"disabled"===n.treeStatus)},function(t,e){t(e,0,0,"disabled"===e.component.treeStatus)})}function it(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function st(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,2,null,it)),a["\u0275did"](1,540672,null,0,s.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),a["\u0275pod"](2,{cellContext:0}),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component,a=t(e,2,0,n.cellContext);t(e,1,0,a,n.column.treeToggleTemplate)},null)}function ot(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,null,null,null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,rt)),a["\u0275did"](2,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,st)),a["\u0275did"](4,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,2,0,!n.column.treeToggleTemplate),t(e,4,0,n.column.treeToggleTemplate)},null)}function ut(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"span",[],[[8,"title",0],[8,"innerHTML",1]],null,null,null,null))],null,function(t,e){var n=e.component;t(e,0,0,n.sanitizedValue,n.value)})}function ct(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function lt(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,[[1,3],["cellTemplate",2]],null,1,null,ct)),a["\u0275did"](1,540672,null,0,s.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,1,0,n.cellContext,n.column.cellTemplate)},null)}function dt(t){return a["\u0275vid"](2,[a["\u0275qud"](671088640,1,{cellTemplate:0}),(t()(),a["\u0275eld"](1,0,null,null,8,"div",[["class","datatable-body-cell-label"]],[[4,"margin-left","px"]],null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,tt)),a["\u0275did"](3,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,ot)),a["\u0275did"](5,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,ut)),a["\u0275did"](7,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,lt)),a["\u0275did"](9,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,n.column.checkboxable&&(!n.displayCheck||n.displayCheck(n.row,n.column,n.value))),t(e,5,0,n.column.isTreeColumn),t(e,7,0,!n.column.cellTemplate),t(e,9,0,n.column.cellTemplate)},function(t,e){var n=e.component;t(e,1,0,n.calcLeftMargin(n.column,n.row))})}var ft=n("syrc"),pt=n("FO+L"),ht=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function gt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-body-cell",[["tabindex","-1"]],[[8,"className",0],[4,"width","px"],[4,"minWidth","px"],[4,"maxWidth","px"],[4,"height",null]],[[null,"activate"],[null,"treeAction"],[null,"focus"],[null,"blur"],[null,"click"],[null,"dblclick"],[null,"keydown"]],function(t,e,n){var r=!0,i=t.component;return"focus"===e&&(r=!1!==a["\u0275nov"](t,1).onFocus()&&r),"blur"===e&&(r=!1!==a["\u0275nov"](t,1).onBlur()&&r),"click"===e&&(r=!1!==a["\u0275nov"](t,1).onClick(n)&&r),"dblclick"===e&&(r=!1!==a["\u0275nov"](t,1).onDblClick(n)&&r),"keydown"===e&&(r=!1!==a["\u0275nov"](t,1).onKeyDown(n)&&r),"activate"===e&&(r=!1!==i.onActivate(n,t.context.index)&&r),"treeAction"===e&&(r=!1!==i.onTreeAction()&&r),r},dt,Q)),a["\u0275did"](1,442368,null,0,J.DataTableBodyCellComponent,[a.ElementRef,a.ChangeDetectorRef],{displayCheck:[0,"displayCheck"],group:[1,"group"],rowHeight:[2,"rowHeight"],isSelected:[3,"isSelected"],expanded:[4,"expanded"],rowIndex:[5,"rowIndex"],column:[6,"column"],row:[7,"row"],treeStatus:[8,"treeStatus"]},{activate:"activate",treeAction:"treeAction"})],function(t,e){var n=e.component;t(e,1,0,n.displayCheck,n.group,n.rowHeight,n.isSelected,n.expanded,n.rowIndex,e.context.$implicit,n.row,n.treeStatus)},function(t,e){t(e,0,0,a["\u0275nov"](e,1).columnCssClasses,a["\u0275nov"](e,1).width,a["\u0275nov"](e,1).minWidth,a["\u0275nov"](e,1).maxWidth,a["\u0275nov"](e,1).height)})}function bt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[],[[8,"className",0]],null,null,null,null)),a["\u0275did"](1,278528,null,0,s.NgStyle,[a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngStyle:[0,"ngStyle"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,gt)),a["\u0275did"](3,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null)],function(t,e){var n=e.component;t(e,1,0,n._groupStyles[e.context.$implicit.type]),t(e,3,0,e.context.$implicit.columns,n.columnTrackingFn)},function(t,e){t(e,0,0,a["\u0275inlineInterpolate"](1,"datatable-row-",e.context.$implicit.type," datatable-row-group"))})}function mt(t){return a["\u0275vid"](2,[(t()(),a["\u0275and"](16777216,null,null,1,null,bt)),a["\u0275did"](1,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null)],function(t,e){var n=e.component;t(e,1,0,n._columnsByPin,n.trackByGroups)},null)}var yt=n("rLYq"),vt=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function _t(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-body-row",[["tabindex","-1"]],[[8,"className",0],[4,"height","px"],[4,"width","px"]],[[null,"keydown"],[null,"mouseenter"]],function(t,e,n){var r=!0;return"keydown"===e&&(r=!1!==a["\u0275nov"](t,1).onKeyDown(n)&&r),"mouseenter"===e&&(r=!1!==a["\u0275nov"](t,1).onMouseenter(n)&&r),r},mt,ht)),a["\u0275did"](1,311296,null,0,ft.DataTableBodyRowComponent,[a.KeyValueDiffers,[1,pt.ScrollbarHelper],a.ChangeDetectorRef,a.ElementRef],{columns:[0,"columns"],innerWidth:[1,"innerWidth"],row:[2,"row"],rowIndex:[3,"rowIndex"],offsetX:[4,"offsetX"],rowHeight:[5,"rowHeight"]},null)],function(t,e){var n=e.component;t(e,1,0,n._internalColumns,n.innerWidth,n.summaryRow,-1,n.offsetX,n.rowHeight)},function(t,e){t(e,0,0,a["\u0275nov"](e,1).cssClass,a["\u0275nov"](e,1).rowHeight,a["\u0275nov"](e,1).columnsTotalWidths)})}function xt(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,_t)),a["\u0275did"](1,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.summaryRow&&n._internalColumns)},null)}var Tt=n("Mfce"),wt=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function St(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function Ot(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,St)),a["\u0275did"](1,540672,null,0,s.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,1,0,n.groupContext,n.groupHeader.template)},null)}function It(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","datatable-group-header"]],null,null,null,null,null)),a["\u0275did"](1,278528,null,0,s.NgStyle,[a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngStyle:[0,"ngStyle"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,Ot)),a["\u0275did"](3,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.getGroupHeaderStyle()),t(e,3,0,n.groupHeader&&n.groupHeader.template)},null)}function Ct(t){return a["\u0275vid"](0,[a["\u0275ncd"](null,0),(t()(),a["\u0275and"](0,null,null,0))],null,null)}function kt(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function Nt(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,kt)),a["\u0275did"](1,540672,null,0,s.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,1,0,n.rowContext,n.rowDetail.template)},null)}function Rt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["class","datatable-row-detail"]],[[4,"height","px"]],null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,Nt)),a["\u0275did"](2,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,n.rowDetail&&n.rowDetail.template)},function(t,e){t(e,0,0,e.component.detailRowHeight)})}function At(t){return a["\u0275vid"](2,[(t()(),a["\u0275and"](16777216,null,null,1,null,It)),a["\u0275did"](1,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,Ct)),a["\u0275did"](3,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,Rt)),a["\u0275did"](5,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.groupHeader&&n.groupHeader.template),t(e,3,0,n.groupHeader&&n.groupHeader.template&&n.expanded||!n.groupHeader||!n.groupHeader.template),t(e,5,0,n.rowDetail&&n.rowDetail.template&&n.expanded)},null)}var Dt=n("SfHT"),Et=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function Lt(t){return a["\u0275vid"](2,[a["\u0275ncd"](null,0)],null,null)}var Pt=n("7F1K"),Mt=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function qt(t){return a["\u0275vid"](2,[a["\u0275ncd"](null,0)],null,null)}var jt=n("IPm6"),Ft=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function zt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-progress",[],null,null,null,X,Z)),a["\u0275did"](1,49152,null,0,$.ProgressBarComponent,[],null,null)],null,null)}function Gt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-summary-row",[["class","datatable-summary-row"]],null,null,null,xt,vt)),a["\u0275did"](1,573440,null,0,yt.DataTableSummaryRowComponent,[],{rows:[0,"rows"],columns:[1,"columns"],rowHeight:[2,"rowHeight"],offsetX:[3,"offsetX"],innerWidth:[4,"innerWidth"]},null)],function(t,e){var n=e.component;t(e,1,0,n.rows,n.columns,n.summaryHeight,n.offsetX,n.innerWidth)},null)}function Yt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-body-row",[["tabindex","-1"]],[[8,"className",0],[4,"height","px"],[4,"width","px"]],[[null,"treeAction"],[null,"activate"],[null,"keydown"],[null,"mouseenter"]],function(t,e,n){var r=!0,i=t.component;return"keydown"===e&&(r=!1!==a["\u0275nov"](t,1).onKeyDown(n)&&r),"mouseenter"===e&&(r=!1!==a["\u0275nov"](t,1).onMouseenter(n)&&r),"treeAction"===e&&(r=!1!==i.onTreeAction(t.parent.context.$implicit)&&r),"activate"===e&&(r=!1!==a["\u0275nov"](t.parent.parent.parent,2).onActivate(n,i.indexes.first+t.parent.context.index)&&r),r},mt,ht)),a["\u0275did"](1,311296,null,0,ft.DataTableBodyRowComponent,[a.KeyValueDiffers,[1,pt.ScrollbarHelper],a.ChangeDetectorRef,a.ElementRef],{columns:[0,"columns"],innerWidth:[1,"innerWidth"],expanded:[2,"expanded"],rowClass:[3,"rowClass"],row:[4,"row"],isSelected:[5,"isSelected"],rowIndex:[6,"rowIndex"],displayCheck:[7,"displayCheck"],treeStatus:[8,"treeStatus"],offsetX:[9,"offsetX"],rowHeight:[10,"rowHeight"]},{activate:"activate",treeAction:"treeAction"})],function(t,e){var n=e.component;t(e,1,1,[n.columns,n.innerWidth,n.getRowExpanded(e.parent.context.$implicit),n.rowClass,e.parent.context.$implicit,a["\u0275nov"](e.parent.parent.parent,2).getRowSelected(e.parent.context.$implicit),n.getRowIndex(e.parent.context.$implicit),n.displayCheck,e.parent.context.$implicit.treeStatus,n.offsetX,n.getRowHeight(e.parent.context.$implicit)])},function(t,e){t(e,0,0,a["\u0275nov"](e,1).cssClass,a["\u0275nov"](e,1).rowHeight,a["\u0275nov"](e,1).columnsTotalWidths)})}function Vt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-body-row",[["tabindex","-1"]],[[8,"className",0],[4,"height","px"],[4,"width","px"]],[[null,"activate"],[null,"keydown"],[null,"mouseenter"]],function(t,e,n){var r=!0;return"keydown"===e&&(r=!1!==a["\u0275nov"](t,1).onKeyDown(n)&&r),"mouseenter"===e&&(r=!1!==a["\u0275nov"](t,1).onMouseenter(n)&&r),"activate"===e&&(r=!1!==a["\u0275nov"](t.parent.parent.parent.parent,2).onActivate(n,t.context.index)&&r),r},mt,ht)),a["\u0275did"](1,311296,null,0,ft.DataTableBodyRowComponent,[a.KeyValueDiffers,[1,pt.ScrollbarHelper],a.ChangeDetectorRef,a.ElementRef],{columns:[0,"columns"],innerWidth:[1,"innerWidth"],expanded:[2,"expanded"],rowClass:[3,"rowClass"],row:[4,"row"],group:[5,"group"],isSelected:[6,"isSelected"],rowIndex:[7,"rowIndex"],offsetX:[8,"offsetX"],rowHeight:[9,"rowHeight"]},{activate:"activate"})],function(t,e){var n=e.component;t(e,1,0,n.columns,n.innerWidth,n.getRowExpanded(e.context.$implicit),n.rowClass,e.context.$implicit,e.parent.parent.context.$implicit.value,a["\u0275nov"](e.parent.parent.parent.parent,2).getRowSelected(e.context.$implicit),n.getRowIndex(e.context.$implicit),n.offsetX,n.getRowHeight(e.context.$implicit))},function(t,e){t(e,0,0,a["\u0275nov"](e,1).cssClass,a["\u0275nov"](e,1).rowHeight,a["\u0275nov"](e,1).columnsTotalWidths)})}function Ht(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,Vt)),a["\u0275did"](1,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.parent.context.$implicit.value,e.component.rowTrackingFn)},null)}function Bt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,5,"datatable-row-wrapper",[["class","datatable-row-wrapper"]],null,[[null,"rowContextmenu"],[null,"contextmenu"]],function(t,e,n){var r=!0,i=t.component;return"contextmenu"===e&&(r=!1!==a["\u0275nov"](t,2).onContextmenu(n)&&r),"rowContextmenu"===e&&(r=!1!==i.rowContextmenu.emit(n)&&r),r},At,wt)),a["\u0275did"](1,278528,null,0,s.NgStyle,[a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngStyle:[0,"ngStyle"]},null),a["\u0275did"](2,311296,null,0,Tt.DataTableRowWrapperComponent,[a.ChangeDetectorRef,a.KeyValueDiffers],{innerWidth:[0,"innerWidth"],rowDetail:[1,"rowDetail"],groupHeader:[2,"groupHeader"],offsetX:[3,"offsetX"],detailRowHeight:[4,"detailRowHeight"],row:[5,"row"],groupedRows:[6,"groupedRows"],rowIndex:[7,"rowIndex"],expanded:[8,"expanded"]},{rowContextmenu:"rowContextmenu"}),(t()(),a["\u0275and"](16777216,null,0,1,null,Yt)),a["\u0275did"](4,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(t()(),a["\u0275and"](0,[["groupedRowsTemplate",2]],0,0,null,Ht))],function(t,e){var n=e.component;t(e,1,0,n.getRowsStyles(e.context.$implicit)),t(e,2,0,n.innerWidth,n.rowDetail,n.groupHeader,n.offsetX,n.getDetailRowHeight(e.context.$implicit[e.context.index],e.context.index),e.context.$implicit,n.groupedRows,n.getRowIndex(e.context.$implicit[e.context.index]),n.getRowExpanded(e.context.$implicit)),t(e,4,0,!n.groupedRows,a["\u0275nov"](e,5))},null)}function Ut(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"datatable-summary-row",[["class","datatable-summary-row"]],null,null,null,xt,vt)),a["\u0275did"](1,278528,null,0,s.NgStyle,[a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngStyle:[0,"ngStyle"]},null),a["\u0275did"](2,573440,null,0,yt.DataTableSummaryRowComponent,[],{rows:[0,"rows"],columns:[1,"columns"],rowHeight:[2,"rowHeight"],offsetX:[3,"offsetX"],innerWidth:[4,"innerWidth"]},null)],function(t,e){var n=e.component;t(e,1,0,n.getBottomSummaryRowStyles()),t(e,2,0,n.rows,n.columns,n.summaryHeight,n.offsetX,n.innerWidth)},null)}function Wt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,7,"datatable-scroller",[["class","datatable-scroll"]],[[4,"height","px"],[4,"width","px"]],[[null,"scroll"]],function(t,e,n){var a=!0;return"scroll"===e&&(a=!1!==t.component.onBodyScroll(n)&&a),a},Lt,Et)),a["\u0275did"](1,245760,[[1,4]],0,Dt.ScrollerComponent,[a.NgZone,a.ElementRef,a.Renderer2],{scrollbarV:[0,"scrollbarV"],scrollbarH:[1,"scrollbarH"],scrollHeight:[2,"scrollHeight"],scrollWidth:[3,"scrollWidth"]},{scroll:"scroll"}),(t()(),a["\u0275and"](16777216,null,0,1,null,Gt)),a["\u0275did"](3,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,0,1,null,Bt)),a["\u0275did"](5,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(t()(),a["\u0275and"](16777216,null,0,1,null,Ut)),a["\u0275did"](7,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.scrollbarV,n.scrollbarH,n.scrollHeight,null==n.columnGroupWidths?null:n.columnGroupWidths.total),t(e,3,0,n.summaryRow&&"top"===n.summaryPosition),t(e,5,0,n.temp,n.rowTrackingFn),t(e,7,0,n.summaryRow&&"bottom"===n.summaryPosition)},function(t,e){t(e,0,0,a["\u0275nov"](e,1).scrollHeight,a["\u0275nov"](e,1).scrollWidth)})}function Kt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"div",[["class","empty-row"]],[[8,"innerHTML",1]],null,null,null,null))],null,function(t,e){t(e,0,0,e.component.emptyMessage)})}function $t(t){return a["\u0275vid"](2,[a["\u0275qud"](671088640,1,{scroller:0}),(t()(),a["\u0275eld"](1,0,null,null,7,"datatable-selection",[],null,[[null,"select"],[null,"activate"]],function(t,e,n){var a=!0,r=t.component;return"select"===e&&(a=!1!==r.select.emit(n)&&a),"activate"===e&&(a=!1!==r.activate.emit(n)&&a),a},qt,Mt)),a["\u0275did"](2,49152,[["selector",4]],0,Pt.DataTableSelectionComponent,[],{rows:[0,"rows"],selected:[1,"selected"],selectEnabled:[2,"selectEnabled"],selectionType:[3,"selectionType"],rowIdentity:[4,"rowIdentity"],selectCheck:[5,"selectCheck"]},{activate:"activate",select:"select"}),(t()(),a["\u0275and"](16777216,null,0,1,null,zt)),a["\u0275did"](4,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,0,1,null,Wt)),a["\u0275did"](6,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,0,1,null,Kt)),a["\u0275did"](8,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,n.rows,n.selected,n.selectEnabled,n.selectionType,n.rowIdentity,n.selectCheck),t(e,4,0,n.loadingIndicator),t(e,6,0,null==n.rows?null:n.rows.length),t(e,8,0,!(null!=n.rows&&n.rows.length||n.loadingIndicator))},null)}var Zt=n("3/HP"),Xt=n("nhM1"),Jt=n("BARL"),Qt=a["\u0275crt"]({encapsulation:2,styles:[[".ngx-datatable{display:block;overflow:hidden;-webkit-box-pack:center;justify-content:center;position:relative;-webkit-transform:translate3d(0,0,0)}.ngx-datatable [hidden]{display:none!important}.ngx-datatable *,.ngx-datatable :after,.ngx-datatable :before{box-sizing:border-box}.ngx-datatable.scroll-vertical .datatable-body{overflow-y:auto}.ngx-datatable.scroll-vertical.virtualized .datatable-body .datatable-row-wrapper{position:absolute}.ngx-datatable.scroll-horz .datatable-body{overflow-x:auto;-webkit-overflow-scrolling:touch}.ngx-datatable.fixed-header .datatable-header .datatable-header-inner{white-space:nowrap}.ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ngx-datatable.fixed-row .datatable-scroll,.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row{white-space:nowrap}.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-cell,.ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-group-cell{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ngx-datatable .datatable-body-row,.ngx-datatable .datatable-header-inner,.ngx-datatable .datatable-row-center{display:-webkit-box;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row;-o-flex-flow:row;flex-flow:row}.ngx-datatable .datatable-body-cell,.ngx-datatable .datatable-header-cell{overflow-x:hidden;vertical-align:top;display:inline-block;line-height:1.625}.ngx-datatable .datatable-body-cell:focus,.ngx-datatable .datatable-header-cell:focus{outline:0}.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{z-index:9}.ngx-datatable .datatable-row-center,.ngx-datatable .datatable-row-group,.ngx-datatable .datatable-row-left,.ngx-datatable .datatable-row-right{position:relative}.ngx-datatable .datatable-header{display:block;overflow:hidden}.ngx-datatable .datatable-header .datatable-header-inner{-webkit-box-align:stretch;align-items:stretch;-webkit-align-items:stretch}.ngx-datatable .datatable-header .datatable-header-cell{position:relative;display:inline-block}.ngx-datatable .datatable-header .datatable-header-cell.sortable .datatable-header-cell-wrapper{cursor:pointer}.ngx-datatable .datatable-header .datatable-header-cell.longpress .datatable-header-cell-wrapper{cursor:move}.ngx-datatable .datatable-header .datatable-header-cell .sort-btn{line-height:100%;vertical-align:middle;display:inline-block;cursor:pointer}.ngx-datatable .datatable-header .datatable-header-cell .resize-handle,.ngx-datatable .datatable-header .datatable-header-cell .resize-handle--not-resizable{display:inline-block;position:absolute;right:0;top:0;bottom:0;width:5px;padding:0 4px;visibility:hidden}.ngx-datatable .datatable-header .datatable-header-cell .resize-handle{cursor:ew-resize}.ngx-datatable .datatable-header .datatable-header-cell.resizeable:hover .resize-handle,.ngx-datatable .datatable-header .datatable-header-cell:hover .resize-handle--not-resizable{visibility:visible}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker{position:absolute;top:0;bottom:0}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromLeft{right:0}.ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromRight{left:0}.ngx-datatable .datatable-header .datatable-header-cell .datatable-header-cell-template-wrap{height:inherit}.ngx-datatable .datatable-body{position:relative;z-index:10;display:block}.ngx-datatable .datatable-body .datatable-scroll{display:inline-block}.ngx-datatable .datatable-body .datatable-row-detail{overflow-y:hidden}.ngx-datatable .datatable-body .datatable-row-wrapper{display:-webkit-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column}.ngx-datatable .datatable-body .datatable-body-row{outline:0}.ngx-datatable .datatable-body .datatable-body-row>div{display:-webkit-box;display:flex}.ngx-datatable .datatable-footer{display:block;width:100%}.ngx-datatable .datatable-footer .datatable-footer-inner{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;width:100%}.ngx-datatable .datatable-footer .selected-count .page-count{-webkit-box-flex:1;flex:1 1 40%}.ngx-datatable .datatable-footer .selected-count .datatable-pager{-webkit-box-flex:1;flex:1 1 60%}.ngx-datatable .datatable-footer .page-count{-webkit-box-flex:1;flex:1 1 20%}.ngx-datatable .datatable-footer .datatable-pager{-webkit-box-flex:1;flex:1 1 80%;text-align:right}.ngx-datatable .datatable-footer .datatable-pager .pager,.ngx-datatable .datatable-footer .datatable-pager .pager li{padding:0;margin:0;display:inline-block;list-style:none}.ngx-datatable .datatable-footer .datatable-pager .pager li,.ngx-datatable .datatable-footer .datatable-pager .pager li a{outline:0}.ngx-datatable .datatable-footer .datatable-pager .pager li a{cursor:pointer;display:inline-block}.ngx-datatable .datatable-footer .datatable-pager .pager li.disabled a{cursor:not-allowed}"]],data:{}});function te(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"datatable-header",[["class","datatable-header"]],[[4,"height",null],[4,"width",null]],[[null,"sort"],[null,"resize"],[null,"reorder"],[null,"select"],[null,"columnContextmenu"]],function(t,e,n){var a=!0,r=t.component;return"sort"===e&&(a=!1!==r.onColumnSort(n)&&a),"resize"===e&&(a=!1!==r.onColumnResize(n)&&a),"reorder"===e&&(a=!1!==r.onColumnReorder(n)&&a),"select"===e&&(a=!1!==r.onHeaderSelect(n)&&a),"columnContextmenu"===e&&(a=!1!==r.onColumnContextmenu(n)&&a),a},F,M)),a["\u0275did"](1,49152,[[2,4]],0,P.DataTableHeaderComponent,[a.ChangeDetectorRef],{sortAscendingIcon:[0,"sortAscendingIcon"],sortDescendingIcon:[1,"sortDescendingIcon"],scrollbarH:[2,"scrollbarH"],dealsWithGroup:[3,"dealsWithGroup"],targetMarkerTemplate:[4,"targetMarkerTemplate"],innerWidth:[5,"innerWidth"],sorts:[6,"sorts"],sortType:[7,"sortType"],allRowsSelected:[8,"allRowsSelected"],selectionType:[9,"selectionType"],reorderable:[10,"reorderable"],headerHeight:[11,"headerHeight"],columns:[12,"columns"],offsetX:[13,"offsetX"]},{sort:"sort",reorder:"reorder",resize:"resize",select:"select",columnContextmenu:"columnContextmenu"}),a["\u0275pid"](131072,s.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,1,1,[n.cssClasses.sortAscending,n.cssClasses.sortDescending,n.scrollbarH,n.groupedRows,n.targetMarkerTemplate,n._innerWidth,n.sorts,n.sortType,n.allRowsSelected,n.selectionType,n.reorderable,n.headerHeight,n._internalColumns,a["\u0275unv"](e,1,13,a["\u0275nov"](e,2).transform(n._offsetX))])},function(t,e){t(e,0,0,a["\u0275nov"](e,1).headerHeight,a["\u0275nov"](e,1).headerWidth)})}function ee(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"datatable-footer",[["class","datatable-footer"]],null,[[null,"page"]],function(t,e,n){var a=!0;return"page"===e&&(a=!1!==t.component.onFooterPage(n)&&a),a},W,G)),a["\u0275did"](1,49152,null,0,z.DataTableFooterComponent,[],{footerHeight:[0,"footerHeight"],rowCount:[1,"rowCount"],pageSize:[2,"pageSize"],offset:[3,"offset"],pagerLeftArrowIcon:[4,"pagerLeftArrowIcon"],pagerRightArrowIcon:[5,"pagerRightArrowIcon"],pagerPreviousIcon:[6,"pagerPreviousIcon"],pagerNextIcon:[7,"pagerNextIcon"],totalMessage:[8,"totalMessage"],footerTemplate:[9,"footerTemplate"],selectedCount:[10,"selectedCount"],selectedMessage:[11,"selectedMessage"]},{page:"page"})],function(t,e){var n=e.component;t(e,1,1,[n.footerHeight,n.rowCount,n.pageSize,n.offset,n.cssClasses.pagerLeftArrow,n.cssClasses.pagerRightArrow,n.cssClasses.pagerPrevious,n.cssClasses.pagerNext,n.messages.totalMessage,n.footer,n.selected.length,!!n.selectionType&&n.messages.selectedMessage])},null)}function ne(t){return a["\u0275vid"](2,[a["\u0275qud"](402653184,1,{bodyComponent:0}),a["\u0275qud"](671088640,2,{headerComponent:0}),(t()(),a["\u0275eld"](2,0,null,null,8,"div",[["visibilityObserver",""]],[[2,"visible",null]],[[null,"visible"]],function(t,e,n){var a=!0;return"visible"===e&&(a=!1!==t.component.recalculate()&&a),a},null,null)),a["\u0275did"](3,212992,null,0,K.VisibilityDirective,[a.ElementRef,a.NgZone],null,{visible:"visible"}),(t()(),a["\u0275and"](16777216,null,null,1,null,te)),a["\u0275did"](5,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](6,0,null,null,2,"datatable-body",[["class","datatable-body"]],[[4,"width",null],[4,"height",null]],[[null,"page"],[null,"activate"],[null,"rowContextmenu"],[null,"select"],[null,"scroll"],[null,"treeAction"]],function(t,e,n){var a=!0,r=t.component;return"page"===e&&(a=!1!==r.onBodyPage(n)&&a),"activate"===e&&(a=!1!==r.activate.emit(n)&&a),"rowContextmenu"===e&&(a=!1!==r.onRowContextmenu(n)&&a),"select"===e&&(a=!1!==r.onBodySelect(n)&&a),"scroll"===e&&(a=!1!==r.onBodyScroll(n)&&a),"treeAction"===e&&(a=!1!==r.onTreeAction(n)&&a),a},$t,Ft)),a["\u0275did"](7,245760,[[1,4]],0,jt.DataTableBodyComponent,[a.ChangeDetectorRef],{scrollbarV:[0,"scrollbarV"],scrollbarH:[1,"scrollbarH"],loadingIndicator:[2,"loadingIndicator"],externalPaging:[3,"externalPaging"],rowHeight:[4,"rowHeight"],offsetX:[5,"offsetX"],emptyMessage:[6,"emptyMessage"],selectionType:[7,"selectionType"],selected:[8,"selected"],rowIdentity:[9,"rowIdentity"],rowDetail:[10,"rowDetail"],groupHeader:[11,"groupHeader"],selectCheck:[12,"selectCheck"],displayCheck:[13,"displayCheck"],trackByProp:[14,"trackByProp"],rowClass:[15,"rowClass"],groupedRows:[16,"groupedRows"],groupExpansionDefault:[17,"groupExpansionDefault"],innerWidth:[18,"innerWidth"],groupRowsBy:[19,"groupRowsBy"],virtualization:[20,"virtualization"],summaryRow:[21,"summaryRow"],summaryPosition:[22,"summaryPosition"],summaryHeight:[23,"summaryHeight"],pageSize:[24,"pageSize"],rows:[25,"rows"],columns:[26,"columns"],offset:[27,"offset"],rowCount:[28,"rowCount"],bodyHeight:[29,"bodyHeight"]},{scroll:"scroll",page:"page",activate:"activate",select:"select",rowContextmenu:"rowContextmenu",treeAction:"treeAction"}),a["\u0275pid"](131072,s.AsyncPipe,[a.ChangeDetectorRef]),(t()(),a["\u0275and"](16777216,null,null,1,null,ee)),a["\u0275did"](10,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0),t(e,5,0,n.headerHeight),t(e,7,1,[n.scrollbarV,n.scrollbarH,n.loadingIndicator,n.externalPaging,n.rowHeight,a["\u0275unv"](e,7,5,a["\u0275nov"](e,8).transform(n._offsetX)),n.messages.emptyMessage,n.selectionType,n.selected,n.rowIdentity,n.rowDetail,n.groupHeader,n.selectCheck,n.displayCheck,n.trackByProp,n.rowClass,n.groupedRows,n.groupExpansionDefault,n._innerWidth,n.groupRowsBy,n.virtualization,n.summaryRow,n.summaryPosition,n.summaryHeight,n.pageSize,n._internalRows,n._internalColumns,n.offset,n.rowCount,n.bodyHeight]),t(e,10,0,n.footerHeight)},function(t,e){t(e,2,0,a["\u0275nov"](e,3).isVisible),t(e,6,0,a["\u0275nov"](e,7).bodyWidth,a["\u0275nov"](e,7).bodyHeight)})}var ae=n("lUjN"),re=n("vxfy");n("uIqm"),n.d(e,"a",function(){return ie}),n.d(e,"b",function(){return Oe});var ie=a["\u0275crt"]({encapsulation:0,styles:[[".dataTables_wrapper[_ngcontent-%COMP%]{margin-bottom:25px}.dataTables_wrapper[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%]{height:30px;border-left:1px solid rgba(0,0,0,.09);padding-left:5px;margin-left:5px;display:inline-block;vertical-align:middle}.dataTables_wrapper[_ngcontent-%COMP%] .widget-toolbar[_ngcontent-%COMP%]{display:inline-block;float:right;width:auto;height:30px;line-height:28px;position:relative;border-left:1px solid rgba(0,0,0,.09);cursor:pointer;padding:0 8px;text-align:center}.dataTables_wrapper[_ngcontent-%COMP%] .dropdown-menu[_ngcontent-%COMP%]{white-space:nowrap}.dataTables_wrapper[_ngcontent-%COMP%] .dropdown-menu[_ngcontent-%COMP%] > li[_ngcontent-%COMP%]{cursor:pointer}.dataTables_wrapper[_ngcontent-%COMP%] .dropdown-menu[_ngcontent-%COMP%] > li[_ngcontent-%COMP%] > label[_ngcontent-%COMP%]{width:100%;margin-bottom:0;padding-left:20px;padding-right:20px;cursor:pointer}.dataTables_wrapper[_ngcontent-%COMP%] .dropdown-menu[_ngcontent-%COMP%] > li[_ngcontent-%COMP%] > label[_ngcontent-%COMP%]:hover{background-color:#f5f5f5}.dataTables_wrapper[_ngcontent-%COMP%] .dropdown-menu[_ngcontent-%COMP%] > li[_ngcontent-%COMP%] > label[_ngcontent-%COMP%] > input[_ngcontent-%COMP%]{cursor:pointer}.dataTables_wrapper[_ngcontent-%COMP%] th.oadatatablecheckbox[_ngcontent-%COMP%]{width:16px}.dataTables_wrapper[_ngcontent-%COMP%] .dataTables_length[_ngcontent-%COMP%] > input[_ngcontent-%COMP%]{line-height:25px;text-align:right}.dataTables_header[_ngcontent-%COMP%]{background-color:#f5f5f5;border:1px solid #d1d1d1;border-bottom:none;padding:5px;position:relative}.dataTables_header[_ngcontent-%COMP%] .oadatatableactions[_ngcontent-%COMP%]{float:left}.dataTables_header[_ngcontent-%COMP%] .table-filters{float:right;border-left:1px solid rgba(0,0,0,.09);padding-left:8px}.dataTables_header[_ngcontent-%COMP%] .table-filters label{margin-right:4px}.dataTables_header[_ngcontent-%COMP%] .form-group[_ngcontent-%COMP%]{padding-left:8px}.dataTables_header[_ngcontent-%COMP%] .input-group[_ngcontent-%COMP%]{float:right;border-left:1px solid rgba(0,0,0,.09);padding-left:8px;padding-right:8px;width:40%;max-width:250px}.dataTables_header[_ngcontent-%COMP%] .input-group[_ngcontent-%COMP%] .clear-input[_ngcontent-%COMP%], .dataTables_header[_ngcontent-%COMP%] .input-group[_ngcontent-%COMP%] .form-control[_ngcontent-%COMP%]{height:30px}.dataTables_header[_ngcontent-%COMP%] .input-group[_ngcontent-%COMP%] .clear-input[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{vertical-align:text-top}.dataTables_header[_ngcontent-%COMP%] .input-group.dataTables_paginate[_ngcontent-%COMP%]{width:8%;min-width:85px;padding-right:8px} .oadatatable{border:1px solid #d1d1d1;margin-bottom:0;max-width:none!important} .oadatatable .progress-linear{display:block;position:relative;width:100%;height:5px;padding:0;margin:0} .oadatatable .progress-linear .container{background-color:#afd9ee} .oadatatable .progress-linear .container .bar{left:0;height:100%;width:100%;position:absolute;overflow:hidden;background-color:#afd9ee} .oadatatable .progress-linear .container .bar:before{display:block;position:absolute;content:'';left:-200px;width:200px;height:100%;background-color:#2b99a8;-webkit-animation:3s linear infinite progress-loading;animation:3s linear infinite progress-loading} .oadatatable .datatable-header{background-clip:padding-box;background-color:#f5f5f5;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f5f5f5),to(#ededed));background-image:linear-gradient(to bottom,#f5f5f5 0,#ededed 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa', endColorstr='#ffededed', GradientType=0)} .oadatatable .datatable-header .sort-asc, .oadatatable .datatable-header .sort-desc{color:#2b99a8} .oadatatable .datatable-header .datatable-header-cell{padding:5px;border:none;border-left:1px solid #d1d1d1;border-bottom:1px solid #d1d1d1;text-align:left;font-weight:700} .oadatatable .datatable-header .datatable-header-cell .datatable-header-cell-label:after{font-family:ForkAwesome;font-weight:400;height:9px;left:10px;line-height:12px;position:relative;vertical-align:baseline;width:12px} .oadatatable .datatable-header .datatable-header-cell.sortable .datatable-header-cell-label:after{content:' \\f0dc'} .oadatatable .datatable-header .datatable-header-cell.sortable.sort-active.sort-asc .datatable-header-cell-label:after{content:' \\f160'} .oadatatable .datatable-header .datatable-header-cell.sortable.sort-active.sort-desc .datatable-header-cell-label:after{content:' \\f161'} .oadatatable .datatable-header .datatable-header-cell:first-child{border-left:none} .oadatatable .datatable-body .empty-row{background-color:#fff3cd;text-align:center;font-weight:700;font-style:italic;padding-top:5px;padding-bottom:5px} .oadatatable .datatable-body .datatable-body-row .label{font-size:.9em} .oadatatable .datatable-body .datatable-body-row.clickable:hover .datatable-row-group{background-color:#eee;-webkit-transition-property:background;transition-property:background;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transition-timing-function:linear;transition-timing-function:linear} .oadatatable .datatable-body .datatable-body-row.datatable-row-even{background-color:#fff} .oadatatable .datatable-body .datatable-body-row.datatable-row-odd{background-color:#f5f5f5} .oadatatable .datatable-body .datatable-body-row.active, .oadatatable .datatable-body .datatable-body-row.active:hover{background-color:#d9edf7} .oadatatable .datatable-body .datatable-body-row .datatable-body-cell{padding:5px;border:none;border-left:1px solid #d1d1d1;border-bottom:1px solid #d1d1d1} .oadatatable .datatable-body .datatable-body-row .datatable-body-cell:first-child{border-left:none} .oadatatable .datatable-body .datatable-body-row .datatable-body-cell .datatable-body-cell-label{display:block} .oadatatable .datatable-footer .page-count, .oadatatable .datatable-footer .selected-count{font-style:italic;padding-left:5px} .oadatatable .datatable-footer .datatable-pager .pager{margin-right:5px!important} .oadatatable .datatable-footer .datatable-pager .pager li:not(:first-child){margin-left:3px} .oadatatable .datatable-footer .datatable-pager .pager li>a, .oadatatable .datatable-footer .datatable-pager .pager li>span{border-radius:3px} .oadatatable .datatable-footer .datatable-pager .pager .pages>a, .oadatatable .datatable-footer .datatable-pager .pager .pages>span{display:inline-block;padding:5px 10px;margin-bottom:5px;border:none} .oadatatable .datatable-footer .datatable-pager .pager .pages a:hover{background-color:#afd9ee} .oadatatable .datatable-footer .datatable-pager .pager .pages.active>a{background-color:#d9edf7}@-webkit-keyframes progress-loading{from{left:-200px;width:15%}50%{width:30%}70%{width:70%}80%{left:50%}95%{left:120%}to{left:100%}}@keyframes progress-loading{from{left:-200px;width:15%}50%{width:30%}70%{width:70%}80%{left:50%}95%{left:120%}to{left:100%}}"]],data:{}});function se(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"cd-error-panel",[],null,null,null,r.b,r.a)),a["\u0275did"](1,49152,null,0,i.a,[],null,null),(t()(),a["\u0275ted"](-1,0,["Failed to load data."]))],null,null)}function oe(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"div",[["class","input-group dataTables_paginate"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,0,"input",[["class","form-control"],["max","9999"],["min","1"],["type","number"]],[[8,"value",0]],[[null,"click"],[null,"keyup"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.setLimit(n)&&a),"keyup"===e&&(a=!1!==r.setLimit(n)&&a),"blur"===e&&(a=!1!==r.setLimit(n)&&a),a},null,null))],null,function(t,e){t(e,1,0,e.component.userConfig.limit)})}function ue(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"li",[],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,3,"label",[],null,null,null,null,null)),(t()(),a["\u0275eld"](2,0,null,null,0,"input",[["type","checkbox"]],[[8,"name",0],[8,"checked",0]],[[null,"change"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==t.component.toggleColumn(n)&&a),a},null,null)),(t()(),a["\u0275eld"](3,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](4,null,["",""]))],null,function(t,e){t(e,2,0,e.context.$implicit.prop,!e.context.$implicit.isHidden),t(e,4,0,e.context.$implicit.name)})}function ce(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"ul",[["class","dropdown-menu"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,ue)),a["\u0275did"](2,278528,null,0,s.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.component.columns)},null)}function le(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["class","widget-toolbar tc_refreshBtn"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"a",[],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.refreshBtn()&&a),a},null,null)),(t()(),a["\u0275eld"](2,0,null,null,0,"i",[["class","fa fa-lg fa-refresh"]],[[2,"fa-spin",null]],null,null,null,null))],null,function(t,e){var n=e.component;t(e,2,0,n.updating||n.loadingIndicator)})}function de(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,28,"div",[["class","dataTables_header clearfix form-inline"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"div",[["class","oadatatableactions"]],null,null,null,null,null)),a["\u0275ncd"](null,0),a["\u0275ncd"](null,1),(t()(),a["\u0275eld"](4,0,null,null,11,"div",[["class","input-group"]],null,null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,1,"span",[["class","input-group-addon"]],null,null,null,null,null)),(t()(),a["\u0275eld"](6,0,null,null,0,"i",[["class","glyphicon glyphicon-search"]],null,null,null,null,null)),(t()(),a["\u0275eld"](7,0,null,null,5,"input",[["class","form-control"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"keyup"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var r=!0,i=t.component;return"input"===e&&(r=!1!==a["\u0275nov"](t,8)._handleInput(n.target.value)&&r),"blur"===e&&(r=!1!==a["\u0275nov"](t,8).onTouched()&&r),"compositionstart"===e&&(r=!1!==a["\u0275nov"](t,8)._compositionStart()&&r),"compositionend"===e&&(r=!1!==a["\u0275nov"](t,8)._compositionEnd(n.target.value)&&r),"ngModelChange"===e&&(r=!1!==(i.search=n)&&r),"keyup"===e&&(r=!1!==i.updateFilter()&&r),r},null,null)),a["\u0275did"](8,16384,null,0,o.e,[a.Renderer2,a.ElementRef,[2,o.b]],null,null),a["\u0275prd"](1024,null,o.p,function(t){return[t]},[o.e]),a["\u0275did"](10,671744,null,0,o.u,[[8,null],[8,null],[8,null],[6,o.p]],{model:[0,"model"]},{update:"ngModelChange"}),a["\u0275prd"](2048,null,o.q,null,[o.u]),a["\u0275did"](12,16384,null,0,o.r,[[4,o.q]],null,null),(t()(),a["\u0275eld"](13,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(t()(),a["\u0275eld"](14,0,null,null,1,"button",[["class","btn btn-default clear-input tc_clearInputBtn"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.updateFilter(!0)&&a),a},null,null)),(t()(),a["\u0275eld"](15,0,null,null,0,"i",[["class","icon-prepend fa fa-remove"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,oe)),a["\u0275did"](17,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](18,0,null,null,8,"div",[["class","widget-toolbar"]],null,null,null,null,null)),(t()(),a["\u0275eld"](19,16777216,null,null,7,"div",[["class","dropdown tc_menuitem tc_menuitem_cluster"],["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),a["\u0275prd"](512,null,u.f,u.f,[]),a["\u0275did"](21,212992,null,0,u.c,[a.ElementRef,a.Renderer2,a.ViewContainerRef,c.a,u.a,u.f],null,null),(t()(),a["\u0275eld"](22,0,null,null,2,"a",[["class","btn btn-sm btn-default dropdown-toggle tc_columnBtn"],["data-toggle","dropdown"],["dropdownToggle",""]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var r=!0;return"click"===e&&(r=!1!==a["\u0275nov"](t,23).onClick()&&r),r},null,null)),a["\u0275did"](23,147456,null,0,u.g,[a.ChangeDetectorRef,u.c,a.ElementRef,a.Renderer2,u.f],null,null),(t()(),a["\u0275eld"](24,0,null,null,0,"i",[["class","fa fa-lg fa-table"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,ce)),a["\u0275did"](26,16384,null,0,u.d,[u.f,a.ViewContainerRef,a.TemplateRef],null,null),(t()(),a["\u0275and"](16777216,null,null,1,null,le)),a["\u0275did"](28,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,10,0,n.search),t(e,17,0,n.limit),t(e,21,0),t(e,28,0,n.fetchData.observers.length>0)},function(t,e){t(e,7,0,a["\u0275nov"](e,12).ngClassUntouched,a["\u0275nov"](e,12).ngClassTouched,a["\u0275nov"](e,12).ngClassPristine,a["\u0275nov"](e,12).ngClassDirty,a["\u0275nov"](e,12).ngClassValid,a["\u0275nov"](e,12).ngClassInvalid,a["\u0275nov"](e,12).ngClassPending),t(e,19,0,a["\u0275nov"](e,21).dropup,a["\u0275nov"](e,21).isOpen,a["\u0275nov"](e,21).isOpen&&a["\u0275nov"](e,21).isBs4),t(e,22,0,!0,a["\u0275nov"](e,23).isDisabled,a["\u0275nov"](e,23).isOpen)})}function fe(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,[" "," "])),(t()(),a["\u0275eld"](2,0,null,null,1,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["selected"])),(t()(),a["\u0275ted"](-1,null,[" / "]))],null,function(t,e){t(e,1,0,e.parent.context.selectedCount)})}function pe(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,[" "," "])),(t()(),a["\u0275eld"](2,0,null,null,1,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["found"])),(t()(),a["\u0275ted"](-1,null,[" / "]))],null,function(t,e){t(e,1,0,e.parent.context.rowCount)})}function he(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,8,"div",[["class","page-count"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,fe)),a["\u0275did"](2,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,pe)),a["\u0275did"](4,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](5,0,null,null,3,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](6,null,[" "," "])),(t()(),a["\u0275eld"](7,0,null,null,1,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["total"])),(t()(),a["\u0275eld"](9,0,null,null,1,"datatable-pager",[["class","datatable-pager"]],[[8,"hidden",0]],[[null,"change"]],function(t,e,n){var r=!0;return"change"===e&&(r=!1!==a["\u0275nov"](t.parent,17).onFooterPage(n)&&r),r},p,d)),a["\u0275did"](10,49152,null,0,l.DataTablePagerComponent,[],{pagerLeftArrowIcon:[0,"pagerLeftArrowIcon"],pagerRightArrowIcon:[1,"pagerRightArrowIcon"],pagerPreviousIcon:[2,"pagerPreviousIcon"],pagerNextIcon:[3,"pagerNextIcon"],size:[4,"size"],count:[5,"count"],page:[6,"page"]},{change:"change"})],function(t,e){var n=e.component;t(e,2,0,n.selectionType),t(e,4,0,e.context.rowCount!=(null==n.data?null:n.data.length)),t(e,10,0,n.paginationClasses.pagerLeftArrow,n.paginationClasses.pagerRightArrow,n.paginationClasses.pagerPrevious,n.paginationClasses.pagerNext,e.context.pageSize,e.context.rowCount,e.context.curPage)},function(t,e){var n=e.component;t(e,6,0,(null==n.data?null:n.data.length)||0),t(e,9,0,!(e.context.rowCount/e.context.pageSize>1))})}function ge(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.context.value)})}function be(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"cd-sparkline",[],null,null,null,h.b,h.a)),a["\u0275did"](1,638976,null,0,g.a,[b.a],{data:[0,"data"],isBinary:[1,"isBinary"]},null)],function(t,e){t(e,1,0,e.context.value,e.context.row.cdIsBinary)},null)}function me(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var r=!0;return"click"===e&&(r=!1!==a["\u0275nov"](t,1).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&r),r},null,null)),a["\u0275did"](1,671744,null,0,m.o,[m.l,m.a,s.LocationStrategy],{queryParams:[0,"queryParams"],routerLink:[1,"routerLink"]},null),a["\u0275pad"](2,1),(t()(),a["\u0275ted"](3,null,["",""]))],function(t,e){var n=e.context.row.cdParams,a=t(e,2,0,e.context.row.cdLink);t(e,1,0,n,a)},function(t,e){t(e,0,0,a["\u0275nov"](e,1).target,a["\u0275nov"](e,1).href),t(e,3,0,e.context.value)})}function ye(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"i",[["class","fa fa-check fa-fw"]],[[8,"hidden",0]],null,null,null,null))],null,function(t,e){t(e,0,0,!e.context.value)})}function ve(t){return a["\u0275vid"](0,[(t()(),a["\u0275ted"](0,null,[" "," /s\n"])),a["\u0275ppd"](1,1)],null,function(t,e){var n=a["\u0275unv"](e,0,0,t(e,1,0,a["\u0275nov"](e.parent,0),e.context.value));t(e,0,0,n)})}function _e(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"i",[["class","fa fa-spinner fa-spin fa-fw"]],null,null,null,null,null))],null,null)}function xe(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"span",[["class","text-muted italic"]],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["(",")"]))],null,function(t,e){t(e,1,0,e.parent.context.row.cdExecuting)})}function Te(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,_e)),a["\u0275did"](1,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275ted"](2,null,[" "," "])),(t()(),a["\u0275and"](16777216,null,null,1,null,xe)),a["\u0275did"](4,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.context.row.cdExecuting),t(e,4,0,e.context.row.cdExecuting)},function(t,e){t(e,2,0,e.context.value)})}function we(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"span",[],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,0,0,a["\u0275inlineInterpolate"](1,"",e.component.useCustomClass(e.context.value),"")),t(e,1,0,e.context.value)})}function Se(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["",""])),a["\u0275ppd"](2,2)],null,function(t,e){var n=a["\u0275unv"](e,1,0,t(e,2,0,a["\u0275nov"](e.parent,1),e.context.value,null==e.context.column?null:e.context.column.customTemplateConfig));t(e,1,0,n)})}function Oe(t){return a["\u0275vid"](2,[a["\u0275pid"](0,y.a,[v.a]),a["\u0275pid"](0,_.a,[]),a["\u0275qud"](402653184,1,{table:0}),a["\u0275qud"](402653184,2,{tableCellBoldTpl:0}),a["\u0275qud"](402653184,3,{sparklineTpl:0}),a["\u0275qud"](402653184,4,{routerLinkTpl:0}),a["\u0275qud"](402653184,5,{checkIconTpl:0}),a["\u0275qud"](402653184,6,{perSecondTpl:0}),a["\u0275qud"](402653184,7,{executingTpl:0}),a["\u0275qud"](402653184,8,{classAddingTpl:0}),a["\u0275qud"](402653184,9,{mapTpl:0}),(t()(),a["\u0275and"](16777216,null,null,1,null,se)),a["\u0275did"](12,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](13,0,null,null,13,"div",[["class","dataTables_wrapper"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,de)),a["\u0275did"](15,16384,null,0,s.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](16,0,null,null,10,"ngx-datatable",[["class","bootstrap oadatatable ngx-datatable"]],[[2,"fixed-header",null],[2,"fixed-row",null],[2,"scroll-vertical",null],[2,"virtualized",null],[2,"scroll-horz",null],[2,"selectable",null],[2,"checkbox-selection",null],[2,"cell-selection",null],[2,"single-selection",null],[2,"multi-selection",null],[2,"multi-click-selection",null]],[[null,"select"],[null,"sort"],["window","resize"]],function(t,e,n){var r=!0,i=t.component;return"window:resize"===e&&(r=!1!==a["\u0275nov"](t,17).onWindowResize()&&r),"select"===e&&(r=!1!==i.onSelect(n)&&r),"sort"===e&&(r=!1!==i.changeSorting(n)&&r),r},ne,Qt)),a["\u0275did"](17,5750784,[[1,4],["table",4]],4,Zt.DatatableComponent,[[1,pt.ScrollbarHelper],[1,Xt.DimensionsHelper],a.ChangeDetectorRef,a.ElementRef,a.KeyValueDiffers,Jt.ColumnChangesService],{rows:[0,"rows"],columns:[1,"columns"],selected:[2,"selected"],rowHeight:[3,"rowHeight"],columnMode:[4,"columnMode"],headerHeight:[5,"headerHeight"],footerHeight:[6,"footerHeight"],limit:[7,"limit"],loadingIndicator:[8,"loadingIndicator"],selectionType:[9,"selectionType"],sorts:[10,"sorts"],cssClasses:[11,"cssClasses"],rowIdentity:[12,"rowIdentity"],rowClass:[13,"rowClass"]},{select:"select",sort:"sort"}),a["\u0275qud"](603979776,10,{columnTemplates:1}),a["\u0275qud"](335544320,11,{rowDetail:0}),a["\u0275qud"](335544320,12,{groupHeader:0}),a["\u0275qud"](335544320,13,{footer:0}),(t()(),a["\u0275eld"](22,0,null,null,4,"ngx-datatable-footer",[],null,null,null,null,null)),a["\u0275did"](23,16384,[[13,4]],1,ae.DatatableFooterDirective,[],null,null),a["\u0275qud"](335544320,14,{template:0}),(t()(),a["\u0275and"](0,[[14,2]],null,1,null,he)),a["\u0275did"](26,16384,null,0,re.DataTableFooterTemplateDirective,[a.TemplateRef],null,null),a["\u0275ncd"](null,2),(t()(),a["\u0275and"](0,[[2,2],["tableCellBoldTpl",2]],null,0,null,ge)),(t()(),a["\u0275and"](0,[[3,2],["sparklineTpl",2]],null,0,null,be)),(t()(),a["\u0275and"](0,[[4,2],["routerLinkTpl",2]],null,0,null,me)),(t()(),a["\u0275and"](0,[[5,2],["checkIconTpl",2]],null,0,null,ye)),(t()(),a["\u0275and"](0,[[6,2],["perSecondTpl",2]],null,0,null,ve)),(t()(),a["\u0275and"](0,[[7,2],["executingTpl",2]],null,0,null,Te)),(t()(),a["\u0275and"](0,[[8,2],["classAddingTpl",2]],null,0,null,we)),(t()(),a["\u0275and"](0,[[9,2],["mapTpl",2]],null,0,null,Se))],function(t,e){var n=e.component;t(e,12,0,n.loadingError),t(e,15,0,n.toolHeader),t(e,17,1,[n.rows,n.tableColumns,n.selection.selected,"auto",n.columnMode,n.header?"auto":0,n.footer?"auto":0,n.userConfig.limit>0?n.userConfig.limit:void 0,n.loadingIndicator,n.selectionType,n.userConfig.sorts,n.paginationClasses,n.rowIdentity(),n.getRowClass()])},function(t,e){t(e,16,1,[a["\u0275nov"](e,17).isFixedHeader,a["\u0275nov"](e,17).isFixedRow,a["\u0275nov"](e,17).isVertScroll,a["\u0275nov"](e,17).isVirtualized,a["\u0275nov"](e,17).isHorScroll,a["\u0275nov"](e,17).isSelectable,a["\u0275nov"](e,17).isCheckboxSelection,a["\u0275nov"](e,17).isCellSelection,a["\u0275nov"](e,17).isSingleSelection,a["\u0275nov"](e,17).isMultiSelection,a["\u0275nov"](e,17).isMultiClickSelection])})}},"26FU":function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("mrSG"),r=n("K9Ia"),i=n("8g8A"),s=function(t){function e(e){var n=t.call(this)||this;return n._value=e,n}return a.__extends(e,t),Object.defineProperty(e.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0}),e.prototype._subscribe=function(e){var n=t.prototype._subscribe.call(this,e);return n&&!n.closed&&e.next(this._value),n},e.prototype.getValue=function(){if(this.hasError)throw this.thrownError;if(this.closed)throw new i.a;return this._value},e.prototype.next=function(e){t.prototype.next.call(this,this._value=e)},e}(r.a)},"2Bdj":function(t,e,n){"use strict";function a(t){return"function"==typeof t}n.d(e,"a",function(){return a})},"2EZI":function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("mrSG"),r=n("gIcY"),i=n("QFaf"),s=n("CcnG"),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return a.__extends(e,t),e.prototype.group=function(e,n){void 0===n&&(n=null);var a=t.prototype.group.call(this,e,n);return new i.a(a.controls,a.validator,a.asyncValidator)},e.ngInjectableDef=s.defineInjectable({factory:function(){return new e},token:e,providedIn:"root"}),e}(r.h)},"2UWG":function(t,e,n){"use strict";var a=n("CDJp"),r=n("K2E3");function i(t){return void 0!==t._view.width}function s(t){var e,n,a,r,s=t._view;if(i(t)){var o=s.width/2;e=s.x-o,n=s.x+o,a=Math.min(s.y,s.base),r=Math.max(s.y,s.base)}else{var u=s.height/2;e=Math.min(s.x,s.base),n=Math.max(s.x,s.base),a=s.y-u,r=s.y+u}return{left:e,top:a,right:n,bottom:r}}a._set("global",{elements:{rectangle:{backgroundColor:a.global.defaultColor,borderColor:a.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),t.exports=r.extend({draw:function(){var t,e,n,a,r,i,s,o=this._chart.ctx,u=this._view,c=u.borderWidth;if(u.horizontal?(n=u.y-u.height/2,a=u.y+u.height/2,r=(e=u.x)>(t=u.base)?1:-1,i=1,s=u.borderSkipped||"left"):(t=u.x-u.width/2,e=u.x+u.width/2,r=1,i=(a=u.base)>(n=u.y)?1:-1,s=u.borderSkipped||"bottom"),c){var l=Math.min(Math.abs(t-e),Math.abs(n-a)),d=(c=c>l?l:c)/2,f=t+("left"!==s?d*r:0),p=e+("right"!==s?-d*r:0),h=n+("top"!==s?d*i:0),g=a+("bottom"!==s?-d*i:0);f!==p&&(n=h,a=g),h!==g&&(t=f,e=p)}o.beginPath(),o.fillStyle=u.backgroundColor,o.strokeStyle=u.borderColor,o.lineWidth=c;var b=[[t,a],[t,n],[e,n],[e,a]],m=["bottom","left","top","right"].indexOf(s,0);function y(t){return b[(m+t)%4]}-1===m&&(m=0);var v=y(0);o.moveTo(v[0],v[1]);for(var _=1;_<4;_++)v=y(_),o.lineTo(v[0],v[1]);o.fill(),c&&o.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var n=!1;if(this._view){var a=s(this);n=t>=a.left&&t<=a.right&&e>=a.top&&e<=a.bottom}return n},inLabelRange:function(t,e){if(!this._view)return!1;var n=s(this);return i(this)?t>=n.left&&t<=n.right:e>=n.top&&e<=n.bottom},inXRange:function(t){var e=s(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=s(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,n=this._view;return i(this)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},"2V7f":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("IPm6")),a(n("YVFZ")),a(n("syrc")),a(n("PNOi")),a(n("SfHT")),a(n("Mfce")),a(n("7F1K")),a(n("99TG")),a(n("Fjl2")),a(n("VHo1"))},"2WpN":function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("mrSG"),r=n("FFOo"),i=n("pugT");function s(t){return function(e){return e.lift(new o(t))}}var o=function(){function t(t){this.callback=t}return t.prototype.call=function(t,e){return e.subscribe(new u(t,this.callback))},t}(),u=function(t){function e(e,n){var a=t.call(this,e)||this;return a.add(new i.a(n)),a}return a.__extends(e,t),e}(r.a)},"2ePl":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(t){return t&&"number"==typeof t.length&&"function"!=typeof t}},"2fjn":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("fr-ca",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(t,e){switch(e){default:case"M":case"Q":case"D":case"DDD":case"d":return t+(1===t?"er":"e");case"w":case"W":return t+(1===t?"re":"e")}}})}()},"2ykv":function(t,e,n){!function(t){"use strict";var e="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),n="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),a=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],r=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;t.defineLocale("nl-be",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(t,a){return t?/-MMM-/.test(a)?n[t.month()]:e[t.month()]:e},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:a,longMonthsParse:a,shortMonthsParse:a,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"\xe9\xe9n minuut",mm:"%d minuten",h:"\xe9\xe9n uur",hh:"%d uur",d:"\xe9\xe9n dag",dd:"%d dagen",M:"\xe9\xe9n maand",MM:"%d maanden",y:"\xe9\xe9n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(t){return t+(1===t||8===t||t>=20?"ste":"de")},week:{dow:1,doy:4}})}(n("wd/R"))},"3/HP":function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata,i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,n=1,a=arguments.length;na){for(var o=r[a],u=a;un;u--)r[u]=r[u-1];r[n]=o}this._internalColumns=r,this.reorder.emit({column:e,newValue:n,prevValue:a})},t.prototype.onColumnSort=function(t){this.selectAllRowsOnPage&&(this.selected=[],this.select.emit({selected:this.selected})),this.sorts=t.sorts,!1===this.externalSorting&&this.sortInternalRows(),this._internalRows=o.groupRowsByParents(this._internalRows,o.optionalGetterForProp(this.treeFromRelation),o.optionalGetterForProp(this.treeToRelation)),this.offset=0,this.bodyComponent.updateOffsetY(this.offset),this.sort.emit(t)},t.prototype.onHeaderSelect=function(t){var e,n;if(this.selectAllRowsOnPage){var a=this.bodyComponent.indexes.first,r=this.bodyComponent.indexes.last,i=this.selected.length===r-a;this.selected=[],i||(e=this.selected).push.apply(e,this._internalRows.slice(a,r))}else i=this.selected.length===this.rows.length,this.selected=[],i||(n=this.selected).push.apply(n,this.rows);this.select.emit({selected:this.selected})},t.prototype.onBodySelect=function(t){this.select.emit(t)},t.prototype.onTreeAction=function(t){var e=this,n=t.row,a=this._rows.findIndex(function(n){return n[e.treeToRelation]===t.row[e.treeToRelation]});this.treeAction.emit({row:n,rowIndex:a})},t.prototype.ngOnDestroy=function(){this._subscriptions.forEach(function(t){return t.unsubscribe()})},t.prototype.listenForColumnInputChanges=function(){var t=this;this._subscriptions.push(this.columnChangesService.columnInputChanges$.subscribe(function(){t.columnTemplates&&t.columnTemplates.notifyOnChanges()}))},t.prototype.sortInternalRows=function(){this._internalRows=o.sortRows(this._internalRows,this._internalColumns,this.sorts)},a([s.Input(),r("design:type",Object)],t.prototype,"targetMarkerTemplate",void 0),a([s.Input(),r("design:type",Object),r("design:paramtypes",[Object])],t.prototype,"rows",null),a([s.Input(),r("design:type",String),r("design:paramtypes",[String])],t.prototype,"groupRowsBy",null),a([s.Input(),r("design:type",Array)],t.prototype,"groupedRows",void 0),a([s.Input(),r("design:type",Array),r("design:paramtypes",[Array])],t.prototype,"columns",null),a([s.Input(),r("design:type",Array)],t.prototype,"selected",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"scrollbarV",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"scrollbarH",void 0),a([s.Input(),r("design:type",Number)],t.prototype,"rowHeight",void 0),a([s.Input(),r("design:type",String)],t.prototype,"columnMode",void 0),a([s.Input(),r("design:type",Object)],t.prototype,"headerHeight",void 0),a([s.Input(),r("design:type",Number)],t.prototype,"footerHeight",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"externalPaging",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"externalSorting",void 0),a([s.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"limit",null),a([s.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"count",null),a([s.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"offset",null),a([s.Input(),r("design:type",Boolean)],t.prototype,"loadingIndicator",void 0),a([s.Input(),r("design:type",String)],t.prototype,"selectionType",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"reorderable",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"swapColumns",void 0),a([s.Input(),r("design:type",String)],t.prototype,"sortType",void 0),a([s.Input(),r("design:type",Array)],t.prototype,"sorts",void 0),a([s.Input(),r("design:type",Object)],t.prototype,"cssClasses",void 0),a([s.Input(),r("design:type",Object)],t.prototype,"messages",void 0),a([s.Input(),r("design:type",Function)],t.prototype,"rowIdentity",void 0),a([s.Input(),r("design:type",Object)],t.prototype,"rowClass",void 0),a([s.Input(),r("design:type",Object)],t.prototype,"selectCheck",void 0),a([s.Input(),r("design:type",Function)],t.prototype,"displayCheck",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"groupExpansionDefault",void 0),a([s.Input(),r("design:type",String)],t.prototype,"trackByProp",void 0),a([s.Input(),r("design:type",Object)],t.prototype,"selectAllRowsOnPage",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"virtualization",void 0),a([s.Input(),r("design:type",String)],t.prototype,"treeFromRelation",void 0),a([s.Input(),r("design:type",String)],t.prototype,"treeToRelation",void 0),a([s.Input(),r("design:type",Boolean)],t.prototype,"summaryRow",void 0),a([s.Input(),r("design:type",Number)],t.prototype,"summaryHeight",void 0),a([s.Input(),r("design:type",String)],t.prototype,"summaryPosition",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"scroll",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"activate",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"select",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"sort",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"page",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"reorder",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"resize",void 0),a([s.Output(),r("design:type",Object)],t.prototype,"tableContextmenu",void 0),a([s.Output(),r("design:type",s.EventEmitter)],t.prototype,"treeAction",void 0),a([s.HostBinding("class.fixed-header"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isFixedHeader",null),a([s.HostBinding("class.fixed-row"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isFixedRow",null),a([s.HostBinding("class.scroll-vertical"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isVertScroll",null),a([s.HostBinding("class.virtualized"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isVirtualized",null),a([s.HostBinding("class.scroll-horz"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isHorScroll",null),a([s.HostBinding("class.selectable"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isSelectable",null),a([s.HostBinding("class.checkbox-selection"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isCheckboxSelection",null),a([s.HostBinding("class.cell-selection"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isCellSelection",null),a([s.HostBinding("class.single-selection"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isSingleSelection",null),a([s.HostBinding("class.multi-selection"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isMultiSelection",null),a([s.HostBinding("class.multi-click-selection"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isMultiClickSelection",null),a([s.ContentChildren(d.DataTableColumnDirective),r("design:type",s.QueryList),r("design:paramtypes",[s.QueryList])],t.prototype,"columnTemplates",null),a([s.ContentChild(f.DatatableRowDetailDirective),r("design:type",f.DatatableRowDetailDirective)],t.prototype,"rowDetail",void 0),a([s.ContentChild(l.DatatableGroupHeaderDirective),r("design:type",l.DatatableGroupHeaderDirective)],t.prototype,"groupHeader",void 0),a([s.ContentChild(p.DatatableFooterDirective),r("design:type",p.DatatableFooterDirective)],t.prototype,"footer",void 0),a([s.ViewChild(c.DataTableBodyComponent),r("design:type",c.DataTableBodyComponent)],t.prototype,"bodyComponent",void 0),a([s.ViewChild(h.DataTableHeaderComponent),r("design:type",h.DataTableHeaderComponent)],t.prototype,"headerComponent",void 0),a([s.HostListener("window:resize"),o.throttleable(5),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",void 0)],t.prototype,"onWindowResize",null),a([s.Component({selector:"ngx-datatable",template:'\n \n \n \n \n \n \n \n \n ',changeDetection:s.ChangeDetectionStrategy.OnPush,encapsulation:s.ViewEncapsulation.None,styleUrls:["./datatable.component.css"],host:{class:"ngx-datatable"}})],t)}()},"35yf":function(t,e,n){"use strict";n("CDJp")._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),t.exports=function(t){t.controllers.scatter=t.controllers.line}},"3E1r":function(t,e,n){!function(t){"use strict";var e={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},n={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};t.defineLocale("hi",{months:"\u091c\u0928\u0935\u0930\u0940_\u092b\u093c\u0930\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948\u0932_\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0938\u094d\u0924_\u0938\u093f\u0924\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u0942\u092c\u0930_\u0928\u0935\u092e\u094d\u092c\u0930_\u0926\u093f\u0938\u092e\u094d\u092c\u0930".split("_"),monthsShort:"\u091c\u0928._\u092b\u093c\u0930._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u0948._\u092e\u0908_\u091c\u0942\u0928_\u091c\u0941\u0932._\u0905\u0917._\u0938\u093f\u0924._\u0905\u0915\u094d\u091f\u0942._\u0928\u0935._\u0926\u093f\u0938.".split("_"),monthsParseExact:!0,weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0932\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0932_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u092c\u091c\u0947",LTS:"A h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A h:mm \u092c\u091c\u0947"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0915\u0932] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u0932] LT",lastWeek:"[\u092a\u093f\u091b\u0932\u0947] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u092e\u0947\u0902",past:"%s \u092a\u0939\u0932\u0947",s:"\u0915\u0941\u091b \u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0902\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u091f",mm:"%d \u092e\u093f\u0928\u091f",h:"\u090f\u0915 \u0918\u0902\u091f\u093e",hh:"%d \u0918\u0902\u091f\u0947",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u0940\u0928\u0947",MM:"%d \u092e\u0939\u0940\u0928\u0947",y:"\u090f\u0915 \u0935\u0930\u094d\u0937",yy:"%d \u0935\u0930\u094d\u0937"},preparse:function(t){return t.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0930\u093e\u0924|\u0938\u0941\u092c\u0939|\u0926\u094b\u092a\u0939\u0930|\u0936\u093e\u092e/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0930\u093e\u0924"===e?t<4?t:t+12:"\u0938\u0941\u092c\u0939"===e?t:"\u0926\u094b\u092a\u0939\u0930"===e?t>=10?t:t+12:"\u0936\u093e\u092e"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"\u0930\u093e\u0924":t<10?"\u0938\u0941\u092c\u0939":t<17?"\u0926\u094b\u092a\u0939\u0930":t<20?"\u0936\u093e\u092e":"\u0930\u093e\u0924"},week:{dow:0,doy:6}})}(n("wd/R"))},"3MdB":function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("DtyJ"),o=n("ahDk");e.DraggableDirective=function(){function t(t){this.dragX=!0,this.dragY=!0,this.dragStart=new i.EventEmitter,this.dragging=new i.EventEmitter,this.dragEnd=new i.EventEmitter,this.isDragging=!1,this.element=t.nativeElement}return t.prototype.ngOnChanges=function(t){t.dragEventTarget&&t.dragEventTarget.currentValue&&this.dragModel.dragging&&this.onMousedown(t.dragEventTarget.currentValue)},t.prototype.ngOnDestroy=function(){this._destroySubscription()},t.prototype.onMouseup=function(t){this.isDragging&&(this.isDragging=!1,this.element.classList.remove("dragging"),this.subscription&&(this._destroySubscription(),this.dragEnd.emit({event:t,element:this.element,model:this.dragModel})))},t.prototype.onMousedown=function(t){var e=this;if(t.target.classList.contains("draggable")&&(this.dragX||this.dragY)){t.preventDefault(),this.isDragging=!0;var n={x:t.clientX,y:t.clientY},a=s.fromEvent(document,"mouseup");this.subscription=a.subscribe(function(t){return e.onMouseup(t)});var r=s.fromEvent(document,"mousemove").pipe(o.takeUntil(a)).subscribe(function(t){return e.move(t,n)});this.subscription.add(r),this.dragStart.emit({event:t,element:this.element,model:this.dragModel})}},t.prototype.move=function(t,e){if(this.isDragging){var n=t.clientY-e.y;this.dragX&&(this.element.style.left=t.clientX-e.x+"px"),this.dragY&&(this.element.style.top=n+"px"),this.element.classList.add("dragging"),this.dragging.emit({event:t,element:this.element,model:this.dragModel})}},t.prototype._destroySubscription=function(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)},a([i.Input(),r("design:type",Object)],t.prototype,"dragEventTarget",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"dragModel",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"dragX",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"dragY",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"dragStart",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"dragging",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"dragEnd",void 0),a([i.Directive({selector:"[draggable]"})],t)}()},"3U0i":function(t,e,n){"use strict";function a(){return Error.call(this),this.message="Timeout has occurred",this.name="TimeoutError",this}n.d(e,"a",function(){return r}),a.prototype=Object.create(Error.prototype);var r=a},"3fWJ":function(t,e,n){"use strict";function a(){return Error.call(this),this.message="no elements in sequence",this.name="EmptyError",this}n.d(e,"a",function(){return r}),a.prototype=Object.create(Error.prototype);var r=a},"4HWh":function(t,e,n){"use strict";var a=n("CcnG"),r=n("OZfm"),i=n("lqqz"),s=n("NJnL");n("p4Cf"),n.d(e,"a",function(){return o}),n.d(e,"b",function(){return c});var o=a["\u0275crt"]({encapsulation:0,styles:[["i[_ngcontent-%COMP%]{color:#2b99a8;cursor:pointer;padding-left:4px}"]],data:{}});function u(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"div",[],[[8,"innerHTML",1]],null,null,null,null)),a["\u0275ncd"](null,0),(t()(),a["\u0275and"](0,null,null,0))],null,function(t,e){t(e,0,0,e.component.html)})}function c(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,[["popoverTpl",2]],null,0,null,u)),(t()(),a["\u0275eld"](1,16777216,null,null,1,"i",[["aria-hidden","true"],["class","fa fa-question-circle"],["container","body"],["placement","bottom"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==n.preventDefault()&&a),a},null,null)),a["\u0275did"](2,212992,null,0,r.c,[r.a,a.ElementRef,a.Renderer2,a.ViewContainerRef,i.a,s.a],{popover:[0,"popover"],placement:[1,"placement"],outsideClick:[2,"outsideClick"],container:[3,"container"]},null)],function(t,e){t(e,2,0,a["\u0275nov"](e,0),"bottom",!0,"body")},null)}},"4MV3":function(t,e,n){!function(t){"use strict";var e={1:"\u0ae7",2:"\u0ae8",3:"\u0ae9",4:"\u0aea",5:"\u0aeb",6:"\u0aec",7:"\u0aed",8:"\u0aee",9:"\u0aef",0:"\u0ae6"},n={"\u0ae7":"1","\u0ae8":"2","\u0ae9":"3","\u0aea":"4","\u0aeb":"5","\u0aec":"6","\u0aed":"7","\u0aee":"8","\u0aef":"9","\u0ae6":"0"};t.defineLocale("gu",{months:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0_\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0_\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2_\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe\u0a88_\u0a91\u0a97\u0ab8\u0acd\u0a9f_\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0a91\u0a95\u0acd\u0a9f\u0acd\u0aac\u0ab0_\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0_\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0".split("_"),monthsShort:"\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1._\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1._\u0aae\u0abe\u0ab0\u0acd\u0a9a_\u0a8f\u0aaa\u0acd\u0ab0\u0abf._\u0aae\u0ac7_\u0a9c\u0ac2\u0aa8_\u0a9c\u0ac1\u0ab2\u0abe._\u0a91\u0a97._\u0ab8\u0aaa\u0acd\u0a9f\u0ac7._\u0a91\u0a95\u0acd\u0a9f\u0acd._\u0aa8\u0ab5\u0ac7._\u0aa1\u0abf\u0ab8\u0ac7.".split("_"),monthsParseExact:!0,weekdays:"\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0_\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0_\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0_\u0aac\u0ac1\u0aa7\u0acd\u0ab5\u0abe\u0ab0_\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0_\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0_\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0".split("_"),weekdaysShort:"\u0ab0\u0ab5\u0abf_\u0ab8\u0acb\u0aae_\u0aae\u0a82\u0a97\u0ab3_\u0aac\u0ac1\u0aa7\u0acd_\u0a97\u0ac1\u0ab0\u0ac1_\u0ab6\u0ac1\u0a95\u0acd\u0ab0_\u0ab6\u0aa8\u0abf".split("_"),weekdaysMin:"\u0ab0_\u0ab8\u0acb_\u0aae\u0a82_\u0aac\u0ac1_\u0a97\u0ac1_\u0ab6\u0ac1_\u0ab6".split("_"),longDateFormat:{LT:"A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LTS:"A h:mm:ss \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7",LLLL:"dddd, D MMMM YYYY, A h:mm \u0ab5\u0abe\u0a97\u0acd\u0aaf\u0ac7"},calendar:{sameDay:"[\u0a86\u0a9c] LT",nextDay:"[\u0a95\u0abe\u0ab2\u0ac7] LT",nextWeek:"dddd, LT",lastDay:"[\u0a97\u0a87\u0a95\u0abe\u0ab2\u0ac7] LT",lastWeek:"[\u0aaa\u0abe\u0a9b\u0ab2\u0abe] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0aae\u0abe",past:"%s \u0aaa\u0ac7\u0ab9\u0ab2\u0abe",s:"\u0a85\u0aae\u0ac1\u0a95 \u0aaa\u0ab3\u0acb",ss:"%d \u0ab8\u0ac7\u0a95\u0a82\u0aa1",m:"\u0a8f\u0a95 \u0aae\u0abf\u0aa8\u0abf\u0a9f",mm:"%d \u0aae\u0abf\u0aa8\u0abf\u0a9f",h:"\u0a8f\u0a95 \u0a95\u0ab2\u0abe\u0a95",hh:"%d \u0a95\u0ab2\u0abe\u0a95",d:"\u0a8f\u0a95 \u0aa6\u0abf\u0ab5\u0ab8",dd:"%d \u0aa6\u0abf\u0ab5\u0ab8",M:"\u0a8f\u0a95 \u0aae\u0ab9\u0abf\u0aa8\u0acb",MM:"%d \u0aae\u0ab9\u0abf\u0aa8\u0acb",y:"\u0a8f\u0a95 \u0ab5\u0ab0\u0acd\u0ab7",yy:"%d \u0ab5\u0ab0\u0acd\u0ab7"},preparse:function(t){return t.replace(/[\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0ae6]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0ab0\u0abe\u0aa4|\u0aac\u0aaa\u0acb\u0ab0|\u0ab8\u0ab5\u0abe\u0ab0|\u0ab8\u0abe\u0a82\u0a9c/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0ab0\u0abe\u0aa4"===e?t<4?t:t+12:"\u0ab8\u0ab5\u0abe\u0ab0"===e?t:"\u0aac\u0aaa\u0acb\u0ab0"===e?t>=10?t:t+12:"\u0ab8\u0abe\u0a82\u0a9c"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"\u0ab0\u0abe\u0aa4":t<10?"\u0ab8\u0ab5\u0abe\u0ab0":t<17?"\u0aac\u0aaa\u0acb\u0ab0":t<20?"\u0ab8\u0abe\u0a82\u0a9c":"\u0ab0\u0abe\u0aa4"},week:{dow:0,doy:6}})}(n("wd/R"))},"4dOw":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")},week:{dow:1,doy:4}})}()},"4fRq":function(t,e){var n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(n){var a=new Uint8Array(16);t.exports=function(){return n(a),a}}else{var r=new Array(16);t.exports=function(){for(var t,e=0;e<16;e++)0==(3&e)&&(t=4294967296*Math.random()),r[e]=t>>>((3&e)<<3)&255;return r}}},"58b6":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("kQXf");e.FoldingType=function(){function t(t){this._cssClass=t}return Object.defineProperty(t.prototype,"cssClass",{get:function(){return this._cssClass},enumerable:!0,configurable:!0}),t.Expanded=new t("node-expanded"),t.Collapsed=new t("node-collapsed"),t.Empty=new t("node-empty"),t.Leaf=new t("node-leaf"),t}(),e.TreeModelSettings=function(){function t(){}return t.merge=function(e,n){var r=a.omit(a.get(n,"settings"),t.NOT_CASCADING_SETTINGS);return a.defaultsDeep({},a.get(e,"settings"),r,{static:!1,leftMenu:!1,rightMenu:!0,isCollapsedOnInit:!1,checked:!1,keepNodesInDOM:!1,selectionAllowed:!0})},t.NOT_CASCADING_SETTINGS=["selectionAllowed"],t}(),e.Ng2TreeSettings=function(){return function(){this.rootIsVisible=!0,this.showCheckboxes=!1,this.enableCheckboxes=!0}}(),e.TreeStatus=function(t){return t[t.New=0]="New",t[t.Modified=1]="Modified",t[t.IsBeingRenamed=2]="IsBeingRenamed",t}(e.TreeStatus||{})},"5ZZ7":function(t,e,n){"use strict";var a=n("CDJp"),r=n("vvH+"),i=n("RDha");a._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e=[];e.push('
    ');var n=t.data,a=n.datasets,r=n.labels;if(a.length)for(var i=0;i'),r[i]&&e.push(r[i]),e.push("");return e.push("
"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,a){var r=t.getDatasetMeta(0),s=e.datasets[0],o=r.data[a].custom||{},u=i.valueAtIndexOrDefault,c=t.options.elements.arc;return{text:n,fillStyle:o.backgroundColor?o.backgroundColor:u(s.backgroundColor,a,c.backgroundColor),strokeStyle:o.borderColor?o.borderColor:u(s.borderColor,a,c.borderColor),lineWidth:o.borderWidth?o.borderWidth:u(s.borderWidth,a,c.borderWidth),hidden:isNaN(s.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,a,r,i=e.index,s=this.chart;for(n=0,a=(s.data.datasets||[]).length;n=11?t:t+12:"petang"===e||"malam"===e?t+12:void 0},meridiem:function(t,e,n){return t<11?"pagi":t<15?"tengahari":t<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}()},"60iU":function(t,e,n){"use strict";n.d(e,"b",function(){return a}),n.d(e,"a",function(){return o});var a,r=n("G5J1"),i=n("F/XL"),s=n("XlPw");a||(a={});var o=function(){function t(t,e,n){this.kind=t,this.value=e,this.error=n,this.hasValue="N"===t}return t.prototype.observe=function(t){switch(this.kind){case"N":return t.next&&t.next(this.value);case"E":return t.error&&t.error(this.error);case"C":return t.complete&&t.complete()}},t.prototype.do=function(t,e,n){switch(this.kind){case"N":return t&&t(this.value);case"E":return e&&e(this.error);case"C":return n&&n()}},t.prototype.accept=function(t,e,n){return t&&"function"==typeof t.next?this.observe(t):this.do(t,e,n)},t.prototype.toObservable=function(){switch(this.kind){case"N":return Object(i.a)(this.value);case"E":return Object(s.a)(this.error);case"C":return Object(r.b)()}throw new Error("unexpected notification kind value")},t.createNext=function(e){return void 0!==e?new t("N",e):t.undefinedValueNotification},t.createError=function(e){return new t("E",void 0,e)},t.createComplete=function(){return t.completeNotification},t.completeNotification=new t("C"),t.undefinedValueNotification=new t("N",void 0),t}()},"67Y/":function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("mrSG"),r=n("FFOo");function i(t,e){return function(n){if("function"!=typeof t)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return n.lift(new s(t,e))}}var s=function(){function t(t,e){this.project=t,this.thisArg=e}return t.prototype.call=function(t,e){return e.subscribe(new o(t,this.project,this.thisArg))},t}(),o=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.project=n,r.count=0,r.thisArg=a||r,r}return a.__extends(e,t),e.prototype._next=function(t){var e;try{e=this.project.call(this.thisArg,t,this.count++)}catch(n){return void this.destination.error(n)}this.destination.next(e)},e}(r.a)},"6B0Y":function(t,e,n){!function(t){"use strict";var e={1:"\u17e1",2:"\u17e2",3:"\u17e3",4:"\u17e4",5:"\u17e5",6:"\u17e6",7:"\u17e7",8:"\u17e8",9:"\u17e9",0:"\u17e0"},n={"\u17e1":"1","\u17e2":"2","\u17e3":"3","\u17e4":"4","\u17e5":"5","\u17e6":"6","\u17e7":"7","\u17e8":"8","\u17e9":"9","\u17e0":"0"};t.defineLocale("km",{months:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),monthsShort:"\u1798\u1780\u179a\u17b6_\u1780\u17bb\u1798\u17d2\u1797\u17c8_\u1798\u17b8\u1793\u17b6_\u1798\u17c1\u179f\u17b6_\u17a7\u179f\u1797\u17b6_\u1798\u17b7\u1790\u17bb\u1793\u17b6_\u1780\u1780\u17d2\u1780\u178a\u17b6_\u179f\u17b8\u17a0\u17b6_\u1780\u1789\u17d2\u1789\u17b6_\u178f\u17bb\u179b\u17b6_\u179c\u17b7\u1785\u17d2\u1786\u17b7\u1780\u17b6_\u1792\u17d2\u1793\u17bc".split("_"),weekdays:"\u17a2\u17b6\u1791\u17b7\u178f\u17d2\u1799_\u1785\u17d0\u1793\u17d2\u1791_\u17a2\u1784\u17d2\u1782\u17b6\u179a_\u1796\u17bb\u1792_\u1796\u17d2\u179a\u17a0\u179f\u17d2\u1794\u178f\u17b7\u17cd_\u179f\u17bb\u1780\u17d2\u179a_\u179f\u17c5\u179a\u17cd".split("_"),weekdaysShort:"\u17a2\u17b6_\u1785_\u17a2_\u1796_\u1796\u17d2\u179a_\u179f\u17bb_\u179f".split("_"),weekdaysMin:"\u17a2\u17b6_\u1785_\u17a2_\u1796_\u1796\u17d2\u179a_\u179f\u17bb_\u179f".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u1796\u17d2\u179a\u17b9\u1780|\u179b\u17d2\u1784\u17b6\u1785/,isPM:function(t){return"\u179b\u17d2\u1784\u17b6\u1785"===t},meridiem:function(t,e,n){return t<12?"\u1796\u17d2\u179a\u17b9\u1780":"\u179b\u17d2\u1784\u17b6\u1785"},calendar:{sameDay:"[\u1790\u17d2\u1784\u17c3\u1793\u17c1\u17c7 \u1798\u17c9\u17c4\u1784] LT",nextDay:"[\u179f\u17d2\u17a2\u17c2\u1780 \u1798\u17c9\u17c4\u1784] LT",nextWeek:"dddd [\u1798\u17c9\u17c4\u1784] LT",lastDay:"[\u1798\u17d2\u179f\u17b7\u179b\u1798\u17b7\u1789 \u1798\u17c9\u17c4\u1784] LT",lastWeek:"dddd [\u179f\u1794\u17d2\u178f\u17b6\u17a0\u17cd\u1798\u17bb\u1793] [\u1798\u17c9\u17c4\u1784] LT",sameElse:"L"},relativeTime:{future:"%s\u1791\u17c0\u178f",past:"%s\u1798\u17bb\u1793",s:"\u1794\u17c9\u17bb\u1793\u17d2\u1798\u17b6\u1793\u179c\u17b7\u1793\u17b6\u1791\u17b8",ss:"%d \u179c\u17b7\u1793\u17b6\u1791\u17b8",m:"\u1798\u17bd\u1799\u1793\u17b6\u1791\u17b8",mm:"%d \u1793\u17b6\u1791\u17b8",h:"\u1798\u17bd\u1799\u1798\u17c9\u17c4\u1784",hh:"%d \u1798\u17c9\u17c4\u1784",d:"\u1798\u17bd\u1799\u1790\u17d2\u1784\u17c3",dd:"%d \u1790\u17d2\u1784\u17c3",M:"\u1798\u17bd\u1799\u1781\u17c2",MM:"%d \u1781\u17c2",y:"\u1798\u17bd\u1799\u1786\u17d2\u1793\u17b6\u17c6",yy:"%d \u1786\u17d2\u1793\u17b6\u17c6"},dayOfMonthOrdinalParse:/\u1791\u17b8\d{1,2}/,ordinal:"\u1791\u17b8%d",preparse:function(t){return t.replace(/[\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u17e0]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},week:{dow:1,doy:4}})}(n("wd/R"))},"6ahw":function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("iLxQ"),r=n("DKTb"),i={closed:!0,next:function(t){},error:function(t){if(a.a.useDeprecatedSynchronousErrorHandling)throw t;Object(r.a)(t)},complete:function(){}}},"6blF":function(t,e,n){"use strict";var a=n("1fDf"),r=n("FFOo"),i=n("L/V9"),s=n("6ahw"),o=n("xTla"),u=n("y3By"),c=n("iLxQ");n.d(e,"a",function(){return l});var l=function(){function t(t){this._isScalar=!1,t&&(this._subscribe=t)}return t.prototype.lift=function(e){var n=new t;return n.source=this,n.operator=e,n},t.prototype.subscribe=function(t,e,n){var a=this.operator,o=function(t,e,n){if(t){if(t instanceof r.a)return t;if(t[i.a])return t[i.a]()}return t||e||n?new r.a(t,e,n):new r.a(s.a)}(t,e,n);if(o.add(a?a.call(o,this.source):this.source||c.a.useDeprecatedSynchronousErrorHandling&&!o.syncErrorThrowable?this._subscribe(o):this._trySubscribe(o)),c.a.useDeprecatedSynchronousErrorHandling&&o.syncErrorThrowable&&(o.syncErrorThrowable=!1,o.syncErrorThrown))throw o.syncErrorValue;return o},t.prototype._trySubscribe=function(t){try{return this._subscribe(t)}catch(e){c.a.useDeprecatedSynchronousErrorHandling&&(t.syncErrorThrown=!0,t.syncErrorValue=e),Object(a.a)(t)?t.error(e):console.warn(e)}},t.prototype.forEach=function(t,e){var n=this;return new(e=d(e))(function(e,a){var r;r=n.subscribe(function(e){try{t(e)}catch(n){a(n),r&&r.unsubscribe()}},a,e)})},t.prototype._subscribe=function(t){var e=this.source;return e&&e.subscribe(t)},t.prototype[o.a]=function(){return this},t.prototype.pipe=function(){for(var t=[],e=0;e=0;--n)e.isDatasetVisible(n)&&e.drawDataset(n,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n=this.getDatasetMeta(t),a={meta:n,index:t,easingValue:e};!1!==l.notify(this,"beforeDatasetDraw",[a])&&(n.controller.draw(e),l.notify(this,"afterDatasetDraw",[a]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==l.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),l.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return o.modes.single(this,t)},getElementsAtEvent:function(t){return o.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return o.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var a=o.modes[e];return"function"==typeof a?a(this,t,n):[]},getDatasetAtEvent:function(t){return o.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;en?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,a=void 0===e?.5:e,r=2*a-1,i=this.alpha()-n.alpha(),s=((r*i==-1?r:(r+i)/(1+r*i))+1)/2,o=1-s;return this.rgb(s*this.red()+o*n.red(),s*this.green()+o*n.green(),s*this.blue()+o*n.blue()).alpha(this.alpha()*a+n.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new i,a=this.values,r=n.values;for(var s in a)a.hasOwnProperty(s)&&("[object Array]"===(e={}.toString.call(t=a[s]))?r[s]=t.slice(0):"[object Number]"===e?r[s]=t:console.error("unexpected color value:",t));return n}},i.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},i.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},i.prototype.getValues=function(t){for(var e=this.values,n={},a=0;a-1},t.prototype.getRowSelectedIdx=function(t,e){var n=this;if(!e||!e.length)return-1;var a=this.rowIdentity(t);return e.findIndex(function(t){return n.rowIdentity(t)===a})},a([i.Input(),r("design:type",Array)],t.prototype,"rows",void 0),a([i.Input(),r("design:type",Array)],t.prototype,"selected",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"selectEnabled",void 0),a([i.Input(),r("design:type",String)],t.prototype,"selectionType",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"rowIdentity",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"selectCheck",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"activate",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"select",void 0),a([i.Component({selector:"datatable-selection",template:"\n \n ",changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},"7O6V":function(t,e,n){"use strict";t.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},"7aV9":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("si",{months:"\u0da2\u0db1\u0dc0\u0dcf\u0dbb\u0dd2_\u0db4\u0dd9\u0db6\u0dbb\u0dc0\u0dcf\u0dbb\u0dd2_\u0db8\u0dcf\u0dbb\u0dca\u0dad\u0dd4_\u0d85\u0db4\u0dca\u200d\u0dbb\u0dda\u0dbd\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd\u0dc3\u0dca\u0dad\u0dd4_\u0dc3\u0dd0\u0db4\u0dca\u0dad\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0d94\u0d9a\u0dca\u0dad\u0ddd\u0db6\u0dbb\u0dca_\u0db1\u0ddc\u0dc0\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca_\u0daf\u0dd9\u0dc3\u0dd0\u0db8\u0dca\u0db6\u0dbb\u0dca".split("_"),monthsShort:"\u0da2\u0db1_\u0db4\u0dd9\u0db6_\u0db8\u0dcf\u0dbb\u0dca_\u0d85\u0db4\u0dca_\u0db8\u0dd0\u0dba\u0dd2_\u0da2\u0dd6\u0db1\u0dd2_\u0da2\u0dd6\u0dbd\u0dd2_\u0d85\u0d9c\u0ddd_\u0dc3\u0dd0\u0db4\u0dca_\u0d94\u0d9a\u0dca_\u0db1\u0ddc\u0dc0\u0dd0_\u0daf\u0dd9\u0dc3\u0dd0".split("_"),weekdays:"\u0d89\u0dbb\u0dd2\u0daf\u0dcf_\u0dc3\u0db3\u0dd4\u0daf\u0dcf_\u0d85\u0d9f\u0dc4\u0dbb\u0dd4\u0dc0\u0dcf\u0daf\u0dcf_\u0db6\u0daf\u0dcf\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4\u0dc3\u0dca\u0db4\u0dad\u0dd2\u0db1\u0dca\u0daf\u0dcf_\u0dc3\u0dd2\u0d9a\u0dd4\u0dbb\u0dcf\u0daf\u0dcf_\u0dc3\u0dd9\u0db1\u0dc3\u0dd4\u0dbb\u0dcf\u0daf\u0dcf".split("_"),weekdaysShort:"\u0d89\u0dbb\u0dd2_\u0dc3\u0db3\u0dd4_\u0d85\u0d9f_\u0db6\u0daf\u0dcf_\u0db6\u0dca\u200d\u0dbb\u0dc4_\u0dc3\u0dd2\u0d9a\u0dd4_\u0dc3\u0dd9\u0db1".split("_"),weekdaysMin:"\u0d89_\u0dc3_\u0d85_\u0db6_\u0db6\u0dca\u200d\u0dbb_\u0dc3\u0dd2_\u0dc3\u0dd9".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"a h:mm",LTS:"a h:mm:ss",L:"YYYY/MM/DD",LL:"YYYY MMMM D",LLL:"YYYY MMMM D, a h:mm",LLLL:"YYYY MMMM D [\u0dc0\u0dd0\u0db1\u0dd2] dddd, a h:mm:ss"},calendar:{sameDay:"[\u0d85\u0daf] LT[\u0da7]",nextDay:"[\u0dc4\u0dd9\u0da7] LT[\u0da7]",nextWeek:"dddd LT[\u0da7]",lastDay:"[\u0d8a\u0dba\u0dda] LT[\u0da7]",lastWeek:"[\u0db4\u0dc3\u0dd4\u0d9c\u0dd2\u0dba] dddd LT[\u0da7]",sameElse:"L"},relativeTime:{future:"%s\u0d9a\u0dd2\u0db1\u0dca",past:"%s\u0d9a\u0da7 \u0db4\u0dd9\u0dbb",s:"\u0dad\u0dad\u0dca\u0db4\u0dbb \u0d9a\u0dd2\u0dc4\u0dd2\u0db4\u0dba",ss:"\u0dad\u0dad\u0dca\u0db4\u0dbb %d",m:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4\u0dc0",mm:"\u0db8\u0dd2\u0db1\u0dd2\u0dad\u0dca\u0dad\u0dd4 %d",h:"\u0db4\u0dd0\u0dba",hh:"\u0db4\u0dd0\u0dba %d",d:"\u0daf\u0dd2\u0db1\u0dba",dd:"\u0daf\u0dd2\u0db1 %d",M:"\u0db8\u0dcf\u0dc3\u0dba",MM:"\u0db8\u0dcf\u0dc3 %d",y:"\u0dc0\u0dc3\u0dbb",yy:"\u0dc0\u0dc3\u0dbb %d"},dayOfMonthOrdinalParse:/\d{1,2} \u0dc0\u0dd0\u0db1\u0dd2/,ordinal:function(t){return t+" \u0dc0\u0dd0\u0db1\u0dd2"},meridiemParse:/\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4|\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4|\u0db4\u0dd9.\u0dc0|\u0db4.\u0dc0./,isPM:function(t){return"\u0db4.\u0dc0."===t||"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4"===t},meridiem:function(t,e,n){return t>11?n?"\u0db4.\u0dc0.":"\u0db4\u0dc3\u0dca \u0dc0\u0dbb\u0dd4":n?"\u0db4\u0dd9.\u0dc0.":"\u0db4\u0dd9\u0dbb \u0dc0\u0dbb\u0dd4"}})}()},"8/+R":function(t,e,n){!function(t){"use strict";var e={1:"\u0a67",2:"\u0a68",3:"\u0a69",4:"\u0a6a",5:"\u0a6b",6:"\u0a6c",7:"\u0a6d",8:"\u0a6e",9:"\u0a6f",0:"\u0a66"},n={"\u0a67":"1","\u0a68":"2","\u0a69":"3","\u0a6a":"4","\u0a6b":"5","\u0a6c":"6","\u0a6d":"7","\u0a6e":"8","\u0a6f":"9","\u0a66":"0"};t.defineLocale("pa-in",{months:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),monthsShort:"\u0a1c\u0a28\u0a35\u0a30\u0a40_\u0a2b\u0a3c\u0a30\u0a35\u0a30\u0a40_\u0a2e\u0a3e\u0a30\u0a1a_\u0a05\u0a2a\u0a4d\u0a30\u0a48\u0a32_\u0a2e\u0a08_\u0a1c\u0a42\u0a28_\u0a1c\u0a41\u0a32\u0a3e\u0a08_\u0a05\u0a17\u0a38\u0a24_\u0a38\u0a24\u0a70\u0a2c\u0a30_\u0a05\u0a15\u0a24\u0a42\u0a2c\u0a30_\u0a28\u0a35\u0a70\u0a2c\u0a30_\u0a26\u0a38\u0a70\u0a2c\u0a30".split("_"),weekdays:"\u0a10\u0a24\u0a35\u0a3e\u0a30_\u0a38\u0a4b\u0a2e\u0a35\u0a3e\u0a30_\u0a2e\u0a70\u0a17\u0a32\u0a35\u0a3e\u0a30_\u0a2c\u0a41\u0a27\u0a35\u0a3e\u0a30_\u0a35\u0a40\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a41\u0a71\u0a15\u0a30\u0a35\u0a3e\u0a30_\u0a38\u0a3c\u0a28\u0a40\u0a1a\u0a30\u0a35\u0a3e\u0a30".split("_"),weekdaysShort:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),weekdaysMin:"\u0a10\u0a24_\u0a38\u0a4b\u0a2e_\u0a2e\u0a70\u0a17\u0a32_\u0a2c\u0a41\u0a27_\u0a35\u0a40\u0a30_\u0a38\u0a3c\u0a41\u0a15\u0a30_\u0a38\u0a3c\u0a28\u0a40".split("_"),longDateFormat:{LT:"A h:mm \u0a35\u0a1c\u0a47",LTS:"A h:mm:ss \u0a35\u0a1c\u0a47",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47",LLLL:"dddd, D MMMM YYYY, A h:mm \u0a35\u0a1c\u0a47"},calendar:{sameDay:"[\u0a05\u0a1c] LT",nextDay:"[\u0a15\u0a32] LT",nextWeek:"[\u0a05\u0a17\u0a32\u0a3e] dddd, LT",lastDay:"[\u0a15\u0a32] LT",lastWeek:"[\u0a2a\u0a3f\u0a1b\u0a32\u0a47] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0a35\u0a3f\u0a71\u0a1a",past:"%s \u0a2a\u0a3f\u0a1b\u0a32\u0a47",s:"\u0a15\u0a41\u0a1d \u0a38\u0a15\u0a3f\u0a70\u0a1f",ss:"%d \u0a38\u0a15\u0a3f\u0a70\u0a1f",m:"\u0a07\u0a15 \u0a2e\u0a3f\u0a70\u0a1f",mm:"%d \u0a2e\u0a3f\u0a70\u0a1f",h:"\u0a07\u0a71\u0a15 \u0a18\u0a70\u0a1f\u0a3e",hh:"%d \u0a18\u0a70\u0a1f\u0a47",d:"\u0a07\u0a71\u0a15 \u0a26\u0a3f\u0a28",dd:"%d \u0a26\u0a3f\u0a28",M:"\u0a07\u0a71\u0a15 \u0a2e\u0a39\u0a40\u0a28\u0a3e",MM:"%d \u0a2e\u0a39\u0a40\u0a28\u0a47",y:"\u0a07\u0a71\u0a15 \u0a38\u0a3e\u0a32",yy:"%d \u0a38\u0a3e\u0a32"},preparse:function(t){return t.replace(/[\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0a66]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0a30\u0a3e\u0a24|\u0a38\u0a35\u0a47\u0a30|\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30|\u0a38\u0a3c\u0a3e\u0a2e/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0a30\u0a3e\u0a24"===e?t<4?t:t+12:"\u0a38\u0a35\u0a47\u0a30"===e?t:"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30"===e?t>=10?t:t+12:"\u0a38\u0a3c\u0a3e\u0a2e"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"\u0a30\u0a3e\u0a24":t<10?"\u0a38\u0a35\u0a47\u0a30":t<17?"\u0a26\u0a41\u0a2a\u0a39\u0a3f\u0a30":t<20?"\u0a38\u0a3c\u0a3e\u0a2e":"\u0a30\u0a3e\u0a24"},week:{dow:0,doy:6}})}(n("wd/R"))},"8//i":function(t,e,n){"use strict";var a=n("CDJp"),r=n("RDha"),i=n("tjFV"),s=n("g8vO");t.exports=function(t){var e=a.global,n={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:s.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function o(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function u(t){var n=t.options.pointLabels,a=r.valueOrDefault(n.fontSize,e.defaultFontSize),i=r.valueOrDefault(n.fontStyle,e.defaultFontStyle),s=r.valueOrDefault(n.fontFamily,e.defaultFontFamily);return{size:a,style:i,family:s,font:r.fontString(a,i,s)}}function c(t,e,n,a,r){return t===a||t===r?{start:e-n/2,end:e+n/2}:tr?{start:e-n-5,end:e}:{start:e,end:e+n+5}}function l(t){return 0===t||180===t?"center":t<180?"left":"right"}function d(t,e,n,a){if(r.isArray(e))for(var i=n.y,s=1.5*a,o=0;o270||t<90)&&(n.y-=e.h)}function p(t){return r.isNumber(t)?t:0}var h=t.LinearScaleBase.extend({setDimensions:function(){var t=this,n=t.options,a=n.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var i=r.min([t.height,t.width]),s=r.valueOrDefault(a.fontSize,e.defaultFontSize);t.drawingArea=n.display?i/2-(s/2+a.backdropPaddingY):i/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;r.each(e.data.datasets,function(i,s){if(e.isDatasetVisible(s)){var o=e.getDatasetMeta(s);r.each(i.data,function(e,r){var i=+t.getRightValue(e);isNaN(i)||o.data[r].hidden||(n=Math.min(i,n),a=Math.max(i,a))})}}),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=a===Number.NEGATIVE_INFINITY?0:a,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,n=r.valueOrDefault(t.fontSize,e.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*n)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t;this.options.pointLabels.display?function(t){var e,n,a,i=u(t),s=Math.min(t.height/2,t.width/2),l={r:t.width,l:0,t:t.height,b:0},d={};t.ctx.font=i.font,t._pointLabelSizes=[];var f,p,h,g=o(t);for(e=0;el.r&&(l.r=y.end,d.r=b),v.startl.b&&(l.b=v.end,d.b=b)}t.setReductions(s,l,d)}(this):(t=Math.min(this.height/2,this.width/2),this.drawingArea=Math.round(t),this.setCenterPoint(0,0,0,0))},setReductions:function(t,e,n){var a=e.l/Math.sin(n.l),r=Math.max(e.r-this.width,0)/Math.sin(n.r),i=-e.t/Math.cos(n.t),s=-Math.max(e.b-this.height,0)/Math.cos(n.b);a=p(a),r=p(r),i=p(i),s=p(s),this.drawingArea=Math.min(Math.round(t-(a+r)/2),Math.round(t-(i+s)/2)),this.setCenterPoint(a,r,i,s)},setCenterPoint:function(t,e,n,a){var r=this,i=n+r.drawingArea,s=r.height-a-r.drawingArea;r.xCenter=Math.round((t+r.drawingArea+(r.width-e-r.drawingArea))/2+r.left),r.yCenter=Math.round((i+s)/2+r.top)},getIndexAngle:function(t){return t*(2*Math.PI/o(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(n)*e)+this.xCenter,y:Math.round(Math.sin(n)*e)+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0)},draw:function(){var t=this,n=t.options,a=n.gridLines,i=n.ticks,s=r.valueOrDefault;if(n.display){var c=t.ctx,p=this.getIndexAngle(0),h=s(i.fontSize,e.defaultFontSize),g=s(i.fontStyle,e.defaultFontStyle),b=s(i.fontFamily,e.defaultFontFamily),m=r.fontString(h,g,b);r.each(t.ticks,function(n,u){if(u>0||i.reverse){var l=t.getDistanceFromCenterForValue(t.ticksAsNumbers[u]);if(a.display&&0!==u&&function(t,e,n,a){var i=t.ctx;if(i.strokeStyle=r.valueAtIndexOrDefault(e.color,a-1),i.lineWidth=r.valueAtIndexOrDefault(e.lineWidth,a-1),t.options.gridLines.circular)i.beginPath(),i.arc(t.xCenter,t.yCenter,n,0,2*Math.PI),i.closePath(),i.stroke();else{var s=o(t);if(0===s)return;i.beginPath();var u=t.getPointPosition(0,n);i.moveTo(u.x,u.y);for(var c=1;c=0;h--){if(i.display){var g=t.getPointPosition(h,c);n.beginPath(),n.moveTo(t.xCenter,t.yCenter),n.lineTo(g.x,g.y),n.stroke(),n.closePath()}if(s.display){var b=t.getPointPosition(h,c+5),m=r.valueAtIndexOrDefault(s.fontColor,h,e.defaultFontColor);n.font=p.font,n.fillStyle=m;var y=t.getIndexAngle(h),v=r.toDegrees(y);n.textAlign=l(v),f(v,t._pointLabelSizes[h],b),d(n,t.pointLabels[h]||"",b,p.size)}}}(t)}}});i.registerScaleType("radialLinear",h,n)}},"85J/":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){}return t.prototype.transform=function(t){var e=/ceph version\s+([^ ]+)\s+\(.+\)/.exec(t);return e?e[1]:t},t}()},"88/t":function(t,e,n){"use strict";n.r(e);var a=n("DtyJ");n.d(e,"Observable",function(){return a.Observable})},"8TtQ":function(t,e,n){"use strict";var a=n("cdu6"),r=n("tjFV");t.exports=function(){var t=a.extend({getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t,e=this,n=e.getLabels();e.minIndex=0,e.maxIndex=n.length-1,void 0!==e.options.ticks.min&&(t=n.indexOf(e.options.ticks.min),e.minIndex=-1!==t?t:e.minIndex),void 0!==e.options.ticks.max&&(t=n.indexOf(e.options.ticks.max),e.maxIndex=-1!==t?t:e.maxIndex),e.min=n[e.minIndex],e.max=n[e.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,a=n.chart.data,r=n.isHorizontal();return a.yLabels&&!r?n.getRightValue(a.datasets[e].data[t]):n.ticks[t-n.minIndex]},getPixelForValue:function(t,e){var n,a=this,r=a.options.offset,i=Math.max(a.maxIndex+1-a.minIndex-(r?0:1),1);if(null!=t&&(n=a.isHorizontal()?t.x:t.y),void 0!==n||void 0!==t&&isNaN(e)){var s=a.getLabels().indexOf(t=n||t);e=-1!==s?s:e}if(a.isHorizontal()){var o=a.width/i,u=o*(e-a.minIndex);return r&&(u+=o/2),a.left+Math.round(u)}var c=a.height/i,l=c*(e-a.minIndex);return r&&(l+=c/2),a.top+Math.round(l)},getPixelForTick:function(t){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null)},getValueForPixel:function(t){var e=this,n=e.options.offset,a=Math.max(e._ticks.length-(n?0:1),1),r=e.isHorizontal(),i=(r?e.width:e.height)/a;return t-=r?e.left:e.top,n&&(t-=i/2),(t<=0?0:Math.round(t/i))+e.minIndex},getBasePixel:function(){return this.bottom}});r.registerScaleType("category",t,{position:"bottom"})}},"8g8A":function(t,e,n){"use strict";function a(){return Error.call(this),this.message="object unsubscribed",this.name="ObjectUnsubscribedError",this}n.d(e,"a",function(){return r}),a.prototype=Object.create(Error.prototype);var r=a},"8iEZ":function(t,e,n){var a=n("mrSG").__decorate;Object.defineProperty(e,"__esModule",{value:!0});var r=n("CcnG");e.DataTableColumnCellDirective=function(){return a([r.Directive({selector:"[ngx-datatable-cell-template]"})],function(t){this.template=t})}()},"8mBD":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("pt",{months:"Janeiro_Fevereiro_Mar\xe7o_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"h\xe1 %s",s:"segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}()},"8xTl":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("LvDl"),r=function(){function t(){}return t.prototype.transform=function(t){return a.upperFirst(t)},t}()},"909l":function(t,e,n){"use strict";n.d(e,"b",function(){return l}),n.d(e,"a",function(){return d});var a=n("mrSG"),r=n("IUTb"),i=n("isby"),s=n("FFOo"),o=n("MGBS"),u=n("zotm"),c=n("En8+");function l(){for(var t=[],e=0;ethis.index},t.prototype.hasCompleted=function(){return this.array.length===this.index},t}(),g=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.parent=n,r.observable=a,r.stillUnsubscribed=!0,r.buffer=[],r.isComplete=!1,r}return a.__extends(e,t),e.prototype[c.a]=function(){return this},e.prototype.next=function(){var t=this.buffer;return 0===t.length&&this.isComplete?{value:null,done:!0}:{value:t.shift(),done:!1}},e.prototype.hasValue=function(){return this.buffer.length>0},e.prototype.hasCompleted=function(){return 0===this.buffer.length&&this.isComplete},e.prototype.notifyComplete=function(){this.buffer.length>0?(this.isComplete=!0,this.parent.notifyInactive()):this.destination.complete()},e.prototype.notifyNext=function(t,e,n,a,r){this.buffer.push(e),this.parent.checkIterators()},e.prototype.subscribe=function(t,e){return Object(u.a)(this,this.observable,this,e)},e}(o.a)},"99TG":function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("Fjl2");e.DatatableGroupHeaderDirective=function(){function t(){this.rowHeight=0,this.toggle=new i.EventEmitter}return t.prototype.toggleExpandGroup=function(t){this.toggle.emit({type:"group",value:t})},t.prototype.expandAllGroups=function(){this.toggle.emit({type:"all",value:!0})},t.prototype.collapseAllGroups=function(){this.toggle.emit({type:"all",value:!1})},a([i.Input(),r("design:type",Object)],t.prototype,"rowHeight",void 0),a([i.Input(),i.ContentChild(s.DatatableGroupHeaderTemplateDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"template",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"toggle",void 0),a([i.Directive({selector:"ngx-datatable-group-header"})],t)}()},"9GXa":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){this.title="Warning"}}()},"9Kw/":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(t){this.i18n=t,this.title=this.i18n("Information")}}()},"9Xeq":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},"9Z1F":function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("mrSG"),r=n("MGBS"),i=n("rPjj"),s=n("zotm");function o(t){return function(e){var n=new u(t),a=e.lift(n);return n.caught=a}}var u=function(){function t(t){this.selector=t}return t.prototype.call=function(t,e){return e.subscribe(new c(t,this.selector,this.caught))},t}(),c=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.selector=n,r.caught=a,r}return a.__extends(e,t),e.prototype.error=function(e){if(!this.isStopped){var n=void 0;try{n=this.selector(e,this.caught)}catch(r){return void t.prototype.error.call(this,r)}this._unsubscribeAndRecycle();var a=new i.a(this,void 0,void 0);this.add(a),Object(s.a)(this,n,void 0,void 0,a)}},e}(r.a)},"9nlD":function(t,e,n){"use strict";n.d(e,"a",function(){return d});var a=n("LvDl"),r=n("26FU"),i=n("mtw6"),s=n("G1I9"),o=n("a0VL"),u=n("ufoC"),c=n("CcnG"),l=n("SZbH"),d=function(){function t(t,e,n){this.toastr=t,this.taskMessageService=e,this.cdDatePipe=n,this.hideToasties=!1,this.dataSource=new r.a([]),this.data$=this.dataSource.asObservable(),this.queued=[],this.KEY="cdNotifications";var i=localStorage.getItem(this.KEY),o=[];a.isString(i)&&(o=JSON.parse(i,function(t,e){return a.isPlainObject(e)?a.assign(new s.a,e):e})),this.dataSource.next(o)}return t.prototype.removeAll=function(){localStorage.removeItem(this.KEY),this.dataSource.next([])},t.prototype.save=function(t){var e=this.dataSource.getValue();for(e.push(t);e.length>10;)e.shift();this.dataSource.next(e),localStorage.setItem(this.KEY,JSON.stringify(e))},t.prototype.show=function(t,e,n,r,i){var o=this;return window.setTimeout(function(){var u;u=a.isFunction(t)?t():a.isObject(t)?t:new s.b(t,e,n,r,i),o.queueToShow(u)},10)},t.prototype.queueToShow=function(t){var e=this;this.cancel(this.queuedTimeoutId),this.queued.find(function(e){return a.isEqual(e,t)})||this.queued.push(t),this.queuedTimeoutId=window.setTimeout(function(){e.showQueued()},500)},t.prototype.showQueued=function(){var t=this;this.getUnifiedTitleQueue().forEach(function(e){var n=new s.a(e);t.save(n),t.showToasty(n)})},t.prototype.getUnifiedTitleQueue=function(){return Object.values(this.queueShiftByTitle()).map(function(t){var e=t[0];return t.length>1&&(e.message="
    "+t.map(function(t){return"
  • "+t.message+"
  • "}).join("")+"
"),e})},t.prototype.queueShiftByTitle=function(){for(var t,e={};t=this.queued.shift();)e[t.title]||(e[t.title]=[]),e[t.title].push(t);return e},t.prototype.showToasty=function(t){this.hideToasties||this.toastr[["error","info","success"][t.type]]((t.message?t.message+"
":"")+this.renderTimeAndApplicationHtml(t),t.title,t.options)},t.prototype.renderTimeAndApplicationHtml=function(t){return''+this.cdDatePipe.transform(t.timestamp)+''},t.prototype.notifyTask=function(t,e){var n;return void 0===e&&(e=!0),n=t.success&&e?new s.b(i.a.success,this.taskMessageService.getSuccessTitle(t)):new s.b(i.a.error,this.taskMessageService.getErrorTitle(t),this.taskMessageService.getErrorMessage(t)),this.show(n)},t.prototype.cancel=function(t){window.clearTimeout(t)},t.prototype.suspendToasties=function(t){this.hideToasties=t},t.ngInjectableDef=c.defineInjectable({factory:function(){return new t(c.inject(l.j),c.inject(u.a),c.inject(o.a))},token:t,providedIn:"root"}),t}()},"9rRi":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("gd",{months:["Am Faoilleach","An Gearran","Am M\xe0rt","An Giblean","An C\xe8itean","An t-\xd2gmhios","An t-Iuchar","An L\xf9nastal","An t-Sultain","An D\xe0mhair","An t-Samhain","An D\xf9bhlachd"],monthsShort:["Faoi","Gear","M\xe0rt","Gibl","C\xe8it","\xd2gmh","Iuch","L\xf9n","Sult","D\xe0mh","Samh","D\xf9bh"],monthsParseExact:!0,weekdays:["Did\xf2mhnaich","Diluain","Dim\xe0irt","Diciadain","Diardaoin","Dihaoine","Disathairne"],weekdaysShort:["Did","Dil","Dim","Dic","Dia","Dih","Dis"],weekdaysMin:["D\xf2","Lu","M\xe0","Ci","Ar","Ha","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[An-diugh aig] LT",nextDay:"[A-m\xe0ireach aig] LT",nextWeek:"dddd [aig] LT",lastDay:"[An-d\xe8 aig] LT",lastWeek:"dddd [seo chaidh] [aig] LT",sameElse:"L"},relativeTime:{future:"ann an %s",past:"bho chionn %s",s:"beagan diogan",ss:"%d diogan",m:"mionaid",mm:"%d mionaidean",h:"uair",hh:"%d uairean",d:"latha",dd:"%d latha",M:"m\xecos",MM:"%d m\xecosan",y:"bliadhna",yy:"%d bliadhna"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(t){return t+(1===t?"d":t%10==2?"na":"mh")},week:{dow:1,doy:4}})}()},"A+xa":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("cv",{months:"\u043a\u04d1\u0440\u043b\u0430\u0447_\u043d\u0430\u0440\u04d1\u0441_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440\u0442\u043c\u0435_\u0443\u0442\u04d1_\u04ab\u0443\u0440\u043b\u0430_\u0430\u0432\u04d1\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448\u0442\u0430\u0432".split("_"),monthsShort:"\u043a\u04d1\u0440_\u043d\u0430\u0440_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u04ab\u04d7\u0440_\u0443\u0442\u04d1_\u04ab\u0443\u0440_\u0430\u0432\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448".split("_"),weekdays:"\u0432\u044b\u0440\u0441\u0430\u0440\u043d\u0438\u043a\u0443\u043d_\u0442\u0443\u043d\u0442\u0438\u043a\u0443\u043d_\u044b\u0442\u043b\u0430\u0440\u0438\u043a\u0443\u043d_\u044e\u043d\u043a\u0443\u043d_\u043a\u04d7\u04ab\u043d\u0435\u0440\u043d\u0438\u043a\u0443\u043d_\u044d\u0440\u043d\u0435\u043a\u0443\u043d_\u0448\u04d1\u043c\u0430\u0442\u043a\u0443\u043d".split("_"),weekdaysShort:"\u0432\u044b\u0440_\u0442\u0443\u043d_\u044b\u0442\u043b_\u044e\u043d_\u043a\u04d7\u04ab_\u044d\u0440\u043d_\u0448\u04d1\u043c".split("_"),weekdaysMin:"\u0432\u0440_\u0442\u043d_\u044b\u0442_\u044e\u043d_\u043a\u04ab_\u044d\u0440_\u0448\u043c".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7]",LLL:"YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm",LLLL:"dddd, YYYY [\u04ab\u0443\u043b\u0445\u0438] MMMM [\u0443\u0439\u04d1\u0445\u04d7\u043d] D[-\u043c\u04d7\u0448\u04d7], HH:mm"},calendar:{sameDay:"[\u041f\u0430\u044f\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextDay:"[\u042b\u0440\u0430\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastDay:"[\u04d6\u043d\u0435\u0440] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextWeek:"[\u04aa\u0438\u0442\u0435\u0441] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastWeek:"[\u0418\u0440\u0442\u043d\u04d7] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",sameElse:"L"},relativeTime:{future:function(t){return t+(/\u0441\u0435\u0445\u0435\u0442$/i.exec(t)?"\u0440\u0435\u043d":/\u04ab\u0443\u043b$/i.exec(t)?"\u0442\u0430\u043d":"\u0440\u0430\u043d")},past:"%s \u043a\u0430\u044f\u043b\u043b\u0430",s:"\u043f\u04d7\u0440-\u0438\u043a \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",ss:"%d \u04ab\u0435\u043a\u043a\u0443\u043d\u0442",m:"\u043f\u04d7\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u043f\u04d7\u0440 \u0441\u0435\u0445\u0435\u0442",hh:"%d \u0441\u0435\u0445\u0435\u0442",d:"\u043f\u04d7\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u043f\u04d7\u0440 \u0443\u0439\u04d1\u0445",MM:"%d \u0443\u0439\u04d1\u0445",y:"\u043f\u04d7\u0440 \u04ab\u0443\u043b",yy:"%d \u04ab\u0443\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-\u043c\u04d7\u0448/,ordinal:"%d-\u043c\u04d7\u0448",week:{dow:1,doy:7}})}()},A5uo:function(t,e,n){"use strict";var a=n("K2E3");e=t.exports=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),Object.defineProperty(e.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(e.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})},ANnk:function(t,e,n){"use strict";n.d(e,"a",function(){return a}),n("aexS"),n("f/UV");var a=function(){function t(t,e,n){this.formScope=t,this.authStorageService=e,this.elementRef=n}return t.prototype.ngAfterViewInit=function(){this.permissions=this.authStorageService.getPermissions(),null!==this.formScope&&(this.service_name=this.formScope.cdFormScope),this.service_name&&!this.permissions[this.service_name].update&&(this.elementRef.nativeElement.disabled=!0)},t}()},AQ68:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("uz-latn",{months:"Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr".split("_"),monthsShort:"Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek".split("_"),weekdays:"Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba".split("_"),weekdaysShort:"Yak_Dush_Sesh_Chor_Pay_Jum_Shan".split("_"),weekdaysMin:"Ya_Du_Se_Cho_Pa_Ju_Sha".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Bugun soat] LT [da]",nextDay:"[Ertaga] LT [da]",nextWeek:"dddd [kuni soat] LT [da]",lastDay:"[Kecha soat] LT [da]",lastWeek:"[O'tgan] dddd [kuni soat] LT [da]",sameElse:"L"},relativeTime:{future:"Yaqin %s ichida",past:"Bir necha %s oldin",s:"soniya",ss:"%d soniya",m:"bir daqiqa",mm:"%d daqiqa",h:"bir soat",hh:"%d soat",d:"bir kun",dd:"%d kun",M:"bir oy",MM:"%d oy",y:"bir yil",yy:"%d yil"},week:{dow:1,doy:7}})}()},ARl4:function(t,e,n){"use strict";n.d(e,"a",function(){return h}),n.d(e,"b",function(){return z}),n.d(e,"c",function(){return G}),n.d(e,"d",function(){return Y}),n.d(e,"e",function(){return V}),n.d(e,"f",function(){return H}),n.d(e,"g",function(){return at}),n.d(e,"h",function(){return B}),n.d(e,"i",function(){return U}),n.d(e,"j",function(){return m}),n.d(e,"k",function(){return ot}),n.d(e,"l",function(){return it}),n.d(e,"m",function(){return st}),n.d(e,"n",function(){return dt}),n.d(e,"o",function(){return ut}),n.d(e,"p",function(){return ct}),n.d(e,"q",function(){return lt}),n.d(e,"r",function(){return F}),n.d(e,"s",function(){return y}),n.d(e,"t",function(){return b}),n.d(e,"u",function(){return Z}),n.d(e,"v",function(){return K}),n.d(e,"w",function(){return J}),n.d(e,"x",function(){return et}),n.d(e,"y",function(){return W}),n.d(e,"z",function(){return Q}),n.d(e,"A",function(){return tt}),n.d(e,"B",function(){return nt}),n.d(e,"C",function(){return $});var a=n("CcnG"),r=n("mrSG"),i=n("VnD/"),s=n("67Y/"),o=n("t9fZ"),u=n("lHUG"),c=n("26FU"),l=n("MwfX"),d=n("NJnL"),f=(n("ihYY"),n("lqqz")),p=(n("gIcY"),n("rpEJ")),h=function(){return function(){this.adaptivePosition=!1,this.isAnimated=!1,this.containerClass="theme-green",this.displayMonths=1,this.showWeekNumbers=!0,this.dateInputFormat="L",this.rangeSeparator=" - ",this.rangeInputFormat="L",this.monthTitle="MMMM",this.yearTitle="YYYY",this.dayLabel="D",this.monthLabel="MMMM",this.yearLabel="YYYY",this.weekNumbers="w"}}(),g=function(){function t(){this._customRangesFish=[]}return Object.defineProperty(t.prototype,"minDate",{set:function(t){this._effects.setMinDate(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"maxDate",{set:function(t){this._effects.setMaxDate(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"daysDisabled",{set:function(t){this._effects.setDaysDisabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"datesDisabled",{set:function(t){this._effects.setDatesDisabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isDisabled",{set:function(t){this._effects.setDisabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"dateCustomClasses",{set:function(t){this._effects.setDateCustomClasses(t)},enumerable:!0,configurable:!0}),t.prototype.setViewMode=function(t){},t.prototype.navigateTo=function(t){},t.prototype.dayHoverHandler=function(t){},t.prototype.weekHoverHandler=function(t){},t.prototype.monthHoverHandler=function(t){},t.prototype.yearHoverHandler=function(t){},t.prototype.daySelectHandler=function(t){},t.prototype.monthSelectHandler=function(t){},t.prototype.yearSelectHandler=function(t){},t.prototype._stopPropagation=function(t){t.stopPropagation()},t}(),b=function(){function t(){}return t.prototype.calculate=function(){return{type:t.CALCULATE}},t.prototype.format=function(){return{type:t.FORMAT}},t.prototype.flag=function(){return{type:t.FLAG}},t.prototype.select=function(e){return{type:t.SELECT,payload:e}},t.prototype.changeViewMode=function(e){return{type:t.CHANGE_VIEWMODE,payload:e}},t.prototype.navigateTo=function(e){return{type:t.NAVIGATE_TO,payload:e}},t.prototype.navigateStep=function(e){return{type:t.NAVIGATE_OFFSET,payload:e}},t.prototype.setOptions=function(e){return{type:t.SET_OPTIONS,payload:e}},t.prototype.selectRange=function(e){return{type:t.SELECT_RANGE,payload:e}},t.prototype.hoverDay=function(e){return{type:t.HOVER,payload:e.isHovered?e.cell.date:null}},t.prototype.minDate=function(e){return{type:t.SET_MIN_DATE,payload:e}},t.prototype.maxDate=function(e){return{type:t.SET_MAX_DATE,payload:e}},t.prototype.daysDisabled=function(e){return{type:t.SET_DAYSDISABLED,payload:e}},t.prototype.datesDisabled=function(e){return{type:t.SET_DATESDISABLED,payload:e}},t.prototype.isDisabled=function(e){return{type:t.SET_IS_DISABLED,payload:e}},t.prototype.setDateCustomClasses=function(e){return{type:t.SET_DATE_CUSTOM_CLASSES,payload:e}},t.prototype.setLocale=function(e){return{type:t.SET_LOCALE,payload:e}},t.CALCULATE="[datepicker] calculate dates matrix",t.FORMAT="[datepicker] format datepicker values",t.FLAG="[datepicker] set flags",t.SELECT="[datepicker] select date",t.NAVIGATE_OFFSET="[datepicker] shift view date",t.NAVIGATE_TO="[datepicker] change view date",t.SET_OPTIONS="[datepicker] update render options",t.HOVER="[datepicker] hover date",t.CHANGE_VIEWMODE="[datepicker] switch view mode",t.SET_MIN_DATE="[datepicker] set min date",t.SET_MAX_DATE="[datepicker] set max date",t.SET_DAYSDISABLED="[datepicker] set days disabled",t.SET_DATESDISABLED="[datepicker] set dates disabled",t.SET_IS_DISABLED="[datepicker] set is disabled",t.SET_DATE_CUSTOM_CLASSES="[datepicker] set date custom classes",t.SET_LOCALE="[datepicker] set datepicker locale",t.SELECT_RANGE="[daterangepicker] select dates range",t}(),m=function(){function t(){this._defaultLocale="en",this._locale=new c.a(this._defaultLocale),this._localeChange=this._locale.asObservable()}return Object.defineProperty(t.prototype,"locale",{get:function(){return this._locale},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localeChange",{get:function(){return this._localeChange},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"currentLocale",{get:function(){return this._locale.getValue()},enumerable:!0,configurable:!0}),t.prototype.use=function(t){t!==this.currentLocale&&this._locale.next(t)},t}(),y=function(){function t(t,e){this._actions=t,this._localeService=e,this._subs=[]}return t.prototype.init=function(t){return this._store=t,this},t.prototype.setValue=function(t){this._store.dispatch(this._actions.select(t))},t.prototype.setRangeValue=function(t){this._store.dispatch(this._actions.selectRange(t))},t.prototype.setMinDate=function(t){return this._store.dispatch(this._actions.minDate(t)),this},t.prototype.setMaxDate=function(t){return this._store.dispatch(this._actions.maxDate(t)),this},t.prototype.setDaysDisabled=function(t){return this._store.dispatch(this._actions.daysDisabled(t)),this},t.prototype.setDatesDisabled=function(t){return this._store.dispatch(this._actions.datesDisabled(t)),this},t.prototype.setDisabled=function(t){return this._store.dispatch(this._actions.isDisabled(t)),this},t.prototype.setDateCustomClasses=function(t){return this._store.dispatch(this._actions.setDateCustomClasses(t)),this},t.prototype.setOptions=function(t){var e=Object.assign({locale:this._localeService.currentLocale},t);return this._store.dispatch(this._actions.setOptions(e)),this},t.prototype.setBindings=function(t){return t.daysCalendar=this._store.select(function(t){return t.flaggedMonths}).pipe(Object(i.a)(function(t){return!!t})),t.monthsCalendar=this._store.select(function(t){return t.flaggedMonthsCalendar}).pipe(Object(i.a)(function(t){return!!t})),t.yearsCalendar=this._store.select(function(t){return t.yearsCalendarFlagged}).pipe(Object(i.a)(function(t){return!!t})),t.viewMode=this._store.select(function(t){return t.view.mode}),t.options=this._store.select(function(t){return t.showWeekNumbers}).pipe(Object(s.a)(function(t){return{showWeekNumbers:t}})),this},t.prototype.setEventHandlers=function(t){var e=this;return t.setViewMode=function(t){e._store.dispatch(e._actions.changeViewMode(t))},t.navigateTo=function(t){e._store.dispatch(e._actions.navigateStep(t.step))},t.dayHoverHandler=function(t){var n=t.cell;n.isOtherMonth||n.isDisabled||(e._store.dispatch(e._actions.hoverDay(t)),n.isHovered=t.isHovered)},t.monthHoverHandler=function(t){t.cell.isHovered=t.isHovered},t.yearHoverHandler=function(t){t.cell.isHovered=t.isHovered},t.monthSelectHandler=function(t){t.isDisabled||e._store.dispatch(e._actions.navigateTo({unit:{month:Object(u.l)(t.date),year:Object(u.j)(t.date)},viewMode:"day"}))},t.yearSelectHandler=function(t){t.isDisabled||e._store.dispatch(e._actions.navigateTo({unit:{year:Object(u.j)(t.date)},viewMode:"month"}))},this},t.prototype.registerDatepickerSideEffects=function(){var t=this;return this._subs.push(this._store.select(function(t){return t.view}).subscribe(function(e){t._store.dispatch(t._actions.calculate())})),this._subs.push(this._store.select(function(t){return t.monthsModel}).pipe(Object(i.a)(function(t){return!!t})).subscribe(function(e){return t._store.dispatch(t._actions.format())})),this._subs.push(this._store.select(function(t){return t.formattedMonths}).pipe(Object(i.a)(function(t){return!!t})).subscribe(function(e){return t._store.dispatch(t._actions.flag())})),this._subs.push(this._store.select(function(t){return t.selectedDate}).pipe(Object(i.a)(function(t){return!!t})).subscribe(function(e){return t._store.dispatch(t._actions.flag())})),this._subs.push(this._store.select(function(t){return t.selectedRange}).pipe(Object(i.a)(function(t){return!!t})).subscribe(function(e){return t._store.dispatch(t._actions.flag())})),this._subs.push(this._store.select(function(t){return t.monthsCalendar}).subscribe(function(){return t._store.dispatch(t._actions.flag())})),this._subs.push(this._store.select(function(t){return t.yearsCalendarModel}).pipe(Object(i.a)(function(t){return!!t})).subscribe(function(){return t._store.dispatch(t._actions.flag())})),this._subs.push(this._store.select(function(t){return t.hoveredDate}).pipe(Object(i.a)(function(t){return!!t})).subscribe(function(e){return t._store.dispatch(t._actions.flag())})),this._subs.push(this._store.select(function(t){return t.dateCustomClasses}).pipe(Object(i.a)(function(t){return!!t})).subscribe(function(e){return t._store.dispatch(t._actions.flag())})),this._subs.push(this._localeService.localeChange.subscribe(function(e){return t._store.dispatch(t._actions.setLocale(e))})),this},t.prototype.destroy=function(){var t,e;try{for(var n=Object(r.__values)(this._subs),a=n.next();!a.done;a=n.next())a.value.unsubscribe()}catch(i){t={error:i}}finally{try{a&&!a.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}},t}(),v={date:new Date,mode:"day"},_=Object.assign(new h,{locale:"en",view:v,selectedRange:[],monthViewOptions:{width:7,height:6}});function x(t,e,n){var a=e&&Object(u.p)(Object(u.d)(t,"month"),e,"day"),r=n&&Object(u.n)(Object(u.G)(t,"month"),n,"day");return a||r}function T(t,e,n){var a=e&&Object(u.p)(Object(u.d)(t,"year"),e,"day"),r=n&&Object(u.n)(Object(u.G)(t,"year"),n,"day");return a||r}function w(t,e){for(var n=t.initialDate,a=new Array(t.height),r=0;r=e}var I=4,C=3,k={month:1};function N(t,e){var n=Object(u.G)(t,"year");return{months:w({width:C,height:I,initialDate:n,shift:k},function(t){return{date:t,label:Object(u.f)(t,e.monthLabel,e.locale)}}),monthTitle:"",yearTitle:Object(u.f)(t,e.yearTitle,e.locale)}}var R=4,A=4,D=R*A,E=-1*(Math.floor(D/2)-1),L={year:1};function P(t,e){var n=Object(u.F)(t,{year:E}),a=w({width:A,height:R,initialDate:n,shift:L},function(t){return{date:t,label:Object(u.f)(t,e.yearLabel,e.locale)}});return{years:a,monthTitle:"",yearTitle:function(t,e){return Object(u.f)(t[0][0].date,e.yearTitle,e.locale)+" - "+Object(u.f)(t[R-1][A-1].date,e.yearTitle,e.locale)}(a,e)}}function M(t,e){switch(void 0===t&&(t=_),e.type){case b.CALCULATE:return function(t){var e,n,a,r,i=t.displayMonths,s=t.view.date;if("day"===t.view.mode){t.monthViewOptions.firstDayOfWeek=Object(u.k)(t.locale).firstDayOfWeek();for(var o=new Array(i),c=0;ce[0]&&t<=e[1]:!!n&&t>e[0]&&t<=n)}(a.date,e.selectedRange,e.hoveredDate),h=e.isDisabled||Object(u.p)(a.date,e.minDate,"day")||Object(u.n)(a.date,e.maxDate,"day")||Object(u.s)(a.date,e.daysDisabled)||(i=a.date,!(void 0===(s=e.datesDisabled)||!s||!s.length)&&s.some(function(t){return Object(u.u)(i,t,"date")})),g=new Date,b=!o&&Object(u.v)(a.date,g),m=e.dateCustomClasses&&e.dateCustomClasses.map(function(t){return Object(u.v)(a.date,t.date)?t.classes:[]}).reduce(function(t,e){return t.concat(e)},[]).join(" ")||"",y=Object.assign({},a,{isOtherMonth:o,isHovered:c,isSelected:f,isSelectionStart:l,isSelectionEnd:d,isInRange:p,isDisabled:h,isToday:b,customClasses:m});a.isOtherMonth===y.isOtherMonth&&a.isHovered===y.isHovered&&a.isSelected===y.isSelected&&a.isSelectionStart===y.isSelectionStart&&a.isSelectionEnd===y.isSelectionEnd&&a.isDisabled===y.isDisabled&&a.isInRange===y.isInRange&&a.customClasses===y.customClasses||(n.days[r]=y)})}),t.hideLeftArrow=e.isDisabled||e.monthIndex>0&&e.monthIndex!==e.displayMonths,t.hideRightArrow=e.isDisabled||e.monthIndex0&&r.monthIndex!==r.displayMonths,a.hideRightArrow=r.monthIndex0&&e.yearIndex!==e.displayMonths,t.hideRightArrow=e.yearIndex=this._rangeStack[0]?[this._rangeStack[0],t.date]:[t.date]),0===this._rangeStack.length&&(this._rangeStack=[t.date]),this._store.dispatch(this._actions.selectRange(this._rangeStack)),2===this._rangeStack.length&&(this._rangeStack=[]))},e.prototype.ngOnDestroy=function(){var t,e;try{for(var n=Object(r.__values)(this._subs),a=n.next();!a.done;a=n.next())a.value.unsubscribe()}catch(i){t={error:i}}finally{try{a&&!a.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}this._effects.destroy()},e}(g),W=function(){return function(){}}(),K=function(){return function(){}}(),$=function(){return function(){}}(),Z=function(){function t(t,e,n){this._config=t,this._elRef=e,this._renderer=n}return t.prototype.ngOnInit=function(){var t=this;this.day.isToday&&this._config&&this._config.customTodayClass&&this._renderer.addClass(this._elRef.nativeElement,this._config.customTodayClass),"string"==typeof this.day.customClasses&&this.day.customClasses.split(" ").filter(function(t){return t}).forEach(function(e){t._renderer.addClass(t._elRef.nativeElement,e)})},t}(),X=function(){var t={UP:0,DOWN:1};return t[t.UP]="UP",t[t.DOWN]="DOWN",t}(),J=function(){function t(){this.onNavigate=new a.EventEmitter,this.onViewMode=new a.EventEmitter}return t.prototype.navTo=function(t){this.onNavigate.emit(t?X.DOWN:X.UP)},t.prototype.view=function(t){this.onViewMode.emit(t)},t}(),Q=function(){function t(t){this._config=t,this.onNavigate=new a.EventEmitter,this.onViewMode=new a.EventEmitter,this.onSelect=new a.EventEmitter,this.onHover=new a.EventEmitter,this.onHoverWeek=new a.EventEmitter}return t.prototype.navigateTo=function(t){this.onNavigate.emit({step:{month:X.DOWN===t?-1:1}})},t.prototype.changeViewMode=function(t){this.onViewMode.emit(t)},t.prototype.selectDay=function(t){this.onSelect.emit(t)},t.prototype.selectWeek=function(t){var e=this;if(this._config.selectWeek)if(t.days&&t.days[0]&&!t.days[0].isDisabled&&this._config.selectFromOtherMonth)this.onSelect.emit(t.days[0]);else if(0!==t.days.length){var n=t.days.find(function(t){return e._config.selectFromOtherMonth?!t.isDisabled:!t.isOtherMonth&&!t.isDisabled});this.onSelect.emit(n)}},t.prototype.weekHoverHandler=function(t,e){var n=this;this._config.selectWeek&&t.days.find(function(t){return n._config.selectFromOtherMonth?!t.isDisabled:!t.isOtherMonth&&!t.isDisabled})&&(t.isHovered=e,this.isWeekHovered=e,this.onHoverWeek.emit(t))},t.prototype.hoverDay=function(t,e){this._config.selectFromOtherMonth&&t.isOtherMonth&&(t.isOtherMonthHovered=e),this.onHover.emit({cell:t,isHovered:e})},t}(),tt=function(){function t(){this.onNavigate=new a.EventEmitter,this.onViewMode=new a.EventEmitter,this.onSelect=new a.EventEmitter,this.onHover=new a.EventEmitter}return t.prototype.navigateTo=function(t){this.onNavigate.emit({step:{year:X.DOWN===t?-1:1}})},t.prototype.viewMonth=function(t){this.onSelect.emit(t)},t.prototype.hoverMonth=function(t,e){this.onHover.emit({cell:t,isHovered:e})},t.prototype.changeViewMode=function(t){this.onViewMode.emit(t)},t}(),et=function(){return function(){this.ampm="ok",this.hours=0,this.minutes=0}}(),nt=function(){function t(){this.onNavigate=new a.EventEmitter,this.onViewMode=new a.EventEmitter,this.onSelect=new a.EventEmitter,this.onHover=new a.EventEmitter}return t.prototype.navigateTo=function(t){this.onNavigate.emit({step:{year:(X.DOWN===t?-1:1)*D}})},t.prototype.viewYear=function(t){this.onSelect.emit(t)},t.prototype.hoverYear=function(t,e){this.onHover.emit({cell:t,isHovered:e})},t.prototype.changeViewMode=function(t){this.onViewMode.emit(t)},t}(),at=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[f.a,d.a,F,b,h,B,Y,y,m]}},t}(),rt=function(){function t(){}return t.prototype.format=function(t,e,n){return Object(u.f)(t,e,n)},t}(),it=function(){function t(){this.selectionDone=new a.EventEmitter(void 0),this.update=new a.EventEmitter(!1),this.activeDateChange=new a.EventEmitter(void 0),this.stepDay={},this.stepMonth={},this.stepYear={},this.modes=["day","month","year"],this.dateFormatter=new rt}return Object.defineProperty(t.prototype,"activeDate",{get:function(){return this._activeDate},set:function(t){this._activeDate=t},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){this.uniqueId="datepicker--"+Math.floor(1e4*Math.random()),this.initDate?(this.activeDate=this.initDate,this.selectedDate=new Date(this.activeDate.valueOf()),this.update.emit(this.activeDate)):void 0===this.activeDate&&(this.activeDate=new Date)},t.prototype.ngOnChanges=function(t){this.refreshView(),this.checkIfActiveDateGotUpdated(t.activeDate)},t.prototype.checkIfActiveDateGotUpdated=function(t){if(t&&!t.firstChange){var e=t.previousValue;e&&e instanceof Date&&e.getTime()!==t.currentValue.getTime()&&this.activeDateChange.emit(this.activeDate)}},t.prototype.setCompareHandler=function(t,e){"day"===e&&(this.compareHandlerDay=t),"month"===e&&(this.compareHandlerMonth=t),"year"===e&&(this.compareHandlerYear=t)},t.prototype.compare=function(t,e){if(void 0!==t&&void 0!==e)return"day"===this.datepickerMode&&this.compareHandlerDay?this.compareHandlerDay(t,e):"month"===this.datepickerMode&&this.compareHandlerMonth?this.compareHandlerMonth(t,e):"year"===this.datepickerMode&&this.compareHandlerYear?this.compareHandlerYear(t,e):void 0},t.prototype.setRefreshViewHandler=function(t,e){"day"===e&&(this.refreshViewHandlerDay=t),"month"===e&&(this.refreshViewHandlerMonth=t),"year"===e&&(this.refreshViewHandlerYear=t)},t.prototype.refreshView=function(){"day"===this.datepickerMode&&this.refreshViewHandlerDay&&this.refreshViewHandlerDay(),"month"===this.datepickerMode&&this.refreshViewHandlerMonth&&this.refreshViewHandlerMonth(),"year"===this.datepickerMode&&this.refreshViewHandlerYear&&this.refreshViewHandlerYear()},t.prototype.dateFilter=function(t,e){return this.dateFormatter.format(t,e,this.locale)},t.prototype.isActive=function(t){return 0===this.compare(t.date,this.activeDate)&&(this.activeDateId=t.uid,!0)},t.prototype.createDateObject=function(t,e){var n={};return n.date=new Date(t.getFullYear(),t.getMonth(),t.getDate()),n.date=this.fixTimeZone(n.date),n.label=this.dateFilter(t,e),n.selected=0===this.compare(t,this.selectedDate),n.disabled=this.isDisabled(t),n.current=0===this.compare(t,new Date),n.customClass=this.getCustomClassForDate(n.date),n},t.prototype.split=function(t,e){for(var n=[];t.length>0;)n.push(t.splice(0,e));return n},t.prototype.fixTimeZone=function(t){var e=t.getHours();return new Date(t.getFullYear(),t.getMonth(),t.getDate(),23===e?e+2:0)},t.prototype.select=function(t,e){void 0===e&&(e=!0),this.datepickerMode===this.minMode?(this.activeDate||(this.activeDate=new Date(0,0,0,0,0,0,0)),this.activeDate=new Date(t.getFullYear(),t.getMonth(),t.getDate()),this.activeDate=this.fixTimeZone(this.activeDate),e&&this.selectionDone.emit(this.activeDate)):(this.activeDate=new Date(t.getFullYear(),t.getMonth(),t.getDate()),this.activeDate=this.fixTimeZone(this.activeDate),e&&(this.datepickerMode=this.modes[this.modes.indexOf(this.datepickerMode)-1])),this.selectedDate=new Date(this.activeDate.valueOf()),this.update.emit(this.activeDate),this.refreshView()},t.prototype.move=function(t){var e;if("day"===this.datepickerMode&&(e=this.stepDay),"month"===this.datepickerMode&&(e=this.stepMonth),"year"===this.datepickerMode&&(e=this.stepYear),e){var n=this.activeDate.getFullYear()+t*(e.years||0),a=this.activeDate.getMonth()+t*(e.months||0);this.activeDate=new Date(n,a,1),this.refreshView(),this.activeDateChange.emit(this.activeDate)}},t.prototype.toggleMode=function(t){var e=t||1;this.datepickerMode===this.maxMode&&1===e||this.datepickerMode===this.minMode&&-1===e||(this.datepickerMode=this.modes[this.modes.indexOf(this.datepickerMode)+e],this.refreshView())},t.prototype.getCustomClassForDate=function(t){var e=this;if(!this.customClass)return"";var n=this.customClass.find(function(n){return n.date.valueOf()===t.valueOf()&&n.mode===e.datepickerMode},this);return void 0===n?"":n.clazz},t.prototype.compareDateDisabled=function(t,e){if(void 0!==t&&void 0!==e)return"day"===t.mode&&this.compareHandlerDay?this.compareHandlerDay(t.date,e):"month"===t.mode&&this.compareHandlerMonth?this.compareHandlerMonth(t.date,e):"year"===t.mode&&this.compareHandlerYear?this.compareHandlerYear(t.date,e):void 0},t.prototype.isDisabled=function(t){var e=this,n=!1;return this.dateDisabled&&this.dateDisabled.forEach(function(a){0===e.compareDateDisabled(a,t)&&(n=!0)}),this.dayDisabled&&(n=n||this.dayDisabled.indexOf(t.getDay())>-1),n||this.minDate&&this.compare(t,this.minDate)<0||this.maxDate&&this.compare(t,this.maxDate)>0},t}(),st=function(){return function(){this.locale="en",this.datepickerMode="day",this.startingDay=0,this.yearRange=20,this.minMode="day",this.maxMode="year",this.showWeeks=!0,this.formatDay="DD",this.formatMonth="MMMM",this.formatYear="YYYY",this.formatDayHeader="dd",this.formatDayTitle="MMMM YYYY",this.formatMonthTitle="YYYY",this.onlyCurrentMonth=!1,this.monthColLimit=3,this.yearColLimit=5,this.shortcutPropagation=!1}}(),ot=function(){function t(t){this.datepickerMode="day",this.showWeeks=!0,this.selectionDone=new a.EventEmitter(void 0),this.activeDateChange=new a.EventEmitter(void 0),this.onChange=Function.prototype,this.onTouched=Function.prototype,this._now=new Date,this.config=t,this.configureOptions()}return Object.defineProperty(t.prototype,"activeDate",{get:function(){return this._activeDate||this._now},set:function(t){this._activeDate=t},enumerable:!0,configurable:!0}),t.prototype.configureOptions=function(){Object.assign(this,this.config)},t.prototype.onUpdate=function(t){this.activeDate=t,this.onChange(t)},t.prototype.onSelectionDone=function(t){this.selectionDone.emit(t)},t.prototype.onActiveDateChange=function(t){this.activeDateChange.emit(t)},t.prototype.writeValue=function(t){if(0!==this._datePicker.compare(t,this._activeDate))return t&&t instanceof Date?(this.activeDate=t,void this._datePicker.select(t,!1)):void(this.activeDate=t?new Date(t):void 0)},t.prototype.registerOnChange=function(t){this.onChange=t},t.prototype.registerOnTouched=function(t){this.onTouched=t},t}(),ut=function(){function t(t){this.labels=[],this.rows=[],this.weekNumbers=[],this.datePicker=t}return Object.defineProperty(t.prototype,"isBs4",{get:function(){return!Object(p.d)()},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){var t=this;this.datePicker.stepDay={months:1},this.datePicker.setRefreshViewHandler(function(){var e=this.activeDate.getFullYear(),n=this.activeDate.getMonth(),a=new Date(e,n,1),r=this.startingDay-a.getDay(),i=r>0?7-r:-r,s=new Date(a.getTime());i>0&&s.setDate(1-i);for(var o=t.getDates(s,42),u=[],c=0;c<42;c++){var l=this.createDateObject(o[c],this.formatDay);l.secondary=o[c].getMonth()!==n,l.uid=this.uniqueId+"-"+c,u[c]=l}t.labels=[];for(var d=0;d<7;d++)t.labels[d]={},t.labels[d].abbr=this.dateFilter(u[d].date,this.formatDayHeader),t.labels[d].full=this.dateFilter(u[d].date,"EEEE");if(t.title=this.dateFilter(this.activeDate,this.formatDayTitle),t.rows=this.split(u,7),this.showWeeks){t.weekNumbers=[];for(var f=(11-this.startingDay)%7,p=t.rows.length,h=0;h');for(var n=0;n'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("");return e.push(""),e.join("")}});var c=r.extend({initialize:function(t){i.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:o,update:function(t,e,n){var a=this;return a.beforeUpdate(),a.maxWidth=t,a.maxHeight=e,a.margins=n,a.beforeSetDimensions(),a.setDimensions(),a.afterSetDimensions(),a.beforeBuildLabels(),a.buildLabels(),a.afterBuildLabels(),a.beforeFit(),a.fit(),a.afterFit(),a.afterUpdate(),a.minSize},afterUpdate:o,beforeSetDimensions:o,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:o,beforeBuildLabels:o,buildLabels:function(){var t=this,e=t.options.labels||{},n=i.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(n=n.filter(function(n){return e.filter(n,t.chart.data)})),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:o,beforeFit:o,fit:function(){var t=this,e=t.options,n=e.labels,r=e.display,s=t.ctx,o=a.global,c=i.valueOrDefault,l=c(n.fontSize,o.defaultFontSize),d=c(n.fontStyle,o.defaultFontStyle),f=c(n.fontFamily,o.defaultFontFamily),p=i.fontString(l,d,f),h=t.legendHitBoxes=[],g=t.minSize,b=t.isHorizontal();if(b?(g.width=t.maxWidth,g.height=r?10:0):(g.width=r?10:0,g.height=t.maxHeight),r)if(s.font=p,b){var m=t.lineWidths=[0],y=t.legendItems.length?l+n.padding:0;s.textAlign="left",s.textBaseline="top",i.each(t.legendItems,function(e,a){var r=u(n,l)+l/2+s.measureText(e.text).width;m[m.length-1]+r+n.padding>=t.width&&(y+=l+n.padding,m[m.length]=t.left),h[a]={left:0,top:0,width:r,height:l},m[m.length-1]+=r+n.padding}),g.height+=y}else{var v=n.padding,_=t.columnWidths=[],x=n.padding,T=0,w=0,S=l+v;i.each(t.legendItems,function(t,e){var a=u(n,l)+l/2+s.measureText(t.text).width;w+S>g.height&&(x+=T+n.padding,_.push(T),T=0,w=0),T=Math.max(T,a),w+=S,h[e]={left:0,top:0,width:a,height:l}}),x+=T,_.push(T),g.width+=x}t.width=g.width,t.height=g.height},afterFit:o,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,r=a.global,s=r.elements.line,o=t.width,c=t.lineWidths;if(e.display){var l,d=t.ctx,f=i.valueOrDefault,p=f(n.fontColor,r.defaultFontColor),h=f(n.fontSize,r.defaultFontSize),g=f(n.fontStyle,r.defaultFontStyle),b=f(n.fontFamily,r.defaultFontFamily),m=i.fontString(h,g,b);d.textAlign="left",d.textBaseline="middle",d.lineWidth=.5,d.strokeStyle=p,d.fillStyle=p,d.font=m;var y=u(n,h),v=t.legendHitBoxes,_=t.isHorizontal();l=_?{x:t.left+(o-c[0])/2,y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+n.padding,line:0};var x=h+n.padding;i.each(t.legendItems,function(a,u){var p=d.measureText(a.text).width,g=y+h/2+p,b=l.x,m=l.y;_?b+g>=o&&(m=l.y+=x,l.line++,b=l.x=t.left+(o-c[l.line])/2):m+x>t.bottom&&(b=l.x=b+t.columnWidths[l.line]+n.padding,m=l.y=t.top+n.padding,l.line++),function(t,n,a){if(!(isNaN(y)||y<=0)){d.save(),d.fillStyle=f(a.fillStyle,r.defaultColor),d.lineCap=f(a.lineCap,s.borderCapStyle),d.lineDashOffset=f(a.lineDashOffset,s.borderDashOffset),d.lineJoin=f(a.lineJoin,s.borderJoinStyle),d.lineWidth=f(a.lineWidth,s.borderWidth),d.strokeStyle=f(a.strokeStyle,r.defaultColor);var o=0===f(a.lineWidth,s.borderWidth);if(d.setLineDash&&d.setLineDash(f(a.lineDash,s.borderDash)),e.labels&&e.labels.usePointStyle){var u=h*Math.SQRT2/2,c=u/Math.SQRT2;i.canvas.drawPoint(d,a.pointStyle,u,t+c,n+c)}else o||d.strokeRect(t,n,y,h),d.fillRect(t,n,y,h);d.restore()}}(b,m,a),v[u].left=b,v[u].top=m,function(t,e,n,a){var r=h/2,i=y+r+t,s=e+r;d.fillText(n.text,i,s),n.hidden&&(d.beginPath(),d.lineWidth=2,d.moveTo(i,s),d.lineTo(i+a,s),d.stroke())}(b,m,a,p),_?l.x+=g+n.padding:l.y+=x})}},handleEvent:function(t){var e=this,n=e.options,a="mouseup"===t.type?"click":t.type,r=!1;if("mousemove"===a){if(!n.onHover)return}else{if("click"!==a)return;if(!n.onClick)return}var i=t.x,s=t.y;if(i>=e.left&&i<=e.right&&s>=e.top&&s<=e.bottom)for(var o=e.legendHitBoxes,u=0;u=c.left&&i<=c.left+c.width&&s>=c.top&&s<=c.top+c.height){if("click"===a){n.onClick.call(e,t.native,e.legendItems[u]),r=!0;break}if("mousemove"===a){n.onHover.call(e,t.native,e.legendItems[u]),r=!0;break}}}return r}});function l(t,e){var n=new c({ctx:t.ctx,options:e,chart:t});s.configure(t,n,e),s.addBox(t,n),t.legend=n}t.exports={id:"legend",_element:c,beforeInit:function(t){var e=t.options.legend;e&&l(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(i.mergeIf(e,a.global.legend),n?(s.configure(t,n,e),n.options=e):l(t,e)):n&&(s.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}}},Ahxa:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("lUjN");e.DataTableFooterComponent=function(){function t(){this.selectedCount=0,this.page=new i.EventEmitter}return Object.defineProperty(t.prototype,"isVisible",{get:function(){return this.rowCount/this.pageSize>1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"curPage",{get:function(){return this.offset+1},enumerable:!0,configurable:!0}),a([i.Input(),r("design:type",Number)],t.prototype,"footerHeight",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"rowCount",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"pageSize",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"offset",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerLeftArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerRightArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerPreviousIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerNextIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"totalMessage",void 0),a([i.Input(),r("design:type",s.DatatableFooterDirective)],t.prototype,"footerTemplate",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"selectedCount",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"selectedMessage",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"page",void 0),a([i.Component({selector:"datatable-footer",template:'\n \n \n \n
\n \n {{selectedCount?.toLocaleString()}} {{selectedMessage}} / \n \n {{rowCount?.toLocaleString()}} {{totalMessage}}\n
\n \n \n \n ',host:{class:"datatable-footer"},changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},AqeW:function(t,e,n){"use strict";function a(t,e){for(var n,a,r,i=[],s=[];(n=document.elementFromPoint(t,e))&&-1===i.indexOf(n)&&null!=n;)i.push(n),s.push({value:n.style.getPropertyValue("pointer-events"),priority:n.style.getPropertyPriority("pointer-events")}),n.style.setProperty("pointer-events","none","important");for(a=s.length;r=s[--a];)i[a].style.setProperty("pointer-events",r.value?r.value:"",r.priority);return i}Object.defineProperty(e,"__esModule",{value:!0}),"undefined"==typeof document||document.elementsFromPoint||(document.elementsFromPoint=a),e.elementsFromPoint=a},As3K:function(t,e,n){"use strict";var a=n("TC34");t.exports={toLineHeight:function(t,e){var n=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!n||"normal"===n[1])return 1.2*e;switch(t=+n[2],n[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,n,r,i;return a.isObject(t)?(e=+t.top||0,n=+t.right||0,r=+t.bottom||0,i=+t.left||0):e=n=r=i=+t||0,{top:e,right:n,bottom:r,left:i,height:e+r,width:i+n}},resolve:function(t,e,n){var r,i,s;for(r=0,i=t.length;r=4||"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d"===e||"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02"===e?t+12:t},meridiem:function(t,e,n){return t<4?"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f":t<12?"\u0d30\u0d3e\u0d35\u0d3f\u0d32\u0d46":t<17?"\u0d09\u0d1a\u0d4d\u0d1a \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d4d":t<20?"\u0d35\u0d48\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d47\u0d30\u0d02":"\u0d30\u0d3e\u0d24\u0d4d\u0d30\u0d3f"}})}()},AxiF:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("mrSG"),r=n("FFOo"),i=n("b7mW"),s=n("G5J1");function o(t){return function(e){return 0===t?Object(s.b)():e.lift(new u(t))}}var u=function(){function t(t){if(this.total=t,this.total<0)throw new i.a}return t.prototype.call=function(t,e){return e.subscribe(new c(t,this.total))},t}(),c=function(t){function e(e,n){var a=t.call(this,e)||this;return a.total=n,a.ring=new Array,a.count=0,a}return a.__extends(e,t),e.prototype._next=function(t){var e=this.ring,n=this.total,a=this.count++;e.length0)for(var n=this.count>=this.total?this.total:this.count,a=this.ring,r=0;rdocumentation\n on how to\n add dashboards to Grafana.\n \n Das Grafana-Dashboard ist nicht vorhanden. In der\n Dokumentation\n wird beschrieben,\n wie Grafana Dashboards hinzugef\xfcgt werden.\n \n \n \n Grafana Time Picker\n Grafana-Zeitauswahl\n \n \n Reset Settings\n Einstellungen f\xfcr Zur\xfccksetzungen\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n Daten konnten nicht geladen werden.\n \n \n selected\n ausgew\xe4hlt\n X selected\n \n \n found\n gefunden\n X found\n \n \n total\n insgesamt\n X total\n \n \n Edit\n Bearbeiten\n \n \n Name\n Name\n \n \n Description\n Beschreibung\n \n \n Long description\n Lange Beschreibung\n \n \n Default\n Standard\n \n \n Daemon default\n Daemon-Standard\n \n \n Services\n Services\n \n \n Values\n Werte\n \n \n The entered value is too high! It must not be greater than \n .\n \n Der eingegebene Wert ist zu gro\xdf! Er darf nicht gr\xf6\xdfer als \n sein.\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Der eingegebene Wert ist zu klein! Er darf nicht kleiner als \n sein.\n \n \n \n Save\n Speichern\n \n \n CRUSH map viewer\n CRUSH-Zuordnungsanzeige\n \n \n Hosts List\n Liste mit Hosts\n \n \n Overall Performance\n Gesamtleistung\n \n \n No entries found\n Keine Eintr\xe4ge gefunden\n \n \n Cluster Logs\n Clusterprotokolle\n \n \n Audit Logs\n Revisionsprotokoll\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n Konfiguration wird geladen...\n \n \n The configuration could not be loaded.\n Die Konfiguration konnte nicht geladen werden.\n \n \n Edit Manager module\n Manager-Modul bearbeiten\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n Der eingegebene Wert ist kein g\xfcltiger UUID, z. B.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n Der eingegebene Wert muss eine g\xfcltige IP-Adresse sein.\n \n \n This field is required.\n Dies ist ein Pflichtfeld.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n Der eingegebene Wert ist zu gro\xdf! Er muss kleiner als \n sein oder diesem Wert entsprechen.\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n Der eingegebene Wert ist zu klein! Er muss gr\xf6\xdfer als \n sein oder diesem Wert entsprechen.\n \n \n \n The entered value needs to be a number.\n Der eingegebene Wert muss eine Zahl sein.\n \n \n The entered value needs to be a number or decimal.\n Der eingegebene Wert muss eine Zahl oder Dezimalzahl sein.\n \n \n Update\n Aktualisieren\n \n \n Status\n Status\n \n \n Cluster ID\n Cluster-ID\n \n \n monmap modified\n Monmap ge\xe4ndert\n \n \n monmap epoch\n Monmap-Epoche\n \n \n quorum con\n quorum con\n \n \n quorum mon\n quorum mon\n \n \n required con\n erforderliche Verbindung\n \n \n required mon\n erforderliche \xdcberwachung\n \n \n In Quorum\n In Quorum\n \n \n Not In Quorum\n Nicht in Quorum\n \n \n Cancel\n Abbrechen\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n Sind Sie sicher dass Sie die ausgew\xe4hlten \n \n m\xf6chten?\n \n \n \n Yes, I am sure.\n Ja, ich bin sicher.\n \n \n Cluster-wide OSD Flags\n Clusterweite OSD-Flags\n \n \n Submit\n Absenden\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Erweitert...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n OSD-Wiederherstellungspriorit\xe4t\n \n \n Priority\n Priorit\xe4t\n \n \n Customize priority values\n Priorit\xe4tswerte anpassen\n \n \n This field is required!\n Dies ist ein Pflichtfeld!\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n Der eingegebene Wert ist zu gro\xdf! Er darf nicht gr\xf6\xdfer als \n sein.\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Der eingegebene Wert ist zu klein! Er darf nicht kleiner als \n sein.\n \n \n \n Reweight OSD\n OSD neu gewichten\n \n \n The value needs to be between 0 and 1.\n Der Wert muss zwischen 0 und 1 liegen.\n \n \n Reweight\n Neu gewichten\n \n \n OSDs \n Scrub\n \n OSDs \n Scrub\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {Tief } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Sie sind dabei, einen \n Scrub auf\n das OSD \n \n \n anzuwenden.\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {tief } }\n \n \n OSDs List\n OSD-Liste\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \n OSD \n \n wird markiert als\n \n \n , wenn Sie den Vorgang fortsetzen.\n \n \n \n The OSD is not safe to destroy!\n Es ist nicht sicher, das OSD zu vernichten!\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \n OSD \n \n wird\n \n \n , wenn Sie den Vorgang fortsetzen.\n \n \n \n Details\n Details\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Wert\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Schlie\xdfen\n \n \n Delete\n L\xf6schen\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Integrit\xe4t\n \n \n Statistics\n Statistiken\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Lesen Sie die \n Dokumentation\n zum\n Konfigurieren und Aktivieren der Verwaltungsfunktion f\xfcr NFS Ganesha.\n \n \n \n Clients\n Clients\n \n \n Any client can access\n Jeder Client hat Zugriff\n \n \n Addresses\n Adressen\n \n \n Required field\n Pflichtfeld\n \n \n Must contain one or more comma-separated values\n Muss mindestens einen kommagetrennten Wert enthalten\n \n \n For example:\n Beispielsweise:\n \n \n Access Type\n Zugriffstyp\n \n \n Squash\n Squash\n \n \n Add clients\n Clients hinzuf\xfcgen\n \n \n Loading...\n Laden...\n \n \n -- No cluster available --\n -- Kein Cluster verf\xfcgbar --\n \n \n -- Select the cluster --\n -- Cluster ausw\xe4hlen --\n \n \n Add daemon\n Daemon hinzuf\xfcgen\n \n \n Storage Backend\n Speicher-Back-End\n \n \n -- No data pools available --\n -- Keine Datenpools verf\xfcgbar --\n \n \n -- Select the storage backend --\n -- Speicher-Back-End ausw\xe4hlen --\n \n \n Object Gateway User\n Objektgatewaybenutzer\n \n \n -- No users available --\n -- Keine Benutzer verf\xfcgbar --\n \n \n -- Select the object gateway user --\n -- Objektgatewaybenutzer ausw\xe4hlen --\n \n \n CephFS User ID\n CephFS-Benutzer-ID\n \n \n -- No clients available --\n -- keine Clients verf\xfcgbar --\n \n \n -- Select the cephx client --\n -- cephx-Client ausw\xe4hlen --\n \n \n CephFS Name\n CephFS-Name\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n Sicherheitsbezeichnung\n \n \n Enable security label\n Sicherheitsbezeichnung aktivieren\n \n \n CephFS Path\n CephFS-Pfad\n \n \n Path need to start with a \'/\' and can be followed by a word\n Pfad muss mit einem \'/\' beginnen und kann von einem Wort gefolgt werden\n \n \n New directory will be created\n Neues Verzeichnis wird erstellt\n \n \n Path\n Pfad\n \n \n Path can only be a single \'/\' or a word\n Pfad darf nur ein einzelner \'/\' oder ein Wort sein\n \n \n New bucket will be created\n Neuer Bucket wird erstellt\n \n \n NFS Protocol\n NFS-Protokoll\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n NFS-Tag\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Alternativer Zugriff f\xfcr \n NFS v3\n -Mountpunkte (d\xfcrfen keinen f\xfchrenden / enthalten)\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n Clients k\xf6nnen Unterverzeichnisse m\xf6glicherweise nicht mounten (d. h. wenn das Tag = foo, kann der Client foo/baz m\xf6glicherweise nicht mounten).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n Wenn unterschiedliche Tagoptionen verwendet werden, wird derselbe Pfad m\xf6glicherweise mehrfach exportiert.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n Die Position dieses \n NFS v4\n -Exports\n auf dem \n Pseudo-Dateisystem\n (muss eindeutig sein).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n Wenn unterschiedliche Pseudo-Optionen verwendet werden, wird derselbe Pfad m\xf6glicherweise mehrfach exportiert.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- Kein Zugriffstyp verf\xfcgbar --\n \n \n -- Select the access type --\n -- Zugriffstyp ausw\xe4hlen --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- Kein Squash verf\xfcgbar --\n \n \n --Select what kind of user id squashing is performed --\n -- Durchzuf\xfchrende Benutzer-ID-Squashing-Art ausw\xe4hlen --\n \n \n Transport Protocol\n Transportprotokoll\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Willkommen bei Ceph!\n The welcome message on the login page\n \n \n Username is required\n Benutzername ist erforderlich\n \n \n Password is required\n Passwort ist erforderlich\n \n \n Login\n Anmeldung\n \n \n Sorry, the user does not exist in Ceph.\n Der Benutzer ist in Ceph leider nicht enthalten.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Kehren Sie zur \n Anmeldeseite\n zur\xfcck. Sie werden vom Identit\xe4tsanbieter abgemeldet, wenn Sie versuchen, sich erneut anzumelden.\n \n \n \n Forbidden\n Verboten\n \n \n Sorry, you are not allowed to see what you were looking for.\n Leider sind Sie nicht berechtigt, den gew\xfcnschten Inhalt anzuzeigen.\n \n \n Sorry, we could not find what you were looking for\n Leider konnte der gew\xfcnschte Inhalt nicht gefunden werden.\n \n \n Remove all\n Alle l\xf6schen\n \n \n Recent Notifications\n Neue Benachrichtigungen\n \n \n There are no background tasks.\n Keine Hintergrundaufgaben vorhanden.\n \n \n Background Tasks\n Hintergrundaufgaben\n \n \n Help\n Hilfe\n \n \n Documentation\n Dokumentation\n \n \n API\n API\n \n \n About\n \xdcber\n \n \n Dashboard Settings\n Dashboard-Einstellungen\n \n \n User management\n Benutzerverwaltung\n \n \n Logged in user\n Angemeldeter Benutzer\n \n \n Signed in as\n \n \n \n \n Angemeldet als\n \n \n \n \n \n \n Sign out\n Abmelden\n \n \n Name...\n Name...\n \n \n The chosen name is already in use.\n Der ausgew\xe4hlte Name wird bereits verwendet.\n \n \n Description...\n Beschreibung...\n \n \n Permissions\n Berechtigungen\n \n \n Roles\n Rollen\n \n \n Username\n Benutzername\n \n \n Password\n Passwort\n \n \n Confirm password\n Passwort best\xe4tigen\n \n \n Password confirmation doesn\'t match the password.\n Passwortbest\xe4tigung stimmt nicht mit dem Passwort \xfcberein.\n \n \n Full name\n Vollst\xe4ndiger Name\n \n \n Email\n E-Mail-Adresse\n \n \n Invalid email.\n Ung\xfcltige E-Mail-Adresse.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Sie sind dabei, die Lese-/Aktualisierungsberechtigungen f\xfcr Benutzer von Ihrem eigenen Benutzer zu entfernen.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Wenn Sie den Vorgang fortsetzen, k\xf6nnen Sie Benutzerrollen nicht mehr hinzuf\xfcgen oder entfernen.\n \n \n Are you sure you want to continue?\n M\xf6chten Sie den Vorgang wirklich fortsetzen?\n \n \n Performance counters not available\n Leistungsindikatoren nicht verf\xfcgbar\n \n \n Attributes (OSD map)\n Attribute (OSD-Zuordnung)\n \n \n Metadata not available\n Metadaten nicht verf\xfcgbar\n \n \n Metadata\n Metadaten\n \n \n Performance counter\n Leistungsindikator\n \n \n Histogram not available: \n \n \n Histogramm nicht verf\xfcgbar: \n \n \n \n \n Writes\n Schreibvorg\xe4nge\n \n \n Reads\n Lesevorg\xe4nge\n \n \n Histogram\n Histogramm\n \n \n Performance Details\n Leistungsdetails\n \n \n Current values\n Aktuelle Werte\n \n \n Type\n Typ\n \n \n Min\n Min.\n \n \n Max\n Max.\n \n \n Flags\n Flags\n \n \n Source\n Quelle\n \n \n Level\n Ebene\n \n \n Can be updated at runtime (editable)\n Kann zur Laufzeit aktualisiert werden (bearbeitbar)\n \n \n Tags\n Tags\n \n \n Enum values\n Auflistungswerte\n \n \n See also\n Siehe auch\n \n \n Cluster Status\n Clusterstatus\n \n \n Manager Daemons\n Manager-Daemons\n \n \n Object Gateways\n Objektgateways\n \n \n Metadata Servers\n Metadatenserver\n \n \n iSCSI Gateways\n iSCSI-Gateways\n \n \n Client IOPS\n Client-IOPS\n \n \n Client Throughput\n Clientdurchsatz\n \n \n Client Read/Write\n Client-Lese-/Schreibvorg\xe4nge\n \n \n Recovery Throughput\n Wiederherstellungsdurchsatz\n \n \n Scrub\n Scrub\n \n \n Performance\n Leistung\n \n \n Raw Capacity\n Rohkapazit\xe4t\n \n \n Objects\n Objekte\n \n \n PGs per OSD\n Platzierungsgruppen pro OSD\n \n \n PG Status\n Platzierungsgruppenstatus\n \n \n Capacity\n Kapazit\xe4t\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n Weitere Details finden Sie in den \n Protokollen\n .\n \n \n \n Ranks\n R\xe4nge\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Clients: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n Image in Papierkorb verschieben\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n Um \n \n /\n \n in den Papierkorb zu verschieben,\n klicken Sie auf \n Image verschieben\n . Optional k\xf6nnen Sie ein Ablaufdatum ausw\xe4hlen.\n \n \n \n Protection expires at\n Schutz l\xe4uft ab am\n \n \n NOT PROTECTED\n NICHT GESCH\xdcTZT\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Falsches Datumsformat. Verwenden Sie "TT.MM.JJJJ HH:mm:ss".\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n Schutz ist bereits abgelaufen. W\xe4hlen Sie ein k\xfcnftiges Datum aus oder lassen Sie es leer.\n \n \n Move Image\n Image verschieben\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n \xdcbersicht\n \n \n Targets\n Ziele\n \n \n Discovery Authentication\n Ermittlungsauthentifizierung\n \n \n User\n Benutzer\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Benutzernamen m\xfcssen zwischen 8 und 64 Zeichen lang sein und\n d\xfcrfen nur Buchstaben, \'.\', \'@\', \'-\', \'_\' oder \':\' enthalten.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n Gemeinsamer Benutzer\n \n \n Mutual Password\n Gemeinsames Passwort\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Lesen Sie die\n Dokumentation\n zum\n Konfigurieren und Aktivieren der Verwaltungsfunktion f\xfcr iSCSI-Ziele.\n \n \n \n Available information:\n Verf\xfcgbare Informationen:\n \n \n iSCSI Targets not available\n iSCSI-Ziele nicht verf\xfcgbar\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n Nur f\xfcr RBD-Images verf\xfcgbar, bei denen \n fast-diff\n aktiviert ist\n \n \n \n Pool\n Pool\n \n \n Data Pool\n Datenpool\n \n \n Created\n Erstellt\n \n \n Size\n Gr\xf6\xdfe\n \n \n Object size\n Objektgr\xf6\xdfe\n \n \n Features\n Funktionen\n \n \n Provisioned\n Bereitgestellt\n \n \n N/A\n n. v.\n \n \n Total provisioned\n Bereitgestellt gesamt\n \n \n Striping unit\n Striping-Einheit\n \n \n Striping count\n Striping-Anzahl\n \n \n Parent\n \xdcbergeordnet\n \n \n Block name prefix\n Pr\xe4fix f\xfcr Blockname\n \n \n Order\n Reihenfolge\n \n \n Snapshots\n Snapshots\n \n \n Image\n Image\n \n \n This setting overrides the global value\n Diese Einstellung \xfcberschreibt den globalen Wert\n \n \n Global\n Global\n \n \n This is the global value. No value for this option has been set for this image.\n Dies ist der globale Wert. Kein Wert f\xfcr diese Option wurde f\xfcr dieses Image festgelegt.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \'/\' und \'@\' sind nicht zul\xe4ssig.\n \n \n -- No rbd pools available --\n -- Keine rbd-Pools verf\xfcgbar --\n \n \n -- Select a pool --\n -- Pool ausw\xe4hlen --\n \n \n Use a dedicated data pool\n Dedizierten Datenpool verwenden\n \n \n Data pool\n Datenpool\n \n \n Dedicated pool that stores the object-data of the RBD.\n Dedizierter Pool zur Speicherung von RBD-Objektdaten.\n \n \n e.g., 10GiB\n z. B. 10GiB\n \n \n You have to increase the size.\n Sie m\xfcssen die Gr\xf6\xdfe erh\xf6hen.\n \n \n Advanced\n Erweitert\n \n \n Striping\n Striping\n \n \n Stripe unit\n Stripe-Einheit\n \n \n -- Select stripe unit --\n -- Stripe-Einheit ausw\xe4hlen --\n \n \n This field is required because stripe count is defined!\n Dies ist ein Pflichtfeld, da eine Stripe-Anzahl definiert wurde!\n \n \n Stripe unit is greater than object size.\n Die Stripe-Einheit ist gr\xf6\xdfer als die Objektgr\xf6\xdfe.\n \n \n Stripe count\n Stripe-Anzahl\n \n \n This field is required because stripe unit is defined!\n Dies ist ein Pflichtfeld, da eine Stripe-Einheit definiert wurde!\n \n \n Stripe count must be greater than 0.\n Die Stripe-Anzahl muss gr\xf6\xdfer als 0 sein.\n \n \n \n RBD Snapshot\n \n \n RBD-Snapshot\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Umbenennen} other {Erstellen} }\n \n \n \n Snapshot\n \n \n Snapshot\n \n \n \n PROTECTED\n GESCH\xdcTZT\n \n \n UNPROTECTED\n NICHT GESCH\xdcTZT\n \n \n You are about to rollback\n Sie sind dabei, ein Rollback durchzuf\xfchren\n \n \n Purge Trash\n Papierkorb bereinigen\n \n \n To purge, select one or All images and click\n Zum Bereinigen ein oder alle Images ausw\xe4hlen und klicken\n \n \n Pool:\n Pool:\n \n \n Pool name...\n Poolname...\n \n \n All\n Alle\n \n \n Restore Image\n Image wiederherstellen\n \n \n To restore\n Zum Wiederherstellen\n \n \n type the image\'s new name and click\n Neuen Namen des Images eingeben und klicken\n \n \n New Name\n Neuer Name\n \n \n Expired at\n Abgelaufen am\n \n \n Protected until\n Gesch\xfctzt bis\n \n \n This image is protected until \n .\n \n Dieses Image ist gesch\xfctzt bis \n .\n \n \n \n Trash\n Papierkorb\n \n \n iSCSI Topology\n iSCSI-Topologie\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n Eine \xc4nderung dieser Parameter von ihren Standardwerten ist in der Regel nicht erforderlich.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Einstellungen\n \n \n Backstore\n Backstore\n \n \n Confirm\n Best\xe4tigen\n \n \n Advanced Settings\n Erweiterte Einstellungen\n \n \n Target IQN\n Ziel-IQN\n \n \n IQN has wrong pattern.\n IQN hat ein fehlerhaftes Muster.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n Eine IQN hat die folgende Notation \'iqn.$jahr-$monat.$umkehradresse:$definierterName\'\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Zum Beispiel: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n Weitere Informationen\n \n \n This target has modified advanced settings.\n Erweiterte Einstellungen bei diesem Ziel wurden ge\xe4ndert.\n \n \n Portals\n Portale\n \n \n At least \n gateways are required.\n \n Es sind mindestens \n Gateways erforderlich.\n \n \n \n Add portal\n Portal hinzuf\xfcgen\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Einstellungen bei diesem Image wurden ge\xe4ndert.\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n Image hinzuf\xfcgen\n \n \n ACL authentication\n ACL-Authentifizierung\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Initiatoren\n \n \n Initiator\n Initiator\n \n \n Client IQN\n Client-IQN\n \n \n Initiator IQN needs to be unique.\n Initiator-IQN muss eindeutig sein.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Benutzernamen m\xfcssen zwischen 8 und 64 Zeichen lang sein und\n d\xfcrfen nur Buchstaben, \'.\', \'@\', \'-\', \'_\' oder \':\' enthalten.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n Der Initiator geh\xf6rt zu einer Gruppe. Images werden in der Gruppe konfiguriert.\n \n \n No items added.\n Keine Elemente hinzugef\xfcgt.\n \n \n Add initiator\n Initiator hinzuf\xfcgen\n \n \n Groups\n Gruppen\n \n \n Group\n Gruppe\n \n \n Add group\n Gruppe hinzuf\xfcgen\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n RBD-Konfiguration\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Entfernen Sie den lokalen Konfigurationswert. Stattdessen wird der \xfcbergeordnete Konfigurationswert \xfcbernommen und verwendet.\n \n \n The mininum value is 0\n Der Mindestwert lautet 0\n \n \n Issues\n Probleme\n \n \n Syncing\n Wird synchronisiert\n \n \n Ready\n Fertig\n \n \n Edit pool mirror mode\n Spiegelungsmodus f\xfcr Pool bearbeiten\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n W\xe4hlen Sie zum Bearbeiten des Spiegelungsmodus f\xfcr den Pool\xa0\n \n \n einen neuen Modus aus der Liste aus und klicken Sie auf\xa0\n Aktualisieren\n .\n \n \n \n Mode\n Modus\n \n \n Peer clusters must be removed prior to disabling mirror.\n Vor dem Deaktivieren der Spiegelung m\xfcssen Peer-Cluster entfernt werden.\n \n \n \n \n pool mirror peer\n \n \n \n Peer f\xfcr Poolspiegelung\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Bearbeiten} other {Hinzuf\xfcgen} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n Der Pool\n Spiegeln Sie Peer-Attribute f\xfcr Pool \n \n \n und klicken Sie auf \n Absenden\n .\n \n \n \n Cluster Name\n Clustername\n \n \n The cluster name is not valid.\n Der Clustername ist ung\xfcltig.\n \n \n CephX ID\n CephX-ID\n \n \n CephX ID...\n CephX-ID...\n \n \n The CephX ID is not valid.\n Die CephX ID ist ung\xfcltig.\n \n \n Monitor Addresses\n Adressen der Monitore\n \n \n Comma-delimited addresses...\n Kommagetrennte Adressen...\n \n \n The monitory address is not valid.\n Die Anrede ist ung\xfcltig.\n \n \n CephX Key\n CephX-Schl\xfcssel\n \n \n Base64-encoded key...\n Base64-codierter Schl\xfcssel...\n \n \n CephX key must be base64 encoded.\n CephX-Schl\xfcssel muss base64-codiert sein.\n \n \n Pools List\n Pool-Liste\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n Der Name darf nur alphanumerische Zeichen, Bindestriche und Unterstriche enthalten.\n \n \n The chosen erasure code profile name is already in use.\n Der ausgew\xe4hlte L\xf6schcode-Profilname wird bereits verwendet.\n \n \n Plugin\n Plugin\n \n \n Data chunks (k)\n Datenbl\xf6cke (k)\n \n \n Must be equal to or greater than 2.\n Muss gr\xf6\xdfer oder gleich 2 sein.\n \n \n Coding chunks (m)\n Datenbl\xf6cke f\xfcr die Codierung (m)\n \n \n Must be equal to or greater than 1.\n Muss gr\xf6\xdfer oder gleich 1 sein.\n \n \n Durability estimator (c)\n Dauerhaftigkeitssch\xe4tzung (c)\n \n \n Locality (l)\n Standort (l)\n \n \n Crush failure domain\n Crush-Ausfalldom\xe4ne\n \n \n Crush Locality\n Crush-Standort\n \n \n None\n Keine\n \n \n Technique\n Technik\n \n \n Packetsize\n Paketgr\xf6\xdfe\n \n \n Crush root\n Crush-Stamm\n \n \n Crush device class\n Crush-Ger\xe4teklasse\n \n \n any\n beliebig\n \n \n Directory\n Verzeichnis\n \n \n The chosen Ceph pool name is already in use.\n Der ausgew\xe4hlte Poolname wird bereits verwendet.\n \n \n Pool type\n Pooltyp\n \n \n -- Select a pool type --\n -- Pooltyp ausw\xe4hlen --\n \n \n Placement groups\n Platzierungsgruppen\n \n \n At least one placement group is needed!\n Es wird mindestens eine Platzierungsgruppe ben\xf6tigt.\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n Ihr Cluster kann nicht so viele Platzierungsgruppen verarbeiten. Berechnen Sie die ben\xf6tigte Anzahl an Platzierungsgruppen.\n \n \n Calculation help\n Hilfe zur Berechnung\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n Die aktuellen Einstellungen f\xfcr die Platzierungsgruppen wurden f\xfcr Sie berechnet.\n Stellen Sie vor dem Senden sicher, dass die Werte Ihren Anforderungen entsprechen.\n \n \n Crush ruleset\n Crush-Regelsatz\n \n \n -- Select a crush rule --\n -- Crush-Regel ausw\xe4hlen --\n \n \n Crush rule\n Crush-Regel\n \n \n Crush steps\n Crush-Schritte\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n Die Regel kann im aktuellen Cluster nicht verwendet werden,\n da es zu wenige OSDs enth\xe4lt, um das von dieser Regel geforderte OSD-Minimum zu erf\xfcllen.\n \n \n Replicated size\n Reproduzierte Gr\xf6\xdfe\n \n \n Minimum: \n \n \n Minimum: \n \n \n \n \n Maximum: \n \n \n Maximum: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n Die angegebene Gr\xf6\xdfe liegt au\xdferhalb des Bereichs. G\xfcltige Werte liegen zwischen\n und \n .\n \n \n \n Erasure code profile\n L\xf6schcode-Profil\n \n \n -- No erasure code profile available --\n -- Kein L\xf6schcode-Profil verf\xfcgbar --\n \n \n -- Select an erasure code profile --\n -- L\xf6schcode-Profil ausw\xe4hlen --\n \n \n EC Overwrites\n EC-\xdcberschreibungen\n \n \n Applications\n Anwendungen\n \n \n Compression\n Komprimierung\n \n \n Algorithm\n Algorithmus\n \n \n -- No erasure compression algorithm available --\n -- Kein L\xf6schkomprimierungsalgorithmus verf\xfcgbar --\n \n \n Minimum blob size\n Minimale Blobgr\xf6\xdfe\n \n \n e.g., 128KiB\n z. B. 128KiB\n \n \n Value should be greater than 0\n Wert sollte gr\xf6\xdfer als 0 sein\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Maximale Blobgr\xf6\xdfe\n \n \n e.g., 512KiB\n z. B. 512KiB\n \n \n Value should be greater than the minimum blob size\n Wert sollte gr\xf6\xdfer als die minimale Blobgr\xf6\xdfe sein\n \n \n Ratio\n Verh\xe4ltnis\n \n \n Compression ratio\n Komprimierungsverh\xe4ltnis\n \n \n Value should be between 0.0 and 1.0\n Wert sollte zwischen 0,0 und 1,0 liegen\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n Es ist nicht m\xf6glich, einen RBD-Pool mit \'/\' im Namen zu erstellen.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n \xc4ndern Sie den Namen oder entfernen Sie \'rbd\' aus der Anwendungsliste.\n \n \n Cache Tiers Details\n Details zu den Cache-Ebenen\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Lesen Sie die \n Dokumentation\n zum\n Konfigurieren und Aktivieren der Verwaltungsfunktion f\xfcr das Objektgateway.\n \n \n \n Daemons List\n Liste der Daemons\n \n \n Performance Counters\n Leistungsindikatoren\n \n \n Loading bucket data...\n Bucket-Daten werden geladen...\n \n \n The bucket data could not be loaded.\n Die Bucket-Daten konnten nicht geladen werden.\n \n \n Id\n ID\n \n \n The value is not valid.\n Der Wert ist ung\xfcltig.\n \n \n Owner\n Inhaber\n \n \n -- Select a user --\n -- Benutzer ausw\xe4hlen --\n \n \n ID\n ID\n \n \n Index type\n Indextyp\n \n \n Placement rule\n Platzierungsregel\n \n \n Marker\n Marker\n \n \n Maximum marker\n Maximum f\xfcr Marker\n \n \n Version\n Version\n \n \n Master version\n Masterversion\n \n \n Modification time\n \xc4nderungszeit\n \n \n Zonegroup\n Zonengruppe\n \n \n Bucket quota\n Bucket-Quote\n \n \n Enabled\n Aktiviert\n \n \n Maximum size\n Maximale Gr\xf6\xdfe\n \n \n Unlimited\n Unbegrenzt\n \n \n Maximum objects\n Maximale Objekte\n \n \n -- Select a username --\n -- Benutzername ausw\xe4hlen --\n \n \n Auto-generate key\n Schl\xfcssel automatisch generieren\n \n \n Access key\n Zugriffsschl\xfcssel\n \n \n Secret key\n Geheimer Schl\xfcssel\n \n \n Email address\n E-Mail-Adresse\n \n \n Suspended\n Angehalten\n \n \n System\n System\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {Nein} 1 {Ja} }\n \n \n Maximum buckets\n Maximale Buckets\n \n \n Subusers\n Unterbenutzer\n \n \n Capabilities\n Bef\xe4higungen\n \n \n User quota\n Benutzerquote\n \n \n Show\n Anzeigen\n \n \n Keys\n Schl\xfcssel\n \n \n -- Select a type --\n -- Typ ausw\xe4hlen --\n \n \n Permission\n Berechtigung\n \n \n -- Select a permission --\n -- Berechtigung ausw\xe4hlen --\n \n \n Subuser\n Unterbenutzer\n \n \n The chosen subuser ID is already in use.\n Die ausgew\xe4hlte Unterbenutzer-ID wird bereits verwendet.\n \n \n read, write\n lesen, schreiben\n \n \n full\n voll\n \n \n Swift key\n Swift-Schl\xfcssel\n \n \n Auto-generate secret\n Geheimnis automatisch generieren\n \n \n Loading user data...\n Benutzerdaten werden geladen...\n \n \n The user data could not be loaded.\n Die Benutzerdaten konnten nicht geladen werden.\n \n \n The chosen user ID is already in use.\n Die ausgew\xe4hlte Benutzer-ID wird bereits verwendet.\n \n \n This is not a valid email address.\n Dies ist keine g\xfcltige E-Mail-Adresse.\n \n \n The chosen email address is already in use.\n Die ausgew\xe4hlte E-Mail-Adresse wird bereits verwendet.\n \n \n Max. buckets\n Max. Buckets\n \n \n The entered value must be >= 0.\n Der eingegebene Wert muss >=0 sein.\n \n \n S3 key\n S3-Schl\xfcssel\n \n \n There are no subusers.\n Keine Unterbenutzer vorhanden.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n Keine Schl\xfcssel vorhanden.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n Keine Bef\xe4higungen vorhanden.\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Unbegrenzte Gr\xf6\xdfe\n \n \n Max. size\n Max. Gr\xf6\xdfe\n \n \n Unlimited objects\n Unbegrenzte Objekte\n \n \n Max. objects\n Max. Objekte\n \n \n Current\n Aktuell\n \n \n Updated discovery authentication\n Ermittlungsauthentifizierung aktualisiert\n \n \n There are no portals available.\n Keine Portale verf\xfcgbar.\n \n \n There are no images available.\n Keine Images verf\xfcgbar.\n \n \n There are no images available. Please make sure you add an image to the target.\n Keine Images verf\xfcgbar. F\xfcgen Sie dem Ziel ein Image hinzu.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n Keine Initiatoren verf\xfcgen. F\xfcgen Sie dem Ziel einen Initiator hinzu.\n \n \n target\n target\n \n \n Target\n Ziel\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n Zustand\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Bytes f\xfcr Lesevorgang\n \n \n Write Bytes\n Bytes f\xfcr Schreibvorgang\n \n \n Read Ops\n Lesevorg\xe4nge\n \n \n Write Ops\n Schreibvorg\xe4nge\n \n \n A/O Since\n A/O seit\n \n \n Instance\n Instanz\n \n \n Hostname\n Hostname\n \n \n Issue\n Problem\n \n \n Progress\n Fortschritt\n \n \n Disabled\n Deaktiviert\n \n \n Edit Mode\n Bearbeitungsmodus\n \n \n Add Peer\n Peer hinzuf\xfcgen\n \n \n Edit Peer\n Peer bearbeiten\n \n \n Delete Peer\n Peer l\xf6schen\n \n \n Leader\n Leader\n \n \n # Local\n # lokal\n \n \n # Remote\n # remote\n \n \n mirror peer\n Peer spiegeln\n \n \n Key\n Schl\xfcssel\n \n \n RBD\n RBD\n \n \n Deep flatten\n Umfassende Vereinfachung\n \n \n Layering\n Schichtung\n \n \n Exclusive lock\n Exklusive Sperre\n \n \n Object map (requires exclusive-lock)\n Objektzuordnung (erfordert exklusive Sperre)\n \n \n Journaling (requires exclusive-lock)\n Journaling (erfordert exklusive Sperre)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Rollback f\xfcr RBD-Snapshot\n \n \n Rollback\n Rollback\n \n \n RBD snapshot\n RBD-Snapshot\n \n \n Deleted At\n Gel\xf6scht am\n \n \n id\n ID\n \n \n type\n Typ\n \n \n state\n Zustand\n \n \n version\n Version\n \n \n Host\n Host\n \n \n root\n Stamm\n \n \n Rank\n Rang\n \n \n Daemon\n Daemon\n \n \n Activity\n Aktivit\xe4t\n \n \n Dentries\n Dentries\n \n \n Inodes\n Inodes\n \n \n Usage\n Nutzung\n \n \n Standby daemons\n Standby-Daemons\n \n \n The value can be updated at runtime.\n Der Wert kann zur Laufzeit aktualisiert werden.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n Daemons/Clients rufen diesen Wert nicht aus der\n Datenbank \'monitor config\' ab. Es ist nicht zul\xe4ssig, diese Option \xfcber \'ceph config\n set ...\' festzulegen. Diese Option sollte \xfcber \'ceph.conf\' oder an der\n Befehlszeile konfiguriert werden.\n \n \n Option takes effect only during daemon startup.\n Die Option wird nur w\xe4hrend des Daemon-Starts wirksam.\n \n \n Option only affects cluster creation.\n Die Option wirkt sich nur auf die Cluster-Erstellung aus.\n \n \n Option only affects daemon creation.\n Die Option wirkt sich nur auf die Daemon-Erstellung aus.\n \n \n Updated config option \n \n \n Aktualisierte config-Option \n \n \n \n \n Service\n Service\n \n \n Current value\n Aktueller Wert\n \n \n Editable\n Bearbeitbar\n \n \n Updated options for module "\n ".\n \n Aktualisierte Optionen f\xfcr Modul &quot;\n &quot;.\n \n \n \n Enable\n Aktivieren\n \n \n Disable\n Deaktivieren\n \n \n Reconnecting, please wait ...\n Verbindung wird erneut hergestellt, bitte warten...\n \n \n Public Address\n \xd6ffentliche Adresse\n \n \n Open Sessions\n Offene Sitzungen\n \n \n No In\n Kein In-Vorgang\n \n \n OSDs that were previously marked out will not be marked back in when they start\n OSDs, die zuvor als \'out\' markiert wurden, werden beim Start nicht wieder markiert\n \n \n No Out\n Kein Out-Vorgang\n \n \n OSDs will not automatically be marked out after the configured interval\n OSDs werden nach dem konfigurierten Intervall nicht automatisch als \'out\' markiert\n \n \n No Up\n Kein Up-Vorgang\n \n \n OSDs are not allowed to start\n OSDs d\xfcrfen nicht gestartet werden\n \n \n No Down\n Kein Down-Vorgang\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n OSD-Fehlerberichte werden ignoriert, sodass die Monitore die OSDs nicht als ausgefallen markieren\n \n \n Pause\n Pause\n \n \n Pauses reads and writes\n H\xe4lt Lese- und Schreibvorg\xe4nge an\n \n \n No Scrub\n Kein Scrub\n \n \n Scrubbing is disabled\n Scrubbing ist deaktiviert\n \n \n No Deep Scrub\n Kein umfassender Scrub\n \n \n Deep Scrubbing is disabled\n Umfassendes Scrubbing ist deaktiviert\n \n \n No Backfill\n Kein Abgleich\n \n \n Backfilling of PGs is suspended\n Abgleich der Platzierungsgruppen ist ausgesetzt\n \n \n No Recover\n Keine Wiederherstellung\n \n \n Recovery of PGs is suspended\n Wiederherstellung der Platzierungsgruppen ist ausgesetzt\n \n \n Bitwise Sort\n Bitweise Sortierung\n \n \n Use bitwise sort\n Bitweise Sortierung verwenden\n \n \n Purged Snapdirs\n Bereinigte Snapdirs\n \n \n OSDs have converted snapsets\n OSDs besitzen konvertierte Snapsets\n \n \n Recovery Deletes\n L\xf6schvorg\xe4nge bei Wiederherstellungen\n \n \n Deletes performed during recovery instead of peering\n Bei der Wiederherstellung anstelle des Peerings durchgef\xfchrte L\xf6schvorg\xe4nge\n \n \n PG Log Hard Limit\n Hardlimit f\xfcr Platzierungsgruppen-Protokoll\n \n \n Puts a hard limit on pg log length\n Legt ein Hardlimit f\xfcr die Platzierungsgruppen-Protokolll\xe4nge fest\n \n \n Updated OSD Flags\n Aktualisierte OSD-Flags\n \n \n out\n aus\n \n \n in\n ein\n \n \n down\n ausgefallen\n \n \n Mark\n Markieren\n \n \n OSD lost\n OSD verloren\n \n \n marked lost\n markierter Verlust\n \n \n Purge\n Bereinigen\n \n \n OSD\n OSD\n \n \n purged\n bereinigt\n \n \n destroy\n vernichten\n \n \n destroyed\n vernichtet\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n Platzierungsgruppen\n \n \n Read bytes\n Bytes f\xfcr Lesevorgang\n \n \n Writes bytes\n Bytes f\xfcr Schreibvorgang\n \n \n Read ops\n Lesevorg\xe4nge\n \n \n Write ops\n Schreibvorg\xe4nge\n \n \n Mark OSD \n \n \n OSD \n markieren\n \n \n \n Mark \n \n \n \n markieren\n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n Max. Abgleiche\n \n \n Recovery Max Active\n Wiederherstellung, max. aktiv\n \n \n Recovery Max Single Start\n Wiederherstellung, max. - einzelner Start\n \n \n Recovery Sleep\n Wiederherstellung - Inaktivit\xe4t\n \n \n Custom\n Benutzerdefiniert\n \n \n Updated OSD recovery speed priority "\n "\n \n Aktualisierte OSD-Wiederherstellungsgeschwindigkeits-Priorit\xe4t &quot;\n &quot;\n \n \n \n \n was initialized in the following OSD: \n \n \n \n wurde im folgenden OSD initialisiert: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n Auftrag\n \n \n Severity\n Schweregrad\n \n \n Started\n Gestartet\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Aktualisiert\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n Verwendet\n \n \n Avail.\n Verf.\n \n \n Clean\n Bereinigen\n \n \n Working\n In Bearbeitung\n \n \n Warning\n Warnung\n \n \n Unknown\n Unbekannt\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n aktiv\n \n \n no filesystems\n keine Dateisysteme\n \n \n active\n aktiv\n \n \n standby\n Standby\n \n \n n/a\n n. v.\n \n \n active daemon\n aktiver Daemon\n \n \n quorum\n Quorum\n \n \n The NFS Ganesha service is not configured.\n Der NFS Ganesha-Dienst ist nicht konfiguriert.\n \n \n Transport\n Transport\n \n \n CephFS User\n CephFS-Benutzer\n \n \n CephFS Filesystem\n CephFS-Dateisystem\n \n \n (inherited from global config)\n (aus globaler Konfiguration \xfcbernommen)\n \n \n inherited from global config\n aus globaler Konfiguration \xfcbernommen\n \n \n -- Select what kind of user id squashing is performed --\n -- Durchzuf\xfchrende Benutzer-ID-Squashing-Art ausw\xe4hlen --\n \n \n There are no daemons available.\n Keine Daemons verf\xfcgbar.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Cache-Modus\n \n \n Min Evict Age\n Min. Alter f\xfcr Vertreibung\n \n \n Min Flush Age\n Min. Alter f\xfcr Leerung\n \n \n Target Max Bytes\n Max. Bytes f\xfcr Ziel\n \n \n Target Max Objects\n Max. Objekte f\xfcr Ziel\n \n \n No applications added\n Keine Anwendungen hinzugef\xfcgt\n \n \n Applications limit reached\n Anwendungslimit erreicht\n \n \n A pool can only have up to four applications definitions.\n Ein Pool kann nur bis zu vier Anwendungsdefinitionen aufweisen.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n Zul\xe4ssige Zeichen \'_a-zA-Z0-9\'\n \n \n Maximum length is 128 characters\n Maximale L\xe4nge betr\xe4gt 128 Zeichen\n \n \n Filter or add applications\n Anwendungen filtern oder hinzuf\xfcgen\n \n \n Add application\n Anwendung hinzuf\xfcgen\n \n \n pool\n pool\n \n \n erasure code profile\n L\xf6schcode-Profil\n \n \n Replica Size\n Gr\xf6\xdfe des Replikats\n \n \n Last Change\n Letzte \xc4nderung\n \n \n Erasure Coded Profile\n Profil mit L\xf6schcodierung\n \n \n Crush Ruleset\n Crush-Regelsatz\n \n \n Write bytes\n Bytes f\xfcr Schreibvorgang\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n Bucket\n \n \n Updated Object Gateway bucket "\n "\n \n Aktualisierter Objektgateway-Bucket &quot;\n &quot;\n \n \n \n Created Object Gateway bucket "\n "\n \n Erstellter Objektgateway-Bucket &quot;\n &quot;\n \n \n \n buckets\n Buckets\n \n \n capability\n capability\n \n \n user\n Benutzer\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Aktualisierter Objektgatewaybenutzer &quot;\n &quot;\n \n \n \n Created Object Gateway user "\n "\n \n Erstellter Objektgatewaybenutzer &quot;\n &quot;\n \n \n \n users\n Benutzer\n \n \n Swift Key\n Swift Key\n \n \n Scope\n Bereich\n \n \n Read\n Lesen\n \n \n Create\n Erstellen\n \n \n role\n role\n \n \n Created role \'\n \'\n \n Erstellte Rolle \'\n \'\n \n \n \n Updated role \'\n \'\n \n Aktualisierte Rolle \'\n \'\n \n \n \n System Role\n Systemrolle\n \n \n Deleted role \'\n \'\n \n Gel\xf6schte Rolle \'\n \'\n \n \n \n Created user "\n "\n \n Erstellter Benutzer &quot;\n &quot;\n \n \n \n Update user\n Benutzer aktualisieren\n \n \n Continue\n Fortfahren\n \n \n You were automatically logged out because your roles have been changed.\n Sie wurden automatisch abgemeldet, da Ihre Rollen ge\xe4ndert wurden.\n \n \n Updated user "\n "\n \n Aktualisierter Benutzer &quot;\n &quot;\n \n \n \n Deleted user "\n "\n \n Gel\xf6schter Benutzer &quot;\n &quot;\n \n \n \n Failed to delete user "\n "\n \n Fehler beim L\xf6schen des Benutzers &quot;\n &quot;\n \n \n \n You are currently logged in as "\n ".\n \n Sie sind derzeit angemeldet als &quot;\n &quot;.\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Jedes Objekt wird in Datenbl\xf6cke aufgeteilt und jeweils auf einem anderen OSD gespeichert.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Berechnen Sie Codierungsdatenbl\xf6cke f\xfcr jedes Objekt und speichern Sie sie auf unterschiedlichen OSDs.\n Die Anzahl der Codierungsdatenbl\xf6cke entspricht auch der Anzahl der OSDs, die ausfallen k\xf6nnen, ohne dass Daten verloren gehen.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Das jerasure-Modul ist das allgemeinste und flexibelste Modul\n und fungiert auch als der Standard f\xfcr Ceph-Pools mit L\xf6schcodierung.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n Die flexiblere Technik ist \'reed_sol_van :\', wobei es ausreicht, k\n und m festzulegen. Die Technik \'cauchy_good\' kann schneller sein. Sie m\xfcssen jedoch die Paketgr\xf6\xdfe sorgf\xe4ltig\n ausw\xe4hlen. S\xe4mtliche \'reed_sol_r6_op\'-, \'liberation\'-, \'blaum_roth\'- und \'liber8tion\'-Vorg\xe4nge sind dahingehend RAID6-Entsprechungen,\n dass sie nur mit \'m=2\' konfiguriert werden k\xf6nnen.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n Die Codierung wird jeweils f\xfcr Pakete auf Bytes-Gr\xf6\xdfe vorgenommen.\n Die Auswahl der richtigen Paketgr\xf6\xdfe ist schwierig.\n In der Jerasure-Dokumentation sind ausf\xfchrliche Informationen zu diesem Thema enthalten.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n Bei Verwendung des Jerasure-Moduls, wenn ein Objekt mit L\xf6schcodierung auf mehreren OSDs gespeichert ist,\n m\xfcssen alle anderen OSDs gelesen werden, um die verloren gegangenen Daten eines OSDs wiederherzustellen.\n Wenn jerasure beispielsweise mit \'k=8\' und \'m=4\' konfiguriert ist,\n m\xfcssen bei Verlust eines OSDs zum Reparieren die elf anderen gelesen werden.\n\n Das lrc-L\xf6schcode-Modul erstellt lokale Parit\xe4tsdatenbl\xf6cke, um die Wiederherstellung mit weniger OSDs auszuf\xfchren.\n Wenn lrc beispielsweise mit \'k=8\', \'m=4\' und \'l=4\' konfiguriert ist, wird ein zus\xe4tzlicher Parit\xe4tsdatenblock f\xfcr jeweils vier OSDs erstellt.\n Geht ein einzelnes OSD verloren, kann es mit nur vier OSDs anstelle\n von elf wiederhergestellt werden.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Gruppieren Sie die Codierungs- und Datenbl\xf6cke in S\xe4tze entsprechend dem Speicherort.\n Beispielsweise werden f\xfcr \'k=4\' und \'m=2\', wenn der Speicherort \'3\' entspricht, zwei Dreiergruppen erstellt.\n Jeder Satz kann wiederhergestellt werden, ohne dass Datenbl\xf6cke aus einem anderen Satz gelesen werden.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n Der Typ des Crush-Buckets, in dem jeder durch l definierte Satz von Datenbl\xf6cken gespeichert wird.\n Wenn er beispielsweise auf \'rack\' festgelegt ist, wird jede Gruppe an l-Datenbl\xf6cken in einem anderen Rack platziert.\n Er wird zum Erstellen eines CRUSH-Regelschritts verwendet, beispielsweise f\xfcr einen Schritt zum Ausw\xe4hlen des Racks.\n Wenn er nicht festgelegt ist, wird keine solche Gruppierung vorgenommen.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n Das isa-Modul kapselt die ISA-Bibliothek und wird nur auf Intel-Prozessoren ausgef\xfchrt.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n Das ISA-Modul wird in zwei Reed Solomon-Formularen bereitgestellt.\n Wenn \'reed_sol_van\' festgelegt ist, entspricht dies Vandermonde. Ist \'cauchy\' festgelegt, entspricht dies \'Cauchy\'.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n Das shec-Modul kapselt die SHEC-Mehrfachbibliothek.\n Dadurch kann ceph Daten effizienter wiederherstellen als Reed Solomon-Codes.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n Die Anzahl der Parit\xe4tsdatenbl\xf6cke, von denen jeder jeden Datenblock in seinem Berechnungsbereich enth\xe4lt.\n Die Anzahl wird als eine Dauerhaftigkeitssch\xe4tzung verwendet. Wenn beispielsweise \'c=2\' vorliegt,\n k\xf6nnen 2 OSDs ausfallen, ohne dass Daten verloren gehen.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n Der Name des f\xfcr den ersten Schritt der CRUSH-Regel verwendeten Crush-Buckets.\n Beispielsweise \'step take default\'.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n Stellen Sie sicher, dass sich keine zwei Datenbl\xf6cke in einem Bucket mit derselben Ausfalldom\xe4ne befinden.\n Wenn die Ausfalldom\xe4ne beispielsweise als Host fungiert, werden keine zwei Datenbl\xf6cke auf demselben Host gespeichert.\n Er wird zum Erstellen eines CRUSH-Regelschritts verwendet, beispielsweise \'step chooseleaf host\'.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Schr\xe4nken Sie mithilfe der Klassennamen f\xfcr Crush-Ger\xe4te in der CRUSH-Zuordnung die Platzierung\n auf Ger\xe4te einer bestimmten Klasse (z. B. SSD oder HDD) ein.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n Legen Sie den Verzeichnisnamen fest, \xfcber den das L\xf6schcode-Modul geladen wird.\n \n \n Allows all operations\n L\xe4sst alle Vorg\xe4nge zu\n \n \n Allows only operations that do not modify the server\n L\xe4sst nur Vorg\xe4nge zu, die den Server nicht \xe4ndern\n \n \n Does not allow read or write operations, but allows any other operation\n L\xe4sst weder Lese- noch Schreibvorg\xe4nge zu, jedoch alle anderen Vorg\xe4nge\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n L\xe4sst Lese-/Schreibvorg\xe4nge und andere Vorg\xe4nge nicht zu, die Dateiattribute oder Verzeichnisinhalte \xe4ndern\n \n \n Allows no access at all\n L\xe4sst \xfcberhaupt keinen Zugriff zu\n \n \n -- Select the priority --\n -- Priorit\xe4t ausw\xe4hlen --\n \n \n Low\n Niedrig\n \n \n High\n Hoch\n \n \n Last 5 minutes\n Letzte 5 Minuten\n \n \n Last 15 minutes\n Letzte 15 Minuten\n \n \n Last 30 minutes\n Letzte 30 Minuten\n \n \n Last 1 hour (Default)\n Letzte Stunde (Standard)\n \n \n Last 3 hours\n Letzte 3 Stunden\n \n \n Last 6 hours\n Letzte 6 Stunden\n \n \n Last 12 hours\n Letzte 12 Stunden\n \n \n Last 24 hours\n Letzte 24 Stunden\n \n \n Yesterday\n Gestern\n \n \n Today\n Heute\n \n \n Today so far\n Heute bisher\n \n \n Day before yesterday\n Vorgestern\n \n \n Last 2 days\n Letzte 2 Tage\n \n \n This day last week\n Dieser Tag letzte Woche\n \n \n Previous week\n Vorwoche\n \n \n This week\n Diese Woche\n \n \n This week so far\n Diese Woche bisher\n \n \n Last 7 days\n Letzte 7 Tage\n \n \n Previous month\n Vormonat\n \n \n This month\n Dieser Monat\n \n \n This month so far\n Dieser Monat bisher\n \n \n Last 30 days\n Letzte 30 Tage\n \n \n Last 90 days\n Letzte 90 Tage\n \n \n Last 6 months\n Letzte 6 Monate\n \n \n Last 1 year\n Letztes Jahr\n \n \n Previous year\n Vorjahr\n \n \n This year\n Dieses Jahr\n \n \n This year so far\n Dieses Jahr bisher\n \n \n Last 2 years\n Letzte 2 Jahre\n \n \n Last 5 years\n Letzte 5 Jahre\n \n \n Information\n Informationen\n \n \n No items selected.\n Keine Elemente ausgew\xe4hlt.\n \n \n Deselect item to select again\n Elementauswahl zum erneuten Ausw\xe4hlen aufheben\n \n \n Selection limit reached\n Auswahllimit erreicht\n \n \n Filter tags\n Tags filtern\n \n \n Add badge\n Badge hinzuf\xfcgen\n \n \n There are no items available.\n Keine Elemente verf\xfcgbar.\n \n \n Add\n Hinzuf\xfcgen\n \n \n Remove\n Remove\n \n \n Clone\n Klonen\n \n \n Copy\n Kopieren\n \n \n Deep Scrub\n Umfassender Scrub\n \n \n Destroy\n Vernichten\n \n \n Flatten\n Vereinfachen\n \n \n Mark Down\n Als ausgefallen markieren\n \n \n Mark In\n Mit Befehl \'In\' markieren\n \n \n Mark Lost\n Als verloren markieren\n \n \n Mark Out\n Mit Befehl \'Out\' markieren\n \n \n Protect\n Sch\xfctzen\n \n \n Rename\n Umbenennen\n \n \n Restore\n Wiederherstellen\n \n \n Move to Trash\n In Papierkorb verschieben\n \n \n Unprotect\n Schutz aufheben\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Gel\xf6scht\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Geklont\n \n \n Copied\n Kopiert\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n Ja\n \n \n No\n Nein\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Quality of Service\n \n \n BPS Limit\n BPS-Limit\n \n \n The desired limit of IO bytes per second.\n Das gew\xfcnschte Limit der E/A-Bytes pro Sekunde.\n \n \n IOPS Limit\n IOPS-Limit\n \n \n The desired limit of IO operations per second.\n Das gew\xfcnschte Limit der E/A-Vorg\xe4nge pro Sekunde.\n \n \n Read BPS Limit\n BPS-Limit f\xfcr Lesevorg\xe4nge\n \n \n The desired limit of read bytes per second.\n Das gew\xfcnschte Limit der gelesenen Bytes pro Sekunde.\n \n \n Read IOPS Limit\n IOPS-Limit f\xfcr Lesevorg\xe4nge\n \n \n The desired limit of read operations per second.\n Das gew\xfcnschte Limit f\xfcr Lesevorg\xe4nge pro Sekunde.\n \n \n Write BPS Limit\n BPS-Limit f\xfcr Schreibvorg\xe4nge\n \n \n The desired limit of write bytes per second.\n Das gew\xfcnschte Limit der geschriebenen Bytes pro Sekunde.\n \n \n Write IOPS Limit\n IOPS-Limit f\xfcr Schreibvorg\xe4nge\n \n \n The desired limit of write operations per second.\n Das gew\xfcnschte Limit f\xfcr Schreibvorg\xe4nge pro Sekunde.\n \n \n BPS Burst\n BPS-Block\n \n \n The desired burst limit of IO bytes.\n Das gew\xfcnschte Blocklimit der E/A-Bytes.\n \n \n IOPS Burst\n IOPS-Block\n \n \n The desired burst limit of IO operations.\n Das gew\xfcnschte Blocklimit der E/A-Vorg\xe4nge.\n \n \n Read BPS Burst\n BPS-Block f\xfcr Lesevorg\xe4nge\n \n \n The desired burst limit of read bytes.\n Das gew\xfcnschte Blocklimit der gelesenen Bytes.\n \n \n Read IOPS Burst\n IOPS-Block f\xfcr Lesevorg\xe4nge\n \n \n The desired burst limit of read operations.\n Das gew\xfcnschte Blocklimit der Lesevorg\xe4nge.\n \n \n Write BPS Burst\n BPS-Block f\xfcr Schreibvorg\xe4nge\n \n \n The desired burst limit of write bytes.\n Das gew\xfcnschte Blocklimit der geschriebenen Bytes.\n \n \n Write IOPS Burst\n IOPS-Block f\xfcr Schreibvorg\xe4nge\n \n \n The desired burst limit of write operations.\n Das gew\xfcnschte Blocklimit der Schreibvorg\xe4nge.\n \n \n Failed to \n \n \n \n Fehler bei \n \n \n \n \n \n Executing\n Wird ausgef\xfchrt\n \n \n execute\n ausf\xfchren\n \n \n Executed\n Ausgef\xfchrt\n \n \n unknown task\n Unbekannte Aufgabe\n \n \n Creating\n Wird erstellt\n \n \n create\n erstellen\n \n \n Updating\n Wird aktualisiert\n \n \n update\n aktualisieren\n \n \n Deleting\n Wird gel\xf6scht\n \n \n delete\n l\xf6schen\n \n \n RBD \'\n \'\n \n RBD \'\n \'\n \n \n \n RBD snapshot \'\n \'\n \n RBD-Snapshot \'\n \'\n \n \n \n mirror mode for pool \'\n \'\n \n Spiegelungsmodus f\xfcr Pool \'\n \'\n \n \n \n mirror peer for pool \'\n \'\n \n Peer f\xfcr Pool \'\n \' spiegeln\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n Name wird bereits von \n verwendet.\n \n \n \n Name is already used by \n .\n \n Name wird bereits von \n verwendet.\n \n \n \n Name is already used by \n .\n \n Name wird bereits von \n verwendet.\n \n \n \n \n contains snapshots.\n \n \n enth\xe4lt Snapshots.\n \n \n \n Cloning\n Wird geklont\n \n \n clone\n klonen\n \n \n Snapshot of \n must be protected.\n \n Snapshot von \n muss gesch\xfctzt sein.\n \n \n \n Copying\n Wird kopiert\n \n \n copy\n kopieren\n \n \n Flattening\n Wird vereinfacht\n \n \n flatten\n vereinfachen\n \n \n Flattened\n Vereinfacht\n \n \n Name is already used by \n .\n \n Name wird bereits von \n verwendet.\n \n \n \n Cannot unprotect \n because it contains child images.\n \n Der Schutz von \n kann aufgrund enthaltener untergeordneter Images nicht aufgehoben werden.\n \n \n \n Cannot delete \n because it\'s protected.\n \n Kann \n nicht l\xf6schen, da es gesch\xfctzt ist.\n \n \n \n Rolling back\n Rollback wird ausgef\xfchrt\n \n \n rollback\n Rollback\n \n \n Rolled back\n Rollback wurde ausgef\xfchrt\n \n \n Moving\n Wird verschoben\n \n \n move\n verschieben\n \n \n Moved\n Verschoben\n \n \n image \'\n \' to trash\n \n Image \'\n \' in Papierkorb verschieben\n \n \n \n Could not find image.\n Image konnte nicht gefunden werden.\n \n \n Restoring\n Wird wiederhergestellt\n \n \n restore\n wiederherstellen\n \n \n Restored\n Wiederhergestellt\n \n \n image \'\n \' into \'\n \'\n \n Image \'\n \' in \'\n \' verschieben\n \n \n \n Image name \'\n \' is already in use.\n \n Image-Name \'\n \' wird bereits verwendet.\n \n \n \n image \'\n \'\n \n Image \'\n \'\n \n \n \n Purging\n Wird bereinigt\n \n \n purge\n bereinigen\n \n \n Purged\n Bereinigt\n \n \n all pools\n alle Pools\n \n \n images from \n \n \n Images von \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n Spiegelung kann nicht deaktiviert werden, da sie einen Peer enth\xe4lt.\n \n \n pool \'\n \'\n \n Pool \'\n \'\n \n \n \n erasure code profile \'\n \'\n \n L\xf6schcode-Profil \'\n \'\n \n \n \n target \'\n \'\n \n Ziel \'\n \'\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},ByF4:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("fo",{months:"januar_februar_mars_apr\xedl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_m\xe1nadagur_t\xfdsdagur_mikudagur_h\xf3sdagur_fr\xedggjadagur_leygardagur".split("_"),weekdaysShort:"sun_m\xe1n_t\xfds_mik_h\xf3s_fr\xed_ley".split("_"),weekdaysMin:"su_m\xe1_t\xfd_mi_h\xf3_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D. MMMM, YYYY HH:mm"},calendar:{sameDay:"[\xcd dag kl.] LT",nextDay:"[\xcd morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\xcd gj\xe1r kl.] LT",lastWeek:"[s\xed\xf0stu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s s\xed\xf0ani",s:"f\xe1 sekund",ss:"%d sekundir",m:"ein minuttur",mm:"%d minuttir",h:"ein t\xedmi",hh:"%d t\xedmar",d:"ein dagur",dd:"%d dagar",M:"ein m\xe1na\xf0ur",MM:"%d m\xe1na\xf0ir",y:"eitt \xe1r",yy:"%d \xe1r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},C6Ij:function(t,e,n){"use strict";var a=n("CcnG"),r=n("TZo1"),i=n("9Kw/"),s=n("Jm/i"),o=n("Ip0R"),u=n("xbqr"),c=n("9GXa"),l=n("M/6F"),d=n("NDi4");n("AWcq"),n.d(e,"a",function(){return f}),n.d(e,"b",function(){return v});var f=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function p(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,[" for "])),(t()(),a["\u0275eld"](2,0,null,null,0,"span",[],[[8,"innerHTML",1]],null,null,null,null))],null,function(t,e){t(e,2,0,e.component.statusFor)})}function h(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,6,"cd-info-panel",[],null,null,null,r.b,r.a)),a["\u0275did"](1,49152,null,0,i.a,[s.a],null,null),(t()(),a["\u0275eld"](2,0,null,0,4,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Retrieving data"])),(t()(),a["\u0275and"](16777216,null,null,1,null,p)),a["\u0275did"](5,16384,null,0,o.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275ted"](-1,null,[". Please wait..."]))],function(t,e){t(e,5,0,e.component.statusFor)},null)}function g(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,[" for "])),(t()(),a["\u0275eld"](2,0,null,null,0,"span",[],[[8,"innerHTML",1]],null,null,null,null))],null,function(t,e){t(e,2,0,e.component.statusFor)})}function b(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,6,"cd-warning-panel",[],null,null,null,u.b,u.a)),a["\u0275did"](1,49152,null,0,c.a,[],null,null),(t()(),a["\u0275eld"](2,0,null,0,4,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Displaying previously cached data"])),(t()(),a["\u0275and"](16777216,null,null,1,null,g)),a["\u0275did"](5,16384,null,0,o.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275ted"](-1,null,["."]))],function(t,e){t(e,5,0,e.component.statusFor)},null)}function m(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,[" for "])),(t()(),a["\u0275eld"](2,0,null,null,0,"span",[],[[8,"innerHTML",1]],null,null,null,null))],null,function(t,e){t(e,2,0,e.component.statusFor)})}function y(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,6,"cd-error-panel",[],null,null,null,l.b,l.a)),a["\u0275did"](1,49152,null,0,d.a,[],null,null),(t()(),a["\u0275eld"](2,0,null,0,4,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Could not load data"])),(t()(),a["\u0275and"](16777216,null,null,1,null,m)),a["\u0275did"](5,16384,null,0,o.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275ted"](-1,null,[". Please check the cluster health."]))],function(t,e){t(e,5,0,e.component.statusFor)},null)}function v(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,h)),a["\u0275did"](1,16384,null,0,o.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,b)),a["\u0275did"](3,16384,null,0,o.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,y)),a["\u0275did"](5,16384,null,0,o.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.status===n.vcs.ValueNone),t(e,3,0,n.status===n.vcs.ValueStale),t(e,5,0,n.status===n.vcs.ValueException)},null)}},CDJp:function(t,e,n){"use strict";var a=n("RDha");t.exports={_set:function(t,e){return a.merge(this[t]||(this[t]={}),e)}}},CS9Q:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("mrSG"),r=n("siIJ"),i=function(t){function e(n,a){void 0===a&&(a=r.a.now);var i=t.call(this,n,function(){return e.delegate&&e.delegate!==i?e.delegate.now():a()})||this;return i.actions=[],i.active=!1,i.scheduled=void 0,i}return a.__extends(e,t),e.prototype.schedule=function(n,a,r){return void 0===a&&(a=0),e.delegate&&e.delegate!==this?e.delegate.schedule(n,a,r):t.prototype.schedule.call(this,n,a,r)},e.prototype.flush=function(t){var e=this.actions;if(this.active)e.push(t);else{var n;this.active=!0;do{if(n=t.execute(t.state,t.delay))break}while(t=e.shift());if(this.active=!1,n){for(;t=e.shift();)t.unsubscribe();throw n}}},e}(r.a)},CVuo:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.camelCase=function(t){return(t=(t=(t=t.replace(/[^a-zA-Z0-9 ]/g," ")).replace(/([a-z](?=[A-Z]))/g,"$1 ")).replace(/([^a-zA-Z0-9 ])|^[0-9]+/g,"").trim().toLowerCase()).replace(/([ 0-9]+)([a-zA-Z])/g,function(t,e,n){return e.trim()+n.toUpperCase()})},e.deCamelCase=function(t){return t.replace(/([A-Z])/g,function(t){return" "+t}).replace(/^./,function(t){return t.toUpperCase()})}},Cc8h:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("DtyJ"),o=n("ahDk");n("czA5"),e.LongPressDirective=function(){function t(){this.pressEnabled=!0,this.duration=500,this.longPressStart=new i.EventEmitter,this.longPressing=new i.EventEmitter,this.longPressEnd=new i.EventEmitter,this.mouseX=0,this.mouseY=0}return Object.defineProperty(t.prototype,"press",{get:function(){return this.pressing},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isLongPress",{get:function(){return this.isLongPressing},enumerable:!0,configurable:!0}),t.prototype.onMouseDown=function(t){var e=this;if(1===t.which&&this.pressEnabled&&!t.target.classList.contains("resize-handle")){this.mouseX=t.clientX,this.mouseY=t.clientY,this.pressing=!0,this.isLongPressing=!1;var n=s.fromEvent(document,"mouseup");this.subscription=n.subscribe(function(t){return e.onMouseup()}),this.timeout=setTimeout(function(){e.isLongPressing=!0,e.longPressStart.emit({event:t,model:e.pressModel}),e.subscription.add(s.fromEvent(document,"mousemove").pipe(o.takeUntil(n)).subscribe(function(t){return e.onMouseMove(t)})),e.loop(t)},this.duration),this.loop(t)}},t.prototype.onMouseMove=function(t){if(this.pressing&&!this.isLongPressing){var e=Math.abs(t.clientX-this.mouseX)>10,n=Math.abs(t.clientY-this.mouseY)>10;(e||n)&&this.endPress()}},t.prototype.loop=function(t){var e=this;this.isLongPressing&&(this.timeout=setTimeout(function(){e.longPressing.emit({event:t,model:e.pressModel}),e.loop(t)},50))},t.prototype.endPress=function(){clearTimeout(this.timeout),this.isLongPressing=!1,this.pressing=!1,this._destroySubscription(),this.longPressEnd.emit({model:this.pressModel})},t.prototype.onMouseup=function(){this.endPress()},t.prototype.ngOnDestroy=function(){this._destroySubscription()},t.prototype._destroySubscription=function(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)},a([i.Input(),r("design:type",Boolean)],t.prototype,"pressEnabled",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"pressModel",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"duration",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"longPressStart",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"longPressing",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"longPressEnd",void 0),a([i.HostBinding("class.press"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"press",null),a([i.HostBinding("class.longpress"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isLongPress",null),a([i.HostListener("mousedown",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onMouseDown",null),a([i.Directive({selector:"[long-press]"})],t)}()},CcnG:function(t,e,n){"use strict";n.r(e),n.d(e,"\u0275angular_packages_core_core_t",function(){return Xh}),n.d(e,"\u0275angular_packages_core_core_q",function(){return Kh}),n.d(e,"\u0275angular_packages_core_core_r",function(){return $h}),n.d(e,"\u0275angular_packages_core_core_s",function(){return Zh}),n.d(e,"\u0275angular_packages_core_core_h",function(){return Zf}),n.d(e,"\u0275angular_packages_core_core_o",function(){return kh}),n.d(e,"\u0275angular_packages_core_core_p",function(){return Ph}),n.d(e,"\u0275angular_packages_core_core_n",function(){return gh}),n.d(e,"\u0275angular_packages_core_core_m",function(){return hh}),n.d(e,"\u0275angular_packages_core_core_c",function(){return po}),n.d(e,"\u0275angular_packages_core_core_d",function(){return Ae}),n.d(e,"\u0275angular_packages_core_core_e",function(){return Hf}),n.d(e,"\u0275angular_packages_core_core_f",function(){return Df}),n.d(e,"\u0275angular_packages_core_core_g",function(){return jf}),n.d(e,"\u0275angular_packages_core_core_l",function(){return rd}),n.d(e,"\u0275angular_packages_core_core_u",function(){return Sp}),n.d(e,"\u0275angular_packages_core_core_w",function(){return _p}),n.d(e,"\u0275angular_packages_core_core_v",function(){return vp}),n.d(e,"\u0275angular_packages_core_core_z",function(){return wp}),n.d(e,"\u0275angular_packages_core_core_x",function(){return xp}),n.d(e,"\u0275angular_packages_core_core_y",function(){return Tp}),n.d(e,"\u0275angular_packages_core_core_bc",function(){return kn}),n.d(e,"\u0275angular_packages_core_core_bj",function(){return p}),n.d(e,"\u0275angular_packages_core_core_bd",function(){return Xe}),n.d(e,"\u0275angular_packages_core_core_be",function(){return Qe}),n.d(e,"\u0275angular_packages_core_core_bf",function(){return mn}),n.d(e,"\u0275angular_packages_core_core_bi",function(){return rr}),n.d(e,"\u0275angular_packages_core_core_bm",function(){return Xt}),n.d(e,"\u0275angular_packages_core_core_i",function(){return du}),n.d(e,"\u0275angular_packages_core_core_j",function(){return fu}),n.d(e,"\u0275angular_packages_core_core_k",function(){return pu}),n.d(e,"\u0275angular_packages_core_core_a",function(){return N}),n.d(e,"\u0275angular_packages_core_core_b",function(){return R}),n.d(e,"\u0275angular_packages_core_core_bk",function(){return c}),n.d(e,"\u0275angular_packages_core_core_ba",function(){return Ub}),n.d(e,"\u0275angular_packages_core_core_bb",function(){return ug}),n.d(e,"createPlatform",function(){return Bp}),n.d(e,"assertPlatform",function(){return Wp}),n.d(e,"destroyPlatform",function(){return Kp}),n.d(e,"getPlatform",function(){return $p}),n.d(e,"PlatformRef",function(){return Zp}),n.d(e,"ApplicationRef",function(){return Jp}),n.d(e,"createPlatformFactory",function(){return Up}),n.d(e,"NgProbeToken",function(){return Hp}),n.d(e,"enableProdMode",function(){return zu}),n.d(e,"isDevMode",function(){return Fu}),n.d(e,"APP_ID",function(){return $f}),n.d(e,"PACKAGE_ROOT_URL",function(){return np}),n.d(e,"PLATFORM_INITIALIZER",function(){return Qf}),n.d(e,"PLATFORM_ID",function(){return tp}),n.d(e,"APP_BOOTSTRAP_LISTENER",function(){return ep}),n.d(e,"APP_INITIALIZER",function(){return Wf}),n.d(e,"ApplicationInitStatus",function(){return Kf}),n.d(e,"DebugElement",function(){return Ch}),n.d(e,"DebugNode",function(){return Ih}),n.d(e,"asNativeElements",function(){return bh}),n.d(e,"getDebugNode",function(){return Sh}),n.d(e,"Testability",function(){return qp}),n.d(e,"TestabilityRegistry",function(){return jp}),n.d(e,"setTestabilityGetter",function(){return Fp}),n.d(e,"TRANSLATIONS",function(){return Bh}),n.d(e,"TRANSLATIONS_FORMAT",function(){return Uh}),n.d(e,"LOCALE_ID",function(){return Hh}),n.d(e,"MissingTranslationStrategy",function(){return Wh}),n.d(e,"ApplicationModule",function(){return Jh}),n.d(e,"wtfCreateScope",function(){return Ip}),n.d(e,"wtfLeave",function(){return Cp}),n.d(e,"wtfStartTimeRange",function(){return kp}),n.d(e,"wtfEndTimeRange",function(){return Np}),n.d(e,"Type",function(){return ud}),n.d(e,"EventEmitter",function(){return hl}),n.d(e,"ErrorHandler",function(){return Sf}),n.d(e,"Sanitizer",function(){return Cu}),n.d(e,"SecurityContext",function(){return Iu}),n.d(e,"ANALYZE_FOR_ENTRY_COMPONENTS",function(){return A}),n.d(e,"Attribute",function(){return D}),n.d(e,"ContentChild",function(){return P}),n.d(e,"ContentChildren",function(){return L}),n.d(e,"Query",function(){return E}),n.d(e,"ViewChild",function(){return q}),n.d(e,"ViewChildren",function(){return M}),n.d(e,"Component",function(){return Yd}),n.d(e,"Directive",function(){return Gd}),n.d(e,"HostBinding",function(){return Wd}),n.d(e,"HostListener",function(){return Kd}),n.d(e,"Input",function(){return Bd}),n.d(e,"Output",function(){return Ud}),n.d(e,"Pipe",function(){return Vd}),n.d(e,"CUSTOM_ELEMENTS_SCHEMA",function(){return rf}),n.d(e,"NO_ERRORS_SCHEMA",function(){return sf}),n.d(e,"NgModule",function(){return of}),n.d(e,"ViewEncapsulation",function(){return at}),n.d(e,"Version",function(){return ku}),n.d(e,"VERSION",function(){return Nu}),n.d(e,"defineInjectable",function(){return v}),n.d(e,"defineInjector",function(){return _}),n.d(e,"forwardRef",function(){return X}),n.d(e,"resolveForwardRef",function(){return J}),n.d(e,"Injectable",function(){return gf}),n.d(e,"INJECTOR",function(){return fo}),n.d(e,"Injector",function(){return ho}),n.d(e,"inject",function(){return De}),n.d(e,"\u0275inject",function(){return De}),n.d(e,"InjectFlags",function(){return Ce}),n.d(e,"ReflectiveInjector",function(){return Vf}),n.d(e,"createInjector",function(){return Po}),n.d(e,"ResolvedReflectiveFactory",function(){return Pf}),n.d(e,"ReflectiveKey",function(){return Nf}),n.d(e,"InjectionToken",function(){return w}),n.d(e,"Inject",function(){return Te}),n.d(e,"Optional",function(){return we}),n.d(e,"Self",function(){return Se}),n.d(e,"SkipSelf",function(){return Oe}),n.d(e,"Host",function(){return Ie}),n.d(e,"NgZone",function(){return Rp}),n.d(e,"\u0275NoopNgZone",function(){return Mp}),n.d(e,"RenderComponentType",function(){return mu}),n.d(e,"Renderer",function(){return vu}),n.d(e,"Renderer2",function(){return wu}),n.d(e,"RendererFactory2",function(){return xu}),n.d(e,"RendererStyleFlags2",function(){return Tu}),n.d(e,"RootRenderer",function(){return _u}),n.d(e,"COMPILER_OPTIONS",function(){return mp}),n.d(e,"Compiler",function(){return bp}),n.d(e,"CompilerFactory",function(){return yp}),n.d(e,"ModuleWithComponentFactories",function(){return rp}),n.d(e,"ComponentFactory",function(){return Xo}),n.d(e,"\u0275ComponentFactory",function(){return Xo}),n.d(e,"ComponentRef",function(){return Zo}),n.d(e,"ComponentFactoryResolver",function(){return ru}),n.d(e,"ElementRef",function(){return hu}),n.d(e,"NgModuleFactory",function(){return uu}),n.d(e,"NgModuleRef",function(){return ou}),n.d(e,"NgModuleFactoryLoader",function(){return td}),n.d(e,"getModuleFactory",function(){return sd}),n.d(e,"QueryList",function(){return th}),n.d(e,"SystemJsNgModuleLoader",function(){return ah}),n.d(e,"SystemJsNgModuleLoaderConfig",function(){return eh}),n.d(e,"TemplateRef",function(){return gl}),n.d(e,"ViewContainerRef",function(){return ih}),n.d(e,"EmbeddedViewRef",function(){return fh}),n.d(e,"ViewRef",function(){return dh}),n.d(e,"ChangeDetectionStrategy",function(){return j}),n.d(e,"ChangeDetectorRef",function(){return uh}),n.d(e,"DefaultIterableDiffer",function(){return Rh}),n.d(e,"IterableDiffers",function(){return jh}),n.d(e,"KeyValueDiffers",function(){return Fh}),n.d(e,"SimpleChange",function(){return la}),n.d(e,"WrappedValue",function(){return ca}),n.d(e,"platformCore",function(){return Vh}),n.d(e,"\u0275ALLOW_MULTIPLE_PLATFORMS",function(){return Vp}),n.d(e,"\u0275APP_ID_RANDOM_PROVIDER",function(){return Xf}),n.d(e,"\u0275defaultIterableDiffers",function(){return Gh}),n.d(e,"\u0275defaultKeyValueDiffers",function(){return Yh}),n.d(e,"\u0275devModeEqual",function(){return ua}),n.d(e,"\u0275isListLikeIterable",function(){return da}),n.d(e,"\u0275ChangeDetectorStatus",function(){return F}),n.d(e,"\u0275isDefaultChangeDetectionStrategy",function(){return z}),n.d(e,"\u0275Console",function(){return ap}),n.d(e,"\u0275getInjectableDef",function(){return x}),n.d(e,"\u0275setCurrentInjector",function(){return Ne}),n.d(e,"\u0275APP_ROOT",function(){return No}),n.d(e,"\u0275ivyEnabled",function(){return tg}),n.d(e,"\u0275CodegenComponentFactoryResolver",function(){return iu}),n.d(e,"\u0275resolveComponentResources",function(){return Q}),n.d(e,"\u0275ReflectionCapabilities",function(){return pd}),n.d(e,"\u0275RenderDebugInfo",function(){return yu}),n.d(e,"\u0275_sanitizeHtml",function(){return oc}),n.d(e,"\u0275_sanitizeStyle",function(){return Bl}),n.d(e,"\u0275_sanitizeUrl",function(){return Hu}),n.d(e,"\u0275global",function(){return V}),n.d(e,"\u0275looseIdentical",function(){return K}),n.d(e,"\u0275stringify",function(){return $}),n.d(e,"\u0275makeDecorator",function(){return C}),n.d(e,"\u0275isObservable",function(){return Uf}),n.d(e,"\u0275isPromise",function(){return Bf}),n.d(e,"\u0275clearOverrides",function(){return ky}),n.d(e,"\u0275initServicesIfNeeded",function(){return Vm}),n.d(e,"\u0275overrideComponentView",function(){return Cy}),n.d(e,"\u0275overrideProvider",function(){return Iy}),n.d(e,"\u0275NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR",function(){return Qb}),n.d(e,"\u0275defineBase",function(){return ft}),n.d(e,"\u0275defineComponent",function(){return ot}),n.d(e,"\u0275defineDirective",function(){return pt}),n.d(e,"\u0275definePipe",function(){return ht}),n.d(e,"\u0275defineNgModule",function(){return lt}),n.d(e,"\u0275detectChanges",function(){return gs}),n.d(e,"\u0275renderComponent",function(){return $s}),n.d(e,"\u0275Render3ComponentFactory",function(){return Pu}),n.d(e,"\u0275Render3ComponentRef",function(){return Mu}),n.d(e,"\u0275directiveInject",function(){return Ps}),n.d(e,"\u0275injectAttribute",function(){return Ms}),n.d(e,"\u0275getFactoryOf",function(){return qn}),n.d(e,"\u0275getInheritedFactory",function(){return jn}),n.d(e,"\u0275templateRefExtractor",function(){return Ll}),n.d(e,"\u0275ProvidersFeature",function(){return $o}),n.d(e,"\u0275InheritDefinitionFeature",function(){return no}),n.d(e,"\u0275NgOnChangesFeature",function(){return io}),n.d(e,"\u0275LifecycleHooksFeature",function(){return Qs}),n.d(e,"\u0275Render3NgModuleRef",function(){return Wc}),n.d(e,"\u0275markDirty",function(){return vs}),n.d(e,"\u0275NgModuleFactory",function(){return Kc}),n.d(e,"\u0275NO_CHANGE",function(){return ha}),n.d(e,"\u0275container",function(){return ns}),n.d(e,"\u0275nextContext",function(){return di}),n.d(e,"\u0275elementStart",function(){return xi}),n.d(e,"\u0275namespaceHTML",function(){return mi}),n.d(e,"\u0275namespaceMathML",function(){return bi}),n.d(e,"\u0275namespaceSVG",function(){return gi}),n.d(e,"\u0275element",function(){return yi}),n.d(e,"\u0275listener",function(){return ki}),n.d(e,"\u0275text",function(){return Hi}),n.d(e,"\u0275embeddedViewStart",function(){return ss}),n.d(e,"\u0275query",function(){return Dl}),n.d(e,"\u0275registerContentQuery",function(){return qs}),n.d(e,"\u0275projection",function(){return ls}),n.d(e,"\u0275bind",function(){return _s}),n.d(e,"\u0275interpolation1",function(){return ws}),n.d(e,"\u0275interpolation2",function(){return Ss}),n.d(e,"\u0275interpolation3",function(){return Os}),n.d(e,"\u0275interpolation4",function(){return Is}),n.d(e,"\u0275interpolation5",function(){return Cs}),n.d(e,"\u0275interpolation6",function(){return ks}),n.d(e,"\u0275interpolation7",function(){return Ns}),n.d(e,"\u0275interpolation8",function(){return Rs}),n.d(e,"\u0275interpolationV",function(){return Ts}),n.d(e,"\u0275pipeBind1",function(){return ol}),n.d(e,"\u0275pipeBind2",function(){return ul}),n.d(e,"\u0275pipeBind3",function(){return cl}),n.d(e,"\u0275pipeBind4",function(){return ll}),n.d(e,"\u0275pipeBindV",function(){return dl}),n.d(e,"\u0275pureFunction0",function(){return Zc}),n.d(e,"\u0275pureFunction1",function(){return Xc}),n.d(e,"\u0275pureFunction2",function(){return Jc}),n.d(e,"\u0275pureFunction3",function(){return Qc}),n.d(e,"\u0275pureFunction4",function(){return tl}),n.d(e,"\u0275pureFunction5",function(){return el}),n.d(e,"\u0275pureFunction6",function(){return nl}),n.d(e,"\u0275pureFunction7",function(){return al}),n.d(e,"\u0275pureFunction8",function(){return rl}),n.d(e,"\u0275pureFunctionV",function(){return il}),n.d(e,"\u0275getCurrentView",function(){return zs}),n.d(e,"\u0275getHostElement",function(){return ea}),n.d(e,"\u0275restoreView",function(){return Je}),n.d(e,"\u0275containerRefreshStart",function(){return rs}),n.d(e,"\u0275containerRefreshEnd",function(){return is}),n.d(e,"\u0275queryRefresh",function(){return El}),n.d(e,"\u0275loadQueryList",function(){return Es}),n.d(e,"\u0275elementEnd",function(){return Ni}),n.d(e,"\u0275elementProperty",function(){return Ai}),n.d(e,"\u0275componentHostSyntheticProperty",function(){return Di}),n.d(e,"\u0275projectionDef",function(){return us}),n.d(e,"\u0275reference",function(){return Ds}),n.d(e,"\u0275enableBindings",function(){return $e}),n.d(e,"\u0275disableBindings",function(){return Ze}),n.d(e,"\u0275allocHostVars",function(){return xs}),n.d(e,"\u0275elementAttribute",function(){return Ri}),n.d(e,"\u0275elementContainerStart",function(){return vi}),n.d(e,"\u0275elementContainerEnd",function(){return _i}),n.d(e,"\u0275elementStyling",function(){return ji}),n.d(e,"\u0275elementHostAttrs",function(){return Fi}),n.d(e,"\u0275elementStylingMap",function(){return Vi}),n.d(e,"\u0275elementStyleProp",function(){return Gi}),n.d(e,"\u0275elementStylingApply",function(){return zi}),n.d(e,"\u0275elementClassProp",function(){return Yi}),n.d(e,"\u0275textBinding",function(){return Bi}),n.d(e,"\u0275template",function(){return es}),n.d(e,"\u0275embeddedViewEnd",function(){return os}),n.d(e,"\u0275store",function(){return As}),n.d(e,"\u0275load",function(){return Ls}),n.d(e,"\u0275pipe",function(){return sl}),n.d(e,"\u0275whenRendered",function(){return to}),n.d(e,"\u0275i18n",function(){return Pc}),n.d(e,"\u0275i18nAttributes",function(){return Mc}),n.d(e,"\u0275i18nExp",function(){return Fc}),n.d(e,"\u0275i18nStart",function(){return Nc}),n.d(e,"\u0275i18nEnd",function(){return Dc}),n.d(e,"\u0275i18nApply",function(){return zc}),n.d(e,"\u0275i18nPostprocess",function(){return Ac}),n.d(e,"\u0275setClassMetadata",function(){return $c}),n.d(e,"\u0275compileComponent",function(){return Ed}),n.d(e,"\u0275compileDirective",function(){return Ld}),n.d(e,"\u0275compileNgModule",function(){return Sd}),n.d(e,"\u0275compileNgModuleDefs",function(){return Od}),n.d(e,"\u0275patchComponentDefWithScope",function(){return kd}),n.d(e,"\u0275resetCompiledComponents",function(){return Id}),n.d(e,"\u0275compilePipe",function(){return zd}),n.d(e,"\u0275sanitizeHtml",function(){return Ul}),n.d(e,"\u0275sanitizeStyle",function(){return Wl}),n.d(e,"\u0275defaultStyleSanitizer",function(){return Xl}),n.d(e,"\u0275sanitizeScript",function(){return Zl}),n.d(e,"\u0275sanitizeUrl",function(){return Kl}),n.d(e,"\u0275sanitizeResourceUrl",function(){return $l}),n.d(e,"\u0275bypassSanitizationTrustHtml",function(){return ql}),n.d(e,"\u0275bypassSanitizationTrustStyle",function(){return jl}),n.d(e,"\u0275bypassSanitizationTrustScript",function(){return Fl}),n.d(e,"\u0275bypassSanitizationTrustUrl",function(){return zl}),n.d(e,"\u0275bypassSanitizationTrustResourceUrl",function(){return Gl}),n.d(e,"\u0275getLContext",function(){return Fn}),n.d(e,"\u0275bindPlayerFactory",function(){return ar}),n.d(e,"\u0275addPlayer",function(){return Vs}),n.d(e,"\u0275getPlayers",function(){return Hs}),n.d(e,"\u0275compileNgModuleFactory__POST_R3__",function(){return Yp}),n.d(e,"\u0275SWITCH_COMPILE_COMPONENT__POST_R3__",function(){return $d}),n.d(e,"\u0275SWITCH_COMPILE_DIRECTIVE__POST_R3__",function(){return Zd}),n.d(e,"\u0275SWITCH_COMPILE_PIPE__POST_R3__",function(){return Xd}),n.d(e,"\u0275SWITCH_COMPILE_NGMODULE__POST_R3__",function(){return uf}),n.d(e,"\u0275getDebugNode__POST_R3__",function(){return wh}),n.d(e,"\u0275SWITCH_COMPILE_INJECTABLE__POST_R3__",function(){return bf}),n.d(e,"\u0275SWITCH_IVY_ENABLED__POST_R3__",function(){return Qh}),n.d(e,"\u0275SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__",function(){return ch}),n.d(e,"\u0275Compiler_compileModuleSync__POST_R3__",function(){return up}),n.d(e,"\u0275Compiler_compileModuleAsync__POST_R3__",function(){return lp}),n.d(e,"\u0275Compiler_compileModuleAndAllComponentsSync__POST_R3__",function(){return fp}),n.d(e,"\u0275Compiler_compileModuleAndAllComponentsAsync__POST_R3__",function(){return hp}),n.d(e,"\u0275SWITCH_ELEMENT_REF_FACTORY__POST_R3__",function(){return gu}),n.d(e,"\u0275SWITCH_TEMPLATE_REF_FACTORY__POST_R3__",function(){return bl}),n.d(e,"\u0275SWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__",function(){return sh}),n.d(e,"\u0275SWITCH_RENDERER2_FACTORY__POST_R3__",function(){return Su}),n.d(e,"\u0275getModuleFactory__POST_R3__",function(){return id}),n.d(e,"\u0275publishGlobalUtil",function(){return Ks}),n.d(e,"\u0275publishDefaultGlobalUtils",function(){return Ws}),n.d(e,"\u0275SWITCH_INJECTOR_FACTORY__POST_R3__",function(){return go}),n.d(e,"\u0275registerModuleFactory",function(){return nd}),n.d(e,"\u0275EMPTY_ARRAY",function(){return Zg}),n.d(e,"\u0275EMPTY_MAP",function(){return Xg}),n.d(e,"\u0275and",function(){return Jg}),n.d(e,"\u0275ccf",function(){return yb}),n.d(e,"\u0275cmf",function(){return Ny}),n.d(e,"\u0275crt",function(){return vg}),n.d(e,"\u0275did",function(){return Vb}),n.d(e,"\u0275eld",function(){return Qg}),n.d(e,"\u0275elementEventFullName",function(){return Rg}),n.d(e,"\u0275getComponentViewDefinitionFactory",function(){return vb}),n.d(e,"\u0275inlineInterpolate",function(){return Kg}),n.d(e,"\u0275interpolate",function(){return Wg}),n.d(e,"\u0275mod",function(){return cb}),n.d(e,"\u0275mpd",function(){return ub}),n.d(e,"\u0275ncd",function(){return dm}),n.d(e,"\u0275nov",function(){return Rb}),n.d(e,"\u0275pid",function(){return Hb}),n.d(e,"\u0275prd",function(){return Bb}),n.d(e,"\u0275pad",function(){return hm}),n.d(e,"\u0275pod",function(){return gm}),n.d(e,"\u0275ppd",function(){return pm}),n.d(e,"\u0275qud",function(){return sm}),n.d(e,"\u0275ted",function(){return mm}),n.d(e,"\u0275unv",function(){return bg}),n.d(e,"\u0275vid",function(){return _m});var a=n("mrSG"),r=n("pugT"),i=n("K9Ia"),s=n("6blF"),o=n("p0ib"),u=n("S1nX");function c(t){for(var e in t)if(t[e]===c)return e;throw Error("Could not find renamed property on target object.")}function l(t,e){for(var n in e)e.hasOwnProperty(n)&&!t.hasOwnProperty(n)&&(t[n]=e[n])}var d=c({ngComponentDef:c}),f=c({ngDirectiveDef:c}),p=c({ngInjectableDef:c}),h=c({ngInjectorDef:c}),g=c({ngPipeDef:c}),b=c({ngModuleDef:c}),m=c({ngBaseDef:c}),y=c({__NG_ELEMENT_ID__:c});function v(t){return{providedIn:t.providedIn||null,factory:t.factory,value:void 0}}function _(t){return{factory:t.factory,providers:t.providers||[],imports:t.imports||[]}}function x(t){return t&&t.hasOwnProperty(p)?t[p]:null}function T(t){return t&&t.hasOwnProperty(h)?t[h]:null}var w=function(){function t(t,e){this._desc=t,this.ngMetadataName="InjectionToken",this.ngInjectableDef=void 0!==e?v({providedIn:e.providedIn||"root",factory:e.factory}):void 0}return t.prototype.toString=function(){return"InjectionToken "+this._desc},t}(),S="__annotations__",O="__parameters__",I="__prop__metadata__";function C(t,e,n,r,i){var s=k(e);function o(){for(var t,e=[],n=0;n=qt?n:n[St]}function ae(t){return 0!=(4&t.flags)}function re(t){return 1==(1&t.flags)}function ie(t){return null!==t.template}function se(t){return Array.isArray(t)&&t.length===Yt}function oe(t){return 0!=(128&t[_t])}function ue(t){for(var e=Array.isArray(t)?t:de(t);e&&!(128&e[_t]);)e=e[xt];return e}function ce(t){return ue(t)[kt]}function le(t){return t[Vt]}function de(t){var e=le(t);return e?Array.isArray(e)?e:e.lView:null}function fe(t){return t!==Wt}function pe(t){return 32767&t}function he(t){return t>>16}function ge(t,e){for(var n=he(t),a=e;n>0;)a=a[Mt],n--;return a}var be=("undefined"!=typeof requestAnimationFrame&&requestAnimationFrame||setTimeout).bind(V);function me(t,e){for(var n=0;n0;)e=e[Mt],t--;return e}(t,sn))[kt]}function yn(t){var e=Ue[vt];rn(Ue)?Ue[_t]&=-2:(Ge(Ue,e.viewHooks,e.viewCheckHooks,on),Ue[_t]&=-11,Ue[_t]|=32,Ue[It]=e.bindingStartIndex),bn(t,null)}var vn=!0;function _n(t){var e=vn;return vn=t,e}var xn=255,Tn=0;function wn(t,e){var n=On(t,e);if(-1!==n)return n;var a=e[vt];a.firstTemplatePass&&(t.injectorIndex=e.length,Sn(a.data,t),Sn(e,null),Sn(a.blueprint,null));var r=In(t,e),i=pe(r),s=ge(r,e),o=t.injectorIndex;if(fe(r))for(var u=s[vt].data,c=0;c<8;c++)e[o+c]=s[i+c]|u[i+c];return e[o+Bt]=r,o}function Sn(t,e){t.push(0,0,0,0,0,0,0,0,e)}function On(t,e){return-1===t.injectorIndex||t.parent&&t.parent.injectorIndex===t.injectorIndex||null==e[t.injectorIndex+Bt]?-1:t.injectorIndex}function In(t,e){if(t.parent&&-1!==t.parent.injectorIndex)return t.parent.injectorIndex;for(var n=e[Ot],a=1;n&&-1===n.injectorIndex;)n=(e=e[Mt])?e[Ot]:null,a++;return n?n.injectorIndex|a<<16:-1}function Cn(t,e,n){!function(t,e,n){var a="string"!=typeof n?n[y]:n.charCodeAt(0)||0;null==a&&(a=n[y]=Tn++);var r=a&xn,i=1<>16,l=r?o+c:t.directiveEnd,d=a?o:o+c;d=u&&f.type===n)return d}if(r){var p=s[u];if(p&&ie(p)&&p.type===n)return u}return null}function En(t,e,n,a){var r,i=e[n];if(null!=(r=i)&&"object"==typeof r&&Object.getPrototypeOf(r)==$t){var s=i;if(s.resolving)throw new Error("Circular dep for "+Zt(t[n]));var o=_n(s.canSeeViewProviders);s.resolving=!0;var u=void 0;s.injectImpl&&(u=Re(s.injectImpl));var c=Qe(),l=Xe();en(a,e);try{i=e[n]=s.factory(null,t,e,a)}finally{s.injectImpl&&Re(u),_n(o),s.resolving=!1,en(c,l)}}return i}function Ln(t,e,n){var a=64&t,r=32&t;return!!((128&t?a?r?n[e+7]:n[e+6]:r?n[e+5]:n[e+4]:a?r?n[e+3]:n[e+2]:r?n[e+1]:n[e])&1<=0){var h;Yn(h=Jt(a[p]),u=zn(a,p,h)),n=u;break}}}return n||null}function zn(t,e,n){return{lView:t,nodeIndex:e,native:n,component:void 0,directives:void 0,localRefs:void 0}}function Gn(t){var e,n=le(t);if(Array.isArray(n)){var a=Bn(n,t);(r=zn(n,a,(e=ne(a,n))[St])).component=t,Yn(t,r),Yn(r.native,r)}else{var r;e=ne((r=n).nodeIndex,r.lView)}return e}function Yn(t,e){t[Vt]=e}function Vn(t,e){for(var n=t[vt].firstChild;n;){if(te(n,t)===e)return n.index;n=Hn(n)}return-1}function Hn(t){if(t.child)return t.child;if(t.next)return t.next;for(;t.parent&&!t.parent.next;)t=t.parent;return t.parent&&t.parent.next}function Bn(t,e){var n=t[vt].components;if(n)for(var a=0;a=0)&&null})}}return r.sort(ia),r}function ia(t,e){return t.name==e.name?0:t.name-1?e[xt][n]:null}return e[xt][t.parent.index]}function ka(t,e){var n=Ca(t,e);return n?n[Gt]:null}var Na=[];function Ra(t,e,n,a,r){for(var i=t[vt].node,s=-1,o=t,u=i.child;u;){var c=null;if(3===u.type){Aa(e,n,a,te(u,o),r);var l=o[u.index];se(l)&&Aa(e,n,a,l[zt],r)}else if(0===u.type){var d=o[u.index];Aa(e,n,a,d[zt],r),a&&(d[Gt]=a),d[Ft].length&&(c=(o=d[Ft][0])[vt].node,r=d[zt])}else if(1===u.type){var f=ye(o),p=f[Ot].projection[u.projection];Na[++s]=u,Na[++s]=o,p&&(c=(o=f[xt])[vt].data[p.index])}else c=u.child;if(null===c)for(null===u.next&&2&u.flags&&(o=Na[s--],u=Na[s--]),c=u.next;!c;){if(null===(u=u.parent||o[vt].node)||u===i)return null;0===u.type&&(r=(o=o[xt])[u.index][zt]),c=2===u.type&&o[Tt]?(o=o[Tt])[vt].node:u.next}u=c}}function Aa(t,e,n,a,r){0===t?wa(e)?e.insertBefore(n,a,r):n.insertBefore(a,r,!0):1===t?wa(e)?e.removeChild(n,a):n.removeChild(a):2===t&&e.destroyNode(a)}function Da(t,e){return wa(e)?e.createText(Zt(t)):e.createTextNode(Zt(t))}function Ea(t,e,n){var a=ka(t[vt].node,t);a&&Ra(t,e?0:1,t[At],a,n)}function La(t,e,n,a,r){var i=e[Ft];a>0&&(i[a-1][Tt]=t),a-1&&(t[Lt]=r,t[xt]=n),t[wt]&&t[wt].insertView(a),t[_t]|=16}function Pa(t,e,n){var a=t[Ft],r=a[e];return e>0&&(a[e-1][Tt]=r[Tt]),a.splice(e,1),n||Ea(r,!1),r[wt]&&r[wt].removeView(),r[Lt]=-1,r[xt]=null,r[_t]&=-17,r}function Ma(t,e,n){var a=t[Ft][n];Pa(t,n,!!e.detached),ja(a)}function qa(t){var e=t[vt].childIndex;return-1===e?null:t[e]}function ja(t){var e=t[At];wa(e)&&e.destroyNode&&Ra(t,2,e,null),function(t){if(-1===t[vt].childIndex)return za(t);for(var e=qa(t);e;){var n=null;if(e.length>=qt?e[vt].childIndex>-1&&(n=qa(e)):e[Ft].length&&(n=e[Ft][0]),null==n){for(;e&&!e[Tt]&&e!==t;)za(e),e=Fa(e,t);za(e||t),n=e&&e[Tt]}e=n}}(t),t[_t]|=64}function Fa(t,e){var n;return t.length>=qt&&(n=t[Ot])&&2===n.type?Ca(n,t):t[xt]===e?null:t[xt]}function za(t){if(t.length>=qt){var e=t;!function(t){var e,n=t[vt];null!=n&&null!=(e=n.destroyHooks)&&Ye(t,e)}(e),(r=(a=e)[vt]&&a[vt].pipeDestroyHooks)&&Ye(a,r),function(t){var e=t[vt].cleanup;if(null!=e){for(var n=t[Ct],a=0;a=0?n[s]():n[-s].unsubscribe(),a+=2}else"number"==typeof e[a]?(0,n[e[a]])():e[a].call(n[e[a+1]]);t[Ct]=null}}(e);var n=e[Ot];n&&3===n.type&&wa(e[At])&&e[At].destroy()}var a,r}function Ga(t,e){if(Ya(t,e)){if(oe(e))return Ha(e[At],te(t,e));var n=e[Ot],a=t.parent;return null!=a&&4===a.type&&(t=Ua(a)),null==t.parent&&2===n.type?ka(n,e):Oa(t,e)}return null}function Ya(t,e){var n,a=t,r=t.parent;return t.parent&&(4===t.parent.type?r=(a=Ua(t)).parent:5===t.parent.type&&(r=(a=Ia(a)).parent)),null===r&&(r=e[Ot]),r&&2===r.type?null!=(n=Ca(r,e))&&null!=n[Gt]:null==a.parent||!(3!==a.parent.type||1&a.parent.flags)}function Va(t,e,n,a){wa(t)?t.insertBefore(e,n,a):e.insertBefore(n,a,!0)}function Ha(t,e){return wa(t)?t.parentNode(e):e.parentNode}function Ba(t,e,n){if(void 0===t&&(t=null),null!==t&&Ya(e,n)){var a=n[At],r=Oa(e,n),i=e.parent||n[Ot];if(2===i.type){var s=Ca(i,n),o=s[Ft],u=o.indexOf(n);Va(a,s[Gt],t,Wa(u,o,s[zt]))}else 4===i.type?Va(a,Ga(e,n),t,r):5===i.type?Va(a,r,t,te(e.parent,n)):wa(a)?a.appendChild(r,t):r.appendChild(t);return!0}return!1}function Ua(t){for(;null!=t.parent&&4===t.parent.type;)t=t.parent;return t}function Wa(t,e,n){if(t+1-1&&h>l?"":c[h+1],8&u&&(i=(a=g).length,o=(s=a.indexOf(r=b))+r.length,-1===s||s>0&&" "!==a[s-1]||o=9?e+0:e;n?t[a]|=1:t[a]&=-2}function Tr(t,e){return 1==(1&t[e>=9?e+0:e])}function wr(t,e){return 2==(2&t[e>=9?e+0:e])}function Sr(t,e){return 4==(4&t[e>=9?e+0:e])}function Or(t,e,n){return 63&t|e<<6|n<<20}function Ir(t,e){var n=Cr(e);return(2&e?t[3]:t[2])[n]}function Cr(t){return t>>6&16383}function kr(t){var e=t>>20&16383;return e>=9?e:-1}function Nr(t){return kr(t[0])}function Rr(t,e,n){t[e+1]=n}function Ar(t,e,n){t[e+2]=n}function Dr(t,e,n){var a=t[8];if(e){if(!a||0===n)return!0}else if(!a)return!1;return a[n]!==e}function Er(t,e,n){var a=t[8]||fr(t);return n>0?a[n]=e:(a.splice(n=a[0],0,e,null),a[0]+=2),n}function Lr(t,e,n,a){var r=function(t,e){return n<<16|t}(a);t[e+3]=r}function Pr(t,e){return t[e+3]>>16&65535}function Mr(t,e){var n=Pr(t,e);if(n){var a=t[8];if(a)return a[n]}return null}function qr(t,e,n){t[0===e?e:e+0]=n}function jr(t,e){return t[0===e?e:e+0]}function Fr(t,e){return t[e+2]}function zr(t,e){return t[e+1]}function Gr(t){return 16&t[0]}function Yr(t,e){xr(t,0,e)}function Vr(t,e){e?t[0]|=8:t[0]&=-9}function Hr(t,e,n){for(var a=(n||0)+1;a=0&&qr(t,c,Or(l=jr(t,c),Cr(l),n));var l,d=kr(u);d>=0&&qr(t,d,Or(l=jr(t,d),Cr(l),e)),Ar(t,e,Fr(t,n)),Rr(t,e,zr(t,n)),qr(t,e,jr(t,n)),Lr(t,e,Pr(t,n),0),Ar(t,n,a),Rr(t,n,r),qr(t,n,i),Lr(t,n,s,0)}function Ur(t,e,n,a,r,i,s,o){var u=e0){var i=Cr(jr(t,r));qr(t,r,Or((Tr(t,r)?1:0)|(wr(t,r)?2:0)|(Sr(t,r)?4:0),i,a))}}}(t)}function Wr(t,e){return e?!!t:null!==t}function Kr(t,e,n,a){var r,i=a&&a(e)?4:0;return n?(i|=2,r=ti(t[3],e)):r=ti(t[2],e),Or(i,r=r>0?r+1:0,0)}function $r(t,e,n){return!(2&t)&&e&&n&&4&t?e.toString()!==n.toString():e!==n}var Zr=function(){function t(t,e,n){this._element=e,this._type=n,this._values={},this._dirty=!1,this._factory=t}return t.prototype.setValue=function(t,e){this._values[t]!==e&&(this._values[t]=e,this._dirty=!0)},t.prototype.buildPlayer=function(t,e){if(this._dirty){var n=this._factory.fn(this._element,this._type,this._values,e,t||null);return this._values={},this._dirty=!1,n}},t}();function Xr(t,e){return 65535&t[e+3]}function Jr(t,e){var n=Qr(t[1],e);return n>0?n/4:0}function Qr(t,e){for(var n=0;nr)for(var s=0===e,o=n.data,u=r;u=0)return-1;a=s/4,r[s+1]=i,r[s+3]=n||null}return a}(t,e,r);if(-1!==s){var o=t[4],u=o[1],c=o[0],l=4*c,d=9+l,f=d+4*u,p=f+l,h=o.length;o.push(a?a.length:0,n?n.length:0);var g=0,b=[];if(a&&a.length)for(var m=0;m=f,A=N>=(R?p:d),D=jr(t,N),E=Cr(D),L=kr(D);qr(t,N,Or(D,E,L+=R?A?4*b.length:0:4*k+4*(A?b.length:0)))}for(var P=0;P<4*b.length;P++)t.splice(p,0,null),t.splice(d,0,null),d++,f++,p+=2;for(var M=0;M<4*v.length;M++)t.splice(f,0,null),t.push(null),f++,p++;for(var q=t[3],j=t[2],F=0;F=b.length,G=z?F-b.length:F,Y=z?v[G]:b[G],V=void 0,H=void 0;z?(V=p+4*(u+G),H=d+4*(u+G)):(V=f+4*(c+G),H=9+4*(c+G));var B=z?q:j,U=ti(B,Y);-1===U?(U=B.length+1,B.push(Y,!z&&null)):U+=1;var W=Kr(t,Y,z,r||null);qr(t,H,Or(W,U,V)),Rr(t,H,Y),Ar(t,H,null),Lr(t,H,0,s),qr(t,V,Or(W,U,H)),Rr(t,V,Y),Ar(t,V,null),Lr(t,V,0,s)}o[1]=u+v.length,o[0]=c+b.length,qr(t,0,Or(0,0,f)|(i?16:0))}}}(r.stylingTemplate,a||null,t,e,n,pr(r))}function Fi(t,e){var n=Qe();n.stylingTemplate||(n.stylingTemplate=hr(e)),function(t,e,n){var a=t[1];if(-1==Qr(a,n)){a.push(n,-1,!1,null);for(var r=null,i=null,s=-1,o=0;o0&&ps(ce(n),2)}function Gi(t,e,n,a,r){var i=null;null!==n&&(i=a?Zt(n)+a:n),yr(ur(t+qt,Xe()),e,i,!1,r)}function Yi(t,e,n,a){var r=n instanceof rr?n:!!n;yr(ur(t+qt,Xe()),e,r,!0,a)}function Vi(t,e,n,a){if(null!=a)return function(t,e,n,a){throw new Error("unimplemented. Should not be needed by ViewEngine compatibility")}();var r=Xe(),i=ee(t,r),s=ur(t+qt,r);if(pr(i)&&e!==ha){var o=ai(s);Mi(r,i.inputs.class,(o.length?o+" ":"")+e)}else!function(t,e,n,a){n=n||null;var r=Jr(t,null),i=t[5],s=e instanceof rr?new Zr(e,i,1):null,o=n instanceof rr?new Zr(n,i,2):null,u=s?e.value:e,c=o?n.value:n,l=Gr(t)||u===ha||u===t[6],d=c===ha||c===t[7];if(!l||!d){t[6]=u,t[7]=c;var f=it,p=!1,h=!1,g=s?1:0;Dr(t,s,1)&&(Er(t,s,1),h=!0);var b=o?3:0;Dr(t,o,3)&&(Er(t,o,3),h=!0),l||("string"==typeof u?(f=u.split(/\s+/),p=!0):f=u?Object.keys(u):it);for(var m=u||rt,y=c?Object.keys(c):it,v=c||rt,_=y.length,x=!1,T=Nr(t),w=0,S=y.length+f.length;T=_)&&!d||M&&!l){var O=M?w-_:w,I=M?f[O]:y[O],C=M?!!p||m[I]:v[I],k=M?g:b;if((q=zr(t,T))===I){var N=Fr(t,T),R=jr(t,T);if(Lr(t,T,k,r),$r(R,N,C)){Ar(t,T,C),h=h||!!k;var A=Ir(t,R);(null!=N||$r(R,A,C))&&(xr(t,T,!0),x=!0)}}else{var D=Hr(t,I,T);if(D>0){var E=Fr(t,D),L=jr(t,D);Br(t,T,D),$r(L,E,C)&&(A=Ir(t,L),Ar(t,T,C),(null!=E||$r(L,A,C))&&(xr(t,T,!0),h=h||!!k,x=!0))}else h=h||!!k,Ur(t,T,M,I,Kr(t,I,M,ei(t,r)),C,r,k),x=!0}}T+=4,w++}for(;T=_)&&!d||M&&!l){O=M?w-_:w;var q=M?f[O]:y[O],j=(N=M?!!p||m[q]:v[q],R=1|Kr(t,q,M,P),k=M?g:b,t.length);t.push(R,q,N,0),Lr(t,j,k,r),x=!0}w++}x&&(Yr(t,!0),ni(t,r,!0)),h&&Vr(t,!0)}}(s,e,n)}function Hi(t,e){var n=Xe(),a=Da(e,n[At]),r=oi(t,3,a,null,null);an(!1),Ba(a,r,n)}function Bi(t,e){if(e!==ha){var n=Xe(),a=Qt(t,n),r=n[At];wa(r)?r.setValue(a,Zt(e)):a.textContent=Zt(e)}}function Ui(t,e,n){var a=-(e.index-qt),r=t.data.length-(65535&e.providerIndexes);(t.expandoInstructions||(t.expandoInstructions=[])).push(a,r,n)}function Wi(t,e,n,a){var r=Qe();Ki(t,r,e,n),r&&r.attrs&&function(t,e,a,i){var s=r.initialInputs;(void 0===s||t>=s.length)&&(s=function(t,e,n){var a=n.initialInputs||(n.initialInputs=[]);a[t]=null;for(var r=n.attrs,i=0;i=i.length||null==i[t])&&(i[t]=Oi(t,null,e,n,r.directiveRegistry,r.pipeRegistry,null)),i[t]}(t,e,n,i),null,4),s[wt]&&(o[wt]=s[wt].createView()),ui(t,o),bn(o,o[vt].node)),s&&(rn(o)&&La(o,s,a,s[jt],-1),s[jt]++),rn(o)?3:2}function os(){var t=Xe(),e=t[Ot];rn(t)&&(ii(t),t[_t]&=-2),ii(t),yn(t[xt]),tn(e),an(!1)}function us(t,e){var n=ye(Xe())[Ot];if(!n.projection)for(var a=n.projection=new Array(t?t.length+1:1).fill(null),r=a.slice(),i=n.child;null!==i;){var s=t?nr(i,t,e):0,o=i.next;r[s]?r[s].next=i:(a[s]=i,i.next=null),r[s]=i,i=o}}var cs=[];function ls(t,e,n){void 0===e&&(e=0);var a=Xe(),r=oi(t,1,null,null,n||null);null===r.projection&&(r.projection=e),an(!1);for(var i=ye(a),s=i[Ot].projection[e],o=i[xt],u=-1;s;){if(1===s.type){var c=ye(o),l=c[Ot].projection[s.projection];if(l){cs[++u]=s,cs[++u]=o,s=l,o=c[xt];continue}}else s.flags|=2,$a(s,r,a,o);null===s.next&&o!==i[xt]&&(o=cs[u--],s=cs[u--]),s=s.next}}function ds(t,e,n){var a=t[vt],r=dn();return t[Et]?t[Et][Tt]=n:r&&(a.childIndex=e),t[Et]=n,n}function fs(t){for(;t&&!(128&t[_t]);)t[_t]|=8,t=t[xt];t[_t]|=8,ps(t[kt],1)}function ps(t,e){var n,a=0===t.flags;t.flags|=e,a&&t.clean==ri&&(t.clean=new Promise(function(t){return n=t}),t.scheduler(function(){if(1&t.flags&&(t.flags&=-2,hs(t)),2&t.flags){t.flags&=-3;var e=t.playerHandler;e&&e.flushPlayers()}t.clean=ri,n(null)}))}function hs(t){for(var e=0;e=2&&a[r-2]===e.hostBindings?a[r-1]=a[r-1]+n:a.push(e.hostBindings,n)}(n,We,t),function(t,e,n){for(var a=0;a=a.data.length&&(a.data[r]=null),n[r]=e}function Ds(t){return Xt(sn,t)}function Es(t){return Xe()[Pt][t]}function Ls(t){return Xt(Xe(),t)}function Ps(t,e){return void 0===e&&(e=Ce.Default),t=J(t),Nn(Qe(),Xe(),t,e)}function Ms(t){return kn(Qe(),t)}function qs(t,e){var n=Xe(),a=n[vt],r=(n[Pt]||(n[Pt]=[])).push(t);if(dn()){var i=a.contentQueries||(a.contentQueries=[]);e!==(a.contentQueries.length?a.contentQueries[a.contentQueries.length-2]:-1)&&i.push(e,r-1)}}var js=ri;function Fs(t){return t?(void 0===t.inputs&&(t.inputs=qi(t,0)),t.inputs):null}function zs(){return Xe()}function Gs(t){return t[Ct]||(t[Ct]=[])}function Ys(t){return t[vt].cleanup||(t[vt].cleanup=[])}function Vs(t,e){var n=Fn(t);if(n){var a=n.native,r=n.lView,i=function(t,e){if(!(e=e||Fn(a)))return null;var n=ur(e.nodeIndex,e.lView);return dr(n)||fr(n)}(0,n),s=Zn(r);lr(i,s,a,e,0,t),ps(s,2)}}function Hs(t){var e=Fn(t);if(!e)return[];var n=ur(e.nodeIndex,e.lView),a=n?dr(n):null;return a?function(t){for(var e=[],n=t[0],a=2;a ");else if("object"==typeof e){var r=[];for(var i in e)if(e.hasOwnProperty(i)){var s=e[i];r.push(i+":"+("string"==typeof s?JSON.stringify(s):$(s)))}a="{"+r.join(", ")+"}"}return"StaticInjectorError"+(n?"("+n+")":"")+"["+a+"]: "+t.replace(wo,"\n ")}function ko(t,e){return new Error(Co(t,e))}var No=new w("The presence of this token marks an injector as being the root injector."),Ro={},Ao={},Do=[],Eo=void 0;function Lo(){return void 0===Eo&&(Eo=new po),Eo}function Po(t,e,n){return void 0===e&&(e=null),void 0===n&&(n=null),e=e||Lo(),new Mo(t,n,e)}var Mo=function(){function t(t,e,n){var a=this;this.parent=n,this.records=new Map,this.injectorDefTypes=new Set,this.onDestroy=new Set,this.destroyed=!1;var r=[];zo([t],function(t){return a.processInjectorType(t,[],r)}),e&&zo(e,function(n){return a.processProvider(n,t,e)}),this.records.set(fo,Fo(void 0,this)),this.isRootInjector=this.records.has(No),this.injectorDefTypes.forEach(function(t){return a.get(t)})}return t.prototype.destroy=function(){this.assertNotDestroyed(),this.destroyed=!0;try{this.onDestroy.forEach(function(t){return t.ngOnDestroy()})}finally{this.records.clear(),this.onDestroy.clear(),this.injectorDefTypes.clear()}},t.prototype.get=function(t,e,n){void 0===e&&(e=lo),void 0===n&&(n=Ce.Default),this.assertNotDestroyed();var a,r=Ne(this);try{if(!(n&Ce.SkipSelf)){var i=this.records.get(t);if(void 0===i){var s=("function"==typeof(a=t)||"object"==typeof a&&a instanceof w)&&x(t);s&&this.injectableDefInScope(s)&&(i=Fo(qo(t),Ro),this.records.set(t,i))}if(void 0!==i)return this.hydrate(t,i)}return(n&Ce.Self?Lo():this.parent).get(t,e)}finally{Ne(r)}},t.prototype.assertNotDestroyed=function(){if(this.destroyed)throw new Error("Injector has already been destroyed.")},t.prototype.processInjectorType=function(t,e,n){var a=this;if(t=J(t)){var r=T(t),i=null==r&&t.ngModule||void 0,s=void 0===i?t:i,o=-1!==n.indexOf(s),u=void 0!==i&&t.providers||Do;if(void 0!==i&&(r=T(i)),null!=r){if(this.injectorDefTypes.add(s),this.records.set(s,Fo(r.factory,Ro)),null!=r.imports&&!o){n.push(s);try{zo(r.imports,function(t){return a.processInjectorType(t,e,n)})}finally{}}var c=r.providers;if(null!=c&&!o){var l=t;zo(c,function(t){return a.processProvider(t,l,c)})}var d=t.ngModule;zo(u,function(t){return a.processProvider(t,d,u)})}}},t.prototype.processProvider=function(t,e,n){var a=Yo(t=J(t))?t:J(t&&t.provide),r=function(t,e,n){var a=jo(t,e,n);return Go(t)?Fo(void 0,t.useValue):Fo(a,Ro)}(t,e,n);if(Yo(t)||!0!==t.multi){var i=this.records.get(a);if(i&&void 0!==i.multi)throw new Error("Mixed multi-provider for "+$(a))}else{var s=this.records.get(a);if(s){if(void 0===s.multi)throw new Error("Mixed multi-provider for "+a+".")}else(s=Fo(void 0,Ro,!0)).factory=function(){return Le(s.multi)},this.records.set(a,s);a=t,s.multi.push(t)}this.records.set(a,r)},t.prototype.hydrate=function(t,e){if(e.value===Ao)throw new Error("Cannot instantiate cyclic dependency! "+$(t));var n;return e.value===Ro&&(e.value=Ao,e.value=e.factory()),"object"==typeof e.value&&e.value&&"object"==typeof(n=e.value)&&null!=n&&n.ngOnDestroy&&"function"==typeof n.ngOnDestroy&&this.onDestroy.add(e.value),e.value},t.prototype.injectableDefInScope=function(t){return!!t.providedIn&&("string"==typeof t.providedIn?"any"===t.providedIn||"root"===t.providedIn&&this.isRootInjector:this.injectorDefTypes.has(t.providedIn))},t}();function qo(t){var e=x(t);if(null===e){var n=T(t);if(null!==n)return n.factory;if(t instanceof w)throw new Error("Token "+$(t)+" is missing an ngInjectableDef definition.");if(t instanceof Function){var a=t.length;if(a>0){var r=new Array(a).fill("?");throw new Error("Can't resolve all parameters for "+$(t)+": ("+r.join(", ")+").")}return function(){return new t}}throw new Error("unreachable")}return e.factory}function jo(t,e,n){var r,i=void 0;if(Yo(t))return qo(J(t));if(Go(t))i=function(){return J(t.useValue)};else if((r=t)&&r.useExisting)i=function(){return De(J(t.useExisting))};else if(t&&t.useFactory)i=function(){return t.useFactory.apply(t,Object(a.__spread)(Le(t.deps||[])))};else{var s=J(t&&(t.useClass||t.provide));if(!s){var o="";throw e&&n&&(o=" - only instances of Provider and Type are allowed, got: ["+n.map(function(e){return e==t?"?"+t+"?":"..."}).join(", ")+"]"),new Error("Invalid provider for the NgModule '"+$(e)+"'"+o)}if(!t.deps)return qo(s);i=function(){return new(s.bind.apply(s,Object(a.__spread)([void 0],Le(t.deps))))}}return i}function Fo(t,e,n){return void 0===n&&(n=!1),{factory:t,value:e,multi:n?[]:void 0}}function zo(t,e){t.forEach(function(t){return Array.isArray(t)?zo(t,e):e(t)})}function Go(t){return t&&"object"==typeof t&&xo in t}function Yo(t){return"function"==typeof t}function Vo(t,e,n,a,r){if(t=J(t),Array.isArray(t))for(var i=0;i>16;if(Yo(t)||!t.multi){var p=new Kt(u,r,Ps),h=Bo(o,e,r?l:l+f,d);-1==h?(Cn(wn(c,s),s,o),e.push(o),c.directiveStart++,c.directiveEnd++,r&&(c.providerIndexes+=65536),n.push(p),s.push(p)):(n[h]=p,s[h]=p)}else{var g=Bo(o,e,l+f,d),b=Bo(o,e,l,l+f),m=b>=0&&n[b];r&&!m||!r&&!(g>=0&&n[g])?(Cn(wn(c,s),s,o),p=function(t,e,n,a,r){var i=new Kt(t,n,Ps);return i.multi=[],i.index=e,i.componentProviders=0,Ho(i,r,a&&!n),i}(r?Wo:Uo,n.length,r,a,u),!r&&m&&(n[b].providerFactory=p),e.push(o),c.directiveStart++,c.directiveEnd++,r&&(c.providerIndexes+=65536),n.push(p),s.push(p)):Ho(n[r?b:g],u,!r&&a),!r&&a&&m&&n[b].componentProviders++}}}function Ho(t,e,n){t.multi.push(e),n&&t.componentProviders++}function Bo(t,e,n,a){for(var r=n;r-1&&this._viewContainerRef.detach(t),this._viewContainerRef=null}ja(this._lView)},t.prototype.onDestroy=function(t){var e,n;n=t,Gs(e=this._lView).push(n),e[vt].firstTemplatePass&&Ys(e).push(e[Ct].length-1,null)},t.prototype.markForCheck=function(){fs(this._lView)},t.prototype.detach=function(){this._lView[_t]&=-17},t.prototype.reattach=function(){this._lView[_t]|=16},t.prototype.detectChanges=function(){bs(this._lView,this.context)},t.prototype.checkNoChanges=function(){!function(t){cn(!0);try{gs(t)}finally{cn(!1)}}(this.context)},t.prototype.attachToViewContainerRef=function(t){if(this._appRef)throw new Error("This view is already attached directly to the ApplicationRef!");this._viewContainerRef=t},t.prototype.detachFromAppRef=function(){this._appRef=null},t.prototype.attachToAppRef=function(t){if(this._viewContainerRef)throw new Error("This view is already attached to a ViewContainer!");this._appRef=t},t.prototype._lookUpContext=function(){return this._context=this._lView[xt][this._componentIndex]},t}(),lu=function(t){function e(e){var n=t.call(this,e,null,-1)||this;return n._view=e,n}return Object(a.__extends)(e,t),e.prototype.detectChanges=function(){ms(this._view)},e.prototype.checkNoChanges=function(){!function(t){cn(!0);try{ms(t)}finally{cn(!1)}}(this._view)},Object.defineProperty(e.prototype,"context",{get:function(){return null},enumerable:!0,configurable:!0}),e}(cu);function du(t,e,n){return Qo||(Qo=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e}(t)),new Qo(te(e,n))}function fu(t,e,n,r){if(tu||(tu=function(t){function e(e,n,a,r,i,s){var o=t.call(this)||this;return o._declarationParentView=e,o.elementRef=n,o._tView=a,o._renderer=r,o._queries=i,o._injectorIndex=s,o}return Object(a.__extends)(e,t),e.prototype.createEmbeddedView=function(t,e,n,a,r){var i=function(t,e,n,a,r,i){var s=nn(),o=Qe();an(!0),tn(null);var u=si(n,t,e,4);return u[Mt]=n,r&&(u[wt]=r.createView()),ui(-1,u),t.firstTemplatePass&&(t.node.injectorIndex=i),an(s),tn(o),u}(this._tView,t,this._declarationParentView,0,this._queries,this._injectorIndex);e&&La(i,e,a,r,n.index),li(i,this._tView,t);var s=new cu(i,t,-1);return s._tViewNode=i[Ot],s},e}(t)),0===n.type){var i=r[n.index];return new tu(r,du(e,n,r),n.tViews,Xe()[At],i[wt],n.injectorIndex)}return null}function pu(t,e,n){if(re(t)){var a=t.directiveStart,r=ne(t.index,e);return new cu(r,n,a)}if(3===t.type){var i=ye(e);return new cu(i,i[kt],-1)}return null}var hu=function(){function t(t){this.nativeElement=t}return t.__NG_ELEMENT_ID__=function(){return bu(t)},t}(),gu=function(t){return du(t,Qe(),Xe())},bu=oo,mu=function(){return function(t,e,n,a,r,i){this.id=t,this.templateUrl=e,this.slotCount=n,this.encapsulation=a,this.styles=r,this.animations=i}}(),yu=function(){return function(){}}(),vu=function(){return function(){}}(),_u=function(){return function(){}}(),xu=function(){return function(){}}(),Tu=function(t){return t[t.Important=1]="Important",t[t.DashCase=2]="DashCase",t}({}),wu=function(){function t(){}return t.__NG_ELEMENT_ID__=function(){return Ou()},t}(),Su=function(){return function(t){var e=Xe()[At];if(wa(e))return e;throw new Error("Cannot inject Renderer2 when the application uses Renderer3!")}()},Ou=oo,Iu=function(t){return t[t.NONE=0]="NONE",t[t.HTML=1]="HTML",t[t.STYLE=2]="STYLE",t[t.SCRIPT=3]="SCRIPT",t[t.URL=4]="URL",t[t.RESOURCE_URL=5]="RESOURCE_URL",t}({}),Cu=function(){return function(){}}(),ku=function(){return function(t){this.full=t,this.major=t.split(".")[0],this.minor=t.split(".")[1],this.patch=t.split(".").slice(2).join(".")}}(),Nu=new ku("7.2.6"),Ru=function(t){function e(e){var n=t.call(this)||this;return n.ngModule=e,n}return Object(a.__extends)(e,t),e.prototype.resolveComponentFactory=function(t){var e=gt(t);return new Pu(e,this.ngModule)},e}(ru);function Au(t){var e=[];for(var n in t)t.hasOwnProperty(n)&&e.push({propName:t[n],templateName:n});return e}var Du=new w("ROOT_CONTEXT_TOKEN",{providedIn:"root",factory:function(){return Js(De(Eu))}}),Eu=new w("SCHEDULER_TOKEN",{providedIn:"root",factory:function(){return be}}),Lu={},Pu=function(t){function e(e,n){var a=t.call(this)||this;return a.componentDef=e,a.ngModule=n,a.componentType=e.type,a.selector=e.selectors[0][0],a.ngContentSelectors=[],a}return Object(a.__extends)(e,t),Object.defineProperty(e.prototype,"inputs",{get:function(){return Au(this.componentDef.inputs)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"outputs",{get:function(){return Au(this.componentDef.outputs)},enumerable:!0,configurable:!0}),e.prototype.create=function(t,e,n,a){var r=void 0===n,i=(a=a||this.ngModule)?function(t,e){return{get:function(n,a){var r=t.get(n,Lu);return r!==Lu||a===Lu?r:e.get(n,a)}}}(t,a.injector):t,s=i.get(xu,Sa),o=i.get(Cu,null),u=r?Ti(this.selector,s.createRenderer(null,this.componentDef)):Ci(s,n),c=this.componentDef.onPush?136:132,l=r?Js():i.get(Du),d=s.createRenderer(u,this.componentDef);n&&u&&(wa(d)?d.setAttribute(u,"ng-version",Nu.full):u.setAttribute("ng-version",Nu.full));var f,p,h=si(null,Oi(-1,null,1,0,null,null,null),l,c,s,d,o,i),g=bn(h,null);try{s.begin&&s.begin();var b=Zs(u,this.componentDef,h,s,d);if(p=ee(0,h),e)for(var m=0,y=h[vt],v=p.projection=[],_=0;_',!this.inertBodyElement.querySelector||this.inertBodyElement.querySelector("svg")?(this.inertBodyElement.innerHTML='

',this.getInertBodyElement=this.inertBodyElement.querySelector&&this.inertBodyElement.querySelector("svg img")&&function(){try{return!!window.DOMParser}catch(t){return!1}}()?this.getInertBodyElement_DOMParser:this.getInertBodyElement_InertDocument):this.getInertBodyElement=this.getInertBodyElement_XHR}return t.prototype.getInertBodyElement_XHR=function(t){t=""+t+"";try{t=encodeURI(t)}catch(a){return null}var e=new XMLHttpRequest;e.responseType="document",e.open("GET","data:text/html;charset=utf-8,"+t,!1),e.send(void 0);var n=e.response.body;return n.removeChild(n.firstChild),n},t.prototype.getInertBodyElement_DOMParser=function(t){t=""+t+"";try{var e=(new window.DOMParser).parseFromString(t,"text/html").body;return e.removeChild(e.firstChild),e}catch(n){return null}},t.prototype.getInertBodyElement_InertDocument=function(t){var e=this.inertDocument.createElement("template");return"content"in e?(e.innerHTML=t,e):(this.inertBodyElement.innerHTML=t,this.defaultDoc.documentMode&&this.stripCustomNsAttrs(this.inertBodyElement),this.inertBodyElement)},t.prototype.stripCustomNsAttrs=function(t){for(var e=t.attributes,n=e.length-1;0"),!0},t.prototype.endElement=function(t){var e=t.nodeName.toLowerCase();Qu.hasOwnProperty(e)&&!$u.hasOwnProperty(e)&&(this.buf.push(""))},t.prototype.chars=function(t){this.buf.push(sc(t))},t.prototype.checkClobberedElement=function(t,e){if(e&&(t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_CONTAINED_BY)===Node.DOCUMENT_POSITION_CONTAINED_BY)throw new Error("Failed to sanitize html because the element is clobbered: "+t.outerHTML);return e},t}(),rc=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,ic=/([^\#-~ |!])/g;function sc(t){return t.replace(/&/g,"&").replace(rc,function(t){return"&#"+(1024*(t.charCodeAt(0)-55296)+(t.charCodeAt(1)-56320)+65536)+";"}).replace(ic,function(t){return"&#"+t.charCodeAt(0)+";"}).replace(//g,">")}function oc(t,e){var n=null;try{Ku=Ku||new Gu(t);var a=e?String(e):"";n=Ku.getInertBodyElement(a);var r=5,i=a;do{if(0===r)throw new Error("Failed to sanitize html because the input is unstable");r--,a=i,i=n.innerHTML,n=Ku.getInertBodyElement(a)}while(a!==i);var s=new ac,o=s.sanitizeChildren(uc(n)||n);return Fu()&&s.sanitizedSomething&&console.warn("WARNING: sanitizing HTML stripped some content, see http://g.co/ng/security#xss"),o}finally{if(n)for(var u=uc(n)||n;u.firstChild;)u.removeChild(u.firstChild)}}function uc(t){return"content"in t&&function(t){return t.nodeType===Node.ELEMENT_NODE&&"TEMPLATE"===t.nodeName}(t)?t.content:null}var cc={marker:"element"},lc={marker:"comment"},dc="\ufffd",fc=/^\s*(\ufffd\d+:?\d*\ufffd)\s*,\s*(select|plural)\s*,/,pc=/\ufffd\/?\*(\d+:\d+)\ufffd/gi,hc=/\ufffd(\/?[#*]\d+):?\d*\ufffd/gi,gc=/\ufffd(\d+):?\d*\ufffd/gi,bc=/({\s*\ufffd\d+:?\d*\ufffd\s*,\s*\S{6}\s*,[\s\S]*})/gi,mc=/\[(\ufffd.+?\ufffd?)\]/g,yc=/({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g,vc=/\ufffdI18N_EXP_(ICU(_\d+)?)\ufffd/g;function _c(t){if(!t)return[];var e,n=0,a=[],r=[],i=/[{}]/g;for(i.lastIndex=0;e=i.exec(t);){var s=e.index;if("}"==e[0]){if(a.pop(),0==a.length){var o=t.substring(n,s);fc.test(o)?r.push(xc(o)):o&&r.push(o),n=s+1}}else{if(0==a.length){var u=t.substring(n,s);r.push(u),n=s+1}a.push("{")}}var c=t.substring(n);return""!=c&&r.push(c),r}function xc(t){for(var e=[],n=[],a=1,r=0,i=_c(t=t.replace(fc,function(t,e,n){return a="select"===n?0:1,r=parseInt(e.substr(1),10),""})),s=0;s0&&s!==o&&l.push(s.index<<3|0);for(var d=[],f=[],p=function(t,e){if("number"!=typeof e)return Tc(t);var n=t.indexOf(":"+e+dc)+2+e.toString().length,a=t.search(new RegExp(dc+"\\/\\*\\d+:"+e+dc));return Tc(t.substring(n,a))}(n,a).split(hc),h=0;h>>17,d=void 0;s=Rc(i,d=l===t?a[Ot]:ee(l,a),s),d.next=null;break;case 0:var f=c>>>3;o.push(f),s=i,(i=ee(f,a))&&(tn(i),3===i.type&&an(!0));break;case 5:s=i=ee(c>>>3,a),tn(i),an(!1);break;case 4:Ri(c>>>3,e[++u],e[++u]);break;default:throw new Error('Unable to determine the type of mutate operation for "'+c+'"')}else switch(c){case lc:var p=e[++u],h=r.createComment(p);s=i,i=oi(n++,5,h,null,null),Yn(h,a),i.activeCaseIndex=null,an(!1);break;case cc:var g=e[++u];s=i,i=oi(n++,3,r.createElement(g),g,null);break;default:throw new Error('Unable to determine the type of mutate operation for "'+c+'"')}}return an(!1),o}function Lc(t,e){var n=ee(t,e);Ka(n,Qt(t,e)||null,e),n.detached=!0;var a=Ls(t);if(se(a)){var r=a;0!==n.type&&Ka(n,r[zt]||null,e),r[Gt]=null}}function Pc(t,e,n){Nc(t,e,n),Dc()}function Mc(t,e){var n=Xe()[vt];n.firstTemplatePass&&null===n.data[t+qt]&&function(t,e,n){for(var a=Qe().index-qt,r=[],i=0;i>>2;switch(3&p){case 1:Ri(h,e[++f],d,e[++f]);break;case 0:Bi(h,d);break;case 2:var g=e[++f],b=n[g],m=ee(h,i);if(null!==m.activeCaseIndex)for(var y=b.remove[m.activeCaseIndex],v=0;v>>3,i);break;case 6:var x=ee(y[v+1]>>>3,i).activeCaseIndex;null!==x&&me(n[_>>>3].remove[x],y)}}var T=Yc(b,d);m.activeCaseIndex=-1!==T?T:null,Ec(-1,b.create[T],b.expandoStartIndex,i),o=!0;break;case 3:b=n[g=e[++f]],m=ee(h,i),t(b.update[m.activeCaseIndex],n,a,r,i,o)}}}u+=l}}(a,r,e[It]-jc-1,qc,e),qc=0,jc=0}}var Gc=function(t){return t[t.Zero=0]="Zero",t[t.One=1]="One",t[t.Two=2]="Two",t[t.Few=3]="Few",t[t.Many=4]="Many",t[t.Other=5]="Other",t}({});function Yc(t,e){var n=t.cases.indexOf(e);if(-1===n)switch(t.type){case 1:var a=function(t,n){switch(function(t,e){"string"==typeof e&&(e=parseInt(e,10));var n=e,a=n.toString().replace(/^[^.]*\.?/,""),r=Math.floor(Math.abs(n)),i=a.length,s=parseInt(a,10),o=parseInt(n.toString().replace(/^[^.]*\.?|0+$/g,""),10)||0;switch(t.split("-")[0].toLowerCase()){case"af":case"asa":case"az":case"bem":case"bez":case"bg":case"brx":case"ce":case"cgg":case"chr":case"ckb":case"ee":case"el":case"eo":case"es":case"eu":case"fo":case"fur":case"gsw":case"ha":case"haw":case"hu":case"jgo":case"jmc":case"ka":case"kk":case"kkj":case"kl":case"ks":case"ksb":case"ky":case"lb":case"lg":case"mas":case"mgo":case"ml":case"mn":case"nb":case"nd":case"ne":case"nn":case"nnh":case"nyn":case"om":case"or":case"os":case"ps":case"rm":case"rof":case"rwk":case"saq":case"seh":case"sn":case"so":case"sq":case"ta":case"te":case"teo":case"tk":case"tr":case"ug":case"uz":case"vo":case"vun":case"wae":case"xog":return 1===n?Gc.One:Gc.Other;case"ak":case"ln":case"mg":case"pa":case"ti":return n===Math.floor(n)&&n>=0&&n<=1?Gc.One:Gc.Other;case"am":case"as":case"bn":case"fa":case"gu":case"hi":case"kn":case"mr":case"zu":return 0===r||1===n?Gc.One:Gc.Other;case"ar":return 0===n?Gc.Zero:1===n?Gc.One:2===n?Gc.Two:n%100===Math.floor(n%100)&&n%100>=3&&n%100<=10?Gc.Few:n%100===Math.floor(n%100)&&n%100>=11&&n%100<=99?Gc.Many:Gc.Other;case"ast":case"ca":case"de":case"en":case"et":case"fi":case"fy":case"gl":case"it":case"nl":case"sv":case"sw":case"ur":case"yi":return 1===r&&0===i?Gc.One:Gc.Other;case"be":return n%10==1&&n%100!=11?Gc.One:n%10===Math.floor(n%10)&&n%10>=2&&n%10<=4&&!(n%100>=12&&n%100<=14)?Gc.Few:n%10==0||n%10===Math.floor(n%10)&&n%10>=5&&n%10<=9||n%100===Math.floor(n%100)&&n%100>=11&&n%100<=14?Gc.Many:Gc.Other;case"br":return n%10==1&&n%100!=11&&n%100!=71&&n%100!=91?Gc.One:n%10==2&&n%100!=12&&n%100!=72&&n%100!=92?Gc.Two:n%10===Math.floor(n%10)&&(n%10>=3&&n%10<=4||n%10==9)&&!(n%100>=10&&n%100<=19||n%100>=70&&n%100<=79||n%100>=90&&n%100<=99)?Gc.Few:0!==n&&n%1e6==0?Gc.Many:Gc.Other;case"bs":case"hr":case"sr":return 0===i&&r%10==1&&r%100!=11||s%10==1&&s%100!=11?Gc.One:0===i&&r%10===Math.floor(r%10)&&r%10>=2&&r%10<=4&&!(r%100>=12&&r%100<=14)||s%10===Math.floor(s%10)&&s%10>=2&&s%10<=4&&!(s%100>=12&&s%100<=14)?Gc.Few:Gc.Other;case"cs":case"sk":return 1===r&&0===i?Gc.One:r===Math.floor(r)&&r>=2&&r<=4&&0===i?Gc.Few:0!==i?Gc.Many:Gc.Other;case"cy":return 0===n?Gc.Zero:1===n?Gc.One:2===n?Gc.Two:3===n?Gc.Few:6===n?Gc.Many:Gc.Other;case"da":return 1===n||0!==o&&(0===r||1===r)?Gc.One:Gc.Other;case"dsb":case"hsb":return 0===i&&r%100==1||s%100==1?Gc.One:0===i&&r%100==2||s%100==2?Gc.Two:0===i&&r%100===Math.floor(r%100)&&r%100>=3&&r%100<=4||s%100===Math.floor(s%100)&&s%100>=3&&s%100<=4?Gc.Few:Gc.Other;case"ff":case"fr":case"hy":case"kab":return 0===r||1===r?Gc.One:Gc.Other;case"fil":return 0===i&&(1===r||2===r||3===r)||0===i&&r%10!=4&&r%10!=6&&r%10!=9||0!==i&&s%10!=4&&s%10!=6&&s%10!=9?Gc.One:Gc.Other;case"ga":return 1===n?Gc.One:2===n?Gc.Two:n===Math.floor(n)&&n>=3&&n<=6?Gc.Few:n===Math.floor(n)&&n>=7&&n<=10?Gc.Many:Gc.Other;case"gd":return 1===n||11===n?Gc.One:2===n||12===n?Gc.Two:n===Math.floor(n)&&(n>=3&&n<=10||n>=13&&n<=19)?Gc.Few:Gc.Other;case"gv":return 0===i&&r%10==1?Gc.One:0===i&&r%10==2?Gc.Two:0!==i||r%100!=0&&r%100!=20&&r%100!=40&&r%100!=60&&r%100!=80?0!==i?Gc.Many:Gc.Other:Gc.Few;case"he":return 1===r&&0===i?Gc.One:2===r&&0===i?Gc.Two:0!==i||n>=0&&n<=10||n%10!=0?Gc.Other:Gc.Many;case"is":return 0===o&&r%10==1&&r%100!=11||0!==o?Gc.One:Gc.Other;case"ksh":return 0===n?Gc.Zero:1===n?Gc.One:Gc.Other;case"kw":case"naq":case"se":case"smn":return 1===n?Gc.One:2===n?Gc.Two:Gc.Other;case"lag":return 0===n?Gc.Zero:0!==r&&1!==r||0===n?Gc.Other:Gc.One;case"lt":return n%10!=1||n%100>=11&&n%100<=19?n%10===Math.floor(n%10)&&n%10>=2&&n%10<=9&&!(n%100>=11&&n%100<=19)?Gc.Few:0!==s?Gc.Many:Gc.Other:Gc.One;case"lv":case"prg":return n%10==0||n%100===Math.floor(n%100)&&n%100>=11&&n%100<=19||2===i&&s%100===Math.floor(s%100)&&s%100>=11&&s%100<=19?Gc.Zero:n%10==1&&n%100!=11||2===i&&s%10==1&&s%100!=11||2!==i&&s%10==1?Gc.One:Gc.Other;case"mk":return 0===i&&r%10==1||s%10==1?Gc.One:Gc.Other;case"mt":return 1===n?Gc.One:0===n||n%100===Math.floor(n%100)&&n%100>=2&&n%100<=10?Gc.Few:n%100===Math.floor(n%100)&&n%100>=11&&n%100<=19?Gc.Many:Gc.Other;case"pl":return 1===r&&0===i?Gc.One:0===i&&r%10===Math.floor(r%10)&&r%10>=2&&r%10<=4&&!(r%100>=12&&r%100<=14)?Gc.Few:0===i&&1!==r&&r%10===Math.floor(r%10)&&r%10>=0&&r%10<=1||0===i&&r%10===Math.floor(r%10)&&r%10>=5&&r%10<=9||0===i&&r%100===Math.floor(r%100)&&r%100>=12&&r%100<=14?Gc.Many:Gc.Other;case"pt":return n===Math.floor(n)&&n>=0&&n<=2&&2!==n?Gc.One:Gc.Other;case"ro":return 1===r&&0===i?Gc.One:0!==i||0===n||1!==n&&n%100===Math.floor(n%100)&&n%100>=1&&n%100<=19?Gc.Few:Gc.Other;case"ru":case"uk":return 0===i&&r%10==1&&r%100!=11?Gc.One:0===i&&r%10===Math.floor(r%10)&&r%10>=2&&r%10<=4&&!(r%100>=12&&r%100<=14)?Gc.Few:0===i&&r%10==0||0===i&&r%10===Math.floor(r%10)&&r%10>=5&&r%10<=9||0===i&&r%100===Math.floor(r%100)&&r%100>=11&&r%100<=14?Gc.Many:Gc.Other;case"shi":return 0===r||1===n?Gc.One:n===Math.floor(n)&&n>=2&&n<=10?Gc.Few:Gc.Other;case"si":return 0===n||1===n||0===r&&1===s?Gc.One:Gc.Other;case"sl":return 0===i&&r%100==1?Gc.One:0===i&&r%100==2?Gc.Two:0===i&&r%100===Math.floor(r%100)&&r%100>=3&&r%100<=4||0!==i?Gc.Few:Gc.Other;case"tzm":return n===Math.floor(n)&&n>=0&&n<=1||n===Math.floor(n)&&n>=11&&n<=99?Gc.One:Gc.Other;default:return Gc.Other}}("en-US",e)){case Gc.Zero:return"zero";case Gc.One:return"one";case Gc.Two:return"two";case Gc.Few:return"few";case Gc.Many:return"many";default:return"other"}}();-1===(n=t.cases.indexOf(a))&&"other"!==a&&(n=t.cases.indexOf("other"));break;case 0:n=t.cases.indexOf("other")}return n}function Vc(t,e,n,r){for(var i=[],s=[],o=[],u=[],c=[],l=0;l=0;n--){var a=e[n];if(t===a.name)return a}throw new Error("The pipe '"+t+"' could not be found!")}(e,a.pipeRegistry),a.data[r]=n,n.onDestroy&&(a.pipeDestroyHooks||(a.pipeDestroyHooks=[])).push(r,n.onDestroy)):n=a.data[r];var i=n.factory(null);return As(t,i),i}function ol(t,e,n){var a=Ls(t);return pl(fl(t)?Xc(e,a.transform,n,a):a.transform(n))}function ul(t,e,n,a){var r=Ls(t);return pl(fl(t)?Jc(e,r.transform,n,a,r):r.transform(n,a))}function cl(t,e,n,a,r){var i=Ls(t);return pl(fl(t)?Qc(e,i.transform,n,a,r,i):i.transform(n,a,r))}function ll(t,e,n,a,r,i){var s=Ls(t);return pl(fl(t)?tl(e,s.transform,n,a,r,i,s):s.transform(n,a,r,i))}function dl(t,e,n){var a=Ls(t);return pl(fl(t)?il(e,a.transform,n,a):a.transform.apply(a,n))}function fl(t){return Xe()[vt].data[t+qt].pure}function pl(t){return ca.isWrapped(t)&&(t=ca.unwrap(t),Xe()[hn()]=ha),t}var hl=function(t){function e(e){void 0===e&&(e=!1);var n=t.call(this)||this;return n.__isAsync=e,n}return Object(a.__extends)(e,t),e.prototype.emit=function(e){t.prototype.next.call(this,e)},e.prototype.subscribe=function(e,n,a){var i,s=function(t){return null},o=function(){return null};e&&"object"==typeof e?(i=this.__isAsync?function(t){setTimeout(function(){return e.next(t)})}:function(t){e.next(t)},e.error&&(s=this.__isAsync?function(t){setTimeout(function(){return e.error(t)})}:function(t){e.error(t)}),e.complete&&(o=this.__isAsync?function(){setTimeout(function(){return e.complete()})}:function(){e.complete()})):(i=this.__isAsync?function(t){setTimeout(function(){return e(t)})}:function(t){e(t)},n&&(s=this.__isAsync?function(t){setTimeout(function(){return n(t)})}:function(t){n(t)}),a&&(o=this.__isAsync?function(){setTimeout(function(){return a()})}:function(){a()}));var u=t.prototype.subscribe.call(this,i,s,o);return e instanceof r.a&&e.add(u),u},e}(i.a),gl=function(){function t(){}return t.__NG_ELEMENT_ID__=function(){return ml(t,hu)},t}(),bl=function(t,e){return fu(t,e,Qe(),Xe())},ml=oo,yl=function(){function t(t,e,n){this.parent=t,this.shallow=e,this.deep=n}return t.prototype.track=function(t,e,n,a){n?this.deep=Rl(this.deep,t,e,null!=a?a:null):this.shallow=Rl(this.shallow,t,e,null!=a?a:null)},t.prototype.clone=function(){return new t(this,null,this.deep)},t.prototype.container=function(){var e=vl(this.shallow),n=vl(this.deep);return e||n?new t(this,e,n):null},t.prototype.createView=function(){var e=_l(this.shallow),n=_l(this.deep);return e||n?new t(this,e,n):null},t.prototype.insertView=function(t){xl(t,this.shallow),xl(t,this.deep)},t.prototype.addNode=function(t){return Cl(this.deep,t),ae(t)?(Cl(this.shallow,t),t.parent&&ae(t.parent)&&Cl(this.parent.shallow,t),this.parent):(function(t){return null===t.parent||ae(t.parent)}(t)&&Cl(this.shallow,t),this)},t.prototype.removeView=function(){Tl(this.shallow),Tl(this.deep)},t}();function vl(t){for(var e=null;t;){var n=[];t.values.push(n),e={next:e,list:t.list,predicate:t.predicate,values:n,containerValues:null},t=t.next}return e}function _l(t){for(var e=null;t;)e={next:e,list:t.list,predicate:t.predicate,values:[],containerValues:t.values},t=t.next;return e}function xl(t,e){for(;e;)e.containerValues.splice(t,0,e.values),e=e.next}function Tl(t){for(;t;){var e=t.containerValues,n=e.indexOf(t.values);e.splice(n,1)[0].length&&t.list.setDirty(),t=t.next}}function wl(t,e){var n=t.localNames;if(n)for(var a=0;a-1?En(e[vt].data,e,a,t):function(t,e){return 3===t.type||4===t.type?du(hu,t,e):0===t.type?fu(gl,hu,t,e):null}(t,e)}function Cl(t,e){for(var n=Xe();t;){var a=t.predicate,r=a.type;if(r){var i=null;r===gl?i=Ol(r,e,n,a.read):null!==(u=Dn(e,n,r,!1,!1))&&(i=Il(e,n,a.read,u)),null!==i&&kl(t,i)}else for(var s=a.selector,o=0;o0?(t=a.concat(t.slice(n+1)),n=0):n++:(e.push(a),n++)}return e}(t),this.dirty=!1},t.prototype.notifyOnChanges=function(){this.changes.emit(this)},t.prototype.setDirty=function(){this.dirty=!0},t.prototype.destroy=function(){this.changes.complete(),this.changes.unsubscribe()},t}();function Dl(t,e,n,a){var r,i,s,o=new Al;return(r=yl,i=Xe(),s=i[wt],He&&He!==i[Ot]&&!ae(He)&&(s&&(s=i[wt]=s.clone()),He.flags|=4),s||(i[wt]=new r(null,null,null))).track(o,e,n,a),function(t,e,n){var a=Gs(t);a.push(e),t[vt].firstTemplatePass&&Ys(t).push(n,a.length-1)}(Xe(),o,o.destroy),null!=t&&As(t,o),o}function El(t){return!!t.dirty&&(t.reset(t._valuesTree),t.notifyOnChanges(),!0)}function Ll(t,e){return fu(gl,hu,t,e)}var Pl="__SANITIZER_TRUSTED_BRAND__";function Ml(t,e){return t instanceof String&&t[Pl]===e}function ql(t){return Yl(t,"Html")}function jl(t){return Yl(t,"Style")}function Fl(t){return Yl(t,"Script")}function zl(t){return Yl(t,"Url")}function Gl(t){return Yl(t,"ResourceUrl")}function Yl(t,e){var n=new String(t);return n[Pl]=e,n}var Vl=new RegExp("^([-,.\"'%_!# a-zA-Z0-9]+|(?:(?:matrix|translate|scale|rotate|skew|perspective)(?:X|Y|3d)?|(?:rgb|hsl)a?|(?:repeating-)?(?:linear|radial)-gradient|(?:calc|attr))\\([-0-9.%, #a-zA-Z]+\\))$","g"),Hl=/^url\(([^)]+)\)$/;function Bl(t){if(!(t=String(t).trim()))return"";var e=t.match(Hl);return e&&Hu(e[1])===e[1]||t.match(Vl)&&function(t){for(var e=!0,n=!0,a=0;a=0;t--){var e=xd[t],n=e.moduleType,a=e.ngModule;a.declarations&&a.declarations.every(wd)&&(xd.splice(t,1),Cd(n,a))}}finally{Td=!1}}}(),void 0!==t.ngSelectorScope){var o=Nd(t.ngSelectorScope);kd(n,o)}}return n},configurable:!1})}function Ld(t,e){var n=null;Object.defineProperty(t,f,{get:function(){if(null===n){var a=Md(t,e);n=ve().compileDirective(Ql,"ng://"+(t&&t.name)+"/ngDirectiveDef.js",a)}return n},configurable:!1})}function Pd(t){return Object.getPrototypeOf(t.prototype)===Object.prototype}function Md(t,e){var n=md().propMetadata(t);return{name:t.name,type:t,typeArgumentCount:0,selector:e.selector,deps:yd(t),host:e.host||rt,propMetadata:n,inputs:e.inputs||it,outputs:e.outputs||it,queries:qd(t,n,jd),lifecycle:{usesOnChanges:void 0!==t.prototype.ngOnChanges},typeSourceSpan:null,usesInheritance:!Pd(t),exportAs:e.exportAs||null,providers:e.providers||null}}function qd(t,e,n){var a=[],r=function(r){e.hasOwnProperty(r)&&e[r].forEach(function(e){if(n(e)){if(!e.selector)throw new Error("Can't construct a query for the property \""+r+'" of "'+Zt(t)+"\" since the query selector wasn't defined.");a.push(function(t,e){return{propertyName:r,predicate:(n=e.selector,"string"==typeof n?n.split(",").map(function(t){return t.trim()}):J(n)),descendants:e.descendants,first:e.first,read:e.read?e.read:null};var n}(0,e))}})};for(var i in e)r(i);return a}function jd(t){var e=t.ngMetadataName;return"ContentChild"===e||"ContentChildren"===e}function Fd(t){var e=t.ngMetadataName;return"ViewChild"===e||"ViewChildren"===e}function zd(t,e){var n=null;Object.defineProperty(t,g,{get:function(){return null===n&&(n=ve().compilePipe(Ql,"ng://"+Zt(t)+"/ngPipeDef.js",{type:t,name:t.name,deps:yd(t),pipeName:e.name,pure:void 0===e.pure||e.pure})),n},configurable:!1})}var Gd=C("Directive",function(t){return void 0===t&&(t={}),t},void 0,void 0,function(t,e){return Qd(t,e)}),Yd=C("Component",function(t){return void 0===t&&(t={}),Object(a.__assign)({changeDetection:j.Default},t)},Gd,void 0,function(t,e){return Jd(t,e)}),Vd=C("Pipe",function(t){return Object(a.__assign)({pure:!0},t)},void 0,void 0,function(t,e){return tf(t,e)}),Hd=function(t){return function(e,n){for(var a=[],r=2;r1?" ("+function(t){for(var e=[],n=0;n-1)return e.push(t[n]),e;e.push(t[n])}return e}(t.slice().reverse()).map(function(t){return $(t.token)}).join(" -> ")+")":""}function If(t,e,n,a){var r=[e],i=n(r),s=a?function(t,e){var n=i+" caused by: "+(e instanceof Error?e.message:e),a=Error(n);return a[vf]=e,a}(0,a):Error(i);return s.addKey=Cf,s.keys=r,s.injectors=[t],s.constructResolvingMessage=n,s[vf]=a,s}function Cf(t,e){this.injectors.push(t),this.keys.push(e),this.message=this.constructResolvingMessage(this.keys)}function kf(t,e){for(var n=[],a=0,r=e.length;a=this._providers.length)throw function(t){return Error("Index "+t+" is out-of-bounds.")}(t);return this._providers[t]},t.prototype._new=function(t){if(this._constructionCounter++>this._getMaxNumberOfObjects())throw If(this,t.key,function(t){return"Cannot instantiate cyclic dependency!"+Of(t)});return this._instantiateProvider(t)},t.prototype._getMaxNumberOfObjects=function(){return this.objs.length},t.prototype._instantiateProvider=function(t){if(t.multiProvider){for(var e=new Array(t.resolvedFactories.length),n=0;n0&&(r=setTimeout(function(){a._callbacks=a._callbacks.filter(function(t){return t.timeoutId!==r}),t(a._didWork,a.getPendingTasks())},e)),this._callbacks.push({doneCb:t,timeoutId:r,updateCb:n})},t.prototype.whenStable=function(t,e,n){if(n&&!this.taskTrackingZone)throw new Error('Task tracking zone is required when passing an update callback to whenStable(). Is "zone.js/dist/task-tracking.js" loaded?');this.addCallback(t,e,n),this._runCallbacksIfReady()},t.prototype.getPendingRequestCount=function(){return this._pendingCount},t.prototype.findProviders=function(t,e,n){return[]},t}(),jp=function(){function t(){this._applications=new Map,Gp.addToWindow(this)}return t.prototype.registerApplication=function(t,e){this._applications.set(t,e)},t.prototype.unregisterApplication=function(t){this._applications.delete(t)},t.prototype.unregisterAllApplications=function(){this._applications.clear()},t.prototype.getTestability=function(t){return this._applications.get(t)||null},t.prototype.getAllTestabilities=function(){return Array.from(this._applications.values())},t.prototype.getAllRootElements=function(){return Array.from(this._applications.keys())},t.prototype.findTestabilityInTree=function(t,e){return void 0===e&&(e=!0),Gp.findTestabilityInTree(this,t,e)},Object(a.__decorate)([Object(a.__metadata)("design:paramtypes",[])],t)}();function Fp(t){Gp=t}var zp,Gp=new(function(){function t(){}return t.prototype.addToWindow=function(t){},t.prototype.findTestabilityInTree=function(t,e,n){return null},t}());function Yp(t,e,n){return Promise.resolve(new Kc(n))}var Vp=new w("AllowMultipleToken"),Hp=function(){return function(t,e){this.name=t,this.token=e}}();function Bp(t){if(zp&&!zp.destroyed&&!zp.injector.get(Vp,!1))throw new Error("There can be only one platform. Destroy the previous one to create a new one.");zp=t.get(Zp);var e=t.get(Qf,null);return e&&e.forEach(function(t){return t()}),zp}function Up(t,e,n){void 0===n&&(n=[]);var a="Platform: "+e,r=new w(a);return function(e){void 0===e&&(e=[]);var i=$p();if(!i||i.injector.get(Vp,!1))if(t)t(n.concat(e).concat({provide:r,useValue:!0}));else{var s=n.concat(e).concat({provide:r,useValue:!0});Bp(ho.create({providers:s,name:a}))}return Wp(r)}}function Wp(t){var e=$p();if(!e)throw new Error("No platform exists!");if(!e.injector.get(t,null))throw new Error("A platform with a different configuration has been created. Please destroy it first.");return e}function Kp(){zp&&!zp.destroyed&&zp.destroy()}function $p(){return zp&&!zp.destroyed?zp:null}var Zp=function(){function t(t){this._injector=t,this._modules=[],this._destroyListeners=[],this._destroyed=!1}return t.prototype.bootstrapModuleFactory=function(t,e){var n,a=this,r="noop"===(n=e?e.ngZone:void 0)?new Mp:("zone.js"===n?void 0:n)||new Rp({enableLongStackTrace:Fu()}),i=[{provide:Rp,useValue:r}];return r.run(function(){var e=ho.create({providers:i,parent:a.injector,name:t.moduleType.name}),n=t.create(e),s=n.injector.get(Sf,null);if(!s)throw new Error("No ErrorHandler. Is platform module (BrowserModule) included?");return n.onDestroy(function(){return Qp(a._modules,n)}),r.runOutsideAngular(function(){return r.onError.subscribe({next:function(t){s.handleError(t)}})}),function(t,e,r){try{var i=((s=n.injector.get(Kf)).runInitializers(),s.donePromise.then(function(){return a._moduleDoBootstrap(n),n}));return Bf(i)?i.catch(function(n){throw e.runOutsideAngular(function(){return t.handleError(n)}),n}):i}catch(o){throw e.runOutsideAngular(function(){return t.handleError(o)}),o}var s}(s,r)})},t.prototype.bootstrapModule=function(t,e){var n=this;void 0===e&&(e=[]);var a=Xp({},e);return function(t,e,n){return t.get(yp).createCompiler([e]).compileModuleAsync(n)}(this.injector,a,t).then(function(t){return n.bootstrapModuleFactory(t,a)})},t.prototype._moduleDoBootstrap=function(t){var e=t.injector.get(Jp);if(t._bootstrapComponents.length>0)t._bootstrapComponents.forEach(function(t){return e.bootstrap(t)});else{if(!t.instance.ngDoBootstrap)throw new Error("The module "+$(t.instance.constructor)+' was bootstrapped, but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. Please define one of these.');t.instance.ngDoBootstrap(e)}this._modules.push(t)},t.prototype.onDestroy=function(t){this._destroyListeners.push(t)},Object.defineProperty(t.prototype,"injector",{get:function(){return this._injector},enumerable:!0,configurable:!0}),t.prototype.destroy=function(){if(this._destroyed)throw new Error("The platform has already been destroyed!");this._modules.slice().forEach(function(t){return t.destroy()}),this._destroyListeners.forEach(function(t){return t()}),this._destroyed=!0},Object.defineProperty(t.prototype,"destroyed",{get:function(){return this._destroyed},enumerable:!0,configurable:!0}),t}();function Xp(t,e){return Array.isArray(e)?e.reduce(Xp,t):Object(a.__assign)({},t,e)}var Jp=function(){function t(t,e,n,a,r,i){var c=this;this._zone=t,this._console=e,this._injector=n,this._exceptionHandler=a,this._componentFactoryResolver=r,this._initStatus=i,this._bootstrapListeners=[],this._views=[],this._runningTick=!1,this._enforceNoNewChanges=!1,this._stable=!0,this.componentTypes=[],this.components=[],this._enforceNoNewChanges=Fu(),this._zone.onMicrotaskEmpty.subscribe({next:function(){c._zone.run(function(){c.tick()})}});var l=new s.a(function(t){c._stable=c._zone.isStable&&!c._zone.hasPendingMacrotasks&&!c._zone.hasPendingMicrotasks,c._zone.runOutsideAngular(function(){t.next(c._stable),t.complete()})}),d=new s.a(function(t){var e;c._zone.runOutsideAngular(function(){e=c._zone.onStable.subscribe(function(){Rp.assertNotInAngularZone(),W(function(){c._stable||c._zone.hasPendingMacrotasks||c._zone.hasPendingMicrotasks||(c._stable=!0,t.next(!0))})})});var n=c._zone.onUnstable.subscribe(function(){Rp.assertInAngularZone(),c._stable&&(c._stable=!1,c._zone.runOutsideAngular(function(){t.next(!1)}))});return function(){e.unsubscribe(),n.unsubscribe()}});this.isStable=Object(o.a)(l,d.pipe(Object(u.a)()))}var e;return e=t,t.prototype.bootstrap=function(t,e){var n,a=this;if(!this._initStatus.done)throw new Error("Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.");n=t instanceof Xo?t:this._componentFactoryResolver.resolveComponentFactory(t),this.componentTypes.push(n.componentType);var r=n instanceof su?null:this._injector.get(ou),i=n.create(ho.NULL,[],e||n.selector,r);i.onDestroy(function(){a._unloadComponent(i)});var s=i.injector.get(qp,null);return s&&i.injector.get(jp).registerApplication(i.location.nativeElement,s),this._loadComponent(i),Fu()&&this._console.log("Angular is running in the development mode. Call enableProdMode() to enable the production mode."),i},t.prototype.tick=function(){var t=this;if(this._runningTick)throw new Error("ApplicationRef.tick is called recursively");var n=e._tickScope();try{this._runningTick=!0,this._views.forEach(function(t){return t.detectChanges()}),this._enforceNoNewChanges&&this._views.forEach(function(t){return t.checkNoChanges()})}catch(a){this._zone.runOutsideAngular(function(){return t._exceptionHandler.handleError(a)})}finally{this._runningTick=!1,Cp(n)}},t.prototype.attachView=function(t){var e=t;this._views.push(e),e.attachToAppRef(this)},t.prototype.detachView=function(t){var e=t;Qp(this._views,e),e.detachFromAppRef()},t.prototype._loadComponent=function(t){this.attachView(t.hostView),this.tick(),this.components.push(t),this._injector.get(ep,[]).concat(this._bootstrapListeners).forEach(function(e){return e(t)})},t.prototype._unloadComponent=function(t){this.detachView(t.hostView),Qp(this.components,t)},t.prototype.ngOnDestroy=function(){this._views.slice().forEach(function(t){return t.destroy()})},Object.defineProperty(t.prototype,"viewCount",{get:function(){return this._views.length},enumerable:!0,configurable:!0}),t._tickScope=Ip("ApplicationRef#tick()"),t}();function Qp(t,e){var n=t.indexOf(e);n>-1&&t.splice(n,1)}var th=function(){function t(){this.dirty=!0,this._results=[],this.changes=new hl,this.length=0}return t.prototype.map=function(t){return this._results.map(t)},t.prototype.filter=function(t){return this._results.filter(t)},t.prototype.find=function(t){return this._results.find(t)},t.prototype.reduce=function(t,e){return this._results.reduce(t,e)},t.prototype.forEach=function(t){this._results.forEach(t)},t.prototype.some=function(t){return this._results.some(t)},t.prototype.toArray=function(){return this._results.slice()},t.prototype[U()]=function(){return this._results[U()]()},t.prototype.toString=function(){return this._results.toString()},t.prototype.reset=function(t){this._results=function t(e){return e.reduce(function(e,n){var a=Array.isArray(n)?t(n):n;return e.concat(a)},[])}(t),this.dirty=!1,this.length=this._results.length,this.last=this._results[this.length-1],this.first=this._results[0]},t.prototype.notifyOnChanges=function(){this.changes.emit(this)},t.prototype.setDirty=function(){this.dirty=!0},t.prototype.destroy=function(){this.changes.complete(),this.changes.unsubscribe()},t}(),eh=function(){return function(){}}(),nh={factoryPathPrefix:"",factoryPathSuffix:".ngfactory"},ah=function(){function t(t,e){this._compiler=t,this._config=e||nh}return t.prototype.load=function(t){return this._compiler instanceof bp?this.loadFactory(t):this.loadAndCompile(t)},t.prototype.loadAndCompile=function(t){var e=this,r=Object(a.__read)(t.split("#"),2),i=r[0],s=r[1];return void 0===s&&(s="default"),n("crnd")(i).then(function(t){return t[s]}).then(function(t){return rh(t,i,s)}).then(function(t){return e._compiler.compileModuleAsync(t)})},t.prototype.loadFactory=function(t){var e=Object(a.__read)(t.split("#"),2),r=e[0],i=e[1],s="NgFactory";return void 0===i&&(i="default",s=""),n("crnd")(this._config.factoryPathPrefix+r+this._config.factoryPathSuffix).then(function(t){return t[i+s]}).then(function(t){return rh(t,r,i)})},t}();function rh(t,e,n){if(!t)throw new Error("Cannot find '"+n+"' in '"+e+"'");return t}var ih=function(){function t(){}return t.__NG_ELEMENT_ID__=function(){return oh(t,hu)},t}(),sh=function(t,e){return function(t,e,n,r){var i;eu||(eu=function(t){function n(e,n,a){var r=t.call(this)||this;return r._lContainer=e,r._hostTNode=n,r._hostView=a,r._viewRefs=[],r}return Object(a.__extends)(n,t),Object.defineProperty(n.prototype,"element",{get:function(){return du(e,this._hostTNode,this._hostView)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"injector",{get:function(){return new Mn(this._hostTNode,this._hostView)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"parentInjector",{get:function(){var t=In(this._hostTNode,this._hostView),e=ge(t,this._hostView),n=function(t,e,n){if(n.parent&&-1!==n.parent.injectorIndex){for(var a=n.parent.injectorIndex,r=n.parent;null!=r.parent&&a==r.injectorIndex;)r=r.parent;return r}for(var i=he(t),s=e,o=e[Ot];i>1;)o=(s=s[Mt])[Ot],i--;return o}(t,this._hostView,this._hostTNode);return fe(t)&&null!=n?new Mn(n,e):new Mn(null,this._hostView)},enumerable:!0,configurable:!0}),n.prototype.clear=function(){for(;this._lContainer[Ft].length;)this.remove(0)},n.prototype.get=function(t){return this._viewRefs[t]||null},Object.defineProperty(n.prototype,"length",{get:function(){return this._lContainer[Ft].length},enumerable:!0,configurable:!0}),n.prototype.createEmbeddedView=function(t,e,n){var a=this._adjustIndex(n),r=t.createEmbeddedView(e||{},this._lContainer,this._hostTNode,this._hostView,a);return r.attachToViewContainerRef(this),this._viewRefs.splice(a,0,r),r},n.prototype.createComponent=function(t,e,n,a,r){var i=n||this.parentInjector;!r&&null==t.ngModule&&i&&(r=i.get(ou,null));var s=t.create(i,a,void 0,r);return this.insert(s.hostView,e),s},n.prototype.insert=function(t,e){if(t.destroyed)throw new Error("Cannot insert a destroyed View in a ViewContainer!");var n=t._lView,a=this._adjustIndex(e);return La(n,this._lContainer,this._hostView,a,this._hostTNode.index),Ea(n,!0,Wa(a,this._lContainer[Ft],this._lContainer[zt])),t.attachToViewContainerRef(this),this._viewRefs.splice(a,0,t),t},n.prototype.move=function(t,e){if(t.destroyed)throw new Error("Cannot move a destroyed View in a ViewContainer!");var n=this.indexOf(t);return this.detach(n),this.insert(t,this._adjustIndex(e)),t},n.prototype.indexOf=function(t){return this._viewRefs.indexOf(t)},n.prototype.remove=function(t){var e=this._adjustIndex(t,-1);Ma(this._lContainer,this._hostTNode,e),this._viewRefs.splice(e,1)},n.prototype.detach=function(t){var e=this._adjustIndex(t,-1),n=Pa(this._lContainer,e,!!this._hostTNode.detached);return null!=this._viewRefs.splice(e,1)[0]?new cu(n,n[kt],n[Lt]):null},n.prototype._adjustIndex=function(t,e){return void 0===e&&(e=0),null==t?this._lContainer[Ft].length+e:t},n}(t));var s=r[n.index];if(se(s))(i=s)[jt]=-1;else{var o=r[At].createComment("");if(oe(r)){var u=r[At],c=te(n,r);Va(u,Ha(u,c),o,function(t,e){return wa(t)?t.nextSibling(e):e.nextSibling}(u,c))}else Ba(o,n,r);r[n.index]=i=ts(s,n,r,o,!0),ds(r,n.index,i)}return new eu(i,n,r)}(t,e,Qe(),Xe())},oh=oo,uh=function(){function t(){}return t.__NG_ELEMENT_ID__=function(){return lh()},t}(),ch=function(){return pu(Qe(),Xe(),null)},lh=function(){for(var t=[],e=0;e-1}(a)||"root"===r.providedIn&&a._def.isRoot))){var l=t._providers.length;return t._def.providersByKey[e.tokenKey]={flags:5120,value:o.factory,deps:[],index:l,token:e.token},t._providers[l]=rb,t._providers[l]=db(t,t._def.providersByKey[e.tokenKey])}return 4&e.flags?n:t._parent.get(e.token,n)}finally{Ne(i)}}function db(t,e){var n;switch(201347067&e.flags){case 512:n=function(t,e,n){var r=n.length;switch(r){case 0:return new e;case 1:return new e(lb(t,n[0]));case 2:return new e(lb(t,n[0]),lb(t,n[1]));case 3:return new e(lb(t,n[0]),lb(t,n[1]),lb(t,n[2]));default:for(var i=new Array(r),s=0;s=n.length)&&(e=n.length-1),e<0)return null;var a=n[e];return a.viewContainerParent=null,bb(n,e),cg.dirtyParentQueries(a),hb(a),a}function pb(t,e,n){var a=e?Ng(e,e.def.lastRenderRootNode):t.renderElement,r=n.renderer.parentNode(a),i=n.renderer.nextSibling(a);Fg(n,2,r,i,void 0)}function hb(t){Fg(t,3,null,null,void 0)}function gb(t,e,n){e>=t.length?t.push(n):t.splice(e,0,n)}function bb(t,e){e>=t.length-1?t.pop():t.splice(e,1)}var mb=new Object;function yb(t,e,n,a,r,i){return new _b(t,e,n,a,r,i)}function vb(t){return t.viewDefFactory}var _b=function(t){function e(e,n,a,r,i,s){var o=t.call(this)||this;return o.selector=e,o.componentType=n,o._inputs=r,o._outputs=i,o.ngContentSelectors=s,o.viewDefFactory=a,o}return Object(a.__extends)(e,t),Object.defineProperty(e.prototype,"inputs",{get:function(){var t=[],e=this._inputs;for(var n in e)t.push({propName:n,templateName:e[n]});return t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"outputs",{get:function(){var t=[];for(var e in this._outputs)t.push({propName:e,templateName:this._outputs[e]});return t},enumerable:!0,configurable:!0}),e.prototype.create=function(t,e,n,a){if(!a)throw new Error("ngModule should be provided");var r=jg(this.viewDefFactory),i=r.nodes[0].element.componentProvider.nodeIndex,s=cg.createRootView(t,e||[],n,r,a,mb),o=ig(s,i).instance;return n&&s.renderer.setAttribute(rg(s,0).renderElement,"ng-version",Nu.full),new xb(s,new Ob(s),o)},e}(Xo),xb=function(t){function e(e,n,a){var r=t.call(this)||this;return r._view=e,r._viewRef=n,r._component=a,r._elDef=r._view.def.nodes[0],r.hostView=n,r.changeDetectorRef=n,r.instance=a,r}return Object(a.__extends)(e,t),Object.defineProperty(e.prototype,"location",{get:function(){return new hu(rg(this._view,this._elDef.nodeIndex).renderElement)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"injector",{get:function(){return new Nb(this._view,this._elDef)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"componentType",{get:function(){return this._component.constructor},enumerable:!0,configurable:!0}),e.prototype.destroy=function(){this._viewRef.destroy()},e.prototype.onDestroy=function(t){this._viewRef.onDestroy(t)},e}(Zo);function Tb(t,e,n){return new wb(t,e,n)}var wb=function(){function t(t,e,n){this._view=t,this._elDef=e,this._data=n,this._embeddedViews=[]}return Object.defineProperty(t.prototype,"element",{get:function(){return new hu(this._data.renderElement)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"injector",{get:function(){return new Nb(this._view,this._elDef)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parentInjector",{get:function(){for(var t=this._view,e=this._elDef.parent;!e&&t;)e=kg(t),t=t.parent;return t?new Nb(t,e):new Nb(this._view,null)},enumerable:!0,configurable:!0}),t.prototype.clear=function(){for(var t=this._embeddedViews.length-1;t>=0;t--){var e=fb(this._data,t);cg.destroyView(e)}},t.prototype.get=function(t){var e=this._embeddedViews[t];if(e){var n=new Ob(e);return n.attachToViewContainerRef(this),n}return null},Object.defineProperty(t.prototype,"length",{get:function(){return this._embeddedViews.length},enumerable:!0,configurable:!0}),t.prototype.createEmbeddedView=function(t,e,n){var a=t.createEmbeddedView(e||{});return this.insert(a,n),a},t.prototype.createComponent=function(t,e,n,a,r){var i=n||this.parentInjector;r||t instanceof su||(r=i.get(ou));var s=t.create(i,a,void 0,r);return this.insert(s.hostView,e),s},t.prototype.insert=function(t,e){if(t.destroyed)throw new Error("Cannot insert a destroyed View in a ViewContainer!");var n,a,r,i,s=t;return i=(n=this._data).viewContainer._embeddedViews,null==(a=e)&&(a=i.length),(r=s._view).viewContainerParent=this._view,gb(i,a,r),function(t,e){var n=Cg(e);if(n&&n!==t&&!(16&e.state)){e.state|=16;var a=n.template._projectedViews;a||(a=n.template._projectedViews=[]),a.push(e),function(t,n){if(!(4&n.flags)){e.parent.def.nodeFlags|=4,n.flags|=4;for(var a=n.parent;a;)a.childFlags|=4,a=a.parent}}(0,e.parentNodeDef)}}(n,r),cg.dirtyParentQueries(r),pb(n,a>0?i[a-1]:null,r),s.attachToViewContainerRef(this),t},t.prototype.move=function(t,e){if(t.destroyed)throw new Error("Cannot move a destroyed View in a ViewContainer!");var n,a,r,i,s,o=this._embeddedViews.indexOf(t._view);return r=e,s=(i=(n=this._data).viewContainer._embeddedViews)[a=o],bb(i,a),null==r&&(r=i.length),gb(i,r,s),cg.dirtyParentQueries(s),hb(s),pb(n,r>0?i[r-1]:null,s),t},t.prototype.indexOf=function(t){return this._embeddedViews.indexOf(t._view)},t.prototype.remove=function(t){var e=fb(this._data,t);e&&cg.destroyView(e)},t.prototype.detach=function(t){var e=fb(this._data,t);return e?new Ob(e):null},t}();function Sb(t){return new Ob(t)}var Ob=function(){function t(t){this._view=t,this._viewContainerRef=null,this._appRef=null}return Object.defineProperty(t.prototype,"rootNodes",{get:function(){return Fg(this._view,0,void 0,void 0,t=[]),t;var t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"context",{get:function(){return this._view.context},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"destroyed",{get:function(){return 0!=(128&this._view.state)},enumerable:!0,configurable:!0}),t.prototype.markForCheck=function(){Sg(this._view)},t.prototype.detach=function(){this._view.state&=-5},t.prototype.detectChanges=function(){var t=this._view.root.rendererFactory;t.begin&&t.begin();try{cg.checkAndUpdateView(this._view)}finally{t.end&&t.end()}},t.prototype.checkNoChanges=function(){cg.checkNoChangesView(this._view)},t.prototype.reattach=function(){this._view.state|=4},t.prototype.onDestroy=function(t){this._view.disposables||(this._view.disposables=[]),this._view.disposables.push(t)},t.prototype.destroy=function(){this._appRef?this._appRef.detachView(this):this._viewContainerRef&&this._viewContainerRef.detach(this._viewContainerRef.indexOf(this)),cg.destroyView(this._view)},t.prototype.detachFromAppRef=function(){this._appRef=null,hb(this._view),cg.dirtyParentQueries(this._view)},t.prototype.attachToAppRef=function(t){if(this._viewContainerRef)throw new Error("This view is already attached to a ViewContainer!");this._appRef=t},t.prototype.attachToViewContainerRef=function(t){if(this._appRef)throw new Error("This view is already attached directly to the ApplicationRef!");this._viewContainerRef=t},t}();function Ib(t,e){return new Cb(t,e)}var Cb=function(t){function e(e,n){var a=t.call(this)||this;return a._parentView=e,a._def=n,a}return Object(a.__extends)(e,t),e.prototype.createEmbeddedView=function(t){return new Ob(cg.createEmbeddedView(this._parentView,this._def,this._def.element.template,t))},Object.defineProperty(e.prototype,"elementRef",{get:function(){return new hu(rg(this._parentView,this._def.nodeIndex).renderElement)},enumerable:!0,configurable:!0}),e}(gl);function kb(t,e){return new Nb(t,e)}var Nb=function(){function t(t,e){this.view=t,this.elDef=e}return t.prototype.get=function(t,e){return void 0===e&&(e=ho.THROW_IF_NOT_FOUND),cg.resolveDep(this.view,this.elDef,!!this.elDef&&0!=(33554432&this.elDef.flags),{flags:0,token:t,tokenKey:gg(t)},e)},t}();function Rb(t,e){var n=t.def.nodes[e];if(1&n.flags){var a=rg(t,n.nodeIndex);return n.element.template?a.template:a.renderElement}if(2&n.flags)return ag(t,n.nodeIndex).renderText;if(20240&n.flags)return ig(t,n.nodeIndex).instance;throw new Error("Illegal state: read nodeValue for node index "+e)}function Ab(t){return new Db(t.renderer)}var Db=function(){function t(t){this.delegate=t}return t.prototype.selectRootElement=function(t){return this.delegate.selectRootElement(t)},t.prototype.createElement=function(t,e){var n=Object(a.__read)(Bg(e),2),r=this.delegate.createElement(n[1],n[0]);return t&&this.delegate.appendChild(t,r),r},t.prototype.createViewRoot=function(t){return t},t.prototype.createTemplateAnchor=function(t){var e=this.delegate.createComment("");return t&&this.delegate.appendChild(t,e),e},t.prototype.createText=function(t,e){var n=this.delegate.createText(e);return t&&this.delegate.appendChild(t,n),n},t.prototype.projectNodes=function(t,e){for(var n=0;n0,e.provider.value,e.provider.deps);if(e.outputs.length)for(var a=0;a0,r=e.provider;switch(201347067&e.flags){case 512:return Jb(t,e.parent,n,r.value,r.deps);case 1024:return function(t,e,n,r,i){var s=i.length;switch(s){case 0:return r();case 1:return r(tm(t,e,n,i[0]));case 2:return r(tm(t,e,n,i[0]),tm(t,e,n,i[1]));case 3:return r(tm(t,e,n,i[0]),tm(t,e,n,i[1]),tm(t,e,n,i[2]));default:for(var o=Array(s),u=0;u0)c=g,xm(g)||(l=g);else for(;c&&h===c.nodeIndex+c.childCount;){var y=c.parent;y&&(y.childFlags|=c.childFlags,y.childMatchedQueries|=c.childMatchedQueries),l=(c=y)&&xm(c)?c.renderParent:c}}return{factory:null,nodeFlags:s,rootNodeFlags:o,nodeMatchedQueries:u,flags:t,nodes:e,updateDirectives:n||pg,updateRenderer:a||pg,handleEvent:function(t,n,a,r){return e[n].element.handleEvent(t,a,r)},bindingCount:r,outputCount:i,lastRenderRootNode:p}}function xm(t){return 0!=(1&t.flags)&&null===t.element.name}function Tm(t,e,n){var a=e.element&&e.element.template;if(a){if(!a.lastRenderRootNode)throw new Error("Illegal State: Embedded templates without nodes are not allowed!");if(a.lastRenderRootNode&&16777216&a.lastRenderRootNode.flags)throw new Error("Illegal State: Last root node of a template can't have embedded views, at index "+e.nodeIndex+"!")}if(20224&e.flags&&0==(1&(t?t.flags:0)))throw new Error("Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index "+e.nodeIndex+"!");if(e.query){if(67108864&e.flags&&(!t||0==(16384&t.flags)))throw new Error("Illegal State: Content Query nodes need to be children of directives, at index "+e.nodeIndex+"!");if(134217728&e.flags&&t)throw new Error("Illegal State: View Query nodes have to be top level nodes, at index "+e.nodeIndex+"!")}if(e.childCount){var r=t?t.nodeIndex+t.childCount:n-1;if(e.nodeIndex<=r&&e.nodeIndex+e.childCount>r)throw new Error("Illegal State: childCount of node leads outside of parent, at index "+e.nodeIndex+"!")}}function wm(t,e,n,a){var r=Im(t.root,t.renderer,t,e,n);return Cm(r,t.component,a),km(r),r}function Sm(t,e,n){var a=Im(t,t.renderer,null,null,e);return Cm(a,n,n),km(a),a}function Om(t,e,n,a){var r,i=e.element.componentRendererType;return r=i?t.root.rendererFactory.createRenderer(a,i):t.root.renderer,Im(t.root,r,t,e.element.componentProvider,n)}function Im(t,e,n,a,r){var i=new Array(r.nodes.length),s=r.outputCount?new Array(r.outputCount):null;return{def:r,parent:n,viewContainerParent:null,parentNodeDef:a,context:null,component:null,nodes:i,state:13,root:t,renderer:e,oldValues:new Array(r.bindingCount),disposables:s,initIndex:-1}}function Cm(t,e,n){t.component=e,t.context=n}function km(t){var e;Ag(t)&&(e=rg(t.parent,t.parentNodeDef.parent.nodeIndex).renderElement);for(var n=t.def,a=t.nodes,r=0;r0&&ab(t,e,0,n)&&(p=!0),f>1&&ab(t,e,1,a)&&(p=!0),f>2&&ab(t,e,2,r)&&(p=!0),f>3&&ab(t,e,3,i)&&(p=!0),f>4&&ab(t,e,4,s)&&(p=!0),f>5&&ab(t,e,5,o)&&(p=!0),f>6&&ab(t,e,6,u)&&(p=!0),f>7&&ab(t,e,7,c)&&(p=!0),f>8&&ab(t,e,8,l)&&(p=!0),f>9&&ab(t,e,9,d)&&(p=!0),p}(t,e,n,a,r,i,s,o,u,c,l,d);case 2:return function(t,e,n,a,r,i,s,o,u,c,l,d){var f=!1,p=e.bindings,h=p.length;if(h>0&&Tg(t,e,0,n)&&(f=!0),h>1&&Tg(t,e,1,a)&&(f=!0),h>2&&Tg(t,e,2,r)&&(f=!0),h>3&&Tg(t,e,3,i)&&(f=!0),h>4&&Tg(t,e,4,s)&&(f=!0),h>5&&Tg(t,e,5,o)&&(f=!0),h>6&&Tg(t,e,6,u)&&(f=!0),h>7&&Tg(t,e,7,c)&&(f=!0),h>8&&Tg(t,e,8,l)&&(f=!0),h>9&&Tg(t,e,9,d)&&(f=!0),f){var g=e.text.prefix;h>0&&(g+=vm(n,p[0])),h>1&&(g+=vm(a,p[1])),h>2&&(g+=vm(r,p[2])),h>3&&(g+=vm(i,p[3])),h>4&&(g+=vm(s,p[4])),h>5&&(g+=vm(o,p[5])),h>6&&(g+=vm(u,p[6])),h>7&&(g+=vm(c,p[7])),h>8&&(g+=vm(l,p[8])),h>9&&(g+=vm(d,p[9]));var b=ag(t,e.nodeIndex).renderText;t.renderer.setValue(b,g)}return f}(t,e,n,a,r,i,s,o,u,c,l,d);case 16384:return function(t,e,n,a,r,i,s,o,u,c,l,d){var f=ig(t,e.nodeIndex),p=f.instance,h=!1,g=void 0,b=e.bindings.length;return b>0&&xg(t,e,0,n)&&(h=!0,g=nm(t,f,e,0,n,g)),b>1&&xg(t,e,1,a)&&(h=!0,g=nm(t,f,e,1,a,g)),b>2&&xg(t,e,2,r)&&(h=!0,g=nm(t,f,e,2,r,g)),b>3&&xg(t,e,3,i)&&(h=!0,g=nm(t,f,e,3,i,g)),b>4&&xg(t,e,4,s)&&(h=!0,g=nm(t,f,e,4,s,g)),b>5&&xg(t,e,5,o)&&(h=!0,g=nm(t,f,e,5,o,g)),b>6&&xg(t,e,6,u)&&(h=!0,g=nm(t,f,e,6,u,g)),b>7&&xg(t,e,7,c)&&(h=!0,g=nm(t,f,e,7,c,g)),b>8&&xg(t,e,8,l)&&(h=!0,g=nm(t,f,e,8,l,g)),b>9&&xg(t,e,9,d)&&(h=!0,g=nm(t,f,e,9,d,g)),g&&p.ngOnChanges(g),65536&e.flags&&ng(t,256,e.nodeIndex)&&p.ngOnInit(),262144&e.flags&&p.ngDoCheck(),h}(t,e,n,a,r,i,s,o,u,c,l,d);case 32:case 64:case 128:return function(t,e,n,a,r,i,s,o,u,c,l,d){var f=e.bindings,p=!1,h=f.length;if(h>0&&Tg(t,e,0,n)&&(p=!0),h>1&&Tg(t,e,1,a)&&(p=!0),h>2&&Tg(t,e,2,r)&&(p=!0),h>3&&Tg(t,e,3,i)&&(p=!0),h>4&&Tg(t,e,4,s)&&(p=!0),h>5&&Tg(t,e,5,o)&&(p=!0),h>6&&Tg(t,e,6,u)&&(p=!0),h>7&&Tg(t,e,7,c)&&(p=!0),h>8&&Tg(t,e,8,l)&&(p=!0),h>9&&Tg(t,e,9,d)&&(p=!0),p){var g=sg(t,e.nodeIndex),b=void 0;switch(201347067&e.flags){case 32:b=new Array(f.length),h>0&&(b[0]=n),h>1&&(b[1]=a),h>2&&(b[2]=r),h>3&&(b[3]=i),h>4&&(b[4]=s),h>5&&(b[5]=o),h>6&&(b[6]=u),h>7&&(b[7]=c),h>8&&(b[8]=l),h>9&&(b[9]=d);break;case 64:b={},h>0&&(b[f[0].name]=n),h>1&&(b[f[1].name]=a),h>2&&(b[f[2].name]=r),h>3&&(b[f[3].name]=i),h>4&&(b[f[4].name]=s),h>5&&(b[f[5].name]=o),h>6&&(b[f[6].name]=u),h>7&&(b[f[7].name]=c),h>8&&(b[f[8].name]=l),h>9&&(b[f[9].name]=d);break;case 128:var m=n;switch(h){case 1:b=m.transform(n);break;case 2:b=m.transform(a);break;case 3:b=m.transform(a,r);break;case 4:b=m.transform(a,r,i);break;case 5:b=m.transform(a,r,i,s);break;case 6:b=m.transform(a,r,i,s,o);break;case 7:b=m.transform(a,r,i,s,o,u);break;case 8:b=m.transform(a,r,i,s,o,u,c);break;case 9:b=m.transform(a,r,i,s,o,u,c,l);break;case 10:b=m.transform(a,r,i,s,o,u,c,l,d)}}g.value=b}return p}(t,e,n,a,r,i,s,o,u,c,l,d);default:throw"unreachable"}}(t,e,r,i,s,o,u,c,l,d,f,p):function(t,e,n){switch(201347067&e.flags){case 1:return function(t,e,n){for(var a=!1,r=0;r0&&wg(t,e,0,n),f>1&&wg(t,e,1,a),f>2&&wg(t,e,2,r),f>3&&wg(t,e,3,i),f>4&&wg(t,e,4,s),f>5&&wg(t,e,5,o),f>6&&wg(t,e,6,u),f>7&&wg(t,e,7,c),f>8&&wg(t,e,8,l),f>9&&wg(t,e,9,d)}(t,e,a,r,i,s,o,u,c,l,d,f):function(t,e,n){for(var a=0;a0){var i=new Set(t.modules);Xm.forEach(function(e,a){if(i.has(x(a).providedIn)){var r={token:a,flags:e.flags|(n?4096:0),deps:Pg(e.deps),value:e.value,index:t.providers.length};t.providers.push(r),t.providersByKey[gg(a)]=r}})}}(t=t.factory(function(){return pg})),t):t}(a))}var Zm=new Map,Xm=new Map,Jm=new Map;function Qm(t){var e;Zm.set(t.token,t),"function"==typeof t.token&&(e=x(t.token))&&"function"==typeof e.providedIn&&Xm.set(t.token,t)}function ty(t,e){var n=jg(vb(e)),a=jg(n.nodes[0].element.componentView);Jm.set(t,a)}function ey(){Zm.clear(),Xm.clear(),Jm.clear()}function ny(t){if(0===Zm.size)return t;var e=function(t){for(var e=[],n=null,a=0;a12?t:t+12:"sanje"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"rati":t<12?"sokalli":t<16?"donparam":t<20?"sanje":"rati"}})}()},DNAf:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("LvDl"),r=function(){return function(t,e){this.customValidations={},this.i18n=e,this.empty=this.i18n("No items selected."),this.selectionLimit={tooltip:this.i18n("Deselect item to select again"),text:this.i18n("Selection limit reached")},this.filter=this.i18n("Filter tags"),this.add=this.i18n("Add badge"),this.noOptions=this.i18n("There are no items available."),a.merge(this,t)}}()},DQlY:function(t,e,n){"use strict";n.d(e,"a",function(){return o}),n.d(e,"b",function(){return f}),n.d(e,"c",function(){return d}),n.d(e,"d",function(){return l}),n.d(e,"e",function(){return p}),n.d(e,"f",function(){return u});var a=n("CcnG"),r=n("rpEJ"),i=n("lqqz"),s=n("NJnL"),o=function(){return function(){this.hide=Function,this.setClass=Function}}(),u=function(){return function(){}}(),c={backdrop:!0,keyboard:!0,focus:!0,show:!1,ignoreBackdropClick:!1,class:"",animated:!0,initialState:{}},l=function(){function t(t,e,n){this._element=e,this._renderer=n,this.isShown=!1,this.isModalHiding=!1,this.config=Object.assign({},t)}return t.prototype.ngOnInit=function(){var t=this;this.isAnimated&&this._renderer.addClass(this._element.nativeElement,"fade"),this._renderer.setStyle(this._element.nativeElement,"display","block"),setTimeout(function(){t.isShown=!0,t._renderer.addClass(t._element.nativeElement,Object(r.d)()?"in":"show")},this.isAnimated?150:0),document&&document.body&&(1===this.bsModalService.getModalsCount()&&(this.bsModalService.checkScrollbar(),this.bsModalService.setScrollbar()),this._renderer.addClass(document.body,"modal-open")),this._element.nativeElement&&this._element.nativeElement.focus()},t.prototype.onClick=function(t){this.config.ignoreBackdropClick||"static"===this.config.backdrop||t.target!==this._element.nativeElement||(this.bsModalService.setDismissReason("backdrop-click"),this.hide())},t.prototype.onEsc=function(t){this.isShown&&(27!==t.keyCode&&"Escape"!==t.key||t.preventDefault(),this.config.keyboard&&this.level===this.bsModalService.getModalsCount()&&(this.bsModalService.setDismissReason("esc"),this.hide()))},t.prototype.ngOnDestroy=function(){this.isShown&&this.hide()},t.prototype.hide=function(){var t=this;!this.isModalHiding&&this.isShown&&(this.isModalHiding=!0,this._renderer.removeClass(this._element.nativeElement,Object(r.d)()?"in":"show"),setTimeout(function(){t.isShown=!1,document&&document.body&&1===t.bsModalService.getModalsCount()&&t._renderer.removeClass(document.body,"modal-open"),t.bsModalService.hide(t.level),t.isModalHiding=!1},this.isAnimated?300:0))},t}(),d=function(){function t(t,e){this._isShown=!1,this.element=t,this.renderer=e}return Object.defineProperty(t.prototype,"isAnimated",{get:function(){return this._isAnimated},set:function(t){this._isAnimated=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isShown",{get:function(){return this._isShown},set:function(t){this._isShown=t,t?this.renderer.addClass(this.element.nativeElement,"in"):this.renderer.removeClass(this.element.nativeElement,"in"),Object(r.d)()||(t?this.renderer.addClass(this.element.nativeElement,"show"):this.renderer.removeClass(this.element.nativeElement,"show"))},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){this.isAnimated&&(this.renderer.addClass(this.element.nativeElement,"fade"),r.b.reflow(this.element.nativeElement)),this.isShown=!0},t}(),f=function(){function t(t,e){this.clf=e,this.config=c,this.onShow=new a.EventEmitter,this.onShown=new a.EventEmitter,this.onHide=new a.EventEmitter,this.onHidden=new a.EventEmitter,this.isBodyOverflowing=!1,this.originalBodyPadding=0,this.scrollbarWidth=0,this.modalsCount=0,this.lastDismissReason="",this.loaders=[],this._backdropLoader=this.clf.createLoader(null,null,null),this._renderer=t.createRenderer(null,null)}return t.prototype.show=function(t,e){return this.modalsCount++,this._createLoaders(),this.config=Object.assign({},c,e),this._showBackdrop(),this.lastDismissReason=null,this._showModal(t)},t.prototype.hide=function(t){var e=this;1===this.modalsCount&&(this._hideBackdrop(),this.resetScrollbar()),this.modalsCount=this.modalsCount>=1?this.modalsCount-1:0,setTimeout(function(){e._hideModal(t),e.removeLoaders(t)},this.config.animated?150:0)},t.prototype._showBackdrop=function(){var t=this.config.backdrop||"static"===this.config.backdrop,e=!this.backdropRef||!this.backdropRef.instance.isShown;1===this.modalsCount&&(this.removeBackdrop(),t&&e&&(this._backdropLoader.attach(d).to("body").show({isAnimated:this.config.animated}),this.backdropRef=this._backdropLoader._componentRef))},t.prototype._hideBackdrop=function(){var t=this;this.backdropRef&&(this.backdropRef.instance.isShown=!1,setTimeout(function(){return t.removeBackdrop()},this.config.animated?150:0))},t.prototype._showModal=function(t){var e=this.loaders[this.loaders.length-1],n=new o,a=e.provide({provide:u,useValue:this.config}).provide({provide:o,useValue:n}).attach(l).to("body").show({content:t,isAnimated:this.config.animated,initialState:this.config.initialState,bsModalService:this});return a.instance.level=this.getModalsCount(),n.hide=function(){a.instance.hide()},n.content=e.getInnerComponent()||null,n.setClass=function(t){a.instance.config.class=t},n},t.prototype._hideModal=function(t){var e=this.loaders[t-1];e&&e.hide()},t.prototype.getModalsCount=function(){return this.modalsCount},t.prototype.setDismissReason=function(t){this.lastDismissReason=t},t.prototype.removeBackdrop=function(){this._backdropLoader.hide(),this.backdropRef=null},t.prototype.checkScrollbar=function(){this.isBodyOverflowing=document.body.clientWidth100&&(this.percent-=t-100)},t}(),o=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[r]}},t}()},Dkky:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("fr-ch",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(t,e){switch(e){default:case"M":case"Q":case"D":case"DDD":case"d":return t+(1===t?"er":"e");case"w":case"W":return t+(1===t?"re":"e")}},week:{dow:1,doy:4}})}()},Dmvi:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")},week:{dow:1,doy:4}})}()},DoHr:function(t,e,n){!function(t){"use strict";var e={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'\xfcnc\xfc",4:"'\xfcnc\xfc",100:"'\xfcnc\xfc",6:"'nc\u0131",9:"'uncu",10:"'uncu",30:"'uncu",60:"'\u0131nc\u0131",90:"'\u0131nc\u0131"};t.defineLocale("tr",{months:"Ocak_\u015eubat_Mart_Nisan_May\u0131s_Haziran_Temmuz_A\u011fustos_Eyl\xfcl_Ekim_Kas\u0131m_Aral\u0131k".split("_"),monthsShort:"Oca_\u015eub_Mar_Nis_May_Haz_Tem_A\u011fu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Sal\u0131_\xc7ar\u015famba_Per\u015fembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_\xc7ar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_\xc7a_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn saat] LT",nextDay:"[yar\u0131n saat] LT",nextWeek:"[gelecek] dddd [saat] LT",lastDay:"[d\xfcn] LT",lastWeek:"[ge\xe7en] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s \xf6nce",s:"birka\xe7 saniye",ss:"%d saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir g\xfcn",dd:"%d g\xfcn",M:"bir ay",MM:"%d ay",y:"bir y\u0131l",yy:"%d y\u0131l"},ordinal:function(t,n){switch(n){case"d":case"D":case"Do":case"DD":return t;default:if(0===t)return t+"'\u0131nc\u0131";var a=t%10;return t+(e[a]||e[t%100-a]||e[t>=100?100:null])}},week:{dow:1,doy:7}})}(n("wd/R"))},DtyJ:function(t,e,n){"use strict";n.r(e);var a=n("6blF"),r=n("KhEm"),i=n("IxPp"),s=n("xTla"),o=n("K9Ia"),u=n("26FU"),c=n("S5bw"),l=n("svcd"),d=n("KQya"),f=n("T1DM"),p=n("zo3G"),h=n("tHPV"),g=n("mrSG"),b=n("h9Dq"),m=function(t){function e(e,n){void 0===e&&(e=y),void 0===n&&(n=Number.POSITIVE_INFINITY);var a=t.call(this,e,function(){return a.frame})||this;return a.maxFrames=n,a.frame=0,a.index=-1,a}return g.__extends(e,t),e.prototype.flush=function(){for(var t,e,n=this.actions,a=this.maxFrames;(e=n[0])&&e.delay<=a&&(n.shift(),this.frame=e.delay,!(t=e.execute(e.state,e.delay))););if(t){for(;e=n.shift();)e.unsubscribe();throw t}},e.frameTimeFactor=10,e}(n("CS9Q").a),y=function(t){function e(e,n,a){void 0===a&&(a=e.index+=1);var r=t.call(this,e,n)||this;return r.scheduler=e,r.work=n,r.index=a,r.active=!0,r.index=e.index=a,r}return g.__extends(e,t),e.prototype.schedule=function(n,a){if(void 0===a&&(a=0),!this.id)return t.prototype.schedule.call(this,n,a);this.active=!1;var r=new e(this.scheduler,this.work);return this.add(r),r.schedule(n,a)},e.prototype.requestAsyncId=function(t,n,a){void 0===a&&(a=0),this.delay=t.frame+a;var r=t.actions;return r.push(this),r.sort(e.sortActions),!0},e.prototype.recycleAsyncId=function(t,e,n){void 0===n&&(n=0)},e.prototype._execute=function(e,n){if(!0===this.active)return t.prototype._execute.call(this,e,n)},e.sortActions=function(t,e){return t.delay===e.delay?t.index===e.index?0:t.index>e.index?1:-1:t.delay>e.delay?1:-1},e}(b.a),v=n("siIJ"),_=n("pugT"),x=n("FFOo"),T=n("60iU"),w=n("y3By"),S=n("+umK"),O=n("mChF"),I=n("zrt+"),C=n("b7mW"),k=n("3fWJ"),N=n("8g8A"),R=n("awvh"),A=n("3U0i"),D=n("67Y/"),E=n("1fDf"),L=n("isby"),P=n("nkY7");function M(t,e,n){if(e){if(!Object(P.a)(e))return function(){for(var a=[],r=0;r=e){a.complete();break}if(a.next(i++),a.closed)break}})}function gt(t){var e=t.start,n=t.index,a=t.subscriber;n>=t.count?a.complete():(a.next(e),a.closed||(t.index=n+1,t.start=e+1,this.schedule(t)))}var bt=n("XlPw"),mt=n("gI3B");function yt(t,e){return new a.a(function(n){var a,r;try{a=t()}catch(s){return void n.error(s)}try{r=e(a)}catch(s){return void n.error(s)}var i=(r?Object(K.a)(r):U.a).subscribe(n);return function(){i.unsubscribe(),a&&a.unsubscribe()}})}var vt=n("909l"),_t=n("i4X3"),xt=n("iLxQ");n.d(e,"Observable",function(){return a.a}),n.d(e,"ConnectableObservable",function(){return r.a}),n.d(e,"GroupedObservable",function(){return i.a}),n.d(e,"observable",function(){return s.a}),n.d(e,"Subject",function(){return o.a}),n.d(e,"BehaviorSubject",function(){return u.a}),n.d(e,"ReplaySubject",function(){return c.a}),n.d(e,"AsyncSubject",function(){return l.a}),n.d(e,"asapScheduler",function(){return d.a}),n.d(e,"asyncScheduler",function(){return f.a}),n.d(e,"queueScheduler",function(){return p.a}),n.d(e,"animationFrameScheduler",function(){return h.a}),n.d(e,"VirtualTimeScheduler",function(){return m}),n.d(e,"VirtualAction",function(){return y}),n.d(e,"Scheduler",function(){return v.a}),n.d(e,"Subscription",function(){return _.a}),n.d(e,"Subscriber",function(){return x.a}),n.d(e,"Notification",function(){return T.a}),n.d(e,"NotificationKind",function(){return T.b}),n.d(e,"pipe",function(){return w.a}),n.d(e,"noop",function(){return S.a}),n.d(e,"identity",function(){return O.a}),n.d(e,"isObservable",function(){return I.a}),n.d(e,"ArgumentOutOfRangeError",function(){return C.a}),n.d(e,"EmptyError",function(){return k.a}),n.d(e,"ObjectUnsubscribedError",function(){return N.a}),n.d(e,"UnsubscriptionError",function(){return R.a}),n.d(e,"TimeoutError",function(){return A.a}),n.d(e,"bindCallback",function(){return M}),n.d(e,"bindNodeCallback",function(){return F}),n.d(e,"combineLatest",function(){return V.b}),n.d(e,"concat",function(){return H.a}),n.d(e,"defer",function(){return B.a}),n.d(e,"empty",function(){return U.b}),n.d(e,"forkJoin",function(){return W.a}),n.d(e,"from",function(){return K.a}),n.d(e,"fromEvent",function(){return $.a}),n.d(e,"fromEventPattern",function(){return X}),n.d(e,"generate",function(){return J}),n.d(e,"iif",function(){return tt}),n.d(e,"interval",function(){return et.a}),n.d(e,"merge",function(){return nt.a}),n.d(e,"never",function(){return rt}),n.d(e,"of",function(){return it.a}),n.d(e,"onErrorResumeNext",function(){return st}),n.d(e,"pairs",function(){return ot}),n.d(e,"partition",function(){return ft}),n.d(e,"race",function(){return pt.a}),n.d(e,"range",function(){return ht}),n.d(e,"throwError",function(){return bt.a}),n.d(e,"timer",function(){return mt.a}),n.d(e,"using",function(){return yt}),n.d(e,"zip",function(){return vt.b}),n.d(e,"scheduled",function(){return _t.a}),n.d(e,"EMPTY",function(){return U.a}),n.d(e,"NEVER",function(){return at}),n.d(e,"config",function(){return xt.a})},Dwqy:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("wd/R"),r=function(){function t(){}return t.prototype.transform=function(t){return t?a(1e3*t).fromNow():"unknown"},t}()},DxQv:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"s\xf8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\xf8rdag".split("_"),weekdaysShort:"s\xf8n_man_tir_ons_tor_fre_l\xf8r".split("_"),weekdaysMin:"s\xf8_ma_ti_on_to_fr_l\xf8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"p\xe5 dddd [kl.] LT",lastDay:"[i g\xe5r kl.] LT",lastWeek:"[i] dddd[s kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"f\xe5 sekunder",ss:"%d sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en m\xe5ned",MM:"%d m\xe5neder",y:"et \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},Dysq:function(t,e){t.exports='\n \n \n \n Toggle navigation\n \u5207\u63db\u5c0e\u89bd\n \n \n Dashboard\n \u5100\u8868\u677f\n \n \n Cluster\n \u53e2\u96c6\n \n \n Hosts\n \u4e3b\u6a5f\n \n \n Monitors\n \u76e3\u63a7\u7a0b\u5f0f\n \n \n OSDs\n OSD\n \n \n Configuration\n \u7d44\u614b\n \n \n CRUSH map\n CRUSH \u5730\u5716\n \n \n Manager modules\n \u7ba1\u7406\u54e1\u6a21\u7d44\n \n \n Logs\n \u8a18\u9304\n \n \n Alerts\n \u8b66\u793a\n \n \n Silences\n Silences\n \n \n Pools\n \u6c60\n \n \n Block\n \u5340\u584a\n \n \n Images\n \u5f71\u50cf\n \n \n Mirroring\n \u93e1\u50cf\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n \u6a94\u6848\u7cfb\u7d71\n \n \n Object Gateway\n \u7269\u4ef6\u9598\u9053\n \n \n Daemons\n \u7cbe\u9748\n \n \n Users\n \u4f7f\u7528\u8005\n \n \n Buckets\n \u6876\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Retrieving data\n for\n \n \n . Please wait...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Displaying previously cached data\n \n for \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n \n \n Back\n \u8fd4\u56de\n \n \n Select a Language\n \u9078\u53d6\u8a9e\u8a00\n \n \n Loading panel data...\n \u6b63\u5728\u8f09\u5165\u9762\u677f\u8cc7\u6599...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n \u5982\u9700\u4e86\u89e3\u5982\u4f55\u8a2d\u5b9a\u548c\u555f\u7528\u76e3\u63a7\u529f\u80fd\uff0c\n \u8acb\u53c3\u95b1\n \u6587\u4ef6\n \u3002\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Grafana \u5100\u8868\u677f\u4e0d\u5b58\u5728\u3002\u5982\u9700\u4e86\u89e3\n \u5982\u4f55\u5411 Grafana\xa0\u65b0\u589e\u5100\u8868\u677f\uff0c\n \u8acb\u53c3\u95b1\n \u6587\u4ef6\n \u3002\n \n \n \n Grafana Time Picker\n Grafana \u6642\u9593\u9078\u64c7\u5668\n \n \n Reset Settings\n \u91cd\u8a2d\u8a2d\u5b9a\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n \u7121\u6cd5\u8f09\u5165\u8cc7\u6599\u3002\n \n \n selected\n \u9078\u53d6\u7684\u6578\u76ee\n X selected\n \n \n found\n \u627e\u5230\u7684\u6578\u76ee\n X found\n \n \n total\n \u7e3d\u8a08\n X total\n \n \n Edit\n \u7de8\u8f2f\n \n \n Name\n \u540d\u7a31\n \n \n Description\n \u63cf\u8ff0\n \n \n Long description\n \u8a73\u7d30\u63cf\u8ff0\n \n \n Default\n \u9810\u8a2d\u503c\n \n \n Daemon default\n \u7cbe\u9748\u9810\u8a2d\u503c\n \n \n Services\n \u670d\u52d9\n \n \n Values\n \u503c\n \n \n The entered value is too high! It must not be greater than \n .\n \n \u8f38\u5165\u7684\u503c\u592a\u9ad8\uff01\u8a72\u503c\u4e0d\u5f97\u5927\u65bc \n \u3002\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \u8f38\u5165\u7684\u503c\u592a\u4f4e\uff01\u8a72\u503c\u4e0d\u5f97\u5c0f\u65bc \n \u3002\n \n \n \n Save\n \u5132\u5b58\n \n \n CRUSH map viewer\n CRUSH \u5730\u5716\u6aa2\u8996\u5668\n \n \n Hosts List\n \u4e3b\u6a5f\u6e05\u55ae\n \n \n Overall Performance\n \u6574\u9ad4\u6548\u80fd\n \n \n No entries found\n \u627e\u4e0d\u5230\u9805\u76ee\n \n \n Cluster Logs\n \u53e2\u96c6\u8a18\u9304\n \n \n Audit Logs\n \u7a3d\u6838\u8a18\u9304\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n \u6b63\u5728\u8f09\u5165\u7d44\u614b...\n \n \n The configuration could not be loaded.\n \u7121\u6cd5\u8f09\u5165\u7d44\u614b\u3002\n \n \n Edit Manager module\n \u7de8\u8f2f\u7ba1\u7406\u54e1\u6a21\u7d44\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \u8f38\u5165\u7684\u503c\u4e0d\u662f\u6709\u6548\u7684 UUID\uff0c\u4f8b\u5982 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n \u8f38\u5165\u7684\u503c\u5fc5\u9808\u662f\u6709\u6548\u7684 IP \u4f4d\u5740\u3002\n \n \n This field is required.\n \u6b64\u6b04\u4f4d\u70ba\u5fc5\u586b\u6b04\u4f4d\u3002\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n \u8f38\u5165\u7684\u503c\u592a\u9ad8\uff01\u8a72\u503c\u5fc5\u9808\u5c0f\u65bc\u6216\u7b49\u65bc \n \u3002\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n \u8f38\u5165\u7684\u503c\u592a\u4f4e\uff01\u8a72\u503c\u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc \n \u3002\n \n \n \n The entered value needs to be a number.\n \u8f38\u5165\u7684\u503c\u5fc5\u9808\u70ba\u6578\u5b57\u3002\n \n \n The entered value needs to be a number or decimal.\n \u8f38\u5165\u7684\u503c\u5fc5\u9808\u70ba\u6578\u5b57\u6216\u5c0f\u6578\u3002\n \n \n Update\n \u66f4\u65b0\n \n \n Status\n \u72c0\u614b\n \n \n Cluster ID\n \u53e2\u96c6 ID\n \n \n monmap modified\n monmap \u4fee\u6539\u6642\u9593\n \n \n monmap epoch\n monmap \u7248\u672c\u7de8\u865f\n \n \n quorum con\n quorum con\n \n \n quorum mon\n quorum mon\n \n \n required con\n required con\n \n \n required mon\n required mon\n \n \n In Quorum\n \u4ef2\u88c1\u6210\u54e1\n \n \n Not In Quorum\n \u975e\u4ef2\u88c1\u6210\u54e1\n \n \n Cancel\n \u53d6\u6d88\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n \u78ba\u5b9a\u8981\n \u9078\u53d6\u7684\n \u55ce\uff1f\n \n \n \n Yes, I am sure.\n \u662f\u7684\uff0c\u6211\u78ba\u5b9a\u3002\n \n \n Cluster-wide OSD Flags\n \u53e2\u96c6\u7bc4\u570d\u7684 OSD \u65d7\u6a19\n \n \n Submit\n \u63d0\u4ea4\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n \u9032\u968e...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n OSD \u5fa9\u539f\u512a\u5148\u7a0b\u5ea6\n \n \n Priority\n \u512a\u5148\u7a0b\u5ea6\n \n \n Customize priority values\n \u81ea\u8a02\u512a\u5148\u7a0b\u5ea6\u503c\n \n \n This field is required!\n \u6b64\u6b04\u4f4d\u70ba\u5fc5\u586b\u6b04\u4f4d\uff01\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n \u8f38\u5165\u7684\u503c\u592a\u9ad8\uff01\u8a72\u503c\u4e0d\u5f97\u5927\u65bc \n \u3002\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \u8f38\u5165\u7684\u503c\u592a\u4f4e\uff01\u8a72\u503c\u4e0d\u5f97\u5c0f\u65bc \n \u3002\n \n \n \n Reweight OSD\n \u91cd\u65b0\u8a2d\u5b9a OSD \u7684\u6b0a\u6578\n \n \n The value needs to be between 0 and 1.\n \u8a72\u503c\u5fc5\u9808\u4ecb\u65bc 0 \u81f3 1 \u4e4b\u9593\u3002\n \n \n Reweight\n \u91cd\u65b0\u8a2d\u5b9a\u6b0a\u6578\n \n \n OSDs \n Scrub\n \n OSD \n \u6574\u7406\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {\u6df1\u5c64} }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n \u5373\u5c07\u5c0d OSD\n \n \n \n \u5957\u7528\n \u6574\u7406\u3002 \n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {\u6df1\u5c64} }\n \n \n OSDs List\n OSD \u6e05\u55ae\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \u82e5\u7e7c\u7e8c\uff0c\n OSD\n \n \n \u5c07\u88ab\u6a19\u793a\u70ba\n \n \n \u3002\n \n \n \n The OSD is not safe to destroy!\n OSD \u4e0d\u5b89\u5168\uff0c\u7121\u6cd5\u640d\u6bc0\uff01\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \u82e5\u7e7c\u7e8c\uff0c\n OSD\n \n \n \u5c07\u88ab\n \n \n \u3002\n \n \n \n Details\n \u8a73\u7d30\u8cc7\u6599\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n \u503c\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n \u95dc\u9589\n \n \n Delete\n \u522a\u9664\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n \u72c0\u614b\n \n \n Statistics\n \u7d71\u8a08\u8cc7\u6599\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n \u5982\u9700\u4e86\u89e3\u5982\u4f55\u8a2d\u5b9a\u548c\u555f\u7528 NFS Ganesha \u7ba1\u7406\u529f\u80fd\uff0c\n \u8acb\u53c3\u95b1\n \u6587\u4ef6\n \u3002\n \n \n \n Clients\n \u7528\u6236\u7aef\n \n \n Any client can access\n \u4efb\u4f55\u7528\u6236\u7aef\u5747\u53ef\u5b58\u53d6\n \n \n Addresses\n \u4f4d\u5740\n \n \n Required field\n \u5fc5\u586b\u6b04\u4f4d\n \n \n Must contain one or more comma-separated values\n \u5fc5\u9808\u5305\u542b\u4e00\u6216\u591a\u500b\u9017\u865f\u5206\u9694\u503c\n \n \n For example:\n \u4f8b\u5982\ufe30\n \n \n Access Type\n \u5b58\u53d6\u985e\u578b\n \n \n Squash\n Squash\n \n \n Add clients\n \u65b0\u589e\u7528\u6236\u7aef\n \n \n Loading...\n \u6b63\u5728\u8f09\u5165...\n \n \n -- No cluster available --\n -- \u6c92\u6709\u53ef\u7528\u7684\u53e2\u96c6 --\n \n \n -- Select the cluster --\n -- \u9078\u53d6\u53e2\u96c6 --\n \n \n Add daemon\n \u65b0\u589e\u7cbe\u9748\n \n \n Storage Backend\n \u5132\u5b58\u5f8c\u7aef\n \n \n -- No data pools available --\n -- \u6c92\u6709\u53ef\u7528\u7684\u8cc7\u6599\u6c60 --\n \n \n -- Select the storage backend --\n -- \u9078\u53d6\u5132\u5b58\u5f8c\u7aef --\n \n \n Object Gateway User\n \u7269\u4ef6\u9598\u9053\u4f7f\u7528\u8005\n \n \n -- No users available --\n -- \u6c92\u6709\u53ef\u7528\u7684\u4f7f\u7528\u8005 --\n \n \n -- Select the object gateway user --\n -- \u9078\u53d6\u7269\u4ef6\u9598\u9053\u4f7f\u7528\u8005 --\n \n \n CephFS User ID\n CephFS \u4f7f\u7528\u8005 ID\n \n \n -- No clients available --\n -- \u6c92\u6709\u53ef\u7528\u7684\u7528\u6236\u7aef --\n \n \n -- Select the cephx client --\n -- \u9078\u53d6 cephx \u7528\u6236\u7aef --\n \n \n CephFS Name\n CephFS \u540d\u7a31\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n \u5b89\u5168\u6a19\u7c64\n \n \n Enable security label\n \u555f\u7528\u5b89\u5168\u6a19\u7c64\n \n \n CephFS Path\n CephFS \u8def\u5f91\n \n \n Path need to start with a \'/\' and can be followed by a word\n \u8def\u5f91\u5fc5\u9808\u4ee5\u300c/\u300d\u958b\u982d\uff0c\u5f8c\u9762\u53ef\u63a5\u55ae\u8a5e\n \n \n New directory will be created\n \u5c07\u5efa\u7acb\u65b0\u76ee\u9304\n \n \n Path\n \u8def\u5f91\n \n \n Path can only be a single \'/\' or a word\n \u8def\u5f91\u53ea\u80fd\u4ee5\u55ae\u4e00\u300c/\u300d\u6216\u55ae\u8a5e\u958b\u982d\n \n \n New bucket will be created\n \u5c07\u5efa\u7acb\u65b0\u6876\n \n \n NFS Protocol\n NFS \u901a\u8a0a\u5354\u5b9a\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n NFS \u6a19\u8a18\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n \n NFS v3\n \u639b\u63a5\u7684\u5099\u7528\u5b58\u53d6 (\u4e0d\u5f97\u5305\u542b\u524d\u7f6e /)\u3002\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n \u7528\u6236\u7aef\u4e0d\u80fd\u639b\u63a5\u5b50\u76ee\u9304 (\u5373\u5982\u679c\u6a19\u8a18\u70ba foo\uff0c\u5247\u7528\u6236\u7aef\u7121\u6cd5\u639b\u63a5 foo/baz)\u3002\n \n \n By using different Tag options, the same Path may be exported multiple times.\n \u900f\u904e\u4f7f\u7528\u4e0d\u540c\u6a19\u8a18\u9078\u9805\uff0c\u53ef\u5c07\u540c\u4e00\u8def\u5f91\u8f38\u51fa\u591a\u6b21\u3002\n \n \n Pseudo\n \u865b\u64ec\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n \u6b64 \n NFS v4\n \u8f38\u51fa\u5728\n \u865b\u64ec\u6a94\u6848\u7cfb\u7d71\n \u4e2d\n \u6240\u4f54\u7528\u7684\u4f4d\u7f6e (\u5fc5\u9808\u552f\u4e00)\u3002\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n \u900f\u904e\u4f7f\u7528\u4e0d\u540c\u865b\u64ec\u9078\u9805\uff0c\u53ef\u5c07\u540c\u4e00\u8def\u5f91\u8f38\u51fa\u591a\u6b21\u3002\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- \u6c92\u6709\u53ef\u7528\u7684\u5b58\u53d6\u985e\u578b --\n \n \n -- Select the access type --\n -- \u9078\u53d6\u5b58\u53d6\u985e\u578b --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- \u6c92\u6709\u53ef\u7528\u7684 squash --\n \n \n --Select what kind of user id squashing is performed --\n -- \u9078\u53d6\u57f7\u884c\u54ea\u7a2e\u985e\u578b\u7684\u4f7f\u7528\u8005 ID \u533f\u540d\u5b58\u53d6 --\n \n \n Transport Protocol\n \u50b3\u8f38\u901a\u8a0a\u5354\u5b9a\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n \u6b61\u8fce\u4f7f\u7528 Ceph\uff01\n The welcome message on the login page\n \n \n Username is required\n \u9700\u8981\u6307\u5b9a\u4f7f\u7528\u8005\u540d\u7a31\n \n \n Password is required\n \u9700\u8981\u6307\u5b9a\u5bc6\u78bc\n \n \n Login\n \u767b\u5165\n \n \n Sorry, the user does not exist in Ceph.\n \u62b1\u6b49\uff0c\u8a72\u4f7f\u7528\u8005\u4e0d\u5b58\u5728\u65bc Ceph \u4e2d\u3002\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n \u8fd4\u56de\n \u767b\u5165\u9801\u9762\n \u3002 \u7576\u60a8\u91cd\u8a66\u767b\u5165\u6642\uff0c\u60a8\u5c07\u5f9e\u8eab\u5206\u63d0\u4f9b\u8005\u767b\u51fa\u3002\n \n \n \n Forbidden\n \u5df2\u7981\u6b62\n \n \n Sorry, you are not allowed to see what you were looking for.\n \u62b1\u6b49\uff0c\u60a8\u7121\u6b0a\u67e5\u770b\u60a8\u8981\u5c0b\u627e\u7684\u5167\u5bb9\u3002\n \n \n Sorry, we could not find what you were looking for\n \u62b1\u6b49\uff0c\u6211\u5011\u627e\u4e0d\u5230\u60a8\u8981\u5c0b\u627e\u7684\u5167\u5bb9\u3002\n \n \n Remove all\n \u5168\u90e8\u79fb\u9664\n \n \n Recent Notifications\n \u6700\u8fd1\u7684\u901a\u77e5\n \n \n There are no background tasks.\n \u6c92\u6709\u80cc\u666f\u4efb\u52d9\u3002\n \n \n Background Tasks\n \u80cc\u666f\u4efb\u52d9\n \n \n Help\n \u8aaa\u660e\n \n \n Documentation\n \u6587\u4ef6\n \n \n API\n API\n \n \n About\n \u95dc\u65bc\n \n \n Dashboard Settings\n \u5100\u8868\u677f\u8a2d\u5b9a\n \n \n User management\n \u4f7f\u7528\u8005\u7ba1\u7406\n \n \n Logged in user\n \u767b\u5165\u7684\u4f7f\u7528\u8005\n \n \n Signed in as\n \n \n \n \n \u4ee5\n \n \n \n \u8eab\u5206\u767b\u5165\n \n \n \n Sign out\n \u767b\u51fa\n \n \n Name...\n \u540d\u7a31...\n \n \n The chosen name is already in use.\n \u6240\u9078\u7684\u540d\u7a31\u5df2\u5728\u4f7f\u7528\u4e2d\u3002\n \n \n Description...\n \u63cf\u8ff0...\n \n \n Permissions\n \u8a31\u53ef\u6b0a\n \n \n Roles\n \u89d2\u8272\n \n \n Username\n \u4f7f\u7528\u8005\u540d\u7a31\n \n \n Password\n \u5bc6\u78bc\n \n \n Confirm password\n \u78ba\u8a8d\u5bc6\u78bc\n \n \n Password confirmation doesn\'t match the password.\n \u78ba\u8a8d\u7684\u5bc6\u78bc\u8207\u4e4b\u524d\u8f38\u5165\u7684\u5bc6\u78bc\u4e0d\u7b26\u3002\n \n \n Full name\n \u5168\u540d\n \n \n Email\n \u96fb\u5b50\u90f5\u4ef6\n \n \n Invalid email.\n \u96fb\u5b50\u90f5\u4ef6\u7121\u6548\u3002\n \n \n You are about to remove "user read / update" permissions from your own user.\n \u60a8\u6b63\u8981\u70ba\u60a8\u81ea\u5df1\u7684\u4f7f\u7528\u8005\u79fb\u9664\u300c\u4f7f\u7528\u8005\u8b80\u53d6/\u5beb\u5165\u300d\u8a31\u53ef\u6b0a\u3002\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n \u82e5\u7e7c\u7e8c\uff0c\u60a8\u5c07\u518d\u4e5f\u7121\u6cd5\u70ba\u4efb\u4f55\u4f7f\u7528\u8005\u65b0\u589e\u6216\u79fb\u9664\u89d2\u8272\u3002\n \n \n Are you sure you want to continue?\n \u78ba\u5b9a\u8981\u7e7c\u7e8c\u55ce\uff1f\n \n \n Performance counters not available\n \u6c92\u6709\u53ef\u7528\u7684\u6548\u80fd\u8a08\u6578\u5668\n \n \n Attributes (OSD map)\n \u5c6c\u6027 (OSD \u5730\u5716)\n \n \n Metadata not available\n \u7121\u6cd5\u4f7f\u7528\u4e2d\u7e7c\u8cc7\u6599\n \n \n Metadata\n \u4e2d\u7e7c\u8cc7\u6599\n \n \n Performance counter\n \u6548\u80fd\u8a08\u6578\u5668\n \n \n Histogram not available: \n \n \n \u7121\u6cd5\u4f7f\u7528\u9577\u689d\u5716\ufe30\n \n \n \n \n Writes\n \u5beb\u5165\n \n \n Reads\n \u8b80\u53d6\n \n \n Histogram\n \u9577\u689d\u5716\n \n \n Performance Details\n \u6548\u80fd\u8a73\u7d30\u8cc7\u6599\n \n \n Current values\n \u76ee\u524d\u7684\u503c\n \n \n Type\n \u985e\u578b\n \n \n Min\n \u6700\u5c0f\u503c\n \n \n Max\n \u6700\u5927\u503c\n \n \n Flags\n \u65d7\u6a19\n \n \n Source\n \u4f86\u6e90\n \n \n Level\n \u5c64\u7d1a\n \n \n Can be updated at runtime (editable)\n \u53ef\u5728\u57f7\u884c\u6642\u671f\u66f4\u65b0 (\u53ef\u7de8\u8f2f)\n \n \n Tags\n \u6a19\u8a18\n \n \n Enum values\n \u5217\u8209\u503c\n \n \n See also\n \u53e6\u8acb\u53c3\u95b1\n \n \n Cluster Status\n \u53e2\u96c6\u72c0\u614b\n \n \n Manager Daemons\n \u7ba1\u7406\u54e1\u7cbe\u9748\n \n \n Object Gateways\n \u7269\u4ef6\u9598\u9053\n \n \n Metadata Servers\n \u4e2d\u7e7c\u8cc7\u6599\u4f3a\u670d\u5668\n \n \n iSCSI Gateways\n iSCSI \u9598\u9053\n \n \n Client IOPS\n \u7528\u6236\u7aef IOPS\n \n \n Client Throughput\n \u7528\u6236\u7aef\u8f38\u9001\u91cf\n \n \n Client Read/Write\n \u7528\u6236\u7aef\u8b80\u53d6/\u5beb\u5165\n \n \n Recovery Throughput\n \u5fa9\u539f\u8f38\u9001\u91cf\n \n \n Scrub\n \u6574\u7406\n \n \n Performance\n \u6548\u80fd\n \n \n Raw Capacity\n \u539f\u59cb\u5bb9\u91cf\n \n \n Objects\n \u7269\u4ef6\n \n \n PGs per OSD\n \u6bcf\u500b OSD \u7684 PG \u6578\n \n \n PG Status\n PG \u72c0\u614b\n \n \n Capacity\n \u5bb9\u91cf\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n \u5982\u9700\u8a73\u7d30\u8cc7\u6599\uff0c\u8acb\u53c3\u95b1\n \u8a18\u9304\n \u3002\n \n \n \n Ranks\n \u968e\u5c64\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n \u7528\u6236\u7aef\ufe30\n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n \u5c07\u5f71\u50cf\u79fb\u81f3\u5783\u573e\u6876\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n \u82e5\u8981\u5c07 \n \n /\n \n \u79fb\u81f3\u5783\u573e\u6876\uff0c\n \u8acb\u6309\u4e00\u4e0b\n \u79fb\u52d5\u5f71\u50cf\n \u3002\u6216\u8005\uff0c\u60a8\u53ef\u4ee5\u9078\u53d6\u4e00\u500b\u904e\u671f\u65e5\u3002\n \n \n \n Protection expires at\n \u4fdd\u8b77\u7684\u904e\u671f\u65e5\u70ba\n \n \n NOT PROTECTED\n \u7121\u4fdd\u8b77\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n \u65e5\u671f\u683c\u5f0f\u932f\u8aa4\u3002\u8acb\u4f7f\u7528\u300cYYYY-MM-DD HH:mm:ss\u300d\u3002\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n \u4fdd\u8b77\u5df2\u904e\u671f\u3002\u8acb\u9078\u53d6\u4e00\u500b\u672a\u4f86\u7684\u65e5\u671f\u6216\u4fdd\u7559\u7a7a\u767d\u3002\n \n \n Move Image\n \u79fb\u52d5\u5f71\u50cf\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n \u7d9c\u89bd\n \n \n Targets\n \u76ee\u6a19\n \n \n Discovery Authentication\n \u63a2\u67e5\u9a57\u8b49\n \n \n User\n \u4f7f\u7528\u8005\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \u4f7f\u7528\u8005\u540d\u7a31\u7684\u9577\u5ea6\u5fc5\u9808\u4ecb\u65bc 8 \u81f3 64 \u500b\u5b57\u5143\u4e4b\u9593\uff0c\u4e26\u4e14\u53ea\u80fd\u5305\u542b\u4ee5\u4e0b\n \u5b57\u5143\ufe30\u5b57\u6bcd\u3001\u300c.\u300d\u3001\u300c@\u300d\u3001\u300c-\u300d\u3001\u300c_\u300d\u6216\u300c:\u300d\u3002\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n \u96d9\u5411\u9a57\u8b49\u4f7f\u7528\u8005\n \n \n Mutual Password\n \u96d9\u5411\u9a57\u8b49\u5bc6\u78bc\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n \u5982\u9700\u4e86\u89e3\u5982\u4f55\u8a2d\u5b9a\u548c\u555f\u7528 iSCSI \u76ee\u6a19\u7ba1\u7406\u529f\u80fd\uff0c\n \u8acb\u53c3\u95b1\n \u6587\u4ef6\n \u3002\n \n \n \n Available information:\n \u53ef\u7528\u8cc7\u8a0a\ufe30\n \n \n iSCSI Targets not available\n \u7121\u6cd5\u4f7f\u7528 iSCSI \u76ee\u6a19\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n \u50c5\u9069\u7528\u65bc\u5df2\u555f\u7528 \n fast-diff\n \u7684 RBD \u5f71\u50cf\n \n \n \n Pool\n \u6c60\n \n \n Data Pool\n \u8cc7\u6599\u6c60\n \n \n Created\n \u5df2\u5efa\u7acb\n \n \n Size\n \u5927\u5c0f\n \n \n Object size\n \u7269\u4ef6\u5927\u5c0f\n \n \n Features\n \u529f\u80fd\n \n \n Provisioned\n \u5df2\u4f48\u5efa\n \n \n N/A\n \u7121\n \n \n Total provisioned\n \u7e3d\u4f48\u5efa\u6578\n \n \n Striping unit\n \u5206\u5272\u55ae\u4f4d\n \n \n Striping count\n \u5206\u5272\u8a08\u6578\n \n \n Parent\n \u7236\n \n \n Block name prefix\n \u5340\u584a\u540d\u7a31\u5b57\u9996\n \n \n Order\n \u9806\u5e8f\n \n \n Snapshots\n \u5feb\u7167\n \n \n Image\n \u5f71\u50cf\n \n \n This setting overrides the global value\n \u6b64\u8a2d\u5b9a\u6703\u8986\u5beb\u5168\u57df\u503c\n \n \n Global\n \u5168\u57df\n \n \n This is the global value. No value for this option has been set for this image.\n \u6b64\u503c\u70ba\u5168\u57df\u503c\u3002\u672a\u70ba\u6b64\u5f71\u50cf\u8a2d\u5b9a\u6b64\u9078\u9805\u7684\u503c\u3002\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \u4e0d\u5141\u8a31\u4f7f\u7528\u300c/\u300d\u548c\u300c@\u300d\u3002\n \n \n -- No rbd pools available --\n -- \u6c92\u6709\u53ef\u7528\u7684 RBD \u6c60 --\n \n \n -- Select a pool --\n -- \u9078\u53d6\u6c60 --\n \n \n Use a dedicated data pool\n \u4f7f\u7528\u5c08\u5c6c\u7684\u8cc7\u6599\u6c60\n \n \n Data pool\n \u8cc7\u6599\u6c60\n \n \n Dedicated pool that stores the object-data of the RBD.\n \u5c08\u7528\u65bc\u5132\u5b58 RBD \u7684\u7269\u4ef6\u8cc7\u6599\u7684\u6c60\n \n \n e.g., 10GiB\n \u4f8b\u5982 10 GiB\n \n \n You have to increase the size.\n \u60a8\u5fc5\u9808\u589e\u52a0\u5927\u5c0f\u3002\n \n \n Advanced\n \u9032\u968e\n \n \n Striping\n \u5206\u5272\n \n \n Stripe unit\n \u5206\u5272\u55ae\u4f4d\n \n \n -- Select stripe unit --\n -- \u9078\u53d6\u5206\u5272\u55ae\u4f4d --\n \n \n This field is required because stripe count is defined!\n \u7531\u65bc\u5df2\u5b9a\u7fa9\u5206\u5272\u8a08\u6578\uff0c\u56e0\u6b64\u5fc5\u9808\u586b\u5beb\u6b64\u6b04\u4f4d\uff01\n \n \n Stripe unit is greater than object size.\n \u5206\u5272\u55ae\u4f4d\u5927\u65bc\u7269\u4ef6\u5927\u5c0f\u3002\n \n \n Stripe count\n \u5206\u5272\u8a08\u6578\n \n \n This field is required because stripe unit is defined!\n \u7531\u65bc\u5df2\u5b9a\u7fa9\u5206\u5272\u55ae\u4f4d\uff0c\u56e0\u6b64\u5fc5\u9808\u586b\u5beb\u6b64\u6b04\u4f4d\uff01\n \n \n Stripe count must be greater than 0.\n \u5206\u5272\u8a08\u6578\u5fc5\u9808\u5927\u65bc 0\u3002\n \n \n \n RBD Snapshot\n \n \n RBD \u5feb\u7167\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {\u91cd\u65b0\u547d\u540d} other {\u5efa\u7acb} }\n \n \n \n Snapshot\n \n \n \u5feb\u7167\n \n \n \n PROTECTED\n \u53d7\u4fdd\u8b77\n \n \n UNPROTECTED\n \u672a\u53d7\u4fdd\u8b77\n \n \n You are about to rollback\n \u60a8\u6b63\u8981\u5fa9\u539f\n \n \n Purge Trash\n \u6e05\u9664\u5783\u573e\u6876\n \n \n To purge, select one or All images and click\n \u82e5\u8981\u6e05\u9664\uff0c\u8acb\u9078\u53d6\u4e00\u500b\u6216\u5168\u90e8\u5f71\u50cf\uff0c\u7136\u5f8c\u6309\u4e00\u4e0b\n \n \n Pool:\n \u6c60\ufe30\n \n \n Pool name...\n \u6c60\u540d\u7a31...\n \n \n All\n \u5168\u90e8\n \n \n Restore Image\n \u56de\u5b58\u5f71\u50cf\n \n \n To restore\n \u82e5\u8981\u56de\u5b58\n \n \n type the image\'s new name and click\n \u9375\u5165\u5f71\u50cf\u7684\u65b0\u540d\u7a31\u5e76\u6309\u4e00\u4e0b\n \n \n New Name\n \u65b0\u540d\u7a31\n \n \n Expired at\n \u904e\u671f\u65e5\u70ba\n \n \n Protected until\n \u4fdd\u8b77\u904e\u671f\u65e5\u70ba\n \n \n This image is protected until \n .\n \n \u6b64\u5f71\u50cf\u7684\u4fdd\u8b77\u904e\u671f\u65e5\u70ba \n \u3002\n \n \n \n Trash\n \u5783\u573e\u6876\n \n \n iSCSI Topology\n iSCSI \u62d3\u64b2\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n \u901a\u5e38\u4e0d\u9700\u8981\u8b8a\u66f4\u9019\u4e9b\u53c3\u6578\u7684\u9810\u8a2d\u503c\u3002\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n \u8a2d\u5b9a\n \n \n Backstore\n \u652f\u63f4\u5132\u5b58\n \n \n Confirm\n \u78ba\u8a8d\n \n \n Advanced Settings\n \u9032\u968e\u8a2d\u5b9a\n \n \n Target IQN\n \u76ee\u6a19 IQN\n \n \n IQN has wrong pattern.\n IQN \u6a21\u5f0f\u932f\u8aa4\u3002\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n IQN \u6a21\u5f0f\u61c9\u5982\u4e0b\u6240\u793a\ufe30\u300ciqn.$year-$month.$reversedAddress:$definedName\u300d\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \u4f8b\u5982\uff1aiqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n \u66f4\u591a\u8cc7\u8a0a\n \n \n This target has modified advanced settings.\n \u6b64\u76ee\u6a19\u7684\u9032\u968e\u8a2d\u5b9a\u5b58\u5728\u4fee\u6539\u3002\n \n \n Portals\n \u5165\u53e3\u7db2\u7ad9\n \n \n At least \n gateways are required.\n \n \u81f3\u5c11\u9700\u8981 \n \u500b\u7269\u4ef6\u9598\u9053\u3002\n \n \n \n Add portal\n \u65b0\u589e\u5165\u53e3\u7db2\u7ad9\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n \u6b64\u5f71\u50cf\u7684\u8a2d\u5b9a\u5b58\u5728\u4fee\u6539\u3002\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n \u65b0\u589e\u5f71\u50cf\n \n \n ACL authentication\n ACL \u9a57\u8b49\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n \u555f\u52d5\u5668\n \n \n Initiator\n \u555f\u52d5\u5668\n \n \n Client IQN\n \u7528\u6236\u7aef IQN\n \n \n Initiator IQN needs to be unique.\n \u555f\u52d5\u5668 IQN \u5fc5\u9808\u552f\u4e00\u3002\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \u4f7f\u7528\u8005\u540d\u7a31\u7684\u9577\u5ea6\u5fc5\u9808\u4ecb\u65bc 8 \u81f3 64 \u500b\u5b57\u5143\u4e4b\u9593\uff0c\u4e26\u4e14\u53ea\u80fd\u5305\u542b\u4ee5\u4e0b\n \u5b57\u5143\ufe30\u5b57\u6bcd\u3001\u300c.\u300d\u3001\u300c@\u300d\u3001\u300c-\u300d\u3001\u300c_\u300d\u6216\u300c:\u300d\u3002\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n \u555f\u52d5\u5668\u5c6c\u65bc\u7fa4\u7d44\u3002\u5f71\u50cf\u9808\u5728\u7fa4\u7d44\u4e2d\u9032\u884c\u8a2d\u5b9a\u3002 \n \n \n No items added.\n \u672a\u65b0\u589e\u9805\u76ee\u3002\n \n \n Add initiator\n \u65b0\u589e\u555f\u52d5\u5668\n \n \n Groups\n \u7fa4\u7d44\n \n \n Group\n \u7fa4\u7d44\n \n \n Add group\n \u65b0\u589e\u7fa4\u7d44\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n RBD \u7d44\u614b\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n \u79fb\u9664\u672c\u5730\u7d44\u614b\u503c\u3002\u5c07\u7e7c\u627f\u4e26\u4f7f\u7528\u7236\u7d44\u614b\u503c\u3002\n \n \n The mininum value is 0\n \u6700\u5c0f\u503c\u70ba 0\n \n \n Issues\n \u554f\u984c\n \n \n Syncing\n \u6b63\u5728\u540c\u6b65\n \n \n Ready\n \u6e96\u5099\u5c31\u7dd2\n \n \n Edit pool mirror mode\n \u7de8\u8f2f\u6c60\u93e1\u50cf\u6a21\u5f0f\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n \u82e5\u8981\u7de8\u8f2f\u6c60 \n \n \n \xa0\n \u7684\u93e1\u50cf\u6a21\u5f0f\uff0c\u8acb\u5f9e\u6e05\u55ae\u4e2d\u9078\u53d6\u4e00\u500b\u65b0\u6a21\u5f0f\uff0c\u7136\u5f8c\u6309\u4e00\u4e0b\xa0\n \u66f4\u65b0\n \u3002\n \n \n \n Mode\n \u6a21\u5f0f\n \n \n Peer clusters must be removed prior to disabling mirror.\n \u5728\u505c\u7528\u93e1\u50cf\u4e4b\u524d\uff0c\u5fc5\u9808\u5148\u79fb\u9664\u5c0d\u7b49\u53e2\u96c6\u3002\n \n \n \n \n pool mirror peer\n \n \n \n \u6c60\u93e1\u50cf\u5c0d\u7b49\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {\u7de8\u8f2f} other {\u65b0\u589e} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n \u6c60\n \n \n \u7684\n \u93e1\u50cf\u5c0d\u7b49\u5c6c\u6027\uff0c\u7136\u5f8c\u6309\u4e00\u4e0b\n \u63d0\u4ea4\n \u3002\n \n \n \n Cluster Name\n \u53e2\u96c6\u540d\u7a31\n \n \n The cluster name is not valid.\n \u53e2\u96c6\u540d\u7a31\u7121\u6548\u3002\n \n \n CephX ID\n CephX ID\n \n \n CephX ID...\n CephX ID...\n \n \n The CephX ID is not valid.\n CephX ID \u7121\u6548\u3002\n \n \n Monitor Addresses\n \u76e3\u63a7\u7a0b\u5f0f\u4f4d\u5740\n \n \n Comma-delimited addresses...\n \u9017\u865f\u5206\u9694\u7684\u4f4d\u5740...\n \n \n The monitory address is not valid.\n \u76e3\u63a7\u7a0b\u5f0f\u4f4d\u5740\u7121\u6548\u3002\n \n \n CephX Key\n CephX \u91d1\u9470\n \n \n Base64-encoded key...\n Base64 \u7de8\u78bc\u7684\u91d1\u9470...\n \n \n CephX key must be base64 encoded.\n CephX \u91d1\u9470\u5fc5\u9808\u70ba Base64 \u7de8\u78bc\u7684\u91d1\u9470\u3002\n \n \n Pools List\n \u6c60\u6e05\u55ae\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n \u540d\u7a31\u53ea\u80fd\u7531\u82f1\u6578\u5b57\u5143\u3001\u7834\u6298\u865f\u548c\u5e95\u7dda\u7d44\u6210\u3002\n \n \n The chosen erasure code profile name is already in use.\n \u6240\u9078\u7684\u7cfe\u522a\u78bc\u8a2d\u5b9a\u6a94\u540d\u7a31\u5df2\u5728\u4f7f\u7528\u4e2d\u3002\n \n \n Plugin\n \u5916\u639b\u7a0b\u5f0f\n \n \n Data chunks (k)\n \u8cc7\u6599\u5340\u584a (k)\n \n \n Must be equal to or greater than 2.\n \u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc 2\u3002\n \n \n Coding chunks (m)\n \u7de8\u78bc\u5340\u584a (m)\n \n \n Must be equal to or greater than 1.\n \u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc 1\u3002\n \n \n Durability estimator (c)\n \u6301\u4e45\u6027\u4f30\u503c (c)\n \n \n Locality (l)\n \u672c\u5730\u6027 (l)\n \n \n Crush failure domain\n CRUSH \u6545\u969c\u7db2\u57df\n \n \n Crush Locality\n CRUSH \u672c\u5730\u6027\n \n \n None\n \u7121\n \n \n Technique\n \u6280\u8853\n \n \n Packetsize\n \u5c01\u5305\u5927\u5c0f\n \n \n Crush root\n CRUSH \u6839\n \n \n Crush device class\n CRUSH \u88dd\u7f6e\u985e\u5225\n \n \n any\n \u4efb\u4f55\n \n \n Directory\n \u76ee\u9304\n \n \n The chosen Ceph pool name is already in use.\n \u6240\u9078\u7684 Ceph \u6c60\u540d\u7a31\u5df2\u5728\u4f7f\u7528\u4e2d\u3002\n \n \n Pool type\n \u6c60\u985e\u578b\n \n \n -- Select a pool type --\n -- \u9078\u53d6\u6c60\u985e\u578b --\n \n \n Placement groups\n \u653e\u7f6e\u7fa4\u7d44\n \n \n At least one placement group is needed!\n \u81f3\u5c11\u9700\u8981\u4e00\u500b\u653e\u7f6e\u7fa4\u7d44\uff01\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n \u60a8\u7684\u53e2\u96c6\u7121\u6cd5\u8655\u7406\u9019\u9ebc\u591a\u7684 PG\u3002\u8acb\u91cd\u65b0\u8a08\u7b97\u6240\u9700\u7684 PG \u6578\u91cf\u3002\n \n \n Calculation help\n \u8a08\u7b97\u8aaa\u660e\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n \u5df2\u70ba\u60a8\u8a08\u7b97\u76ee\u524d\u7684 PG \u8a2d\u5b9a\uff0c\u60a8\n \u61c9\u5728\u63d0\u4ea4\u524d\u78ba\u5b9a\u9019\u4e9b\u503c\u7b26\u5408\u60a8\u7684\u9700\u6c42\u3002\n \n \n Crush ruleset\n CRUSH \u898f\u5247\u96c6\n \n \n -- Select a crush rule --\n -- \u9078\u53d6 CRUSH \u898f\u5247 --\n \n \n Crush rule\n CRUSH \u898f\u5247\n \n \n Crush steps\n CRUSH \u6b65\u9a5f\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n \u7121\u6cd5\u5728\u76ee\u524d\u7684\u53e2\u96c6\u4e2d\u4f7f\u7528\u6b64\u898f\u5247\uff0c\u56e0\u70ba\u53e2\u96c6\u7684\n OSD \u6578\u91cf\u904e\u5c11\uff0c\u7121\u6cd5\u6eff\u8db3\u898f\u5247\u6240\u9700\u7684\u6700\u4f4e OSD \u6578\u91cf\u3002\n \n \n Replicated size\n \u8907\u88fd\u5927\u5c0f\n \n \n Minimum: \n \n \n \u6700\u4f4e\ufe30\n \n \n \n \n Maximum: \n \n \n \u6700\u9ad8\ufe30\n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n \u6307\u5b9a\u7684\u5927\u5c0f\u8d85\u51fa\u4e86\u7bc4\u570d\u3002\u4ecb\u65bc\n \u81f3 \n \u4e4b\u9593\u7684\u503c\u624d\u6709\u6548\u3002\n \n \n \n Erasure code profile\n \u7cfe\u522a\u78bc\u8a2d\u5b9a\u6a94\n \n \n -- No erasure code profile available --\n -- \u6c92\u6709\u53ef\u7528\u7684\u7cfe\u522a\u78bc\u8a2d\u5b9a\u6a94 --\n \n \n -- Select an erasure code profile --\n -- \u9078\u53d6\u7cfe\u522a\u78bc\u8a2d\u5b9a\u6a94 --\n \n \n EC Overwrites\n EC \u8986\u5beb\n \n \n Applications\n \u61c9\u7528\u7a0b\u5f0f\n \n \n Compression\n \u58d3\u7e2e\n \n \n Algorithm\n \u6f14\u7b97\u6cd5\n \n \n -- No erasure compression algorithm available --\n -- \u6c92\u6709\u53ef\u7528\u7684\u7cfe\u522a\u58d3\u7e2e\u6f14\u7b97\u6cd5 --\n \n \n Minimum blob size\n Blob \u6700\u5c0f\u5927\u5c0f\n \n \n e.g., 128KiB\n \u4f8b\u5982 128 KiB\n \n \n Value should be greater than 0\n \u503c\u61c9\u5927\u65bc 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Blob \u6700\u5927\u5927\u5c0f\n \n \n e.g., 512KiB\n \u4f8b\u5982 512 KiB\n \n \n Value should be greater than the minimum blob size\n \u503c\u61c9\u5927\u65bc blob \u6700\u5c0f\u5927\u5c0f\n \n \n Ratio\n \u6bd4\u7387\n \n \n Compression ratio\n \u58d3\u7e2e\u7387\n \n \n Value should be between 0.0 and 1.0\n \u503c\u61c9\u4ecb\u65bc 0.0 \u81f3 1.0 \u4e4b\u9593\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n \u7121\u6cd5\u5efa\u7acb\u540d\u7a31\u4e2d\u5305\u542b\u300c/\u300d\u7684 RBD \u6c60\u3002\n \n \n Please change the name or remove \'rbd\' from the applications list.\n \u8acb\u8b8a\u66f4\u540d\u7a31\u6216\u5c07\u300crbd\u300d\u5f9e\u61c9\u7528\u7a0b\u5f0f\u6e05\u55ae\u4e2d\u79fb\u9664\u3002\n \n \n Cache Tiers Details\n \u5feb\u53d6\u5c64\u8a73\u7d30\u8cc7\u6599\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n \u5982\u9700\u4e86\u89e3\u5982\u4f55\u8a2d\u5b9a\u548c\u555f\u7528\u7269\u4ef6\u9598\u9053\u7ba1\u7406\u529f\u80fd\uff0c\n \u8acb\u53c3\u95b1\n \u6587\u4ef6\n \u3002\n \n \n \n Daemons List\n \u7cbe\u9748\u6e05\u55ae\n \n \n Performance Counters\n \u6548\u80fd\u8a08\u6578\u5668\n \n \n Loading bucket data...\n \u6b63\u5728\u8f09\u5165\u6876\u8cc7\u6599...\n \n \n The bucket data could not be loaded.\n \u7121\u6cd5\u8f09\u5165\u6876\u8cc7\u6599\u3002\n \n \n Id\n ID\n \n \n The value is not valid.\n \u8a72\u503c\u7121\u6548\u3002\n \n \n Owner\n \u64c1\u6709\u8005\n \n \n -- Select a user --\n -- \u9078\u53d6\u4f7f\u7528\u8005 --\n \n \n ID\n ID\n \n \n Index type\n \u7d22\u5f15\u985e\u578b\n \n \n Placement rule\n \u653e\u7f6e\u898f\u5247\n \n \n Marker\n \u6a19\u8a18\n \n \n Maximum marker\n \u6700\u5927\u6a19\u8a18\u6578\n \n \n Version\n \u7248\u672c\n \n \n Master version\n \u4e3b\u7248\u672c\n \n \n Modification time\n \u4fee\u6539\u6642\u9593\n \n \n Zonegroup\n \u5340\u57df\u7fa4\u7d44\n \n \n Bucket quota\n \u6876\u5b9a\u984d\n \n \n Enabled\n \u5df2\u555f\u7528\n \n \n Maximum size\n \u6700\u5927\u5927\u5c0f\n \n \n Unlimited\n \u7121\u9650\u5236\n \n \n Maximum objects\n \u6700\u5927\u7269\u4ef6\u6578\n \n \n -- Select a username --\n -- \u9078\u53d6\u4f7f\u7528\u8005\u540d\u7a31 --\n \n \n Auto-generate key\n \u81ea\u52d5\u7522\u751f\u91d1\u9470\n \n \n Access key\n \u5b58\u53d6\u91d1\u9470\n \n \n Secret key\n \u6a5f\u5bc6\u91d1\u9470\n \n \n Email address\n \u96fb\u5b50\u90f5\u4ef6\u5730\u5740\n \n \n Suspended\n \u5df2\u66ab\u505c\n \n \n System\n \u7cfb\u7d71\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {\u5426} 1 {\u662f} }\n \n \n Maximum buckets\n \u6700\u5927\u6876\u6578\n \n \n Subusers\n \u5b50\u4f7f\u7528\u8005\n \n \n Capabilities\n \u529f\u80fd\n \n \n User quota\n \u4f7f\u7528\u8005\u5b9a\u984d\n \n \n Show\n \u986f\u793a\n \n \n Keys\n \u91d1\u9470\n \n \n -- Select a type --\n -- \u9078\u53d6\u985e\u578b --\n \n \n Permission\n \u8a31\u53ef\u6b0a\n \n \n -- Select a permission --\n -- \u9078\u53d6\u8a31\u53ef\u6b0a --\n \n \n Subuser\n \u5b50\u4f7f\u7528\u8005\n \n \n The chosen subuser ID is already in use.\n \u6240\u9078\u7684\u5b50\u4f7f\u7528\u8005 ID \u5df2\u5728\u4f7f\u7528\u4e2d\u3002\n \n \n read, write\n \u8b80\u53d6\u3001\u5beb\u5165\n \n \n full\n \u5b8c\u6574\n \n \n Swift key\n Swift \u91d1\u9470\n \n \n Auto-generate secret\n \u81ea\u52d5\u7522\u751f\u6a5f\u5bc6\u91d1\u9470\n \n \n Loading user data...\n \u6b63\u5728\u8f09\u5165\u4f7f\u7528\u8005\u8cc7\u6599...\n \n \n The user data could not be loaded.\n \u7121\u6cd5\u8f09\u5165\u4f7f\u7528\u8005\u8cc7\u6599\u3002\n \n \n The chosen user ID is already in use.\n \u6240\u9078\u7684\u4f7f\u7528\u8005 ID \u5df2\u5728\u4f7f\u7528\u4e2d\u3002\n \n \n This is not a valid email address.\n \u96fb\u5b50\u90f5\u4ef6\u5730\u5740\u7121\u6548\u3002\n \n \n The chosen email address is already in use.\n \u6240\u9078\u7684\u96fb\u5b50\u90f5\u4ef6\u5730\u5740\u5df2\u5728\u4f7f\u7528\u4e2d\u3002\n \n \n Max. buckets\n \u6700\u5927\u6876\u6578\n \n \n The entered value must be >= 0.\n \u8f38\u5165\u7684\u503c\u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc 0\u3002\n \n \n S3 key\n S3 \u91d1\u9470\n \n \n There are no subusers.\n \u6c92\u6709\u5b50\u4f7f\u7528\u8005\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n \u6c92\u6709\u91d1\u9470\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n \u6c92\u6709\u529f\u80fd\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n \u5927\u5c0f\u4e0d\u9650\n \n \n Max. size\n \u6700\u5927\u5927\u5c0f\n \n \n Unlimited objects\n \u7269\u4ef6\u6578\u4e0d\u9650\n \n \n Max. objects\n \u6700\u5927\u7269\u4ef6\u6578\n \n \n Current\n \u76ee\u524d\n \n \n Updated discovery authentication\n \u5df2\u66f4\u65b0\u63a2\u67e5\u9a57\u8b49\n \n \n There are no portals available.\n \u6c92\u6709\u53ef\u7528\u7684\u5165\u53e3\u7db2\u7ad9\u3002\n \n \n There are no images available.\n \u6c92\u6709\u53ef\u7528\u7684\u5f71\u50cf\u3002\n \n \n There are no images available. Please make sure you add an image to the target.\n \u6c92\u6709\u53ef\u7528\u7684\u5f71\u50cf\u3002\u8acb\u78ba\u5b9a\u70ba\u76ee\u6a19\u65b0\u589e\u4e00\u500b\u5f71\u50cf\u3002\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n \u6c92\u6709\u53ef\u7528\u7684\u555f\u52d5\u5668\u3002\u8acb\u78ba\u5b9a\u70ba\u76ee\u6a19\u65b0\u589e\u4e00\u500b\u555f\u52d5\u5668\u3002\n \n \n target\n target\n \n \n Target\n \u76ee\u6a19\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n \u72c0\u614b\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n \u8b80\u53d6\u4f4d\u5143\u7d44\u6578\n \n \n Write Bytes\n \u5beb\u5165\u4f4d\u5143\u7d44\u6578\n \n \n Read Ops\n \u8b80\u53d6\u64cd\u4f5c\u6578\n \n \n Write Ops\n \u5beb\u5165\u64cd\u4f5c\u6578\n \n \n A/O Since\n \u4f7f\u7528\u4e2d/\u6700\u4f73\u5316\u958b\u59cb\u6642\u9593\n \n \n Instance\n \u4f8b\u9805\n \n \n Hostname\n \u4e3b\u6a5f\u540d\u7a31\n \n \n Issue\n \u554f\u984c\n \n \n Progress\n \u9032\u5ea6\n \n \n Disabled\n \u5df2\u505c\u7528\n \n \n Edit Mode\n \u7de8\u8f2f\u6a21\u5f0f\n \n \n Add Peer\n \u65b0\u589e\u5c0d\u7b49\n \n \n Edit Peer\n \u7de8\u8f2f\u5c0d\u7b49\n \n \n Delete Peer\n \u522a\u9664\u5c0d\u7b49\n \n \n Leader\n Leader\n \n \n # Local\n \u672c\u5730\u6578\u91cf\n \n \n # Remote\n \u9060\u7aef\u6578\u91cf\n \n \n mirror peer\n \u93e1\u50cf\u5c0d\u7b49\n \n \n Key\n \u91d1\u9470\n \n \n RBD\n RBD\n \n \n Deep flatten\n \u6df1\u5c64\u58d3\u5e73\n \n \n Layering\n \u5206\u5c64\n \n \n Exclusive lock\n \u7368\u4f54\u9396\u5b9a\n \n \n Object map (requires exclusive-lock)\n \u7269\u4ef6\u5c0d\u61c9 (\u9700\u8981\u7368\u4f54\u9396\u5b9a)\n \n \n Journaling (requires exclusive-lock)\n \u8a18\u9304 (\u9700\u8981\u7368\u4f54\u9396\u5b9a)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n RBD \u5feb\u7167\u5fa9\u539f\n \n \n Rollback\n \u5fa9\u539f\n \n \n RBD snapshot\n RBD \u5feb\u7167\n \n \n Deleted At\n \u522a\u9664\u4f4d\u7f6e\n \n \n id\n ID\n \n \n type\n \u985e\u578b\n \n \n state\n \u72c0\u614b\n \n \n version\n \u7248\u672c\n \n \n Host\n \u4e3b\u6a5f\n \n \n root\n \u6839\n \n \n Rank\n \u968e\u5c64\n \n \n Daemon\n \u7cbe\u9748\n \n \n Activity\n \u6d3b\u52d5\n \n \n Dentries\n Dentry\n \n \n Inodes\n Inode\n \n \n Usage\n \u4f7f\u7528\u7387\n \n \n Standby daemons\n \u5f85\u547d\u7cbe\u9748\n \n \n The value can be updated at runtime.\n \u8a72\u503c\u53ef\u5728\u57f7\u884c\u6642\u671f\u66f4\u65b0\u3002\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n \u7cbe\u9748/\u7528\u6236\u7aef\u4e0d\u6703\u5f9e\u76e3\u63a7\u7a0b\u5f0f\u7d44\u614b\u8cc7\u6599\u5eab\n \u63d0\u53d6\u6b64\u503c\u3002\u6211\u5011\u4e0d\u5141\u8a31\u900f\u904e\u300cceph config set ...\u300d\n \u8a2d\u5b9a\u6b64\u9078\u9805\u3002\u61c9\u900f\u904e ceph.conf \u6216\u4f7f\u7528\u6307\u4ee4\u884c\n \u9032\u884c\u8a2d\u5b9a\u3002\n \n \n Option takes effect only during daemon startup.\n \u8a72\u9078\u9805\u50c5\u5728\u7cbe\u9748\u555f\u52d5\u671f\u9593\u751f\u6548\u3002\n \n \n Option only affects cluster creation.\n \u8a72\u9078\u9805\u50c5\u5f71\u97ff\u53e2\u96c6\u5efa\u7acb\u3002\n \n \n Option only affects daemon creation.\n \u8a72\u9078\u9805\u50c5\u5f71\u97ff\u7cbe\u9748\u5efa\u7acb\u3002\n \n \n Updated config option \n \n \n \u5df2\u66f4\u65b0\u7d44\u614b\u9078\u9805\n \n \n \n \n Service\n \u670d\u52d9\n \n \n Current value\n \u76ee\u524d\u7684\u503c\n \n \n Editable\n \u53ef\u7de8\u8f2f\n \n \n Updated options for module "\n ".\n \n \u5df2\u66f4\u65b0\u6a21\u7d44\u300c\n \u300d\u7684\u9078\u9805\u3002\n \n \n \n Enable\n \u555f\u7528\n \n \n Disable\n \u505c\u7528\n \n \n Reconnecting, please wait ...\n \u6b63\u5728\u91cd\u65b0\u9023\u63a5\uff0c\u8acb\u7a0d\u5019...\n \n \n Public Address\n \u516c\u7528\u4f4d\u5740\n \n \n Open Sessions\n \u958b\u555f\u7684\u5de5\u4f5c\u968e\u6bb5\n \n \n No In\n \u7981\u6b62\u6a19\u793a\u70ba In\n \n \n OSDs that were previously marked out will not be marked back in when they start\n \u4e4b\u524d\u6a19\u793a\u70ba out \u7684 OSD \u5728\u555f\u52d5\u6642\u5c07\u4e0d\u6703\u91cd\u65b0\u6a19\u793a\u70ba in\n \n \n No Out\n \u7981\u6b62\u6a19\u793a\u70ba Out\n \n \n OSDs will not automatically be marked out after the configured interval\n OSD \u5728\u8a2d\u5b9a\u7684\u9593\u9694\u904e\u5f8c\u5c07\u4e0d\u6703\u81ea\u52d5\u6a19\u793a\u70ba out\n \n \n No Up\n \u7981\u6b62\u6a19\u793a\u70ba Up\n \n \n OSDs are not allowed to start\n \u4e0d\u5141\u8a31 OSD \u555f\u52d5\n \n \n No Down\n \u7981\u6b62\u6a19\u793a\u70ba Down\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n \u5c07\u6703\u5ffd\u7565 OSD \u6545\u969c\u5831\u544a\uff0c\u5982\u6b64\u76e3\u63a7\u7a0b\u5f0f\u4fbf\u4e0d\u6703\u5c07 OSD \u6a19\u793a\u70ba down\n \n \n Pause\n \u66ab\u505c\n \n \n Pauses reads and writes\n \u66ab\u505c\u8b80\u53d6\u548c\u5beb\u5165\n \n \n No Scrub\n \u7981\u6b62\u6574\u7406\n \n \n Scrubbing is disabled\n \u6574\u7406\u5df2\u505c\u7528\n \n \n No Deep Scrub\n \u7981\u6b62\u6df1\u5c64\u6574\u7406\n \n \n Deep Scrubbing is disabled\n \u6df1\u5c64\u6574\u7406\u5df2\u505c\u7528\n \n \n No Backfill\n \u7981\u6b62\u56de\u586b\n \n \n Backfilling of PGs is suspended\n PG \u56de\u586b\u5df2\u66ab\u505c\n \n \n No Recover\n \u7981\u6b62\u5fa9\u539f\n \n \n Recovery of PGs is suspended\n PG \u5fa9\u539f\u5df2\u66ab\u505c\n \n \n Bitwise Sort\n \u6309\u4f4d\u5143\u6392\u5e8f\n \n \n Use bitwise sort\n \u4f7f\u7528\u6309\u4f4d\u5143\u6392\u5e8f\n \n \n Purged Snapdirs\n \u5df2\u6e05\u9664 Snapdir\n \n \n OSDs have converted snapsets\n OSD \u5df2\u8f49\u63db snapset\n \n \n Recovery Deletes\n \u5fa9\u539f\u522a\u9664\n \n \n Deletes performed during recovery instead of peering\n \u5728\u5fa9\u539f\u671f\u9593\uff0c\u800c\u975e\u5728\u5efa\u7acb\u4e92\u806f\u6642\u57f7\u884c\u522a\u9664\n \n \n PG Log Hard Limit\n PG \u8a18\u9304\u786c\u9650\u5236\n \n \n Puts a hard limit on pg log length\n \u70ba pg \u8a18\u9304\u9577\u5ea6\u8a2d\u5b9a\u786c\u9650\u5236\n \n \n Updated OSD Flags\n \u5df2\u66f4\u65b0 OSD \u65d7\u6a19\n \n \n out\n out\n \n \n in\n in\n \n \n down\n down\n \n \n Mark\n \u6a19\u793a\n \n \n OSD lost\n OSD \u907a\u5931\n \n \n marked lost\n \u5df2\u6a19\u793a\u70ba\u907a\u5931\n \n \n Purge\n \u6e05\u9664\n \n \n OSD\n OSD\n \n \n purged\n \u5df2\u6e05\u9664\n \n \n destroy\n \u640d\u6bc0\n \n \n destroyed\n \u5df2\u640d\u6bc0\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n PG\n \n \n Read bytes\n \u8b80\u53d6\u4f4d\u5143\u7d44\u6578\n \n \n Writes bytes\n \u5beb\u5165\u4f4d\u5143\u7d44\u6578\n \n \n Read ops\n \u8b80\u53d6\u64cd\u4f5c\u6578\n \n \n Write ops\n \u5beb\u5165\u64cd\u4f5c\u6578\n \n \n Mark OSD \n \n \n \u5c07 OSD \u6a19\u793a\u70ba \n \n \n \n \n Mark \n \n \n \u6a19\u793a\u70ba \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n \u6700\u5927\u56de\u586b\u6578\n \n \n Recovery Max Active\n \u8655\u65bc\u4f7f\u7528\u4e2d\u72c0\u614b\u7684\u6700\u5927\u5fa9\u539f\u64cd\u4f5c\u6578\n \n \n Recovery Max Single Start\n \u55ae\u6b21\u555f\u52d5\u7684\u6700\u5927\u5fa9\u539f\u64cd\u4f5c\u6578\n \n \n Recovery Sleep\n \u5fa9\u539f\u64cd\u4f5c\u9593\u9694\u7761\u7720\u6642\u9593\n \n \n Custom\n \u81ea\u8a02\n \n \n Updated OSD recovery speed priority "\n "\n \n \u5df2\u66f4\u65b0 OSD \u5fa9\u539f\u901f\u5ea6\u512a\u5148\u7a0b\u5ea6\u300c\n \u300d\n \n \n \n \n was initialized in the following OSD: \n \n \n \u4ee5\u4e0b OSD \u5df2\u555f\u59cb\u5316\n \u64cd\u4f5c\ufe30\n \n \n \n \n Create silence\n Create silence\n \n \n Job\n \u5de5\u4f5c\n \n \n Severity\n \u56b4\u91cd\u6027\n \n \n Started\n \u5df2\u555f\u52d5\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n \u5df2\u66f4\u65b0\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n \u5df2\u4f7f\u7528\n \n \n Avail.\n \u53ef\u7528\n \n \n Clean\n \u4e7e\u6de8\n \n \n Working\n \u5de5\u4f5c\u4e2d\n \n \n Warning\n \u8b66\u544a\n \n \n Unknown\n \u672a\u77e5\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n \u555f\u7528\u4e2d\n \n \n no filesystems\n \u7121\u6a94\u6848\u7cfb\u7d71\n \n \n active\n \u4f7f\u7528\u4e2d\n \n \n standby\n \u5f85\u547d\n \n \n n/a\n \u7121\n \n \n active daemon\n \u4f7f\u7528\u4e2d\u7684\u7cbe\u9748\n \n \n quorum\n quorum\n \n \n The NFS Ganesha service is not configured.\n \u672a\u8a2d\u5b9a NFS Ganesha \u670d\u52d9\u3002\n \n \n Transport\n \u50b3\u8f38\n \n \n CephFS User\n CephFS \u4f7f\u7528\u8005\n \n \n CephFS Filesystem\n CephFS \u6a94\u6848\u7cfb\u7d71\n \n \n (inherited from global config)\n (\u7e7c\u627f\u81ea\u5168\u57df\u7d44\u614b)\n \n \n inherited from global config\n \u7e7c\u627f\u81ea\u5168\u57df\u7d44\u614b\n \n \n -- Select what kind of user id squashing is performed --\n -- \u9078\u53d6\u57f7\u884c\u54ea\u7a2e\u985e\u578b\u7684\u4f7f\u7528\u8005 ID \u533f\u540d\u5b58\u53d6 --\n \n \n There are no daemons available.\n \u6c92\u6709\u53ef\u7528\u7684\u7cbe\u9748\u3002\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n \u5feb\u53d6\u6a21\u5f0f\n \n \n Min Evict Age\n \u9010\u51fa\u524d\u81f3\u5c11\u53ef\u7559\u5b58\u7684\u6642\u9593\n \n \n Min Flush Age\n \u885d\u6d17\u524d\u81f3\u5c11\u53ef\u7559\u5b58\u7684\u6642\u9593\n \n \n Target Max Bytes\n \u76ee\u6a19\u6700\u5927\u4f4d\u5143\u7d44\u6578\n \n \n Target Max Objects\n \u76ee\u6a19\u6700\u5927\u7269\u4ef6\u6578\n \n \n No applications added\n \u672a\u65b0\u589e\u61c9\u7528\u7a0b\u5f0f\n \n \n Applications limit reached\n \u5df2\u9054\u5230\u61c9\u7528\u7a0b\u5f0f\u4e0a\u9650\n \n \n A pool can only have up to four applications definitions.\n \u4e00\u500b\u6c60\u6700\u591a\u53ea\u80fd\u56db\u500b\u61c9\u7528\u7a0b\u5f0f\u5b9a\u7fa9\u3002\n \n \n Allowed characters \'_a-zA-Z0-9\'\n \u5141\u8a31\u7684\u5b57\u5143\u70ba\u300c_a-zA-Z0-9\u300d\n \n \n Maximum length is 128 characters\n \u6700\u5927\u9577\u5ea6\u70ba 128 \u500b\u5b57\u5143\n \n \n Filter or add applications\n \u904e\u6ffe\u6216\u65b0\u589e\u61c9\u7528\u7a0b\u5f0f\n \n \n Add application\n \u65b0\u589e\u61c9\u7528\u7a0b\u5f0f\n \n \n pool\n pool\n \n \n erasure code profile\n \u7cfe\u522a\u78bc\u8a2d\u5b9a\u6a94\n \n \n Replica Size\n \u8907\u672c\u5927\u5c0f\n \n \n Last Change\n \u4e0a\u6b21\u8b8a\u66f4\u6642\u9593\n \n \n Erasure Coded Profile\n \u7cfe\u522a\u78bc\u8a2d\u5b9a\u6a94\n \n \n Crush Ruleset\n CRUSH \u898f\u5247\u96c6\n \n \n Write bytes\n \u5beb\u5165\u4f4d\u5143\u7d44\u6578\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n \u6876\n \n \n Updated Object Gateway bucket "\n "\n \n \u5df2\u66f4\u65b0\u7269\u4ef6\u9598\u9053\u6876\u300c\n \u300d\n \n \n \n Created Object Gateway bucket "\n "\n \n \u5df2\u5efa\u7acb\u7269\u4ef6\u9598\u9053\u6876\u300c\n \u300d\n \n \n \n buckets\n \u6876\n \n \n capability\n capability\n \n \n user\n \u4f7f\u7528\u8005\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n \u5df2\u66f4\u65b0\u7269\u4ef6\u9598\u9053\u4f7f\u7528\u8005\u300c\n \u300d\n \n \n \n Created Object Gateway user "\n "\n \n \u5df2\u5efa\u7acb\u7269\u4ef6\u9598\u9053\u4f7f\u7528\u8005\u300c\n \u300d\n \n \n \n users\n \u4f7f\u7528\u8005\n \n \n Swift Key\n Swift Key\n \n \n Scope\n \u7bc4\u570d\n \n \n Read\n \u8b80\u53d6\n \n \n Create\n \u5efa\u7acb\n \n \n role\n role\n \n \n Created role \'\n \'\n \n \u5df2\u5efa\u7acb\u89d2\u8272\u300c\n \u300d\n \n \n \n Updated role \'\n \'\n \n \u5df2\u66f4\u65b0\u89d2\u8272\u300c\n \u300d\n \n \n \n System Role\n \u7cfb\u7d71\u89d2\u8272\n \n \n Deleted role \'\n \'\n \n \u5df2\u522a\u9664\u89d2\u8272\u300c\n \u300d\n \n \n \n Created user "\n "\n \n \u5df2\u5efa\u7acb\u4f7f\u7528\u8005\u300c\n \u300d\n \n \n \n Update user\n \u66f4\u65b0\u4f7f\u7528\u8005\n \n \n Continue\n \u7e7c\u7e8c\n \n \n You were automatically logged out because your roles have been changed.\n \u60a8\u5df2\u88ab\u81ea\u52d5\u767b\u51fa\uff0c\u56e0\u70ba\u60a8\u7684\u89d2\u8272\u767c\u751f\u4e86\u8b8a\u66f4\u3002\n \n \n Updated user "\n "\n \n \u5df2\u66f4\u65b0\u4f7f\u7528\u8005\u300c\n \u300d\n \n \n \n Deleted user "\n "\n \n \u5df2\u522a\u9664\u4f7f\u7528\u8005\u300c\n \u300d\n \n \n \n Failed to delete user "\n "\n \n \u7121\u6cd5\u522a\u9664\u4f7f\u7528\u8005\u300c\n \u300d\n \n \n \n You are currently logged in as "\n ".\n \n \u60a8\u76ee\u524d\u6b63\u4ee5\u300c\n \u300d\u8eab\u5206\u767b\u5165\u3002\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n \u5404\u7269\u4ef6\u90fd\u88ab\u5206\u5272\u6210\u8cc7\u6599\u5340\u584a\u90e8\u5206\uff0c\u5206\u5225\u5132\u5b58\u65bc\u4e0d\u540c\u7684 OSD\u3002\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n \u904b\u7b97\u5404\u7269\u4ef6\u7684\u7de8\u78bc\u5340\u584a\u5e76\u5c07\u5b83\u5011\u5132\u5b58\u5230\u4e0d\u540c\u7684 OSD\u3002\n \u7de8\u78bc\u5340\u584a\u7684\u6578\u91cf\u7b49\u540c\u65bc\u5728\u4e0d\u907a\u5931\u8cc7\u6599\u7684\u524d\u63d0\u4e0b\uff0c\u53ef\u505c\u6a5f\u7684 OSD \u6578\u91cf\u3002\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Jerasure \u5916\u639b\u7a0b\u5f0f\u662f\u6700\u4e00\u822c\u3001\u6700\u9748\u6d3b\u7684\u5916\u639b\u7a0b\u5f0f\uff0c\n \u4e5f\u662f Ceph \u7cfe\u522a\u78bc\u6c60\u7684\u9810\u8a2d\u5916\u639b\u7a0b\u5f0f\u3002\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n Reed_sol_van \u65b9\u6cd5\u66f4\u9748\u6d3b\ufe30\u5b83\u8db3\u4ee5\u8a2d\u5b9a k\n \u548c m\u3002Cauchy_good \u65b9\u6cd5\u66f4\u5feb\uff0c\u4f46\u60a8\u9700\u8981\u5c0f\u5fc3\u9078\u53d6\u5c01\u5305\u5927\u5c0f\u3002\n \u6240\u6709 reed_sol_r6_op\u3001liberation\u3001blaum_roth\u3001liber8tion \u90fd\n \u7b49\u540c\u65bc RAID6\uff0c\u5b83\u5011\u53ea\u80fd\u8a2d\u5b9a\u70ba m=2\u3002\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n \u5c07\u4ee5\u4f4d\u5143\u7d44\u5927\u5c0f\u7684\u5c01\u5305\u70ba\u55ae\u4f4d\u9032\u884c\u7de8\u78bc\u3002\n \u9078\u53d6\u5408\u9069\u7684\u5c01\u5305\u5927\u5c0f\u5f88\u96e3\u3002\n Jerasure \u6587\u4ef6\u5305\u542b\u6709\u95dc\u6b64\u4e3b\u984c\u7684\u8a73\u7d30\u8cc7\u8a0a\u3002\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n \u4f7f\u7528 jerasure \u5916\u639b\u7a0b\u5f0f\u6642\uff0c\u82e5\u7cfe\u522a\u78bc\u7269\u4ef6\u5132\u5b58\u65bc\n \u591a\u500b OSD \u4e0a\uff0c\u5247\u5fa9\u539f\u4e00\u500b\u907a\u5931\u7684 OSD \u6642\u9700\u8981\u8b80\u53d6\u6240\u6709\u5176\u4ed6 OSD\u3002\n \u4f8b\u5982\uff0c\u82e5 jerasure \u8a2d\u5b9a\u70ba k=8 \u4e14 m=4\uff0c\u5247\u907a\u5931\u4e00\u500b OSD \u5f8c\u9700\u8b80\u53d6\n \u5176\u4ed6\u5341\u4e00\u500b OSD \u624d\u80fd\u4fee\u5fa9\u3002\n\n lrc \u7cfe\u522a\u78bc\u5916\u639b\u7a0b\u5f0f\u6703\u5efa\u7acb\u672c\u5730\u540c\u4f4d\u5340\u584a\uff0c\u56e0\u6b64\u53ea\u9700\u8f03\u5c11\u7684 OSD \u5373\n \u53ef\u5fa9\u539f\u3002\u4f8b\u5982\uff0c\u82e5 lrc \u8a2d\u5b9a\u70ba k=8\u3001m=4 \u4e14 l=4\uff0c\u5b83\u5c07\u70ba\u6bcf\u56db\u500b OSD\n \u5efa\u7acb\u984d\u5916\u7684\u540c\u4f4d\u5340\u584a\u3002\u9019\u6a23\uff0c\u7576\u4e00\u500b OSD \u907a\u5931\u6642\uff0c\u5b83\u53ea\u9700\u56db\u500b OSD\n \u5373\u53ef\u5fa9\u539f\uff0c\u800c\u4e0d\u9700\u8981\u5341\u4e00\u500b\u3002\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n \u5c07\u7de8\u78bc\u5340\u584a\u548c\u8cc7\u6599\u5340\u584a\u5206\u7d44\u70ba\u5927\u5c0f\u70ba locality \u7684\u96c6\u5408\u3002\u4f8b\u5982\uff0c\n k=4 \u4e14 m=2 \u6642\uff0c\u82e5 locality=3\uff0c\u5247\u6703\u5efa\u7acb 2 \u500b\u5927\u5c0f\u70ba 3 \u7684\u7d44\u3002\u9019\u6a23\uff0c\u5404\u7d44\u90fd\u80fd\n \u81ea\u884c\u5fa9\u539f\uff0c\u800c\u7121\u9700\u5f9e\u53e6\u4e00\u7d44\u8b80\u53d6\u5340\u584a\u3002\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n \u7531 l \u5b9a\u7fa9\u7684\u5340\u584a\u96c6\u5c07\u6309\u54ea\u7a2e CRUSH \u6876\u985e\u578b\u5132\u5b58\u3002\n \u4f8b\u5982\uff0c\u82e5\u8a2d\u5b9a\u70ba\u6a5f\u67b6\uff0c\u5247\u5404\u7d44 l \u5340\u584a\u5c07\u6703\u88ab\u653e\u7f6e\u5230\u4e0d\u540c\u7684\n \u6a5f\u67b6\u4e2d\u3002\u8a72\u503c\u7528\u65bc\u5efa\u7acb\u985e\u4f3c step choose rack \u7684 CRUSH\n \u898f\u5247\u6b65\u9a5f\u3002\u82e5\u672a\u8a2d\u5b9a\uff0c\u5247\u4e0d\u6703\u9032\u884c\u6b64\u985e\u5206\u7d44\u3002\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n isa \u5916\u639b\u7a0b\u5f0f\u5c01\u5305\u4e86 ISA \u7a0b\u5f0f\u5eab\u3002\u5b83\u53ea\u80fd\u5728 Intel \u8655\u7406\u5668\u4e0a\u57f7\u884c\u3002\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n ISA \u5916\u639b\u7a0b\u5f0f\u5305\u542b\u5169\u7a2e Reed Solomon \u683c\u5f0f\u3002\n \u82e5\u8a2d\u5b9a\u70ba reed_sol_van\uff0c\u5247\u70ba Vandermonde\u3002\u82e5\u8a2d\u5b9a\u70ba cauchy\uff0c\u5247\u70ba Cauchy\u3002\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n shec \u5916\u639b\u7a0b\u5f0f\u5c01\u5305\u4e86\u591a\u500b SHEC \u7a0b\u5f0f\u5eab\u3002\n \u8207 Reed Solomon \u4ee3\u78bc\u76f8\u6bd4\uff0c\u5b83\u80fd\u66f4\u6709\u6548\u5730\u5fa9\u539f\u8cc7\u6599\u3002\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n \u540c\u4f4d\u5340\u584a\u7684\u6578\u91cf\uff0c\u5b83\u5011\u5728\u5404\u81ea\u7684\u8a08\u7b97\u7bc4\u570d\u5167\u5305\u542b\u4e86\n \u5404\u8cc7\u6599\u5340\u584a\u3002\u8a72\u6578\u503c\u88ab\u7528\u505a\u6301\u4e45\u6027\u4f30\u503c\u3002\u4f8b\u5982\uff0c\u82e5 c=2\uff0c\n \u5247\u5728\u4e0d\u907a\u5931\u8cc7\u6599\u7684\u524d\u63d0\u4e0b\uff0c\u53ef\u6709 2 \u500b OSD \u505c\u6a5f\u3002\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n CRUSH \u898f\u5247\u7684\u7b2c\u4e00\u6b65\u6240\u6307\u5411\u7684 CRUSH \u6876\u540d\u7a31\u3002\n \u4f8b\u5982 step take default\u3002\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n \u78ba\u5b9a\u5169\u500b\u5340\u584a\u4e0d\u6703\u5b58\u5728\u65bc\u540c\u4e00\u6545\u969c\u7db2\u57df\u7684\u6876\u4e2d\u3002\n \u4f8b\u5982\uff0c\u82e5\u6545\u969c\u7db2\u57df\u70ba\u4e3b\u6a5f\uff0c\u5247\u4e0d\u6703\u6709\u5169\u500b\u5340\u584a\u5132\u5b58\u65bc\u540c\u4e00\u4e3b\u6a5f\u4e2d\u3002\n \u8a72\u503c\u7528\u65bc\u5efa\u7acb\u985e\u4f3c step chooseleaf host \u7684 CRUSH \u898f\u5247\u6b65\u9a5f\u3002\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n \u4f7f\u7528 CRUSH \u5730\u5716\u4e2d\u7684 crush \u88dd\u7f6e\u985e\u5225\u540d\u7a31\uff0c\n \u5c07\u653e\u7f6e\u9650\u5236\u65bc\u7279\u5b9a\u985e\u5225\u7684\u88dd\u7f6e (\u4f8b\u5982 ssd \u6216 hdd)\u3002\n \n \n Set the directory name from which the erasure code plugin is loaded.\n \u8a2d\u5b9a\u7cfe\u522a\u78bc\u5916\u639b\u7a0b\u5f0f\u6240\u5728\u76ee\u9304\u3002\n \n \n Allows all operations\n \u5141\u8a31\u6240\u6709\u64cd\u4f5c\n \n \n Allows only operations that do not modify the server\n \u50c5\u5141\u8a31\u4e0d\u4fee\u6539\u4f3a\u670d\u5668\u7684\u64cd\u4f5c\n \n \n Does not allow read or write operations, but allows any other operation\n \u4e0d\u5141\u8a31\u8b80\u53d6\u6216\u5beb\u5165\u64cd\u4f5c\uff0c\u4f46\u662f\u5141\u8a31\u4efb\u4f55\u5176\u4ed6\u64cd\u4f5c\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n \u4e0d\u5141\u8a31\u8b80\u53d6\u3001\u5beb\u5165\u6216\u4efb\u4f55\u53ef\u80fd\u4fee\u6539\u6a94\u6848\u5c6c\u6027\u6216\u76ee\u9304\u5167\u5bb9\u7684\u64cd\u4f5c\n \n \n Allows no access at all\n \u5b8c\u5168\u7981\u6b62\u5b58\u53d6\n \n \n -- Select the priority --\n -- \u9078\u53d6\u512a\u5148\u7a0b\u5ea6 --\n \n \n Low\n \u4f4e\n \n \n High\n \u9ad8\n \n \n Last 5 minutes\n \u904e\u53bb 5 \u5206\u9418\n \n \n Last 15 minutes\n \u904e\u53bb 15 \u5206\u9418\n \n \n Last 30 minutes\n \u904e\u53bb 30 \u5206\u9418\n \n \n Last 1 hour (Default)\n \u904e\u53bb 1 \u5c0f\u6642 (\u9810\u8a2d\u503c)\n \n \n Last 3 hours\n \u904e\u53bb 3 \u5c0f\u6642\n \n \n Last 6 hours\n \u904e\u53bb 6 \u5c0f\u6642\n \n \n Last 12 hours\n \u904e\u53bb 12 \u5c0f\u6642\n \n \n Last 24 hours\n \u904e\u53bb 24 \u5c0f\u6642\n \n \n Yesterday\n \u6628\u5929\n \n \n Today\n \u4eca\u5929\n \n \n Today so far\n \u4eca\u5929\u5230\u76ee\u524d\u70ba\u6b62\n \n \n Day before yesterday\n \u524d\u5929\n \n \n Last 2 days\n \u904e\u53bb 2 \u5929\n \n \n This day last week\n \u4e0a\u9031\u7684\u4eca\u5929\n \n \n Previous week\n \u4e0a\u9031\n \n \n This week\n \u672c\u9031\n \n \n This week so far\n \u672c\u9031\u76ee\u524d\u70ba\u6b62\n \n \n Last 7 days\n \u904e\u53bb 7 \u5929\n \n \n Previous month\n \u4e0a\u500b\u6708\n \n \n This month\n \u672c\u6708\n \n \n This month so far\n \u672c\u6708\u76ee\u524d\u70ba\u6b62\n \n \n Last 30 days\n \u904e\u53bb 30 \u5929\n \n \n Last 90 days\n \u904e\u53bb 90 \u5929\n \n \n Last 6 months\n \u904e\u53bb 6 \u500b\u6708\n \n \n Last 1 year\n \u904e\u53bb 1 \u5e74\n \n \n Previous year\n \u53bb\u5e74\n \n \n This year\n \u4eca\u5e74\n \n \n This year so far\n \u4eca\u5e74\u76ee\u524d\u70ba\u6b62\n \n \n Last 2 years\n \u904e\u53bb 2 \u5e74\n \n \n Last 5 years\n \u904e\u53bb 5 \u5e74\n \n \n Information\n \u8cc7\u8a0a\n \n \n No items selected.\n \u672a\u9078\u53d6\u9805\u76ee\u3002\n \n \n Deselect item to select again\n \u53d6\u6d88\u9078\u53d6\u9805\u76ee\u4ee5\u518d\u6b21\u9078\u53d6\n \n \n Selection limit reached\n \u5df2\u9054\u5230\u9078\u53d6\u4e0a\u9650\n \n \n Filter tags\n \u904e\u6ffe\u6a19\u8a18\n \n \n Add badge\n \u65b0\u589e\u5fbd\u7ae0\n \n \n There are no items available.\n \u6c92\u6709\u53ef\u7528\u7684\u9805\u76ee\u3002\n \n \n Add\n \u65b0\u589e\n \n \n Remove\n Remove\n \n \n Clone\n \u514b\u9686\n \n \n Copy\n \u8907\u88fd\n \n \n Deep Scrub\n \u6df1\u5c64\u6574\u7406\n \n \n Destroy\n \u640d\u6bc0\n \n \n Flatten\n \u58d3\u5e73\n \n \n Mark Down\n \u6a19\u793a\u70ba Down\n \n \n Mark In\n \u6a19\u793a\u70ba In\n \n \n Mark Lost\n \u6a19\u793a\u70ba\u907a\u5931\n \n \n Mark Out\n \u6a19\u793a\u70ba Out\n \n \n Protect\n \u4fdd\u8b77\n \n \n Rename\n \u91cd\u65b0\u547d\u540d\n \n \n Restore\n \u9084\u539f\n \n \n Move to Trash\n \u79fb\u81f3\u5783\u573e\u6876\n \n \n Unprotect\n \u53d6\u6d88\u4fdd\u8b77\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n \u5df2\u522a\u9664\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n \u5df2\u514b\u9686\n \n \n Copied\n \u5df2\u8907\u88fd\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n \u662f\n \n \n No\n \u5426\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n \u670d\u52d9\u54c1\u8cea\n \n \n BPS Limit\n BPS \u4e0a\u9650\n \n \n The desired limit of IO bytes per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2 IO \u4f4d\u5143\u7d44\u6578\u4e0a\u9650\u3002\n \n \n IOPS Limit\n IOPS \u4e0a\u9650\n \n \n The desired limit of IO operations per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2 IO \u64cd\u4f5c\u6b21\u6578\u4e0a\u9650\u3002\n \n \n Read BPS Limit\n \u8b80\u53d6 BPS \u4e0a\u9650\n \n \n The desired limit of read bytes per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u5167\u8b80\u53d6\u7684\u4f4d\u5143\u7d44\u6578\u4e0a\u9650\u3002\n \n \n Read IOPS Limit\n \u8b80\u53d6 IOPS \u4e0a\u9650\n \n \n The desired limit of read operations per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u8b80\u53d6\u64cd\u4f5c\u6b21\u6578\u4e0a\u9650\u3002\n \n \n Write BPS Limit\n \u5beb\u5165 BPS \u4e0a\u9650\n \n \n The desired limit of write bytes per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u5167\u5beb\u5165\u7684\u4f4d\u5143\u7d44\u6578\u4e0a\u9650\u3002\n \n \n Write IOPS Limit\n \u5beb\u5165 IOPS \u4e0a\u9650\n \n \n The desired limit of write operations per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u5beb\u5165\u64cd\u4f5c\u6b21\u6578\u4e0a\u9650\u3002\n \n \n BPS Burst\n BPS \u9ad8\u8f09\n \n \n The desired burst limit of IO bytes.\n \u6307\u5b9a\u7684 IO \u4f4d\u5143\u7d44\u6578\u9ad8\u8f09\u4e0a\u9650\u3002\n \n \n IOPS Burst\n IOPS \u9ad8\u8f09\n \n \n The desired burst limit of IO operations.\n \u6307\u5b9a\u7684 IO \u64cd\u4f5c\u6b21\u6578\u9ad8\u8f09\u4e0a\u9650\u3002\n \n \n Read BPS Burst\n \u8b80\u53d6 BPS \u9ad8\u8f09\n \n \n The desired burst limit of read bytes.\n \u6307\u5b9a\u7684\u8b80\u53d6\u7684\u4f4d\u5143\u7d44\u6578\u9ad8\u8f09\u4e0a\u9650\u3002\n \n \n Read IOPS Burst\n \u8b80\u53d6 IOPS \u9ad8\u8f09\n \n \n The desired burst limit of read operations.\n \u6307\u5b9a\u7684\u8b80\u53d6\u64cd\u4f5c\u6b21\u6578\u9ad8\u8f09\u4e0a\u9650\u3002\n \n \n Write BPS Burst\n \u5beb\u5165 BPS \u9ad8\u8f09\n \n \n The desired burst limit of write bytes.\n \u6307\u5b9a\u7684\u5beb\u5165\u7684\u4f4d\u5143\u7d44\u6578\u9ad8\u8f09\u4e0a\u9650\u3002\n \n \n Write IOPS Burst\n \u5beb\u5165 IOPS \u9ad8\u8f09\n \n \n The desired burst limit of write operations.\n \u6307\u5b9a\u7684\u5beb\u5165\u64cd\u4f5c\u6b21\u6578\u9ad8\u8f09\u4e0a\u9650\u3002\n \n \n Failed to \n \n \n \n \u7121\u6cd5\n \n \n \n \n \n Executing\n \u6b63\u5728\u57f7\u884c\n \n \n execute\n \u57f7\u884c\n \n \n Executed\n \u5df2\u57f7\u884c\n \n \n unknown task\n \u672a\u77e5\u4efb\u52d9\n \n \n Creating\n \u6b63\u5728\u5efa\u7acb\n \n \n create\n \u5efa\u7acb\n \n \n Updating\n \u6b63\u5728\u66f4\u65b0\n \n \n update\n \u66f4\u65b0\n \n \n Deleting\n \u6b63\u5728\u522a\u9664\n \n \n delete\n \u522a\u9664\n \n \n RBD \'\n \'\n \n RBD\u300c\n \u300d\n \n \n \n RBD snapshot \'\n \'\n \n RBD \u5feb\u7167\u300c\n \u300d\n \n \n \n mirror mode for pool \'\n \'\n \n \u6c60\u300c\n \u300d\u7684\u93e1\u50cf\u6a21\u5f0f\n \n \n \n mirror peer for pool \'\n \'\n \n \u6c60\u300c\n \u300d\u7684\u93e1\u50cf\u5c0d\u7b49\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n \u540d\u7a31\u5df2\u88ab \n \u4f7f\u7528\u3002\n \n \n \n Name is already used by \n .\n \n \u540d\u7a31\u5df2\u88ab \n \u4f7f\u7528\u3002\n \n \n \n Name is already used by \n .\n \n \u540d\u7a31\u5df2\u88ab \n \u4f7f\u7528\u3002\n \n \n \n \n contains snapshots.\n \n \n \u5305\u542b\u5feb\u7167\u3002\n \n \n \n Cloning\n \u6b63\u5728\u514b\u9686\n \n \n clone\n \u514b\u9686\n \n \n Snapshot of \n must be protected.\n \n \u5fc5\u9808\u4fdd\u8b77 \n \u7684\u5feb\u7167\u3002\n \n \n \n Copying\n \u6b63\u5728\u8907\u88fd\n \n \n copy\n \u8907\u88fd\n \n \n Flattening\n \u6b63\u5728\u58d3\u5e73\n \n \n flatten\n \u58d3\u5e73\n \n \n Flattened\n \u5df2\u58d3\u5e73\n \n \n Name is already used by \n .\n \n \u540d\u7a31\u5df2\u88ab \n \u4f7f\u7528\u3002\n \n \n \n Cannot unprotect \n because it contains child images.\n \n \u7121\u6cd5\u4fdd\u8b77 \n \uff0c\u56e0\u70ba\u5176\u5305\u542b\u5b50\u5f71\u50cf\u3002\n \n \n \n Cannot delete \n because it\'s protected.\n \n \u7121\u6cd5\u522a\u9664 \n \uff0c\u56e0\u70ba\u5176\u8655\u65bc\u4fdd\u8b77\u72c0\u614b\u3002\n \n \n \n Rolling back\n \u6b63\u5728\u5fa9\u539f\n \n \n rollback\n \u5fa9\u539f\n \n \n Rolled back\n \u5df2\u5fa9\u539f\n \n \n Moving\n \u6b63\u5728\u79fb\u52d5\n \n \n move\n \u79fb\u52d5\n \n \n Moved\n \u5df2\u79fb\u52d5\n \n \n image \'\n \' to trash\n \n \u5f71\u50cf\u300c\n \u300d\u5230\u5783\u573e\u6876\n \n \n \n Could not find image.\n \u627e\u4e0d\u5230\u5f71\u50cf\u3002\n \n \n Restoring\n \u6b63\u5728\u9084\u539f\n \n \n restore\n \u9084\u539f\n \n \n Restored\n \u5df2\u9084\u539f\n \n \n image \'\n \' into \'\n \'\n \n \u5f71\u50cf\u300c\n \u300d(\u5230\u300c\n \u300d)\n \n \n \n Image name \'\n \' is already in use.\n \n \u5f71\u50cf\u540d\u7a31\u300c\n \u300d\u5df2\u5728\u4f7f\u7528\u4e2d\u3002\n \n \n \n image \'\n \'\n \n \u5f71\u50cf\u300c\n \u300d\n \n \n \n Purging\n \u6b63\u5728\u6e05\u9664\n \n \n purge\n \u6e05\u9664\n \n \n Purged\n \u5df2\u6e05\u9664\n \n \n all pools\n \u6240\u6709\u6c60\n \n \n images from \n \n \n \u5f71\u50cf (\u5f9e \n )\n \n \n \n Cannot disable mirroring because it contains a peer.\n \u7121\u6cd5\u505c\u7528\u93e1\u50cf\uff0c\u56e0\u70ba\u5176\u5305\u542b\u5c0d\u7b49\u3002\n \n \n pool \'\n \'\n \n \u6c60\u300c\n \u300d\n \n \n \n erasure code profile \'\n \'\n \n \u7cfe\u522a\u78bc\u8a2d\u5b9a\u6a94\u300c\n \u300d\n \n \n \n target \'\n \'\n \n \u76ee\u6a19\u300c\n \u300d\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},Dzi0:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(t){return t},week:{dow:1,doy:4}})}()},"E+lV":function(t,e,n){!function(t){"use strict";var e={words:{ss:["\u0441\u0435\u043a\u0443\u043d\u0434\u0430","\u0441\u0435\u043a\u0443\u043d\u0434\u0435","\u0441\u0435\u043a\u0443\u043d\u0434\u0438"],m:["\u0458\u0435\u0434\u0430\u043d \u043c\u0438\u043d\u0443\u0442","\u0458\u0435\u0434\u043d\u0435 \u043c\u0438\u043d\u0443\u0442\u0435"],mm:["\u043c\u0438\u043d\u0443\u0442","\u043c\u0438\u043d\u0443\u0442\u0435","\u043c\u0438\u043d\u0443\u0442\u0430"],h:["\u0458\u0435\u0434\u0430\u043d \u0441\u0430\u0442","\u0458\u0435\u0434\u043d\u043e\u0433 \u0441\u0430\u0442\u0430"],hh:["\u0441\u0430\u0442","\u0441\u0430\u0442\u0430","\u0441\u0430\u0442\u0438"],dd:["\u0434\u0430\u043d","\u0434\u0430\u043d\u0430","\u0434\u0430\u043d\u0430"],MM:["\u043c\u0435\u0441\u0435\u0446","\u043c\u0435\u0441\u0435\u0446\u0430","\u043c\u0435\u0441\u0435\u0446\u0438"],yy:["\u0433\u043e\u0434\u0438\u043d\u0430","\u0433\u043e\u0434\u0438\u043d\u0435","\u0433\u043e\u0434\u0438\u043d\u0430"]},correctGrammaticalCase:function(t,e){return 1===t?e[0]:t>=2&&t<=4?e[1]:e[2]},translate:function(t,n,a){var r=e.words[a];return 1===a.length?n?r[0]:r[1]:t+" "+e.correctGrammaticalCase(t,r)}};t.defineLocale("sr-cyrl",{months:"\u0458\u0430\u043d\u0443\u0430\u0440_\u0444\u0435\u0431\u0440\u0443\u0430\u0440_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440_\u043e\u043a\u0442\u043e\u0431\u0430\u0440_\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440_\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440".split("_"),monthsShort:"\u0458\u0430\u043d._\u0444\u0435\u0431._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433._\u0441\u0435\u043f._\u043e\u043a\u0442._\u043d\u043e\u0432._\u0434\u0435\u0446.".split("_"),monthsParseExact:!0,weekdays:"\u043d\u0435\u0434\u0435\u0459\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a_\u0443\u0442\u043e\u0440\u0430\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a_\u043f\u0435\u0442\u0430\u043a_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434._\u043f\u043e\u043d._\u0443\u0442\u043e._\u0441\u0440\u0435._\u0447\u0435\u0442._\u043f\u0435\u0442._\u0441\u0443\u0431.".split("_"),weekdaysMin:"\u043d\u0435_\u043f\u043e_\u0443\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441\u0443".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[\u0434\u0430\u043d\u0430\u0441 \u0443] LT",nextDay:"[\u0441\u0443\u0442\u0440\u0430 \u0443] LT",nextWeek:function(){switch(this.day()){case 0:return"[\u0443] [\u043d\u0435\u0434\u0435\u0459\u0443] [\u0443] LT";case 3:return"[\u0443] [\u0441\u0440\u0435\u0434\u0443] [\u0443] LT";case 6:return"[\u0443] [\u0441\u0443\u0431\u043e\u0442\u0443] [\u0443] LT";case 1:case 2:case 4:case 5:return"[\u0443] dddd [\u0443] LT"}},lastDay:"[\u0458\u0443\u0447\u0435 \u0443] LT",lastWeek:function(){return["[\u043f\u0440\u043e\u0448\u043b\u0435] [\u043d\u0435\u0434\u0435\u0459\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0443\u0442\u043e\u0440\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0440\u0435\u0434\u0435] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u0447\u0435\u0442\u0432\u0440\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u043e\u0433] [\u043f\u0435\u0442\u043a\u0430] [\u0443] LT","[\u043f\u0440\u043e\u0448\u043b\u0435] [\u0441\u0443\u0431\u043e\u0442\u0435] [\u0443] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"\u043f\u0440\u0435 %s",s:"\u043d\u0435\u043a\u043e\u043b\u0438\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:e.translate,m:e.translate,mm:e.translate,h:e.translate,hh:e.translate,d:"\u0434\u0430\u043d",dd:e.translate,M:"\u043c\u0435\u0441\u0435\u0446",MM:e.translate,y:"\u0433\u043e\u0434\u0438\u043d\u0443",yy:e.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n("wd/R"))},E2fk:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){}return t.prototype.transform=function(t){return"[INF]"===t?"info":"[WRN]"===t?"warn":"[ERR]"===t?"err":""},t}()},EEJc:function(t,e,n){"use strict";var a=n("CcnG"),r=n("ajRT");n.d(e,"b",function(){return i}),n.d(e,"c",function(){return s}),n.d(e,"a",function(){return u});var i=a["\u0275crt"]({encapsulation:0,styles:[[".modal-header[_ngcontent-%COMP%]{border-bottom:1px solid #d1d1d1;background-color:#f5f5f5;border-radius:5px 5px 0 0} .modal-footer{border-bottom:1px solid #d1d1d1;background-color:#f5f5f5;border-radius:0 0 5px 5px} .modal-body{max-height:70vh;overflow-y:auto;overflow-x:hidden}"]],data:{}});function s(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,5,"div",[["class","modal-header"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),a["\u0275ncd"](null,0),(t()(),a["\u0275eld"](3,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.close()&&a),a},null,null)),(t()(),a["\u0275eld"](4,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["\xd7"])),a["\u0275ncd"](null,1)],null,null)}function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"cd-modal",[],null,null,null,s,i)),a["\u0275did"](1,49152,null,0,r.a,[],null,null)],null,null)}var u=a["\u0275ccf"]("cd-modal",r.a,o,{modalRef:"modalRef"},{hide:"hide"},[".modal-title",".modal-content"])},EOgW:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("th",{months:"\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21_\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c_\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21_\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19_\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21_\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19_\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21_\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21_\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19_\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21_\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19_\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21".split("_"),monthsShort:"\u0e21.\u0e04._\u0e01.\u0e1e._\u0e21\u0e35.\u0e04._\u0e40\u0e21.\u0e22._\u0e1e.\u0e04._\u0e21\u0e34.\u0e22._\u0e01.\u0e04._\u0e2a.\u0e04._\u0e01.\u0e22._\u0e15.\u0e04._\u0e1e.\u0e22._\u0e18.\u0e04.".split("_"),monthsParseExact:!0,weekdays:"\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c_\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c_\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23_\u0e1e\u0e38\u0e18_\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35_\u0e28\u0e38\u0e01\u0e23\u0e4c_\u0e40\u0e2a\u0e32\u0e23\u0e4c".split("_"),weekdaysShort:"\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c_\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c_\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23_\u0e1e\u0e38\u0e18_\u0e1e\u0e24\u0e2b\u0e31\u0e2a_\u0e28\u0e38\u0e01\u0e23\u0e4c_\u0e40\u0e2a\u0e32\u0e23\u0e4c".split("_"),weekdaysMin:"\u0e2d\u0e32._\u0e08._\u0e2d._\u0e1e._\u0e1e\u0e24._\u0e28._\u0e2a.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY \u0e40\u0e27\u0e25\u0e32 H:mm",LLLL:"\u0e27\u0e31\u0e19dddd\u0e17\u0e35\u0e48 D MMMM YYYY \u0e40\u0e27\u0e25\u0e32 H:mm"},meridiemParse:/\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07|\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07/,isPM:function(t){return"\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"===t},meridiem:function(t,e,n){return t<12?"\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07":"\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"},calendar:{sameDay:"[\u0e27\u0e31\u0e19\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",nextDay:"[\u0e1e\u0e23\u0e38\u0e48\u0e07\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",nextWeek:"dddd[\u0e2b\u0e19\u0e49\u0e32 \u0e40\u0e27\u0e25\u0e32] LT",lastDay:"[\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e27\u0e32\u0e19\u0e19\u0e35\u0e49 \u0e40\u0e27\u0e25\u0e32] LT",lastWeek:"[\u0e27\u0e31\u0e19]dddd[\u0e17\u0e35\u0e48\u0e41\u0e25\u0e49\u0e27 \u0e40\u0e27\u0e25\u0e32] LT",sameElse:"L"},relativeTime:{future:"\u0e2d\u0e35\u0e01 %s",past:"%s\u0e17\u0e35\u0e48\u0e41\u0e25\u0e49\u0e27",s:"\u0e44\u0e21\u0e48\u0e01\u0e35\u0e48\u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",ss:"%d \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35",m:"1 \u0e19\u0e32\u0e17\u0e35",mm:"%d \u0e19\u0e32\u0e17\u0e35",h:"1 \u0e0a\u0e31\u0e48\u0e27\u0e42\u0e21\u0e07",hh:"%d \u0e0a\u0e31\u0e48\u0e27\u0e42\u0e21\u0e07",d:"1 \u0e27\u0e31\u0e19",dd:"%d \u0e27\u0e31\u0e19",M:"1 \u0e40\u0e14\u0e37\u0e2d\u0e19",MM:"%d \u0e40\u0e14\u0e37\u0e2d\u0e19",y:"1 \u0e1b\u0e35",yy:"%d \u0e1b\u0e35"}})}()},ES0t:function(t,e,n){"use strict";n.d(e,"a",function(){return l});var a=n("CcnG"),r=n("OZfm"),i=n("Ip0R"),s=a["\u0275crt"]({encapsulation:0,styles:[".bs3.popover-top[_nghost-%COMP%] {\n margin-bottom: 10px;\n }\n .bs3.popover.top[_nghost-%COMP%] > .arrow[_ngcontent-%COMP%] {\n margin-left: -2px;\n }\n .bs3.popover.top[_nghost-%COMP%] {\n margin-bottom: 10px;\n }\n .popover.bottom[_nghost-%COMP%] > .arrow[_ngcontent-%COMP%] {\n margin-left: -4px;\n }\n .bs3.bs-popover-left[_nghost-%COMP%] {\n margin-right: .5rem;\n }\n .bs3.bs-popover-right[_nghost-%COMP%] .arrow[_ngcontent-%COMP%], .bs3.bs-popover-left[_nghost-%COMP%] .arrow[_ngcontent-%COMP%]{\n margin: .3rem 0;\n }"],data:{}});function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"h3",[["class","popover-title popover-header"]],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.component.title)})}function u(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,0,"div",[["class","popover-arrow arrow"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,o)),a["\u0275did"](2,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](3,0,null,null,1,"div",[["class","popover-content popover-body"]],null,null,null,null,null)),a["\u0275ncd"](null,0)],function(t,e){t(e,2,0,e.component.title)},null)}function c(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"popover-container",[["role","tooltip"],["style","display:block;"]],[[8,"className",0],[2,"show",null],[2,"bs3",null]],null,null,u,s)),a["\u0275did"](1,49152,null,0,r.b,[r.a],null,null)],null,function(t,e){t(e,0,0,"popover in popover-"+a["\u0275nov"](e,1).placement+" bs-popover-"+a["\u0275nov"](e,1).placement+" "+a["\u0275nov"](e,1).placement+" "+a["\u0275nov"](e,1).containerClass,!a["\u0275nov"](e,1).isBs3,a["\u0275nov"](e,1).isBs3)})}var l=a["\u0275ccf"]("popover-container",r.b,c,{placement:"placement",title:"title"},{},["*"])},EgGo:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("Ip0R"),r=n("sne2"),i=function(){function t(t){this.base=t}return t.concatURLSegments=function(t){return t.reduce(a.Location.joinWithSlash)},t.buildURL=function(e){for(var n=[],a=1;a-1&&(c=l),s.parent=a[c],s.row.level=s.parent.row.level+1,s.parent.children.push(s)}var d=[];return a[0].flatten(function(){d=d.concat([this.row])},!0),d}return t};var r=function(){function t(t){void 0===t&&(t=null),t||(t={level:-1,treeStatus:"expanded"}),this.row=t,this.parent=null,this.children=[]}return t.prototype.flatten=function(t,e){if("expanded"===this.row.treeStatus)for(var n=0,a=this.children.length;n0&&this.table.fetchData.subscribe(function(){t.fetchData.emit()}),this.useData()},t.prototype.ngOnChanges=function(){this.useData()},t.prototype.useData=function(){var t=this;if(this.data){var e=this.makePairs(this.data);this.hideKeys&&(e=e.filter(function(e){return!t.hideKeys.includes(e.key)})),this.tableData=e}},t.prototype.makePairs=function(t){var e=this,n=[];if(t){if(r.isArray(t))n=this.makePairsFromArray(t);else{if(!r.isObject(t))throw new Error("Wrong data format");n=this.makePairsFromObject(t)}return n=n.map(function(t){return t.value=e.convertValue(t.value),t}).filter(function(t){return null!==t.value}),r.sortBy(this.renderObjects?this.insertFlattenObjects(n):n,"key")}},t.prototype.makePairsFromArray=function(t){var e=this,n=[],a=t[0];if(r.isArray(a)){if(2!==a.length)throw new Error("Array contains too many elements ("+a.length+"). Needs to be of type [string, any][]");n=t.map(function(t){return{key:t[0],value:t[1]}})}else r.isObject(a)&&(n=r.has(a,"key")&&r.has(a,"value")?t.slice():t.reduce(function(t,n){return t.concat(e.makePairsFromObject(n))},n));return n},t.prototype.makePairsFromObject=function(t){return Object.keys(t).map(function(e){return{key:e,value:t[e]}})},t.prototype.insertFlattenObjects=function(t){var e=this;return r.flattenDeep(t.map(function(t){var n=t.value,a=r.isObject(n);return!a||r.isEmpty(n)?(a&&(t.value=""),t):e.splitItemIntoItems(t)}))},t.prototype.splitItemIntoItems=function(t){var e=this;return this.makePairs(t.value).map(function(n){return e.appendParentKey&&(n.key=t.key+" "+n.key),n})},t.prototype.convertValue=function(t){if(r.isArray(t)){if(r.isEmpty(t)&&this.hideEmpty)return null;t=t.map(function(t){return r.isObject(t)?JSON.stringify(t):t}).join(", ")}else if(r.isObject(t)){if(this.hideEmpty&&r.isEmpty(t)||!this.renderObjects)return null}else if(r.isString(t)){if(""===t&&this.hideEmpty)return null;this.isDate(t)&&(t=this.datePipe.transform(t)||t)}return t},t.prototype.isDate=function(t){var e="\\d{2}[ -:.TZ]";return t.match(new RegExp("^\\d{4}[ -:.TZ]"+e+e+e+e+e+"\\d*Z?$"))},t}())},FYBg:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("CcnG"),r=(n("JZ5S"),n("QG5k")),i=n("TCh0");e.NodeMenuComponent=function(){function t(t,e){this.renderer=t,this.nodeMenuService=e,this.menuItemSelected=new a.EventEmitter,this.availableMenuItems=[{name:"New tag",action:r.NodeMenuItemAction.NewTag,cssClass:"new-tag"},{name:"New folder",action:r.NodeMenuItemAction.NewFolder,cssClass:"new-folder"},{name:"Rename",action:r.NodeMenuItemAction.Rename,cssClass:"rename"},{name:"Remove",action:r.NodeMenuItemAction.Remove,cssClass:"remove"}],this.disposersForGlobalListeners=[]}return t.prototype.ngOnInit=function(){this.availableMenuItems=this.menuItems||this.availableMenuItems,this.disposersForGlobalListeners.push(this.renderer.listen("document","keyup",this.closeMenu.bind(this))),this.disposersForGlobalListeners.push(this.renderer.listen("document","mousedown",this.closeMenu.bind(this)))},t.prototype.ngOnDestroy=function(){this.disposersForGlobalListeners.forEach(function(t){return t()})},t.prototype.onMenuItemSelected=function(t,e){i.isLeftButtonClicked(t)&&(this.menuItemSelected.emit({nodeMenuItemAction:e.action,nodeMenuItemSelected:e.name}),this.nodeMenuService.fireMenuEvent(t.target,r.NodeMenuAction.Close))},t.prototype.closeMenu=function(t){var e=t instanceof MouseEvent,n=this.menuContainer.nativeElement!==t.target&&this.menuContainer.nativeElement.contains(t.target);(e&&!n||i.isEscapePressed(t))&&this.nodeMenuService.fireMenuEvent(t.target,r.NodeMenuAction.Close)},t.decorators=[{type:a.Component,args:[{selector:"node-menu",template:'\n

\n
    \n
  • \n
    \n {{menuItem.name}}\n
  • \n
\n
\n '}]}],t.propDecorators={menuItemSelected:[{type:a.Output}],menuItems:[{type:a.Input}],menuContainer:[{type:a.ViewChild,args:["menuContainer"]}]},t}()},Fgil:function(t,e,n){"use strict";n.d(e,"a",function(){return a}),n("aXbf");var a=function(){function t(t){this.formatter=t}return t.prototype.transform=function(t){return this.formatter.format_number(t,1024,["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"])},t}()},Fjl2:function(t,e,n){var a=n("mrSG").__decorate;Object.defineProperty(e,"__esModule",{value:!0});var r=n("CcnG");e.DatatableGroupHeaderTemplateDirective=function(){return a([r.Directive({selector:"[ngx-datatable-group-header-template]"})],function(t){this.template=t})}()},Fxb1:function(t,e,n){"use strict";var a=n("+tJ4"),r=n("DKTb"),i=n("En8+"),s=n("xTla"),o=n("2ePl"),u=n("/WYv"),c=n("McSo");n.d(e,"a",function(){return l});var l=function(t){if(t&&"function"==typeof t[s.a])return l=t,function(t){var e=l[s.a]();if("function"!=typeof e.subscribe)throw new TypeError("Provided object does not correctly implement Symbol.observable");return e.subscribe(t)};if(Object(o.a)(t))return Object(a.a)(t);if(Object(u.a)(t))return n=t,function(t){return n.then(function(e){t.closed||(t.next(e),t.complete())},function(e){return t.error(e)}).then(null,r.a),t};if(t&&"function"==typeof t[i.a])return e=t,function(t){for(var n=e[i.a]();;){var a=n.next();if(a.done){t.complete();break}if(t.next(a.value),t.closed)break}return"function"==typeof n.return&&t.add(function(){n.return&&n.return()}),t};var e,n,l,d=Object(c.a)(t)?"an invalid object":"'"+t+"'";throw new TypeError("You provided "+d+" where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.")}},G0Q6:function(t,e,n){"use strict";var a=n("CDJp"),r=n("vvH+"),i=n("RDha");a._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),t.exports=function(t){function e(t,e){return i.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:r.Line,dataElementType:r.Point,update:function(t){var n,a,r,s=this,o=s.getMeta(),u=o.dataset,c=o.data||[],l=s.chart.options,d=l.elements.line,f=s.getScaleForId(o.yAxisID),p=s.getDataset(),h=e(p,l);for(h&&(r=u.custom||{},void 0!==p.tension&&void 0===p.lineTension&&(p.lineTension=p.tension),u._scale=f,u._datasetIndex=s.index,u._children=c,u._model={spanGaps:p.spanGaps?p.spanGaps:l.spanGaps,tension:r.tension?r.tension:i.valueOrDefault(p.lineTension,d.tension),backgroundColor:r.backgroundColor?r.backgroundColor:p.backgroundColor||d.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:p.borderWidth||d.borderWidth,borderColor:r.borderColor?r.borderColor:p.borderColor||d.borderColor,borderCapStyle:r.borderCapStyle?r.borderCapStyle:p.borderCapStyle||d.borderCapStyle,borderDash:r.borderDash?r.borderDash:p.borderDash||d.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:p.borderDashOffset||d.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:p.borderJoinStyle||d.borderJoinStyle,fill:r.fill?r.fill:void 0!==p.fill?p.fill:d.fill,steppedLine:r.steppedLine?r.steppedLine:i.valueOrDefault(p.steppedLine,d.stepped),cubicInterpolationMode:r.cubicInterpolationMode?r.cubicInterpolationMode:i.valueOrDefault(p.cubicInterpolationMode,d.cubicInterpolationMode)},u.pivot()),n=0,a=c.length;n=0;)e+=this.treeArray[t],t=(t&t+1)-1;return e},t.prototype.queryBetween=function(t,e){return this.query(e)-this.query(t-1)},t.prototype.calcRowIndex=function(t){if(!this.treeArray.length)return 0;for(var e=-1,n=this.treeArray.length,a=Math.pow(2,n.toString(2).length-1);0!==a;a>>=1){var r=e+a;r=this.treeArray[r]&&(t-=this.treeArray[r],e=r)}return e+1},t}()},GgAd:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){this.decimals=0,this.isBinary=!0}return t.prototype.ngOnChanges=function(){this.usedPercentage=this.total>0?this.used/this.total*100:0,this.freePercentage=100-this.usedPercentage},t}()},Gi3i:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("mrSG"),r=n("FFOo"),i=n("T1DM");function s(t,e){return void 0===e&&(e=i.a),function(n){return n.lift(new o(t,e))}}var o=function(){function t(t,e){this.dueTime=t,this.scheduler=e}return t.prototype.call=function(t,e){return e.subscribe(new u(t,this.dueTime,this.scheduler))},t}(),u=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.dueTime=n,r.scheduler=a,r.debouncedSubscription=null,r.lastValue=null,r.hasValue=!1,r}return a.__extends(e,t),e.prototype._next=function(t){this.clearDebounce(),this.lastValue=t,this.hasValue=!0,this.add(this.debouncedSubscription=this.scheduler.schedule(c,this.dueTime,this))},e.prototype._complete=function(){this.debouncedNext(),this.destination.complete()},e.prototype.debouncedNext=function(){if(this.clearDebounce(),this.hasValue){var t=this.lastValue;this.lastValue=null,this.hasValue=!1,this.destination.next(t)}},e.prototype.clearDebounce=function(){var t=this.debouncedSubscription;null!==t&&(this.remove(t),t.unsubscribe(),this.debouncedSubscription=null)},e}(r.a);function c(t){t.debouncedNext()}},H8ED:function(t,e,n){!function(t){"use strict";function e(t,e,n){var a,r;return"m"===n?e?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443":"h"===n?e?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443":t+" "+(a=+t,r={ss:e?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:e?"\u0445\u0432\u0456\u043b\u0456\u043d\u0430_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d":"\u0445\u0432\u0456\u043b\u0456\u043d\u0443_\u0445\u0432\u0456\u043b\u0456\u043d\u044b_\u0445\u0432\u0456\u043b\u0456\u043d",hh:e?"\u0433\u0430\u0434\u0437\u0456\u043d\u0430_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d":"\u0433\u0430\u0434\u0437\u0456\u043d\u0443_\u0433\u0430\u0434\u0437\u0456\u043d\u044b_\u0433\u0430\u0434\u0437\u0456\u043d",dd:"\u0434\u0437\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u0437\u0451\u043d",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u044b_\u043c\u0435\u0441\u044f\u0446\u0430\u045e",yy:"\u0433\u043e\u0434_\u0433\u0430\u0434\u044b_\u0433\u0430\u0434\u043e\u045e"}[n].split("_"),a%10==1&&a%100!=11?r[0]:a%10>=2&&a%10<=4&&(a%100<10||a%100>=20)?r[1]:r[2])}n("wd/R").defineLocale("be",{months:{format:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044f_\u043b\u044e\u0442\u0430\u0433\u0430_\u0441\u0430\u043a\u0430\u0432\u0456\u043a\u0430_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a\u0430_\u0442\u0440\u0430\u045e\u043d\u044f_\u0447\u044d\u0440\u0432\u0435\u043d\u044f_\u043b\u0456\u043f\u0435\u043d\u044f_\u0436\u043d\u0456\u045e\u043d\u044f_\u0432\u0435\u0440\u0430\u0441\u043d\u044f_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a\u0430_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434\u0430_\u0441\u043d\u0435\u0436\u043d\u044f".split("_"),standalone:"\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044c_\u043b\u044e\u0442\u044b_\u0441\u0430\u043a\u0430\u0432\u0456\u043a_\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u044d\u0440\u0432\u0435\u043d\u044c_\u043b\u0456\u043f\u0435\u043d\u044c_\u0436\u043d\u0456\u0432\u0435\u043d\u044c_\u0432\u0435\u0440\u0430\u0441\u0435\u043d\u044c_\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a_\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434_\u0441\u043d\u0435\u0436\u0430\u043d\u044c".split("_")},monthsShort:"\u0441\u0442\u0443\u0434_\u043b\u044e\u0442_\u0441\u0430\u043a_\u043a\u0440\u0430\u0441_\u0442\u0440\u0430\u0432_\u0447\u044d\u0440\u0432_\u043b\u0456\u043f_\u0436\u043d\u0456\u0432_\u0432\u0435\u0440_\u043a\u0430\u0441\u0442_\u043b\u0456\u0441\u0442_\u0441\u043d\u0435\u0436".split("_"),weekdays:{format:"\u043d\u044f\u0434\u0437\u0435\u043b\u044e_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0443_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0443_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),standalone:"\u043d\u044f\u0434\u0437\u0435\u043b\u044f_\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a_\u0430\u045e\u0442\u043e\u0440\u0430\u043a_\u0441\u0435\u0440\u0430\u0434\u0430_\u0447\u0430\u0446\u0432\u0435\u0440_\u043f\u044f\u0442\u043d\u0456\u0446\u0430_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),isFormat:/\[ ?[\u0423\u0443\u045e] ?(?:\u043c\u0456\u043d\u0443\u043b\u0443\u044e|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0443\u044e)? ?\] ?dddd/},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0430\u0442_\u0441\u0440_\u0447\u0446_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., HH:mm",LLLL:"dddd, D MMMM YYYY \u0433., HH:mm"},calendar:{sameDay:"[\u0421\u0451\u043d\u043d\u044f \u045e] LT",nextDay:"[\u0417\u0430\u045e\u0442\u0440\u0430 \u045e] LT",lastDay:"[\u0423\u0447\u043e\u0440\u0430 \u045e] LT",nextWeek:function(){return"[\u0423] dddd [\u045e] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u0443\u044e] dddd [\u045e] LT";case 1:case 2:case 4:return"[\u0423 \u043c\u0456\u043d\u0443\u043b\u044b] dddd [\u045e] LT"}},sameElse:"L"},relativeTime:{future:"\u043f\u0440\u0430\u0437 %s",past:"%s \u0442\u0430\u043c\u0443",s:"\u043d\u0435\u043a\u0430\u043b\u044c\u043a\u0456 \u0441\u0435\u043a\u0443\u043d\u0434",m:e,mm:e,h:e,hh:e,d:"\u0434\u0437\u0435\u043d\u044c",dd:e,M:"\u043c\u0435\u0441\u044f\u0446",MM:e,y:"\u0433\u043e\u0434",yy:e},meridiemParse:/\u043d\u043e\u0447\u044b|\u0440\u0430\u043d\u0456\u0446\u044b|\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430/,isPM:function(t){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0430\u0440\u0430)$/.test(t)},meridiem:function(t,e,n){return t<4?"\u043d\u043e\u0447\u044b":t<12?"\u0440\u0430\u043d\u0456\u0446\u044b":t<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0430\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0456|\u044b|\u0433\u0430)/,ordinal:function(t,e){switch(e){case"M":case"d":case"DDD":case"w":case"W":return t%10!=2&&t%10!=3||t%100==12||t%100==13?t+"-\u044b":t+"-\u0456";case"D":return t+"-\u0433\u0430";default:return t}},week:{dow:1,doy:7}})}()},"HHO+":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("CcnG"),r=(n("58b6"),n("58b6")),i=n("xZld"),s=n("lJMN"),o=(n("JZ5S"),n("QG5k")),u=n("1PfE"),c=(n("Tff5"),n("TCh0")),l=n("kQXf");e.TreeInternalComponent=function(){function t(t,e,n){this.nodeMenuService=t,this.treeService=e,this.nodeElementRef=n,this.isSelected=!1,this.isRightMenuVisible=!1,this.isLeftMenuVisible=!1,this.isReadOnly=!1,this.subscriptions=[]}return t.prototype.ngAfterViewInit=function(){this.tree.checked&&!this.tree.firstCheckedFired&&(this.tree.firstCheckedFired=!0,this.treeService.fireNodeChecked(this.tree))},t.prototype.ngOnInit=function(){var t=this,e=l.get(this.tree,"node.id","");e&&(this.controller=new s.TreeController(this),this.treeService.setController(e,this.controller)),this.settings=this.settings||new r.Ng2TreeSettings,this.isReadOnly=!l.get(this.settings,"enableCheckboxes",!0),this.tree.isRoot()&&!1===this.settings.rootIsVisible&&this.tree.disableCollapseOnInit(),this.subscriptions.push(this.nodeMenuService.hideMenuStream(this.nodeElementRef).subscribe(function(){t.isRightMenuVisible=!1,t.isLeftMenuVisible=!1})),this.subscriptions.push(this.treeService.unselectStream(this.tree).subscribe(function(){return t.isSelected=!1})),this.subscriptions.push(this.treeService.draggedStream(this.tree,this.nodeElementRef).subscribe(function(e){t.tree.hasSibling(e.captured.tree)?t.swapWithSibling(e.captured.tree,t.tree):t.tree.isBranch()?t.moveNodeToThisTreeAndRemoveFromPreviousOne(e,t.tree):t.moveNodeToParentTreeAndRemoveFromPreviousOne(e,t.tree)})),this.subscriptions.push(this.treeService.nodeChecked$.merge(this.treeService.nodeUnchecked$).filter(function(e){return t.eventContainsId(e)&&t.tree.hasChild(e.node)}).subscribe(function(e){return t.updateCheckboxState()}))},t.prototype.ngOnChanges=function(t){this.controller=new s.TreeController(this)},t.prototype.ngOnDestroy=function(){l.get(this.tree,"node.id","")&&this.treeService.deleteController(this.tree.node.id),this.subscriptions.forEach(function(t){return t&&t.unsubscribe()})},t.prototype.swapWithSibling=function(t,e){e.swapWithSibling(t),this.treeService.fireNodeMoved(t,t.parent)},t.prototype.moveNodeToThisTreeAndRemoveFromPreviousOne=function(t,e){this.treeService.fireNodeRemoved(t.captured.tree);var n=e.addChild(t.captured.tree);this.treeService.fireNodeMoved(n,t.captured.tree.parent)},t.prototype.moveNodeToParentTreeAndRemoveFromPreviousOne=function(t,e){this.treeService.fireNodeRemoved(t.captured.tree);var n=e.addSibling(t.captured.tree,e.positionInParent);this.treeService.fireNodeMoved(n,t.captured.tree.parent)},t.prototype.onNodeSelected=function(t){this.tree.selectionAllowed&&c.isLeftButtonClicked(t)&&(this.isSelected=!0,this.treeService.fireNodeSelected(this.tree))},t.prototype.onNodeUnselected=function(t){this.tree.selectionAllowed&&c.isLeftButtonClicked(t)&&(this.isSelected=!1,this.treeService.fireNodeUnselected(this.tree))},t.prototype.showRightMenu=function(t){this.tree.hasRightMenu()&&(c.isRightButtonClicked(t)&&(this.isRightMenuVisible=!this.isRightMenuVisible,this.nodeMenuService.hideMenuForAllNodesExcept(this.nodeElementRef)),t.preventDefault())},t.prototype.showLeftMenu=function(t){this.tree.hasLeftMenu()&&c.isLeftButtonClicked(t)&&(this.isLeftMenuVisible=!this.isLeftMenuVisible,this.nodeMenuService.hideMenuForAllNodesExcept(this.nodeElementRef),this.isLeftMenuVisible&&t.preventDefault())},t.prototype.onMenuItemSelected=function(t){switch(t.nodeMenuItemAction){case o.NodeMenuItemAction.NewTag:case o.NodeMenuItemAction.NewFolder:this.onNewSelected(t);break;case o.NodeMenuItemAction.Rename:this.onRenameSelected();break;case o.NodeMenuItemAction.Remove:this.onRemoveSelected();break;case o.NodeMenuItemAction.Custom:this.onCustomSelected(),this.treeService.fireMenuItemSelected(this.tree,t.nodeMenuItemSelected);break;default:throw new Error("Chosen menu item doesn't exist")}},t.prototype.onNewSelected=function(t){this.tree.createNode(t.nodeMenuItemAction===o.NodeMenuItemAction.NewFolder),this.isRightMenuVisible=!1,this.isLeftMenuVisible=!1},t.prototype.onRenameSelected=function(){this.tree.markAsBeingRenamed(),this.isRightMenuVisible=!1,this.isLeftMenuVisible=!1},t.prototype.onRemoveSelected=function(){this.treeService.deleteController(l.get(this.tree,"node.id","")),this.treeService.fireNodeRemoved(this.tree)},t.prototype.onCustomSelected=function(){this.isRightMenuVisible=!1,this.isLeftMenuVisible=!1},t.prototype.onSwitchFoldingType=function(){this.tree.switchFoldingType(),this.treeService.fireNodeSwitchFoldingType(this.tree)},t.prototype.applyNewValue=function(t){if((t.action===u.NodeEditableEventAction.Cancel||this.tree.isNew())&&i.Tree.isValueEmpty(t.value))return this.treeService.fireNodeRemoved(this.tree);if(this.tree.isNew()&&(this.tree.value=t.value,this.treeService.fireNodeCreated(this.tree)),this.tree.isBeingRenamed()){var e=this.tree.value;this.tree.value=t.value,this.treeService.fireNodeRenamed(e,this.tree)}this.tree.markAsModified()},t.prototype.shouldShowInputForTreeValue=function(){return this.tree.isNew()||this.tree.isBeingRenamed()},t.prototype.isRootHidden=function(){return this.tree.isRoot()&&!this.settings.rootIsVisible},t.prototype.hasCustomMenu=function(){return this.tree.hasCustomMenu()},t.prototype.switchNodeCheckStatus=function(){this.tree.checked?this.onNodeUnchecked():this.onNodeChecked()},t.prototype.onNodeChecked=function(){this.checkboxElementRef&&(this.checkboxElementRef.nativeElement.indeterminate=!1,this.treeService.fireNodeChecked(this.tree),this.executeOnChildController(function(t){return t.check()}),this.tree.checked=!0)},t.prototype.onNodeUnchecked=function(){this.checkboxElementRef&&(this.checkboxElementRef.nativeElement.indeterminate=!1,this.treeService.fireNodeUnchecked(this.tree),this.executeOnChildController(function(t){return t.uncheck()}),this.tree.checked=!1)},t.prototype.executeOnChildController=function(t){var e=this;this.tree.hasLoadedChildern()&&this.tree.children.forEach(function(n){var a=e.treeService.getController(n.id);l.isNil(a)||t(a)})},t.prototype.updateCheckboxState=function(){var t=this;setTimeout(function(){var e=t.tree.checkedChildrenAmount();0===e?(t.checkboxElementRef.nativeElement.indeterminate=!1,t.tree.checked=!1,t.treeService.fireNodeUnchecked(t.tree)):e===t.tree.loadedChildrenAmount()?(t.checkboxElementRef.nativeElement.indeterminate=!1,t.tree.checked=!0,t.treeService.fireNodeChecked(t.tree)):(t.tree.checked=!1,t.checkboxElementRef.nativeElement.indeterminate=!0,t.treeService.fireNodeIndetermined(t.tree))})},t.prototype.eventContainsId=function(t){return!!t.node.id||(console.warn('"Node with checkbox" feature requires a unique id assigned to every node, please consider to add it.'),!1)},t.decorators=[{type:a.Component,args:[{selector:"tree-internal",template:'\n
    \n
  • \n
    \n\n
    \n\n
    \n \n
    \n\n
    \n
    \n \n \n \n
    \n\n \n\n
    \n
    \n \n \n
    \n\n \n \n\n \n \n\n
    \n \n
    \n \n \n \n
  • \n
\n '}]}],t.propDecorators={tree:[{type:a.Input}],settings:[{type:a.Input}],template:[{type:a.Input}],checkboxElementRef:[{type:a.ViewChild,args:["checkbox"]}]},t}()},HJBe:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("mrSG"),r=n("FFOo");function i(t){return void 0===t&&(t=null),function(e){return e.lift(new s(t))}}var s=function(){function t(t){this.defaultValue=t}return t.prototype.call=function(t,e){return e.subscribe(new o(t,this.defaultValue))},t}(),o=function(t){function e(e,n){var a=t.call(this,e)||this;return a.defaultValue=n,a.isEmpty=!0,a}return a.__extends(e,t),e.prototype._next=function(t){this.isEmpty=!1,this.destination.next(t)},e.prototype._complete=function(){this.isEmpty&&this.destination.next(this.defaultValue),this.destination.complete()},e}(r.a)},HP3h:function(t,e,n){!function(t){"use strict";var e={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},n=function(t){return 0===t?0:1===t?1:2===t?2:t%100>=3&&t%100<=10?3:t%100>=11?4:5},a={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},r=function(t){return function(e,r,i,s){var o=n(e),u=a[t][n(e)];return 2===o&&(u=u[r?0:1]),u.replace(/%d/i,e)}},i=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];t.defineLocale("ar-ly",{months:i,monthsShort:i,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(t){return"\u0645"===t},meridiem:function(t,e,n){return t<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:r("s"),ss:r("s"),m:r("m"),mm:r("m"),h:r("h"),hh:r("h"),d:r("d"),dd:r("d"),M:r("M"),MM:r("M"),y:r("y"),yy:r("y")},preparse:function(t){return t.replace(/\u060c/g,",")},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}})}(n("wd/R"))},HV4d:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.id=function(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}},Hg4g:function(t,e){t.exports={acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}}},I2ZF:function(t,e){for(var n=[],a=0;a<256;++a)n[a]=(a+256).toString(16).substr(1);t.exports=function(t,e){var a=e||0;return[n[t[a++]],n[t[a++]],n[t[a++]],n[t[a++]],"-",n[t[a++]],n[t[a++]],"-",n[t[a++]],n[t[a++]],"-",n[t[a++]],n[t[a++]],"-",n[t[a++]],n[t[a++]],n[t[a++]],n[t[a++]],n[t[a++]],n[t[a++]]].join("")}},IBtZ:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("ka",{months:{standalone:"\u10d8\u10d0\u10dc\u10d5\u10d0\u10e0\u10d8_\u10d7\u10d4\u10d1\u10d4\u10e0\u10d5\u10d0\u10da\u10d8_\u10db\u10d0\u10e0\u10e2\u10d8_\u10d0\u10de\u10e0\u10d8\u10da\u10d8_\u10db\u10d0\u10d8\u10e1\u10d8_\u10d8\u10d5\u10dc\u10d8\u10e1\u10d8_\u10d8\u10d5\u10da\u10d8\u10e1\u10d8_\u10d0\u10d2\u10d5\u10d8\u10e1\u10e2\u10dd_\u10e1\u10d4\u10e5\u10e2\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10dd\u10e5\u10e2\u10dd\u10db\u10d1\u10d4\u10e0\u10d8_\u10dc\u10dd\u10d4\u10db\u10d1\u10d4\u10e0\u10d8_\u10d3\u10d4\u10d9\u10d4\u10db\u10d1\u10d4\u10e0\u10d8".split("_"),format:"\u10d8\u10d0\u10dc\u10d5\u10d0\u10e0\u10e1_\u10d7\u10d4\u10d1\u10d4\u10e0\u10d5\u10d0\u10da\u10e1_\u10db\u10d0\u10e0\u10e2\u10e1_\u10d0\u10de\u10e0\u10d8\u10da\u10d8\u10e1_\u10db\u10d0\u10d8\u10e1\u10e1_\u10d8\u10d5\u10dc\u10d8\u10e1\u10e1_\u10d8\u10d5\u10da\u10d8\u10e1\u10e1_\u10d0\u10d2\u10d5\u10d8\u10e1\u10e2\u10e1_\u10e1\u10d4\u10e5\u10e2\u10d4\u10db\u10d1\u10d4\u10e0\u10e1_\u10dd\u10e5\u10e2\u10dd\u10db\u10d1\u10d4\u10e0\u10e1_\u10dc\u10dd\u10d4\u10db\u10d1\u10d4\u10e0\u10e1_\u10d3\u10d4\u10d9\u10d4\u10db\u10d1\u10d4\u10e0\u10e1".split("_")},monthsShort:"\u10d8\u10d0\u10dc_\u10d7\u10d4\u10d1_\u10db\u10d0\u10e0_\u10d0\u10de\u10e0_\u10db\u10d0\u10d8_\u10d8\u10d5\u10dc_\u10d8\u10d5\u10da_\u10d0\u10d2\u10d5_\u10e1\u10d4\u10e5_\u10dd\u10e5\u10e2_\u10dc\u10dd\u10d4_\u10d3\u10d4\u10d9".split("_"),weekdays:{standalone:"\u10d9\u10d5\u10d8\u10e0\u10d0_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10d8_\u10e8\u10d0\u10d1\u10d0\u10d7\u10d8".split("_"),format:"\u10d9\u10d5\u10d8\u10e0\u10d0\u10e1_\u10dd\u10e0\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10e1\u10d0\u10db\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10dd\u10d7\u10ee\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10ee\u10e3\u10d7\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1_\u10de\u10d0\u10e0\u10d0\u10e1\u10d9\u10d4\u10d5\u10e1_\u10e8\u10d0\u10d1\u10d0\u10d7\u10e1".split("_"),isFormat:/(\u10ec\u10d8\u10dc\u10d0|\u10e8\u10d4\u10db\u10d3\u10d4\u10d2)/},weekdaysShort:"\u10d9\u10d5\u10d8_\u10dd\u10e0\u10e8_\u10e1\u10d0\u10db_\u10dd\u10d7\u10ee_\u10ee\u10e3\u10d7_\u10de\u10d0\u10e0_\u10e8\u10d0\u10d1".split("_"),weekdaysMin:"\u10d9\u10d5_\u10dd\u10e0_\u10e1\u10d0_\u10dd\u10d7_\u10ee\u10e3_\u10de\u10d0_\u10e8\u10d0".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[\u10d3\u10e6\u10d4\u10e1] LT[-\u10d6\u10d4]",nextDay:"[\u10ee\u10d5\u10d0\u10da] LT[-\u10d6\u10d4]",lastDay:"[\u10d2\u10e3\u10e8\u10d8\u10dc] LT[-\u10d6\u10d4]",nextWeek:"[\u10e8\u10d4\u10db\u10d3\u10d4\u10d2] dddd LT[-\u10d6\u10d4]",lastWeek:"[\u10ec\u10d8\u10dc\u10d0] dddd LT-\u10d6\u10d4",sameElse:"L"},relativeTime:{future:function(t){return/(\u10ec\u10d0\u10db\u10d8|\u10ec\u10e3\u10d7\u10d8|\u10e1\u10d0\u10d0\u10d7\u10d8|\u10ec\u10d4\u10da\u10d8)/.test(t)?t.replace(/\u10d8$/,"\u10e8\u10d8"):t+"\u10e8\u10d8"},past:function(t){return/(\u10ec\u10d0\u10db\u10d8|\u10ec\u10e3\u10d7\u10d8|\u10e1\u10d0\u10d0\u10d7\u10d8|\u10d3\u10e6\u10d4|\u10d7\u10d5\u10d4)/.test(t)?t.replace(/(\u10d8|\u10d4)$/,"\u10d8\u10e1 \u10ec\u10d8\u10dc"):/\u10ec\u10d4\u10da\u10d8/.test(t)?t.replace(/\u10ec\u10d4\u10da\u10d8$/,"\u10ec\u10da\u10d8\u10e1 \u10ec\u10d8\u10dc"):void 0},s:"\u10e0\u10d0\u10db\u10d3\u10d4\u10dc\u10d8\u10db\u10d4 \u10ec\u10d0\u10db\u10d8",ss:"%d \u10ec\u10d0\u10db\u10d8",m:"\u10ec\u10e3\u10d7\u10d8",mm:"%d \u10ec\u10e3\u10d7\u10d8",h:"\u10e1\u10d0\u10d0\u10d7\u10d8",hh:"%d \u10e1\u10d0\u10d0\u10d7\u10d8",d:"\u10d3\u10e6\u10d4",dd:"%d \u10d3\u10e6\u10d4",M:"\u10d7\u10d5\u10d4",MM:"%d \u10d7\u10d5\u10d4",y:"\u10ec\u10d4\u10da\u10d8",yy:"%d \u10ec\u10d4\u10da\u10d8"},dayOfMonthOrdinalParse:/0|1-\u10da\u10d8|\u10db\u10d4-\d{1,2}|\d{1,2}-\u10d4/,ordinal:function(t){return 0===t?t:1===t?t+"-\u10da\u10d8":t<20||t<=100&&t%20==0||t%100==0?"\u10db\u10d4-"+t:t+"-\u10d4"},week:{dow:1,doy:7}})}()},ILDN:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.single="single",t.double="double"}(e.ClickType||(e.ClickType={}))},IPm6:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("5tze"),o=(n("qwkt"),n("SfHT"));e.DataTableBodyComponent=function(){function t(t){var e=this;this.cd=t,this.selected=[],this.scroll=new i.EventEmitter,this.page=new i.EventEmitter,this.activate=new i.EventEmitter,this.select=new i.EventEmitter,this.detailToggle=new i.EventEmitter,this.rowContextmenu=new i.EventEmitter(!1),this.treeAction=new i.EventEmitter,this.rowHeightsCache=new s.RowHeightCache,this.temp=[],this.offsetY=0,this.indexes={},this.rowIndexes=new Map,this.rowExpansions=new Map,this.getDetailRowHeight=function(t,n){if(!e.rowDetail)return 0;var a=e.rowDetail.rowHeight;return"function"==typeof a?a(t,n):a},this.rowTrackingFn=(function(t,e){var n=this.getRowIndex(e);return this.trackByProp?n+"-"+this.trackByProp:n}).bind(this)}return Object.defineProperty(t.prototype,"pageSize",{get:function(){return this._pageSize},set:function(t){this._pageSize=t,this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rows",{get:function(){return this._rows},set:function(t){this._rows=t,this.rowExpansions.clear(),this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columns",{get:function(){return this._columns},set:function(t){this._columns=t;var e=s.columnsByPin(t);this.columnGroupWidths=s.columnGroupWidths(e,t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"offset",{get:function(){return this._offset},set:function(t){this._offset=t,this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rowCount",{get:function(){return this._rowCount},set:function(t){this._rowCount=t,this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bodyWidth",{get:function(){return this.scrollbarH?this.innerWidth+"px":"100%"},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bodyHeight",{get:function(){return this._bodyHeight},set:function(t){this._bodyHeight=this.scrollbarV?t+"px":"auto",this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"selectEnabled",{get:function(){return!!this.selectionType},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scrollHeight",{get:function(){if(this.scrollbarV&&this.virtualization&&this.rowCount)return this.rowHeightsCache.query(this.rowCount-1)},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){var t=this;this.rowDetail&&(this.listener=this.rowDetail.toggle.subscribe(function(e){var n=e.type,a=e.value;"row"===n&&t.toggleRowExpansion(a),"all"===n&&t.toggleAllRows(a),t.updateIndexes(),t.updateRows(),t.cd.markForCheck()})),this.groupHeader&&(this.listener=this.groupHeader.toggle.subscribe(function(e){var n=e.type,a=e.value;"group"===n&&t.toggleRowExpansion(a),"all"===n&&t.toggleAllRows(a),t.updateIndexes(),t.updateRows(),t.cd.markForCheck()}))},t.prototype.ngOnDestroy=function(){this.rowDetail&&this.listener.unsubscribe(),this.groupHeader&&this.listener.unsubscribe()},t.prototype.updateOffsetY=function(t){this.scroller&&(this.scrollbarV&&this.virtualization&&t?t=this.rowHeightsCache.query(this.pageSize*t-1):this.scrollbarV&&!this.virtualization&&(t=0),this.scroller.setOffset(t||0))},t.prototype.onBodyScroll=function(t){var e=t.scrollYPos,n=t.scrollXPos;this.offsetY===e&&this.offsetX===n||this.scroll.emit({offsetY:e,offsetX:n}),this.offsetY=e,this.offsetX=n,this.updateIndexes(),this.updatePage(t.direction),this.updateRows()},t.prototype.updatePage=function(t){var e=this.indexes.first/this.pageSize;"up"===t?e=Math.ceil(e):"down"===t&&(e=Math.floor(e)),void 0===t||isNaN(e)||this.page.emit({offset:e})},t.prototype.updateRows=function(){var t=this.indexes,e=t.last,n=t.first,a=0,r=[];if(this.rowIndexes.clear(),this.groupedRows)for(;n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',changeDetection:i.ChangeDetectionStrategy.OnPush,host:{class:"datatable-body"}})],t)}()},IUTb:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("6blF"),r=n("+tJ4"),i=n("JF+6");function s(t,e){return e?Object(i.a)(t,e):new a.a(Object(r.a)(t))}},IZUe:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("LvDl"),r=function(){function t(t){this.elementRef=t}return t.prototype.ngAfterViewInit=function(){var t=this.elementRef.nativeElement;a.isFunction(t.focus)&&t.focus()},t}()},Ip0R:function(t,e,n){"use strict";n.r(e),n.d(e,"\u0275angular_packages_common_common_e",function(){return Xt}),n.d(e,"\u0275angular_packages_common_common_d",function(){return B}),n.d(e,"\u0275angular_packages_common_common_a",function(){return Nt}),n.d(e,"\u0275angular_packages_common_common_b",function(){return Et}),n.d(e,"\u0275angular_packages_common_common_g",function(){return xe}),n.d(e,"\u0275angular_packages_common_common_f",function(){return Ve}),n.d(e,"\u0275registerLocaleData",function(){return b}),n.d(e,"registerLocaleData",function(){return b}),n.d(e,"formatDate",function(){return et}),n.d(e,"formatCurrency",function(){return St}),n.d(e,"formatNumber",function(){return It}),n.d(e,"formatPercent",function(){return Ot}),n.d(e,"NgLocaleLocalization",function(){return Dt}),n.d(e,"NgLocalization",function(){return Rt}),n.d(e,"Plural",function(){return v}),n.d(e,"NumberFormatStyle",function(){return y}),n.d(e,"FormStyle",function(){return _}),n.d(e,"TranslationWidth",function(){return x}),n.d(e,"FormatWidth",function(){return T}),n.d(e,"NumberSymbol",function(){return w}),n.d(e,"WeekDay",function(){return S}),n.d(e,"getNumberOfCurrencyDigits",function(){return K}),n.d(e,"getCurrencySymbol",function(){return U}),n.d(e,"getLocaleDayPeriods",function(){return I}),n.d(e,"getLocaleDayNames",function(){return C}),n.d(e,"getLocaleMonthNames",function(){return k}),n.d(e,"getLocaleId",function(){return O}),n.d(e,"getLocaleEraNames",function(){return N}),n.d(e,"getLocaleWeekEndRange",function(){return A}),n.d(e,"getLocaleFirstDayOfWeek",function(){return R}),n.d(e,"getLocaleDateFormat",function(){return D}),n.d(e,"getLocaleDateTimeFormat",function(){return L}),n.d(e,"getLocaleExtraDayPeriodRules",function(){return G}),n.d(e,"getLocaleExtraDayPeriods",function(){return Y}),n.d(e,"getLocalePluralCase",function(){return F}),n.d(e,"getLocaleTimeFormat",function(){return E}),n.d(e,"getLocaleNumberSymbol",function(){return P}),n.d(e,"getLocaleNumberFormat",function(){return M}),n.d(e,"getLocaleCurrencyName",function(){return j}),n.d(e,"getLocaleCurrencySymbol",function(){return q}),n.d(e,"\u0275parseCookieValue",function(){return Lt}),n.d(e,"CommonModule",function(){return He}),n.d(e,"DeprecatedI18NPipesModule",function(){return Be}),n.d(e,"NgClass",function(){return Pt}),n.d(e,"NgForOf",function(){return jt}),n.d(e,"NgForOfContext",function(){return qt}),n.d(e,"NgIf",function(){return zt}),n.d(e,"NgIfContext",function(){return Gt}),n.d(e,"NgPlural",function(){return Wt}),n.d(e,"NgPluralCase",function(){return Kt}),n.d(e,"NgStyle",function(){return $t}),n.d(e,"NgSwitch",function(){return Ht}),n.d(e,"NgSwitchCase",function(){return Bt}),n.d(e,"NgSwitchDefault",function(){return Ut}),n.d(e,"NgTemplateOutlet",function(){return Zt}),n.d(e,"NgComponentOutlet",function(){return Mt}),n.d(e,"DOCUMENT",function(){return Ue}),n.d(e,"AsyncPipe",function(){return Oe}),n.d(e,"DatePipe",function(){return Re}),n.d(e,"I18nPluralPipe",function(){return De}),n.d(e,"I18nSelectPipe",function(){return Ee}),n.d(e,"JsonPipe",function(){return Le}),n.d(e,"LowerCasePipe",function(){return Ie}),n.d(e,"CurrencyPipe",function(){return Fe}),n.d(e,"DecimalPipe",function(){return qe}),n.d(e,"PercentPipe",function(){return je}),n.d(e,"SlicePipe",function(){return Ye}),n.d(e,"UpperCasePipe",function(){return Ne}),n.d(e,"TitleCasePipe",function(){return ke}),n.d(e,"KeyValuePipe",function(){return Pe}),n.d(e,"DeprecatedDatePipe",function(){return ge}),n.d(e,"DeprecatedCurrencyPipe",function(){return _e}),n.d(e,"DeprecatedDecimalPipe",function(){return ye}),n.d(e,"DeprecatedPercentPipe",function(){return ve}),n.d(e,"\u0275PLATFORM_BROWSER_ID",function(){return We}),n.d(e,"\u0275PLATFORM_SERVER_ID",function(){return Ke}),n.d(e,"\u0275PLATFORM_WORKER_APP_ID",function(){return $e}),n.d(e,"\u0275PLATFORM_WORKER_UI_ID",function(){return Ze}),n.d(e,"isPlatformBrowser",function(){return Xe}),n.d(e,"isPlatformServer",function(){return Je}),n.d(e,"isPlatformWorkerApp",function(){return Qe}),n.d(e,"isPlatformWorkerUi",function(){return tn}),n.d(e,"VERSION",function(){return en}),n.d(e,"ViewportScroller",function(){return nn}),n.d(e,"\u0275NullViewportScroller",function(){return rn}),n.d(e,"PlatformLocation",function(){return i}),n.d(e,"LOCATION_INITIALIZED",function(){return s}),n.d(e,"LocationStrategy",function(){return o}),n.d(e,"APP_BASE_HREF",function(){return u}),n.d(e,"HashLocationStrategy",function(){return d}),n.d(e,"PathLocationStrategy",function(){return f}),n.d(e,"Location",function(){return c});var a=n("CcnG"),r=n("mrSG"),i=function(){return function(){}}(),s=new a.InjectionToken("Location Initialized"),o=function(){return function(){}}(),u=new a.InjectionToken("appBaseHref"),c=function(){function t(t){var n=this;this._subject=new a.EventEmitter,this._platformStrategy=t;var r=this._platformStrategy.getBaseHref();this._baseHref=e.stripTrailingSlash(l(r)),this._platformStrategy.onPopState(function(t){n._subject.emit({url:n.path(!0),pop:!0,state:t.state,type:t.type})})}var e;return e=t,t.prototype.path=function(t){return void 0===t&&(t=!1),this.normalize(this._platformStrategy.path(t))},t.prototype.isCurrentPathEqualTo=function(t,n){return void 0===n&&(n=""),this.path()==this.normalize(t+e.normalizeQueryParams(n))},t.prototype.normalize=function(t){return e.stripTrailingSlash(function(t,e){return t&&e.startsWith(t)?e.substring(t.length):e}(this._baseHref,l(t)))},t.prototype.prepareExternalUrl=function(t){return t&&"/"!==t[0]&&(t="/"+t),this._platformStrategy.prepareExternalUrl(t)},t.prototype.go=function(t,e,n){void 0===e&&(e=""),void 0===n&&(n=null),this._platformStrategy.pushState(n,"",t,e)},t.prototype.replaceState=function(t,e,n){void 0===e&&(e=""),void 0===n&&(n=null),this._platformStrategy.replaceState(n,"",t,e)},t.prototype.forward=function(){this._platformStrategy.forward()},t.prototype.back=function(){this._platformStrategy.back()},t.prototype.subscribe=function(t,e,n){return this._subject.subscribe({next:t,error:e,complete:n})},t.normalizeQueryParams=function(t){return t&&"?"!==t[0]?"?"+t:t},t.joinWithSlash=function(t,e){if(0==t.length)return e;if(0==e.length)return t;var n=0;return t.endsWith("/")&&n++,e.startsWith("/")&&n++,2==n?t+e.substring(1):1==n?t+e:t+"/"+e},t.stripTrailingSlash=function(t){var e=t.match(/#|\?|$/),n=e&&e.index||t.length;return t.slice(0,n-("/"===t[n-1]?1:0))+t.slice(n)},t}();function l(t){return t.replace(/\/index.html$/,"")}var d=function(t){function e(e,n){var a=t.call(this)||this;return a._platformLocation=e,a._baseHref="",null!=n&&(a._baseHref=n),a}return Object(r.__extends)(e,t),e.prototype.onPopState=function(t){this._platformLocation.onPopState(t),this._platformLocation.onHashChange(t)},e.prototype.getBaseHref=function(){return this._baseHref},e.prototype.path=function(t){void 0===t&&(t=!1);var e=this._platformLocation.hash;return null==e&&(e="#"),e.length>0?e.substring(1):e},e.prototype.prepareExternalUrl=function(t){var e=c.joinWithSlash(this._baseHref,t);return e.length>0?"#"+e:e},e.prototype.pushState=function(t,e,n,a){var r=this.prepareExternalUrl(n+c.normalizeQueryParams(a));0==r.length&&(r=this._platformLocation.pathname),this._platformLocation.pushState(t,e,r)},e.prototype.replaceState=function(t,e,n,a){var r=this.prepareExternalUrl(n+c.normalizeQueryParams(a));0==r.length&&(r=this._platformLocation.pathname),this._platformLocation.replaceState(t,e,r)},e.prototype.forward=function(){this._platformLocation.forward()},e.prototype.back=function(){this._platformLocation.back()},e}(o),f=function(t){function e(e,n){var a=t.call(this)||this;if(a._platformLocation=e,null==n&&(n=a._platformLocation.getBaseHrefFromDOM()),null==n)throw new Error("No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.");return a._baseHref=n,a}return Object(r.__extends)(e,t),e.prototype.onPopState=function(t){this._platformLocation.onPopState(t),this._platformLocation.onHashChange(t)},e.prototype.getBaseHref=function(){return this._baseHref},e.prototype.prepareExternalUrl=function(t){return c.joinWithSlash(this._baseHref,t)},e.prototype.path=function(t){void 0===t&&(t=!1);var e=this._platformLocation.pathname+c.normalizeQueryParams(this._platformLocation.search),n=this._platformLocation.hash;return n&&t?""+e+n:e},e.prototype.pushState=function(t,e,n,a){var r=this.prepareExternalUrl(n+c.normalizeQueryParams(a));this._platformLocation.pushState(t,e,r)},e.prototype.replaceState=function(t,e,n,a){var r=this.prepareExternalUrl(n+c.normalizeQueryParams(a));this._platformLocation.replaceState(t,e,r)},e.prototype.forward=function(){this._platformLocation.forward()},e.prototype.back=function(){this._platformLocation.back()},e}(o),p=void 0,h=["en",[["a","p"],["AM","PM"],p],[["AM","PM"],p,p],[["S","M","T","W","T","F","S"],["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["Su","Mo","Tu","We","Th","Fr","Sa"]],p,[["J","F","M","A","M","J","J","A","S","O","N","D"],["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],["January","February","March","April","May","June","July","August","September","October","November","December"]],p,[["B","A"],["BC","AD"],["Before Christ","Anno Domini"]],0,[6,0],["M/d/yy","MMM d, y","MMMM d, y","EEEE, MMMM d, y"],["h:mm a","h:mm:ss a","h:mm:ss a z","h:mm:ss a zzzz"],["{1}, {0}",p,"{1} 'at' {0}",p],[".",",",";","%","+","-","E","\xd7","\u2030","\u221e","NaN",":"],["#,##0.###","#,##0%","\xa4#,##0.00","#E0"],"$","US Dollar",{},function(t){var e=Math.floor(Math.abs(t)),n=t.toString().replace(/^[^.]*\.?/,"").length;return 1===e&&0===n?1:5}],g={};function b(t,e,n){"string"!=typeof e&&(n=e,e=t[0]),e=e.toLowerCase().replace(/_/g,"-"),g[e]=t,n&&(g[e][19]=n)}var m={ADP:[void 0,void 0,0],AFN:[void 0,void 0,0],ALL:[void 0,void 0,0],AMD:[void 0,void 0,0],AOA:[void 0,"Kz"],ARS:[void 0,"$"],AUD:["A$","$"],BAM:[void 0,"KM"],BBD:[void 0,"$"],BDT:[void 0,"\u09f3"],BHD:[void 0,void 0,3],BIF:[void 0,void 0,0],BMD:[void 0,"$"],BND:[void 0,"$"],BOB:[void 0,"Bs"],BRL:["R$"],BSD:[void 0,"$"],BWP:[void 0,"P"],BYN:[void 0,"\u0440.",2],BYR:[void 0,void 0,0],BZD:[void 0,"$"],CAD:["CA$","$",2],CHF:[void 0,void 0,2],CLF:[void 0,void 0,4],CLP:[void 0,"$",0],CNY:["CN\xa5","\xa5"],COP:[void 0,"$",0],CRC:[void 0,"\u20a1",2],CUC:[void 0,"$"],CUP:[void 0,"$"],CZK:[void 0,"K\u010d",2],DJF:[void 0,void 0,0],DKK:[void 0,"kr",2],DOP:[void 0,"$"],EGP:[void 0,"E\xa3"],ESP:[void 0,"\u20a7",0],EUR:["\u20ac"],FJD:[void 0,"$"],FKP:[void 0,"\xa3"],GBP:["\xa3"],GEL:[void 0,"\u20be"],GIP:[void 0,"\xa3"],GNF:[void 0,"FG",0],GTQ:[void 0,"Q"],GYD:[void 0,"$",0],HKD:["HK$","$"],HNL:[void 0,"L"],HRK:[void 0,"kn"],HUF:[void 0,"Ft",2],IDR:[void 0,"Rp",0],ILS:["\u20aa"],INR:["\u20b9"],IQD:[void 0,void 0,0],IRR:[void 0,void 0,0],ISK:[void 0,"kr",0],ITL:[void 0,void 0,0],JMD:[void 0,"$"],JOD:[void 0,void 0,3],JPY:["\xa5",void 0,0],KHR:[void 0,"\u17db"],KMF:[void 0,"CF",0],KPW:[void 0,"\u20a9",0],KRW:["\u20a9",void 0,0],KWD:[void 0,void 0,3],KYD:[void 0,"$"],KZT:[void 0,"\u20b8"],LAK:[void 0,"\u20ad",0],LBP:[void 0,"L\xa3",0],LKR:[void 0,"Rs"],LRD:[void 0,"$"],LTL:[void 0,"Lt"],LUF:[void 0,void 0,0],LVL:[void 0,"Ls"],LYD:[void 0,void 0,3],MGA:[void 0,"Ar",0],MGF:[void 0,void 0,0],MMK:[void 0,"K",0],MNT:[void 0,"\u20ae",0],MRO:[void 0,void 0,0],MUR:[void 0,"Rs",0],MXN:["MX$","$"],MYR:[void 0,"RM"],NAD:[void 0,"$"],NGN:[void 0,"\u20a6"],NIO:[void 0,"C$"],NOK:[void 0,"kr",2],NPR:[void 0,"Rs"],NZD:["NZ$","$"],OMR:[void 0,void 0,3],PHP:[void 0,"\u20b1"],PKR:[void 0,"Rs",0],PLN:[void 0,"z\u0142"],PYG:[void 0,"\u20b2",0],RON:[void 0,"lei"],RSD:[void 0,void 0,0],RUB:[void 0,"\u20bd"],RUR:[void 0,"\u0440."],RWF:[void 0,"RF",0],SBD:[void 0,"$"],SEK:[void 0,"kr",2],SGD:[void 0,"$"],SHP:[void 0,"\xa3"],SLL:[void 0,void 0,0],SOS:[void 0,void 0,0],SRD:[void 0,"$"],SSP:[void 0,"\xa3"],STD:[void 0,void 0,0],STN:[void 0,"Db"],SYP:[void 0,"\xa3",0],THB:[void 0,"\u0e3f"],TMM:[void 0,void 0,0],TND:[void 0,void 0,3],TOP:[void 0,"T$"],TRL:[void 0,void 0,0],TRY:[void 0,"\u20ba"],TTD:[void 0,"$"],TWD:["NT$","$",2],TZS:[void 0,void 0,0],UAH:[void 0,"\u20b4"],UGX:[void 0,void 0,0],USD:["$"],UYI:[void 0,void 0,0],UYU:[void 0,"$"],UZS:[void 0,void 0,0],VEF:[void 0,"Bs"],VND:["\u20ab",void 0,0],VUV:[void 0,void 0,0],XAF:["FCFA",void 0,0],XCD:["EC$","$"],XOF:["CFA",void 0,0],XPF:["CFPF",void 0,0],YER:[void 0,void 0,0],ZAR:[void 0,"R"],ZMK:[void 0,void 0,0],ZMW:[void 0,"ZK"],ZWD:[void 0,void 0,0]},y=function(t){return t[t.Decimal=0]="Decimal",t[t.Percent=1]="Percent",t[t.Currency=2]="Currency",t[t.Scientific=3]="Scientific",t}({}),v=function(t){return t[t.Zero=0]="Zero",t[t.One=1]="One",t[t.Two=2]="Two",t[t.Few=3]="Few",t[t.Many=4]="Many",t[t.Other=5]="Other",t}({}),_=function(t){return t[t.Format=0]="Format",t[t.Standalone=1]="Standalone",t}({}),x=function(t){return t[t.Narrow=0]="Narrow",t[t.Abbreviated=1]="Abbreviated",t[t.Wide=2]="Wide",t[t.Short=3]="Short",t}({}),T=function(t){return t[t.Short=0]="Short",t[t.Medium=1]="Medium",t[t.Long=2]="Long",t[t.Full=3]="Full",t}({}),w=function(t){return t[t.Decimal=0]="Decimal",t[t.Group=1]="Group",t[t.List=2]="List",t[t.PercentSign=3]="PercentSign",t[t.PlusSign=4]="PlusSign",t[t.MinusSign=5]="MinusSign",t[t.Exponential=6]="Exponential",t[t.SuperscriptingExponent=7]="SuperscriptingExponent",t[t.PerMille=8]="PerMille",t[t[1/0]=9]="Infinity",t[t.NaN=10]="NaN",t[t.TimeSeparator=11]="TimeSeparator",t[t.CurrencyDecimal=12]="CurrencyDecimal",t[t.CurrencyGroup=13]="CurrencyGroup",t}({}),S=function(t){return t[t.Sunday=0]="Sunday",t[t.Monday=1]="Monday",t[t.Tuesday=2]="Tuesday",t[t.Wednesday=3]="Wednesday",t[t.Thursday=4]="Thursday",t[t.Friday=5]="Friday",t[t.Saturday=6]="Saturday",t}({});function O(t){return B(t)[0]}function I(t,e,n){var a=B(t),r=V([a[1],a[2]],e);return V(r,n)}function C(t,e,n){var a=B(t),r=V([a[3],a[4]],e);return V(r,n)}function k(t,e,n){var a=B(t),r=V([a[5],a[6]],e);return V(r,n)}function N(t,e){return V(B(t)[7],e)}function R(t){return B(t)[8]}function A(t){return B(t)[9]}function D(t,e){return V(B(t)[10],e)}function E(t,e){return V(B(t)[11],e)}function L(t,e){return V(B(t)[12],e)}function P(t,e){var n=B(t),a=n[13][e];if(void 0===a){if(e===w.CurrencyDecimal)return n[13][w.Decimal];if(e===w.CurrencyGroup)return n[13][w.Group]}return a}function M(t,e){return B(t)[14][e]}function q(t){return B(t)[15]||null}function j(t){return B(t)[16]||null}function F(t){return B(t)[18]}function z(t){if(!t[19])throw new Error('Missing extra locale data for the locale "'+t[0]+'". Use "registerLocaleData" to load new data. See the "I18n guide" on angular.io to know more.')}function G(t){var e=B(t);return z(e),(e[19][2]||[]).map(function(t){return"string"==typeof t?H(t):[H(t[0]),H(t[1])]})}function Y(t,e,n){var a=B(t);z(a);var r=V([a[19][0],a[19][1]],e)||[];return V(r,n)||[]}function V(t,e){for(var n=e;n>-1;n--)if(void 0!==t[n])return t[n];throw new Error("Locale data API: locale data undefined")}function H(t){var e=Object(r.__read)(t.split(":"),2);return{hours:+e[0],minutes:+e[1]}}function B(t){var e=t.toLowerCase().replace(/_/g,"-"),n=g[e];if(n)return n;var a=e.split("-")[0];if(n=g[a])return n;if("en"===a)return h;throw new Error('Missing locale data for the locale "'+t+'".')}function U(t,e,n){void 0===n&&(n="en");var a=function(t){return B(t)[17]}(n)[t]||m[t]||[],r=a[1];return"narrow"===e&&"string"==typeof r?r:a[0]||t}var W=2;function K(t){var e,n=m[t];return n&&(e=n[2]),"number"==typeof e?e:W}var $=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/,Z={},X=/((?:[^GyMLwWdEabBhHmsSzZO']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/,J=function(t){return t[t.Short=0]="Short",t[t.ShortGMT=1]="ShortGMT",t[t.Long=2]="Long",t[t.Extended=3]="Extended",t}({}),Q=function(t){return t[t.FullYear=0]="FullYear",t[t.Month=1]="Month",t[t.Date=2]="Date",t[t.Hours=3]="Hours",t[t.Minutes=4]="Minutes",t[t.Seconds=5]="Seconds",t[t.FractionalSeconds=6]="FractionalSeconds",t[t.Day=7]="Day",t}({}),tt=function(t){return t[t.DayPeriods=0]="DayPeriods",t[t.Days=1]="Days",t[t.Months=2]="Months",t[t.Eras=3]="Eras",t}({});function et(t,e,n,a){var i=function(t){if(pt(t))return t;if("number"==typeof t&&!isNaN(t))return new Date(t);if("string"==typeof t){t=t.trim();var e,n=parseFloat(t);if(!isNaN(t-n))return new Date(n);if(/^(\d{4}-\d{1,2}-\d{1,2})$/.test(t)){var a=Object(r.__read)(t.split("-").map(function(t){return+t}),3);return new Date(a[0],a[1]-1,a[2])}if(e=t.match($))return ft(e)}var i=new Date(t);if(!pt(i))throw new Error('Unable to convert "'+t+'" into a date');return i}(t);e=function t(e,n){var a=O(e);if(Z[a]=Z[a]||{},Z[a][n])return Z[a][n];var r="";switch(n){case"shortDate":r=D(e,T.Short);break;case"mediumDate":r=D(e,T.Medium);break;case"longDate":r=D(e,T.Long);break;case"fullDate":r=D(e,T.Full);break;case"shortTime":r=E(e,T.Short);break;case"mediumTime":r=E(e,T.Medium);break;case"longTime":r=E(e,T.Long);break;case"fullTime":r=E(e,T.Full);break;case"short":var i=t(e,"shortTime"),s=t(e,"shortDate");r=nt(L(e,T.Short),[i,s]);break;case"medium":var o=t(e,"mediumTime"),u=t(e,"mediumDate");r=nt(L(e,T.Medium),[o,u]);break;case"long":var c=t(e,"longTime"),l=t(e,"longDate");r=nt(L(e,T.Long),[c,l]);break;case"full":var d=t(e,"fullTime"),f=t(e,"fullDate");r=nt(L(e,T.Full),[d,f])}return r&&(Z[a][n]=r),r}(n,e)||e;for(var s,o=[];e;){if(!(s=X.exec(e))){o.push(e);break}var u=(o=o.concat(s.slice(1))).pop();if(!u)break;e=u}var c=i.getTimezoneOffset();a&&(c=dt(a,c),i=function(t,e,n){var a=t.getTimezoneOffset();return function(t,e){return(t=new Date(t.getTime())).setMinutes(t.getMinutes()+e),t}(t,-1*(dt(e,a)-a))}(i,a));var l="";return o.forEach(function(t){var e=function(t){if(lt[t])return lt[t];var e;switch(t){case"G":case"GG":case"GGG":e=it(tt.Eras,x.Abbreviated);break;case"GGGG":e=it(tt.Eras,x.Wide);break;case"GGGGG":e=it(tt.Eras,x.Narrow);break;case"y":e=rt(Q.FullYear,1,0,!1,!0);break;case"yy":e=rt(Q.FullYear,2,0,!0,!0);break;case"yyy":e=rt(Q.FullYear,3,0,!1,!0);break;case"yyyy":e=rt(Q.FullYear,4,0,!1,!0);break;case"M":case"L":e=rt(Q.Month,1,1);break;case"MM":case"LL":e=rt(Q.Month,2,1);break;case"MMM":e=it(tt.Months,x.Abbreviated);break;case"MMMM":e=it(tt.Months,x.Wide);break;case"MMMMM":e=it(tt.Months,x.Narrow);break;case"LLL":e=it(tt.Months,x.Abbreviated,_.Standalone);break;case"LLLL":e=it(tt.Months,x.Wide,_.Standalone);break;case"LLLLL":e=it(tt.Months,x.Narrow,_.Standalone);break;case"w":e=ct(1);break;case"ww":e=ct(2);break;case"W":e=ct(1,!0);break;case"d":e=rt(Q.Date,1);break;case"dd":e=rt(Q.Date,2);break;case"E":case"EE":case"EEE":e=it(tt.Days,x.Abbreviated);break;case"EEEE":e=it(tt.Days,x.Wide);break;case"EEEEE":e=it(tt.Days,x.Narrow);break;case"EEEEEE":e=it(tt.Days,x.Short);break;case"a":case"aa":case"aaa":e=it(tt.DayPeriods,x.Abbreviated);break;case"aaaa":e=it(tt.DayPeriods,x.Wide);break;case"aaaaa":e=it(tt.DayPeriods,x.Narrow);break;case"b":case"bb":case"bbb":e=it(tt.DayPeriods,x.Abbreviated,_.Standalone,!0);break;case"bbbb":e=it(tt.DayPeriods,x.Wide,_.Standalone,!0);break;case"bbbbb":e=it(tt.DayPeriods,x.Narrow,_.Standalone,!0);break;case"B":case"BB":case"BBB":e=it(tt.DayPeriods,x.Abbreviated,_.Format,!0);break;case"BBBB":e=it(tt.DayPeriods,x.Wide,_.Format,!0);break;case"BBBBB":e=it(tt.DayPeriods,x.Narrow,_.Format,!0);break;case"h":e=rt(Q.Hours,1,-12);break;case"hh":e=rt(Q.Hours,2,-12);break;case"H":e=rt(Q.Hours,1);break;case"HH":e=rt(Q.Hours,2);break;case"m":e=rt(Q.Minutes,1);break;case"mm":e=rt(Q.Minutes,2);break;case"s":e=rt(Q.Seconds,1);break;case"ss":e=rt(Q.Seconds,2);break;case"S":e=rt(Q.FractionalSeconds,1);break;case"SS":e=rt(Q.FractionalSeconds,2);break;case"SSS":e=rt(Q.FractionalSeconds,3);break;case"Z":case"ZZ":case"ZZZ":e=st(J.Short);break;case"ZZZZZ":e=st(J.Extended);break;case"O":case"OO":case"OOO":case"z":case"zz":case"zzz":e=st(J.ShortGMT);break;case"OOOO":case"ZZZZ":case"zzzz":e=st(J.Long);break;default:return null}return lt[t]=e,e}(t);l+=e?e(i,n,c):"''"===t?"'":t.replace(/(^'|'$)/g,"").replace(/''/g,"'")}),l}function nt(t,e){return e&&(t=t.replace(/\{([^}]+)}/g,function(t,n){return null!=e&&n in e?e[n]:t})),t}function at(t,e,n,a,r){void 0===n&&(n="-");var i="";(t<0||r&&t<=0)&&(r?t=1-t:(t=-t,i=n));for(var s=String(t);s.length0||u>-n)&&(u+=n),t===Q.Hours)0===u&&-12===n&&(u=12);else if(t===Q.FractionalSeconds)return o=e,at(u,3).substr(0,o);var c=P(s,w.MinusSign);return at(u,e,c,a,r)}}function it(t,e,n,a){return void 0===n&&(n=_.Format),void 0===a&&(a=!1),function(r,i){return function(t,e,n,a,r,i){switch(n){case tt.Months:return k(e,r,a)[t.getMonth()];case tt.Days:return C(e,r,a)[t.getDay()];case tt.DayPeriods:var s=t.getHours(),o=t.getMinutes();if(i){var u,c=G(e),l=Y(e,r,a);if(c.forEach(function(t,e){if(Array.isArray(t)){var n=t[0],a=t[1],r=a.hours;s>=n.hours&&o>=n.minutes&&(s0?Math.floor(r/60):Math.ceil(r/60);switch(t){case J.Short:return(r>=0?"+":"")+at(s,2,i)+at(Math.abs(r%60),2,i);case J.ShortGMT:return"GMT"+(r>=0?"+":"")+at(s,1,i);case J.Long:return"GMT"+(r>=0?"+":"")+at(s,2,i)+":"+at(Math.abs(r%60),2,i);case J.Extended:return 0===a?"Z":(r>=0?"+":"")+at(s,2,i)+":"+at(Math.abs(r%60),2,i);default:throw new Error('Unknown zone width "'+t+'"')}}}var ot=0,ut=4;function ct(t,e){return void 0===e&&(e=!1),function(n,a){var r,i,s,o;if(e){var u=new Date(n.getFullYear(),n.getMonth(),1).getDay()-1,c=n.getDate();r=1+Math.floor((c+u)/7)}else{var l=(s=n.getFullYear(),o=new Date(s,ot,1).getDay(),new Date(s,0,1+(o<=ut?ut:ut+7)-o)),d=(i=n,new Date(i.getFullYear(),i.getMonth(),i.getDate()+(ut-i.getDay()))).getTime()-l.getTime();r=1+Math.round(d/6048e5)}return at(r,t,P(a,w.MinusSign))}}var lt={};function dt(t,e){t=t.replace(/:/g,"");var n=Date.parse("Jan 01, 1970 00:00:00 "+t)/6e4;return isNaN(n)?e:n}function ft(t){var e=new Date(0),n=0,a=0,r=t[8]?e.setUTCFullYear:e.setFullYear,i=t[8]?e.setUTCHours:e.setHours;t[9]&&(n=Number(t[9]+t[10]),a=Number(t[9]+t[11])),r.call(e,Number(t[1]),Number(t[2])-1,Number(t[3]));var s=Number(t[4]||0)-n,o=Number(t[5]||0)-a,u=Number(t[6]||0),c=Math.round(1e3*parseFloat("0."+(t[7]||0)));return i.call(e,s,o,u,c),e}function pt(t){return t instanceof Date&&!isNaN(t.valueOf())}var ht=/^(\d+)?\.((\d+)(-(\d+))?)?$/,gt=22,bt=".",mt="0",yt=";",vt=",",_t="#",xt="\xa4",Tt="%";function wt(t,e,n,a,r,i,s){void 0===s&&(s=!1);var o="",u=!1;if(isFinite(t)){var c=function(e){var n,a,r,i,s,o=Math.abs(t)+"",u=0;for((a=o.indexOf(bt))>-1&&(o=o.replace(bt,"")),(r=o.search(/e/i))>0?(a<0&&(a=r),a+=+o.slice(r+1),o=o.substring(0,r)):a<0&&(a=o.length),r=0;o.charAt(r)===mt;r++);if(r===(s=o.length))n=[0],a=1;else{for(s--;o.charAt(s)===mt;)s--;for(a-=r,n=[],i=0;r<=s;r++,i++)n[i]=Number(o.charAt(r))}return a>gt&&(n=n.splice(0,gt-1),u=a-1,a=1),{digits:n,exponent:u,integerLen:a}}();s&&(c=function(t){if(0===t.digits[0])return t;var e=t.digits.length-t.integerLen;return t.exponent?t.exponent+=2:(0===e?t.digits.push(0,0):1===e&&t.digits.push(0),t.integerLen+=2),t}(c));var l=e.minInt,d=e.minFrac,f=e.maxFrac;if(i){var p=i.match(ht);if(null===p)throw new Error(i+" is not a valid digit info");var h=p[1],g=p[3],b=p[5];null!=h&&(l=kt(h)),null!=g&&(d=kt(g)),null!=b?f=kt(b):null!=g&&d>f&&(f=d)}!function(t,e,n){if(e>n)throw new Error("The minimum number of digits after fraction ("+e+") is higher than the maximum ("+n+").");var a=t.digits,r=a.length-t.integerLen,i=Math.min(Math.max(e,r),n),s=i+t.integerLen,o=a[s];if(s>0){a.splice(Math.max(t.integerLen,s));for(var u=s;u=5)if(s-1<0){for(var l=0;l>s;l--)a.unshift(0),t.integerLen++;a.unshift(1),t.integerLen++}else a[s-1]++;for(;r=f?a.pop():d=!1),e>=10?1:0},0);p&&(a.unshift(p),t.integerLen++)}(c,d,f);var m=c.digits,y=c.integerLen,v=c.exponent,_=[];for(u=m.every(function(t){return!t});y0?_=m.splice(y,m.length):(_=m,m=[0]);var x=[];for(m.length>=e.lgSize&&x.unshift(m.splice(-e.lgSize,m.length).join(""));m.length>e.gSize;)x.unshift(m.splice(-e.gSize,m.length).join(""));m.length&&x.unshift(m.join("")),o=x.join(P(n,a)),_.length&&(o+=P(n,r)+_.join("")),v&&(o+=P(n,w.Exponential)+"+"+v)}else o=P(n,w.Infinity);return t<0&&!u?e.negPre+o+e.negSuf:e.posPre+o+e.posSuf}function St(t,e,n,a,r){var i=Ct(M(e,y.Currency),P(e,w.MinusSign));return i.minFrac=K(a),i.maxFrac=i.minFrac,wt(t,i,e,w.CurrencyGroup,w.CurrencyDecimal,r).replace(xt,n).replace(xt,"")}function Ot(t,e,n){return wt(t,Ct(M(e,y.Percent),P(e,w.MinusSign)),e,w.Group,w.Decimal,n,!0).replace(new RegExp(Tt,"g"),P(e,w.PercentSign))}function It(t,e,n){return wt(t,Ct(M(e,y.Decimal),P(e,w.MinusSign)),e,w.Group,w.Decimal,n)}function Ct(t,e){void 0===e&&(e="-");var n={minInt:1,minFrac:0,maxFrac:0,posPre:"",posSuf:"",negPre:"",negSuf:"",gSize:0,lgSize:0},a=t.split(yt),r=a[0],i=a[1],s=-1!==r.indexOf(bt)?r.split(bt):[r.substring(0,r.lastIndexOf(mt)+1),r.substring(r.lastIndexOf(mt)+1)],o=s[0],u=s[1]||"";n.posPre=o.substr(0,o.indexOf(_t));for(var c=0;c-1)return r;if(r=n.getPluralCategory(t,a),e.indexOf(r)>-1)return r;if(e.indexOf("other")>-1)return"other";throw new Error('No plural message found for value "'+t+'"')}var Dt=function(t){function e(e,n){var a=t.call(this)||this;return a.locale=e,a.deprecatedPluralFn=n,a}return Object(r.__extends)(e,t),e.prototype.getPluralCategory=function(t,e){switch(this.deprecatedPluralFn?this.deprecatedPluralFn(e||this.locale,t):F(e||this.locale)(t)){case v.Zero:return"zero";case v.One:return"one";case v.Two:return"two";case v.Few:return"few";case v.Many:return"many";default:return"other"}},e}(Rt);function Et(t,e){"string"==typeof e&&(e=parseInt(e,10));var n=e,a=n.toString().replace(/^[^.]*\.?/,""),r=Math.floor(Math.abs(n)),i=a.length,s=parseInt(a,10),o=parseInt(n.toString().replace(/^[^.]*\.?|0+$/g,""),10)||0;switch(t.split("-")[0].toLowerCase()){case"af":case"asa":case"az":case"bem":case"bez":case"bg":case"brx":case"ce":case"cgg":case"chr":case"ckb":case"ee":case"el":case"eo":case"es":case"eu":case"fo":case"fur":case"gsw":case"ha":case"haw":case"hu":case"jgo":case"jmc":case"ka":case"kk":case"kkj":case"kl":case"ks":case"ksb":case"ky":case"lb":case"lg":case"mas":case"mgo":case"ml":case"mn":case"nb":case"nd":case"ne":case"nn":case"nnh":case"nyn":case"om":case"or":case"os":case"ps":case"rm":case"rof":case"rwk":case"saq":case"seh":case"sn":case"so":case"sq":case"ta":case"te":case"teo":case"tk":case"tr":case"ug":case"uz":case"vo":case"vun":case"wae":case"xog":return 1===n?v.One:v.Other;case"ak":case"ln":case"mg":case"pa":case"ti":return n===Math.floor(n)&&n>=0&&n<=1?v.One:v.Other;case"am":case"as":case"bn":case"fa":case"gu":case"hi":case"kn":case"mr":case"zu":return 0===r||1===n?v.One:v.Other;case"ar":return 0===n?v.Zero:1===n?v.One:2===n?v.Two:n%100===Math.floor(n%100)&&n%100>=3&&n%100<=10?v.Few:n%100===Math.floor(n%100)&&n%100>=11&&n%100<=99?v.Many:v.Other;case"ast":case"ca":case"de":case"en":case"et":case"fi":case"fy":case"gl":case"it":case"nl":case"sv":case"sw":case"ur":case"yi":return 1===r&&0===i?v.One:v.Other;case"be":return n%10==1&&n%100!=11?v.One:n%10===Math.floor(n%10)&&n%10>=2&&n%10<=4&&!(n%100>=12&&n%100<=14)?v.Few:n%10==0||n%10===Math.floor(n%10)&&n%10>=5&&n%10<=9||n%100===Math.floor(n%100)&&n%100>=11&&n%100<=14?v.Many:v.Other;case"br":return n%10==1&&n%100!=11&&n%100!=71&&n%100!=91?v.One:n%10==2&&n%100!=12&&n%100!=72&&n%100!=92?v.Two:n%10===Math.floor(n%10)&&(n%10>=3&&n%10<=4||n%10==9)&&!(n%100>=10&&n%100<=19||n%100>=70&&n%100<=79||n%100>=90&&n%100<=99)?v.Few:0!==n&&n%1e6==0?v.Many:v.Other;case"bs":case"hr":case"sr":return 0===i&&r%10==1&&r%100!=11||s%10==1&&s%100!=11?v.One:0===i&&r%10===Math.floor(r%10)&&r%10>=2&&r%10<=4&&!(r%100>=12&&r%100<=14)||s%10===Math.floor(s%10)&&s%10>=2&&s%10<=4&&!(s%100>=12&&s%100<=14)?v.Few:v.Other;case"cs":case"sk":return 1===r&&0===i?v.One:r===Math.floor(r)&&r>=2&&r<=4&&0===i?v.Few:0!==i?v.Many:v.Other;case"cy":return 0===n?v.Zero:1===n?v.One:2===n?v.Two:3===n?v.Few:6===n?v.Many:v.Other;case"da":return 1===n||0!==o&&(0===r||1===r)?v.One:v.Other;case"dsb":case"hsb":return 0===i&&r%100==1||s%100==1?v.One:0===i&&r%100==2||s%100==2?v.Two:0===i&&r%100===Math.floor(r%100)&&r%100>=3&&r%100<=4||s%100===Math.floor(s%100)&&s%100>=3&&s%100<=4?v.Few:v.Other;case"ff":case"fr":case"hy":case"kab":return 0===r||1===r?v.One:v.Other;case"fil":return 0===i&&(1===r||2===r||3===r)||0===i&&r%10!=4&&r%10!=6&&r%10!=9||0!==i&&s%10!=4&&s%10!=6&&s%10!=9?v.One:v.Other;case"ga":return 1===n?v.One:2===n?v.Two:n===Math.floor(n)&&n>=3&&n<=6?v.Few:n===Math.floor(n)&&n>=7&&n<=10?v.Many:v.Other;case"gd":return 1===n||11===n?v.One:2===n||12===n?v.Two:n===Math.floor(n)&&(n>=3&&n<=10||n>=13&&n<=19)?v.Few:v.Other;case"gv":return 0===i&&r%10==1?v.One:0===i&&r%10==2?v.Two:0!==i||r%100!=0&&r%100!=20&&r%100!=40&&r%100!=60&&r%100!=80?0!==i?v.Many:v.Other:v.Few;case"he":return 1===r&&0===i?v.One:2===r&&0===i?v.Two:0!==i||n>=0&&n<=10||n%10!=0?v.Other:v.Many;case"is":return 0===o&&r%10==1&&r%100!=11||0!==o?v.One:v.Other;case"ksh":return 0===n?v.Zero:1===n?v.One:v.Other;case"kw":case"naq":case"se":case"smn":return 1===n?v.One:2===n?v.Two:v.Other;case"lag":return 0===n?v.Zero:0!==r&&1!==r||0===n?v.Other:v.One;case"lt":return n%10!=1||n%100>=11&&n%100<=19?n%10===Math.floor(n%10)&&n%10>=2&&n%10<=9&&!(n%100>=11&&n%100<=19)?v.Few:0!==s?v.Many:v.Other:v.One;case"lv":case"prg":return n%10==0||n%100===Math.floor(n%100)&&n%100>=11&&n%100<=19||2===i&&s%100===Math.floor(s%100)&&s%100>=11&&s%100<=19?v.Zero:n%10==1&&n%100!=11||2===i&&s%10==1&&s%100!=11||2!==i&&s%10==1?v.One:v.Other;case"mk":return 0===i&&r%10==1||s%10==1?v.One:v.Other;case"mt":return 1===n?v.One:0===n||n%100===Math.floor(n%100)&&n%100>=2&&n%100<=10?v.Few:n%100===Math.floor(n%100)&&n%100>=11&&n%100<=19?v.Many:v.Other;case"pl":return 1===r&&0===i?v.One:0===i&&r%10===Math.floor(r%10)&&r%10>=2&&r%10<=4&&!(r%100>=12&&r%100<=14)?v.Few:0===i&&1!==r&&r%10===Math.floor(r%10)&&r%10>=0&&r%10<=1||0===i&&r%10===Math.floor(r%10)&&r%10>=5&&r%10<=9||0===i&&r%100===Math.floor(r%100)&&r%100>=12&&r%100<=14?v.Many:v.Other;case"pt":return n===Math.floor(n)&&n>=0&&n<=2&&2!==n?v.One:v.Other;case"ro":return 1===r&&0===i?v.One:0!==i||0===n||1!==n&&n%100===Math.floor(n%100)&&n%100>=1&&n%100<=19?v.Few:v.Other;case"ru":case"uk":return 0===i&&r%10==1&&r%100!=11?v.One:0===i&&r%10===Math.floor(r%10)&&r%10>=2&&r%10<=4&&!(r%100>=12&&r%100<=14)?v.Few:0===i&&r%10==0||0===i&&r%10===Math.floor(r%10)&&r%10>=5&&r%10<=9||0===i&&r%100===Math.floor(r%100)&&r%100>=11&&r%100<=14?v.Many:v.Other;case"shi":return 0===r||1===n?v.One:n===Math.floor(n)&&n>=2&&n<=10?v.Few:v.Other;case"si":return 0===n||1===n||0===r&&1===s?v.One:v.Other;case"sl":return 0===i&&r%100==1?v.One:0===i&&r%100==2?v.Two:0===i&&r%100===Math.floor(r%100)&&r%100>=3&&r%100<=4||0!==i?v.Few:v.Other;case"tzm":return n===Math.floor(n)&&n>=0&&n<=1||n===Math.floor(n)&&n>=11&&n<=99?v.One:v.Other;default:return v.Other}}function Lt(t,e){var n,a;e=encodeURIComponent(e);try{for(var i=Object(r.__values)(t.split(";")),s=i.next();!s.done;s=i.next()){var o=s.value,u=o.indexOf("="),c=Object(r.__read)(-1==u?[o,""]:[o.slice(0,u),o.slice(u+1)],2),l=c[1];if(c[0].trim()===e)return decodeURIComponent(l)}}catch(d){n={error:d}}finally{try{s&&!s.done&&(a=i.return)&&a.call(i)}finally{if(n)throw n.error}}return null}var Pt=function(){function t(t,e,n,a){this._iterableDiffers=t,this._keyValueDiffers=e,this._ngEl=n,this._renderer=a,this._initialClasses=[]}return Object.defineProperty(t.prototype,"klass",{set:function(t){this._removeClasses(this._initialClasses),this._initialClasses="string"==typeof t?t.split(/\s+/):[],this._applyClasses(this._initialClasses),this._applyClasses(this._rawClass)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClass",{set:function(t){this._removeClasses(this._rawClass),this._applyClasses(this._initialClasses),this._iterableDiffer=null,this._keyValueDiffer=null,this._rawClass="string"==typeof t?t.split(/\s+/):t,this._rawClass&&(Object(a["\u0275isListLikeIterable"])(this._rawClass)?this._iterableDiffer=this._iterableDiffers.find(this._rawClass).create():this._keyValueDiffer=this._keyValueDiffers.find(this._rawClass).create())},enumerable:!0,configurable:!0}),t.prototype.ngDoCheck=function(){if(this._iterableDiffer){var t=this._iterableDiffer.diff(this._rawClass);t&&this._applyIterableChanges(t)}else if(this._keyValueDiffer){var e=this._keyValueDiffer.diff(this._rawClass);e&&this._applyKeyValueChanges(e)}},t.prototype._applyKeyValueChanges=function(t){var e=this;t.forEachAddedItem(function(t){return e._toggleClass(t.key,t.currentValue)}),t.forEachChangedItem(function(t){return e._toggleClass(t.key,t.currentValue)}),t.forEachRemovedItem(function(t){t.previousValue&&e._toggleClass(t.key,!1)})},t.prototype._applyIterableChanges=function(t){var e=this;t.forEachAddedItem(function(t){if("string"!=typeof t.item)throw new Error("NgClass can only toggle CSS classes expressed as strings, got "+Object(a["\u0275stringify"])(t.item));e._toggleClass(t.item,!0)}),t.forEachRemovedItem(function(t){return e._toggleClass(t.item,!1)})},t.prototype._applyClasses=function(t){var e=this;t&&(Array.isArray(t)||t instanceof Set?t.forEach(function(t){return e._toggleClass(t,!0)}):Object.keys(t).forEach(function(n){return e._toggleClass(n,!!t[n])}))},t.prototype._removeClasses=function(t){var e=this;t&&(Array.isArray(t)||t instanceof Set?t.forEach(function(t){return e._toggleClass(t,!1)}):Object.keys(t).forEach(function(t){return e._toggleClass(t,!1)}))},t.prototype._toggleClass=function(t,e){var n=this;(t=t.trim())&&t.split(/\s+/g).forEach(function(t){e?n._renderer.addClass(n._ngEl.nativeElement,t):n._renderer.removeClass(n._ngEl.nativeElement,t)})},t}(),Mt=function(){function t(t){this._viewContainerRef=t,this._componentRef=null,this._moduleRef=null}return t.prototype.ngOnChanges=function(t){if(this._viewContainerRef.clear(),this._componentRef=null,this.ngComponentOutlet){var e=this.ngComponentOutletInjector||this._viewContainerRef.parentInjector;if(t.ngComponentOutletNgModuleFactory)if(this._moduleRef&&this._moduleRef.destroy(),this.ngComponentOutletNgModuleFactory){var n=e.get(a.NgModuleRef);this._moduleRef=this.ngComponentOutletNgModuleFactory.create(n.injector)}else this._moduleRef=null;var r=(this._moduleRef?this._moduleRef.componentFactoryResolver:e.get(a.ComponentFactoryResolver)).resolveComponentFactory(this.ngComponentOutlet);this._componentRef=this._viewContainerRef.createComponent(r,this._viewContainerRef.length,e,this.ngComponentOutletContent)}},t.prototype.ngOnDestroy=function(){this._moduleRef&&this._moduleRef.destroy()},t}(),qt=function(){function t(t,e,n,a){this.$implicit=t,this.ngForOf=e,this.index=n,this.count=a}return Object.defineProperty(t.prototype,"first",{get:function(){return 0===this.index},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"last",{get:function(){return this.index===this.count-1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"even",{get:function(){return this.index%2==0},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"odd",{get:function(){return!this.even},enumerable:!0,configurable:!0}),t}(),jt=function(){function t(t,e,n){this._viewContainer=t,this._template=e,this._differs=n,this._ngForOfDirty=!0,this._differ=null}return Object.defineProperty(t.prototype,"ngForOf",{set:function(t){this._ngForOf=t,this._ngForOfDirty=!0},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngForTrackBy",{get:function(){return this._trackByFn},set:function(t){Object(a.isDevMode)()&&null!=t&&"function"!=typeof t&&console&&console.warn&&console.warn("trackBy must be a function, but received "+JSON.stringify(t)+". See https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html#!#change-propagation for more information."),this._trackByFn=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngForTemplate",{set:function(t){t&&(this._template=t)},enumerable:!0,configurable:!0}),t.prototype.ngDoCheck=function(){if(this._ngForOfDirty){this._ngForOfDirty=!1;var t=this._ngForOf;if(!this._differ&&t)try{this._differ=this._differs.find(t).create(this.ngForTrackBy)}catch(a){throw new Error("Cannot find a differ supporting object '"+t+"' of type '"+((e=t).name||typeof e)+"'. NgFor only supports binding to Iterables such as Arrays.")}}var e;if(this._differ){var n=this._differ.diff(this._ngForOf);n&&this._applyChanges(n)}},t.prototype._applyChanges=function(t){var e=this,n=[];t.forEachOperation(function(t,a,r){if(null==t.previousIndex){var i=e._viewContainer.createEmbeddedView(e._template,new qt(null,e._ngForOf,-1,-1),r),s=new Ft(t,i);n.push(s)}else null==r?e._viewContainer.remove(a):(i=e._viewContainer.get(a),e._viewContainer.move(i,r),s=new Ft(t,i),n.push(s))});for(var a=0;a1?"short":"narrow":"long",n}function de(t){return t.reduce(function(t,e){return Object(r.__assign)({},t,e)},{})}function fe(t){return function(e,n){return se(e,n,t)}}var pe=new Map,he=function(){function t(){}return t.format=function(t,e,n){return function(t,e,n){var a=ee[t];if(a)return a(e,n);var r=t,i=pe.get(r);if(!i){i=[];var s=void 0;te.exec(t);for(var o=t;o;)(s=te.exec(o))?o=(i=i.concat(s.slice(1))).pop():(i.push(o),o=null);pe.set(r,i)}return i.reduce(function(t,a){var r=ne[a];return t+(r?r(e,n):function(t){return"''"===t?"'":t.replace(/(^'|'$)/g,"").replace(/''/g,"'")}(a))},"")}(n,t,e)},t}(),ge=function(){function t(t){this._locale=t}var e;return e=t,t.prototype.transform=function(t,n){if(void 0===n&&(n="mediumDate"),null==t||""===t||t!=t)return null;var a;if("string"==typeof t&&(t=t.trim()),be(t))a=t;else if(isNaN(t-parseFloat(t)))if("string"==typeof t&&/^(\d{4}-\d{1,2}-\d{1,2})$/.test(t)){var i=Object(r.__read)(t.split("-").map(function(t){return parseInt(t,10)}),3);a=new Date(i[0],i[1]-1,i[2])}else a=new Date(t);else a=new Date(parseFloat(t));if(!be(a)){var s=void 0;if("string"!=typeof t||!(s=t.match($)))throw Jt(e,t);a=ft(s)}return he.format(a,this._locale,e._ALIASES[n]||n)},t._ALIASES={medium:"yMMMdjms",short:"yMdjm",fullDate:"yMMMMEEEEd",longDate:"yMMMMd",mediumDate:"yMMMd",shortDate:"yMd",mediumTime:"jms",shortTime:"jm"},t}();function be(t){return t instanceof Date&&!isNaN(t.valueOf())}function me(t,e,n,a,r,i,s){if(void 0===i&&(i=null),void 0===s&&(s=!1),null==n)return null;if("number"!=typeof(n="string"!=typeof n||isNaN(+n-parseFloat(n))?n:+n))throw Jt(t,n);var o,u,c;if(a!==y.Currency&&(o=1,u=0,c=3),r){var l=r.match(ht);if(null===l)throw new Error(r+" is not a valid digit info for number pipes");null!=l[1]&&(o=kt(l[1])),null!=l[3]&&(u=kt(l[3])),null!=l[5]&&(c=kt(l[5]))}return Qt.format(n,e,a,{minimumIntegerDigits:o,minimumFractionDigits:u,maximumFractionDigits:c,currency:i,currencyAsSymbol:s})}var ye=function(){function t(t){this._locale=t}var e;return e=t,t.prototype.transform=function(t,n){return me(e,this._locale,t,y.Decimal,n)},t}(),ve=function(){function t(t){this._locale=t}var e;return e=t,t.prototype.transform=function(t,n){return me(e,this._locale,t,y.Percent,n)},t}(),_e=function(){function t(t){this._locale=t}var e;return e=t,t.prototype.transform=function(t,n,a,r){return void 0===n&&(n="USD"),void 0===a&&(a=!1),me(e,this._locale,t,y.Currency,r,n,a)},t}(),xe=[ye,ve,_e,ge],Te=function(){function t(){}return t.prototype.createSubscription=function(t,e){return t.subscribe({next:e,error:function(t){throw t}})},t.prototype.dispose=function(t){t.unsubscribe()},t.prototype.onDestroy=function(t){t.unsubscribe()},t}(),we=new(function(){function t(){}return t.prototype.createSubscription=function(t,e){return t.then(e,function(t){throw t})},t.prototype.dispose=function(t){},t.prototype.onDestroy=function(t){},t}()),Se=new Te,Oe=function(){function t(t){this._ref=t,this._latestValue=null,this._latestReturnedValue=null,this._subscription=null,this._obj=null,this._strategy=null}var e;return e=t,t.prototype.ngOnDestroy=function(){this._subscription&&this._dispose()},t.prototype.transform=function(t){return this._obj?t!==this._obj?(this._dispose(),this.transform(t)):this._latestValue===this._latestReturnedValue?this._latestReturnedValue:(this._latestReturnedValue=this._latestValue,a.WrappedValue.wrap(this._latestValue)):(t&&this._subscribe(t),this._latestReturnedValue=this._latestValue,this._latestValue)},t.prototype._subscribe=function(t){var e=this;this._obj=t,this._strategy=this._selectStrategy(t),this._subscription=this._strategy.createSubscription(t,function(n){return e._updateLatestValue(t,n)})},t.prototype._selectStrategy=function(t){if(Object(a["\u0275isPromise"])(t))return we;if(Object(a["\u0275isObservable"])(t))return Se;throw Jt(e,t)},t.prototype._dispose=function(){this._strategy.dispose(this._subscription),this._latestValue=null,this._latestReturnedValue=null,this._subscription=null,this._obj=null},t.prototype._updateLatestValue=function(t,e){t===this._obj&&(this._latestValue=e,this._ref.markForCheck())},t}(),Ie=function(){function t(){}var e;return e=t,t.prototype.transform=function(t){if(!t)return t;if("string"!=typeof t)throw Jt(e,t);return t.toLowerCase()},t}(),Ce=/(?:[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D])\S*/g,ke=function(){function t(){}var e;return e=t,t.prototype.transform=function(t){if(!t)return t;if("string"!=typeof t)throw Jt(e,t);return t.replace(Ce,function(t){return t[0].toUpperCase()+t.substr(1).toLowerCase()})},t}(),Ne=function(){function t(){}var e;return e=t,t.prototype.transform=function(t){if(!t)return t;if("string"!=typeof t)throw Jt(e,t);return t.toUpperCase()},t}(),Re=function(){function t(t){this.locale=t}var e;return e=t,t.prototype.transform=function(t,n,a,r){if(void 0===n&&(n="mediumDate"),null==t||""===t||t!=t)return null;try{return et(t,n,r||this.locale,a)}catch(i){throw Jt(e,i.message)}},t}(),Ae=/#/g,De=function(){function t(t){this._localization=t}var e;return e=t,t.prototype.transform=function(t,n,a){if(null==t)return"";if("object"!=typeof n||null===n)throw Jt(e,n);return n[At(t,Object.keys(n),this._localization,a)].replace(Ae,t.toString())},t}(),Ee=function(){function t(){}var e;return e=t,t.prototype.transform=function(t,n){if(null==t)return"";if("object"!=typeof n||"string"!=typeof t)throw Jt(e,n);return n.hasOwnProperty(t)?n[t]:n.hasOwnProperty("other")?n.other:""},t}(),Le=function(){function t(){}return t.prototype.transform=function(t){return JSON.stringify(t,null,2)},t}(),Pe=function(){function t(t){this.differs=t,this.keyValues=[]}return t.prototype.transform=function(t,e){var n=this;if(void 0===e&&(e=Me),!t||!(t instanceof Map)&&"object"!=typeof t)return null;this.differ||(this.differ=this.differs.find(t).create());var a=this.differ.diff(t);return a&&(this.keyValues=[],a.forEachItem(function(t){n.keyValues.push({key:t.key,value:t.currentValue})}),this.keyValues.sort(e)),this.keyValues},t}();function Me(t,e){var n=t.key,a=e.key;if(n===a)return 0;if(void 0===n)return 1;if(void 0===a)return-1;if(null===n)return 1;if(null===a)return-1;if("string"==typeof n&&"string"==typeof a)return nn.length-1&&(a=n.length-1);for(var r=a,i=0,s=0;i0&&(i++,"\n"!==n[--a]||++s!==e););for(i=0,s=0;i]"+t.after+'")':""},t.prototype.toString=function(){var t=this.span.details?", "+this.span.details:"";return""+this.msg+this.contextualMessage()+": "+this.span.start+t},t}(),I=function(t){function e(e,n){return t.call(this,e,n)||this}return Object(a.__extends)(e,t),e}(O);function C(t){return t.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}var k=new(function(){return function(t,e){this.start=t,this.end=e}}())("{{","}}"),N=0,R=9,A=10,D=11,E=12,L=13,P=32,M=34,q=36,j=39,F=43,z=45,G=47,Y=59,V=61,H=62,B=48,U=57,W=65,K=70,$=90,Z=95,X=97,J=102,Q=110,tt=114,et=116,nt=118,at=122,rt=123,it=160;function st(t){return t>=R&&t<=P||t===it}function ot(t){return B<=t&&t<=U}function ut(t){return t>=X&&t<=at||t>=W&&t<=$}var ct=function(){var t={RAW_TEXT:0,ESCAPABLE_RAW_TEXT:1,PARSABLE_DATA:2};return t[t.RAW_TEXT]="RAW_TEXT",t[t.ESCAPABLE_RAW_TEXT]="ESCAPABLE_RAW_TEXT",t[t.PARSABLE_DATA]="PARSABLE_DATA",t}();function lt(t){if(":"!==t[0])return[null,t];var e=t.indexOf(":",1);if(-1===e)throw new Error('Unsupported format "'+t+'" expecting ":namespace:name"');return[t.slice(1,e),t.slice(e+1)]}function dt(t){return null===t?null:lt(t)[0]}function ft(t,e){return t?":"+t+":"+e:e}var pt={Aacute:"\xc1",aacute:"\xe1",Acirc:"\xc2",acirc:"\xe2",acute:"\xb4",AElig:"\xc6",aelig:"\xe6",Agrave:"\xc0",agrave:"\xe0",alefsym:"\u2135",Alpha:"\u0391",alpha:"\u03b1",amp:"&",and:"\u2227",ang:"\u2220",apos:"'",Aring:"\xc5",aring:"\xe5",asymp:"\u2248",Atilde:"\xc3",atilde:"\xe3",Auml:"\xc4",auml:"\xe4",bdquo:"\u201e",Beta:"\u0392",beta:"\u03b2",brvbar:"\xa6",bull:"\u2022",cap:"\u2229",Ccedil:"\xc7",ccedil:"\xe7",cedil:"\xb8",cent:"\xa2",Chi:"\u03a7",chi:"\u03c7",circ:"\u02c6",clubs:"\u2663",cong:"\u2245",copy:"\xa9",crarr:"\u21b5",cup:"\u222a",curren:"\xa4",dagger:"\u2020",Dagger:"\u2021",darr:"\u2193",dArr:"\u21d3",deg:"\xb0",Delta:"\u0394",delta:"\u03b4",diams:"\u2666",divide:"\xf7",Eacute:"\xc9",eacute:"\xe9",Ecirc:"\xca",ecirc:"\xea",Egrave:"\xc8",egrave:"\xe8",empty:"\u2205",emsp:"\u2003",ensp:"\u2002",Epsilon:"\u0395",epsilon:"\u03b5",equiv:"\u2261",Eta:"\u0397",eta:"\u03b7",ETH:"\xd0",eth:"\xf0",Euml:"\xcb",euml:"\xeb",euro:"\u20ac",exist:"\u2203",fnof:"\u0192",forall:"\u2200",frac12:"\xbd",frac14:"\xbc",frac34:"\xbe",frasl:"\u2044",Gamma:"\u0393",gamma:"\u03b3",ge:"\u2265",gt:">",harr:"\u2194",hArr:"\u21d4",hearts:"\u2665",hellip:"\u2026",Iacute:"\xcd",iacute:"\xed",Icirc:"\xce",icirc:"\xee",iexcl:"\xa1",Igrave:"\xcc",igrave:"\xec",image:"\u2111",infin:"\u221e",int:"\u222b",Iota:"\u0399",iota:"\u03b9",iquest:"\xbf",isin:"\u2208",Iuml:"\xcf",iuml:"\xef",Kappa:"\u039a",kappa:"\u03ba",Lambda:"\u039b",lambda:"\u03bb",lang:"\u27e8",laquo:"\xab",larr:"\u2190",lArr:"\u21d0",lceil:"\u2308",ldquo:"\u201c",le:"\u2264",lfloor:"\u230a",lowast:"\u2217",loz:"\u25ca",lrm:"\u200e",lsaquo:"\u2039",lsquo:"\u2018",lt:"<",macr:"\xaf",mdash:"\u2014",micro:"\xb5",middot:"\xb7",minus:"\u2212",Mu:"\u039c",mu:"\u03bc",nabla:"\u2207",nbsp:"\xa0",ndash:"\u2013",ne:"\u2260",ni:"\u220b",not:"\xac",notin:"\u2209",nsub:"\u2284",Ntilde:"\xd1",ntilde:"\xf1",Nu:"\u039d",nu:"\u03bd",Oacute:"\xd3",oacute:"\xf3",Ocirc:"\xd4",ocirc:"\xf4",OElig:"\u0152",oelig:"\u0153",Ograve:"\xd2",ograve:"\xf2",oline:"\u203e",Omega:"\u03a9",omega:"\u03c9",Omicron:"\u039f",omicron:"\u03bf",oplus:"\u2295",or:"\u2228",ordf:"\xaa",ordm:"\xba",Oslash:"\xd8",oslash:"\xf8",Otilde:"\xd5",otilde:"\xf5",otimes:"\u2297",Ouml:"\xd6",ouml:"\xf6",para:"\xb6",permil:"\u2030",perp:"\u22a5",Phi:"\u03a6",phi:"\u03c6",Pi:"\u03a0",pi:"\u03c0",piv:"\u03d6",plusmn:"\xb1",pound:"\xa3",prime:"\u2032",Prime:"\u2033",prod:"\u220f",prop:"\u221d",Psi:"\u03a8",psi:"\u03c8",quot:'"',radic:"\u221a",rang:"\u27e9",raquo:"\xbb",rarr:"\u2192",rArr:"\u21d2",rceil:"\u2309",rdquo:"\u201d",real:"\u211c",reg:"\xae",rfloor:"\u230b",Rho:"\u03a1",rho:"\u03c1",rlm:"\u200f",rsaquo:"\u203a",rsquo:"\u2019",sbquo:"\u201a",Scaron:"\u0160",scaron:"\u0161",sdot:"\u22c5",sect:"\xa7",shy:"\xad",Sigma:"\u03a3",sigma:"\u03c3",sigmaf:"\u03c2",sim:"\u223c",spades:"\u2660",sub:"\u2282",sube:"\u2286",sum:"\u2211",sup:"\u2283",sup1:"\xb9",sup2:"\xb2",sup3:"\xb3",supe:"\u2287",szlig:"\xdf",Tau:"\u03a4",tau:"\u03c4",there4:"\u2234",Theta:"\u0398",theta:"\u03b8",thetasym:"\u03d1",thinsp:"\u2009",THORN:"\xde",thorn:"\xfe",tilde:"\u02dc",times:"\xd7",trade:"\u2122",Uacute:"\xda",uacute:"\xfa",uarr:"\u2191",uArr:"\u21d1",Ucirc:"\xdb",ucirc:"\xfb",Ugrave:"\xd9",ugrave:"\xf9",uml:"\xa8",upsih:"\u03d2",Upsilon:"\u03a5",upsilon:"\u03c5",Uuml:"\xdc",uuml:"\xfc",weierp:"\u2118",Xi:"\u039e",xi:"\u03be",Yacute:"\xdd",yacute:"\xfd",yen:"\xa5",yuml:"\xff",Yuml:"\u0178",Zeta:"\u0396",zeta:"\u03b6",zwj:"\u200d",zwnj:"\u200c",ngsp:"\ue500"},ht=function(){var t={TAG_OPEN_START:0,TAG_OPEN_END:1,TAG_OPEN_END_VOID:2,TAG_CLOSE:3,TEXT:4,ESCAPABLE_RAW_TEXT:5,RAW_TEXT:6,COMMENT_START:7,COMMENT_END:8,CDATA_START:9,CDATA_END:10,ATTR_NAME:11,ATTR_VALUE:12,DOC_TYPE:13,EXPANSION_FORM_START:14,EXPANSION_CASE_VALUE:15,EXPANSION_CASE_EXP_START:16,EXPANSION_CASE_EXP_END:17,EXPANSION_FORM_END:18,EOF:19};return t[t.TAG_OPEN_START]="TAG_OPEN_START",t[t.TAG_OPEN_END]="TAG_OPEN_END",t[t.TAG_OPEN_END_VOID]="TAG_OPEN_END_VOID",t[t.TAG_CLOSE]="TAG_CLOSE",t[t.TEXT]="TEXT",t[t.ESCAPABLE_RAW_TEXT]="ESCAPABLE_RAW_TEXT",t[t.RAW_TEXT]="RAW_TEXT",t[t.COMMENT_START]="COMMENT_START",t[t.COMMENT_END]="COMMENT_END",t[t.CDATA_START]="CDATA_START",t[t.CDATA_END]="CDATA_END",t[t.ATTR_NAME]="ATTR_NAME",t[t.ATTR_VALUE]="ATTR_VALUE",t[t.DOC_TYPE]="DOC_TYPE",t[t.EXPANSION_FORM_START]="EXPANSION_FORM_START",t[t.EXPANSION_CASE_VALUE]="EXPANSION_CASE_VALUE",t[t.EXPANSION_CASE_EXP_START]="EXPANSION_CASE_EXP_START",t[t.EXPANSION_CASE_EXP_END]="EXPANSION_CASE_EXP_END",t[t.EXPANSION_FORM_END]="EXPANSION_FORM_END",t[t.EOF]="EOF",t}(),gt=function(){return function(t,e,n){this.type=t,this.parts=e,this.sourceSpan=n}}(),bt=function(t){function e(e,n,a){var r=t.call(this,a,e)||this;return r.tokenType=n,r}return Object(a.__extends)(e,t),e}(O),mt=function(){return function(t,e){this.tokens=t,this.errors=e}}(),yt=/\r\n?/g;function vt(t){return'Unexpected character "'+(t===N?"EOF":String.fromCharCode(t))+'"'}function _t(t){return'Unknown entity "'+t+'" - use the "&#;" or "&#x;" syntax'}var xt=function(){return function(t){this.error=t}}(),Tt=function(){function t(t,e,n,a){void 0===a&&(a=k),this._file=t,this._getTagDefinition=e,this._tokenizeIcu=n,this._interpolationConfig=a,this._peek=-1,this._nextPeek=-1,this._index=-1,this._line=0,this._column=-1,this._expansionCaseStack=[],this._inInterpolation=!1,this.tokens=[],this.errors=[],this._input=t.content,this._length=t.content.length,this._advance()}return t.prototype._processCarriageReturns=function(t){return t.replace(yt,"\n")},t.prototype.tokenize=function(){for(;this._peek!==N;){var t=this._getLocation();try{this._attemptCharCode(60)?this._attemptCharCode(33)?this._attemptCharCode(91)?this._consumeCdata(t):this._attemptCharCode(z)?this._consumeComment(t):this._consumeDocType(t):this._attemptCharCode(G)?this._consumeTagClose(t):this._consumeTagOpen(t):this._tokenizeIcu&&this._tokenizeExpansionForm()||this._consumeText()}catch(e){if(!(e instanceof xt))throw e;this.errors.push(e.error)}}return this._beginToken(ht.EOF),this._endToken([]),new mt(function(t){for(var e=[],n=void 0,a=0;a=this._length)throw this._createError(vt(N),this._getSpan());this._peek===A?(this._line++,this._column=0):this._peek!==A&&this._peek!==L&&this._column++,this._index++,this._peek=this._index>=this._length?N:this._input.charCodeAt(this._index),this._nextPeek=this._index+1>=this._length?N:this._input.charCodeAt(this._index+1)},t.prototype._attemptCharCode=function(t){return this._peek===t&&(this._advance(),!0)},t.prototype._attemptCharCodeCaseInsensitive=function(t){return e=t,kt(this._peek)===kt(e)&&(this._advance(),!0);var e},t.prototype._requireCharCode=function(t){var e=this._getLocation();if(!this._attemptCharCode(t))throw this._createError(vt(this._peek),this._getSpan(e,e))},t.prototype._attemptStr=function(t){var e=t.length;if(this._index+e>this._length)return!1;for(var n=this._savePosition(),a=0;aa.offset&&i.push(this._input.substring(a.offset,this._index));this._peek!==e;)i.push(this._readChar(t));return this._endToken([this._processCarriageReturns(i.join(""))],a)},t.prototype._consumeComment=function(t){var e=this;this._beginToken(ht.COMMENT_START,t),this._requireCharCode(z),this._endToken([]);var n=this._consumeRawText(!1,z,function(){return e._attemptStr("->")});this._beginToken(ht.COMMENT_END,n.sourceSpan.end),this._endToken([])},t.prototype._consumeCdata=function(t){var e=this;this._beginToken(ht.CDATA_START,t),this._requireStr("CDATA["),this._endToken([]);var n=this._consumeRawText(!1,93,function(){return e._attemptStr("]>")});this._beginToken(ht.CDATA_END,n.sourceSpan.end),this._endToken([])},t.prototype._consumeDocType=function(t){this._beginToken(ht.DOC_TYPE,t),this._attemptUntilChar(H),this._advance(),this._endToken([this._input.substring(t.offset+2,this._index-1)])},t.prototype._consumePrefixAndName=function(){for(var t,e,n=this._index,a=null;58!==this._peek&&!(((t=this._peek)U));)this._advance();return 58===this._peek?(this._advance(),a=this._input.substring(n,this._index-1),e=this._index):e=n,this._requireCharCodeUntilFn(St,this._index===e?1:0),[a,this._input.substring(e,this._index)]},t.prototype._consumeTagOpen=function(t){var e,n,a=this._savePosition();try{if(!ut(this._peek))throw this._createError(vt(this._peek),this._getSpan());var r=this._index;for(this._consumeTagOpenStart(t),n=(e=this._input.substring(r,this._index)).toLowerCase(),this._attemptCharCodeUntilFn(wt);this._peek!==G&&this._peek!==H;)this._consumeAttributeName(),this._attemptCharCodeUntilFn(wt),this._attemptCharCode(V)&&(this._attemptCharCodeUntilFn(wt),this._consumeAttributeValue()),this._attemptCharCodeUntilFn(wt);this._consumeTagOpenEnd()}catch(s){if(s instanceof xt)return this._restorePosition(a),this._beginToken(ht.TEXT,t),void this._endToken(["<"]);throw s}var i=this._getTagDefinition(e).contentType;i===ct.RAW_TEXT?this._consumeRawTextWithTagClose(n,!1):i===ct.ESCAPABLE_RAW_TEXT&&this._consumeRawTextWithTagClose(n,!0)},t.prototype._consumeRawTextWithTagClose=function(t,e){var n=this,a=this._consumeRawText(e,60,function(){return!!n._attemptCharCode(G)&&(n._attemptCharCodeUntilFn(wt),!!n._attemptStrCaseInsensitive(t)&&(n._attemptCharCodeUntilFn(wt),n._attemptCharCode(H)))});this._beginToken(ht.TAG_CLOSE,a.sourceSpan.end),this._endToken([null,t])},t.prototype._consumeTagOpenStart=function(t){this._beginToken(ht.TAG_OPEN_START,t);var e=this._consumePrefixAndName();this._endToken(e)},t.prototype._consumeAttributeName=function(){this._beginToken(ht.ATTR_NAME);var t=this._consumePrefixAndName();this._endToken(t)},t.prototype._consumeAttributeValue=function(){var t;if(this._beginToken(ht.ATTR_VALUE),this._peek===j||this._peek===M){var e=this._peek;this._advance();for(var n=[];this._peek!==e;)n.push(this._readChar(!0));t=n.join(""),this._advance()}else{var a=this._index;this._requireCharCodeUntilFn(St,1),t=this._input.substring(a,this._index)}this._endToken([this._processCarriageReturns(t)])},t.prototype._consumeTagOpenEnd=function(){var t=this._attemptCharCode(G)?ht.TAG_OPEN_END_VOID:ht.TAG_OPEN_END;this._beginToken(t),this._requireCharCode(H),this._endToken([])},t.prototype._consumeTagClose=function(t){this._beginToken(ht.TAG_CLOSE,t),this._attemptCharCodeUntilFn(wt);var e=this._consumePrefixAndName();this._attemptCharCodeUntilFn(wt),this._requireCharCode(H),this._endToken(e)},t.prototype._consumeExpansionFormStart=function(){this._beginToken(ht.EXPANSION_FORM_START,this._getLocation()),this._requireCharCode(rt),this._endToken([]),this._expansionCaseStack.push(ht.EXPANSION_FORM_START),this._beginToken(ht.RAW_TEXT,this._getLocation());var t=this._readUntil(44);this._endToken([t],this._getLocation()),this._requireCharCode(44),this._attemptCharCodeUntilFn(wt),this._beginToken(ht.RAW_TEXT,this._getLocation());var e=this._readUntil(44);this._endToken([e],this._getLocation()),this._requireCharCode(44),this._attemptCharCodeUntilFn(wt)},t.prototype._consumeExpansionCaseStart=function(){this._beginToken(ht.EXPANSION_CASE_VALUE,this._getLocation());var t=this._readUntil(rt).trim();this._endToken([t],this._getLocation()),this._attemptCharCodeUntilFn(wt),this._beginToken(ht.EXPANSION_CASE_EXP_START,this._getLocation()),this._requireCharCode(rt),this._endToken([],this._getLocation()),this._attemptCharCodeUntilFn(wt),this._expansionCaseStack.push(ht.EXPANSION_CASE_EXP_START)},t.prototype._consumeExpansionCaseEnd=function(){this._beginToken(ht.EXPANSION_CASE_EXP_END,this._getLocation()),this._requireCharCode(125),this._endToken([],this._getLocation()),this._attemptCharCodeUntilFn(wt),this._expansionCaseStack.pop()},t.prototype._consumeExpansionFormEnd=function(){this._beginToken(ht.EXPANSION_FORM_END,this._getLocation()),this._requireCharCode(125),this._endToken([]),this._expansionCaseStack.pop()},t.prototype._consumeText=function(){var t=this._getLocation();this._beginToken(ht.TEXT,t);var e=[];do{this._interpolationConfig&&this._attemptStr(this._interpolationConfig.start)?(e.push(this._interpolationConfig.start),this._inInterpolation=!0):this._interpolationConfig&&this._inInterpolation&&this._attemptStr(this._interpolationConfig.end)?(e.push(this._interpolationConfig.end),this._inInterpolation=!1):e.push(this._readChar(!0))}while(!this._isTextEnd());this._endToken([this._processCarriageReturns(e.join(""))])},t.prototype._isTextEnd=function(){if(60===this._peek||this._peek===N)return!0;if(this._tokenizeIcu&&!this._inInterpolation){if(Ct(this._input,this._index,this._interpolationConfig))return!0;if(125===this._peek&&this._isInExpansionCase())return!0}return!1},t.prototype._savePosition=function(){return[this._peek,this._index,this._column,this._line,this.tokens.length]},t.prototype._readUntil=function(t){var e=this._index;return this._attemptUntilChar(t),this._input.substring(e,this._index)},t.prototype._restorePosition=function(t){this._peek=t[0],this._index=t[1],this._column=t[2],this._line=t[3];var e=t[4];e0&&this._expansionCaseStack[this._expansionCaseStack.length-1]===ht.EXPANSION_CASE_EXP_START},t.prototype._isInExpansionForm=function(){return this._expansionCaseStack.length>0&&this._expansionCaseStack[this._expansionCaseStack.length-1]===ht.EXPANSION_FORM_START},t}();function wt(t){return!st(t)||t===N}function St(t){return st(t)||t===H||t===G||t===j||t===M||t===V}function Ot(t){return t===Y||t===N||!function(t){return t>=X&&t<=J||t>=W&&t<=K||ot(t)}(t)}function It(t){return t===Y||t===N||!ut(t)}function Ct(t,e,n){var a=!!n&&t.indexOf(n.start,e)===e;return t.charCodeAt(e)===rt&&!a}function kt(t){return t>=X&&t<=at?t-X+W:t}var Nt=function(t){function e(e,n,a){var r=t.call(this,n,a)||this;return r.elementName=e,r}return Object(a.__extends)(e,t),e.create=function(t,n,a){return new e(t,n,a)},e}(O),Rt=function(){return function(t,e){this.rootNodes=t,this.errors=e}}(),At=function(){function t(t){this.getTagDefinition=t}return t.prototype.parse=function(t,e,n,a){void 0===n&&(n=!1),void 0===a&&(a=k);var r=function(t,e,n,a,r){return void 0===a&&(a=!1),void 0===r&&(r=k),new Tt(new T(t,e),n,a,r).tokenize()}(t,e,this.getTagDefinition,n,a),i=new Dt(r.tokens,this.getTagDefinition).build();return new Rt(i.rootNodes,r.errors.concat(i.errors))},t}(),Dt=function(){function t(t,e){this.tokens=t,this.getTagDefinition=e,this._index=-1,this._rootNodes=[],this._errors=[],this._elementStack=[],this._advance()}return t.prototype.build=function(){for(;this._peek.type!==ht.EOF;)this._peek.type===ht.TAG_OPEN_START?this._consumeStartTag(this._advance()):this._peek.type===ht.TAG_CLOSE?this._consumeEndTag(this._advance()):this._peek.type===ht.CDATA_START?(this._closeVoidElement(),this._consumeCdata(this._advance())):this._peek.type===ht.COMMENT_START?(this._closeVoidElement(),this._consumeComment(this._advance())):this._peek.type===ht.TEXT||this._peek.type===ht.RAW_TEXT||this._peek.type===ht.ESCAPABLE_RAW_TEXT?(this._closeVoidElement(),this._consumeText(this._advance())):this._peek.type===ht.EXPANSION_FORM_START?this._consumeExpansion(this._advance()):this._advance();return new Rt(this._rootNodes,this._errors)},t.prototype._advance=function(){var t=this._peek;return this._index0)return this._errors=this._errors.concat(i.errors),null;var s=new w(e.sourceSpan.start,r.sourceSpan.end),o=new w(n.sourceSpan.start,r.sourceSpan.end);return new u(e.parts[0],i.rootNodes,s,e.sourceSpan,o)},t.prototype._collectExpansionExpTokens=function(t){for(var e=[],n=[ht.EXPANSION_CASE_EXP_START];;){if(this._peek.type!==ht.EXPANSION_FORM_START&&this._peek.type!==ht.EXPANSION_CASE_EXP_START||n.push(this._peek.type),this._peek.type===ht.EXPANSION_CASE_EXP_END){if(!Et(n,ht.EXPANSION_CASE_EXP_START))return this._errors.push(Nt.create(null,t.sourceSpan,"Invalid ICU message. Missing '}'.")),null;if(n.pop(),0===n.length)return e}if(this._peek.type===ht.EXPANSION_FORM_END){if(!Et(n,ht.EXPANSION_FORM_START))return this._errors.push(Nt.create(null,t.sourceSpan,"Invalid ICU message. Missing '}'.")),null;n.pop()}if(this._peek.type===ht.EOF)return this._errors.push(Nt.create(null,t.sourceSpan,"Invalid ICU message. Missing '}'.")),null;e.push(this._advance())}},t.prototype._consumeText=function(t){var e=t.parts[0];if(e.length>0&&"\n"===e[0]){var n=this._getParentElement();null!==n&&0===n.children.length&&this.getTagDefinition(n.name).ignoreFirstLf&&(e=e.substring(1))}e.length>0&&this._addToParent(new s(e,t.sourceSpan))},t.prototype._closeVoidElement=function(){var t=this._getParentElement();t&&this.getTagDefinition(t.name).isVoid&&this._elementStack.pop()},t.prototype._consumeStartTag=function(t){for(var e=t.parts[0],n=t.parts[1],a=[];this._peek.type===ht.ATTR_NAME;)a.push(this._consumeAttr(this._advance()));var r=this._getElementFullName(e,n,this._getParentElement()),i=!1;if(this._peek.type===ht.TAG_OPEN_END_VOID){this._advance(),i=!0;var s=this.getTagDefinition(r);s.canSelfClose||null!==dt(r)||s.isVoid||this._errors.push(Nt.create(r,t.sourceSpan,'Only void and foreign elements can be self closed "'+t.parts[1]+'"'))}else this._peek.type===ht.TAG_OPEN_END&&(this._advance(),i=!1);var o=new w(t.sourceSpan.start,this._peek.sourceSpan.start),u=new l(r,a,[],o,o,void 0);this._pushElement(u),i&&(this._popElement(r),u.endSourceSpan=o)},t.prototype._pushElement=function(t){var e=this._getParentElement();e&&this.getTagDefinition(e.name).isClosedByChild(t.name)&&this._elementStack.pop();var n=this.getTagDefinition(t.name),a=this._getParentElementSkippingContainers(),r=a.parent,i=a.container;if(r&&n.requireExtraParent(r.name)){var s=new l(n.parentToAdd,[],[],t.sourceSpan,t.startSourceSpan,t.endSourceSpan);this._insertBeforeContainer(r,i,s)}this._addToParent(t),this._elementStack.push(t)},t.prototype._consumeEndTag=function(t){var e=this._getElementFullName(t.parts[0],t.parts[1],this._getParentElement());this._getParentElement()&&(this._getParentElement().endSourceSpan=t.sourceSpan),this.getTagDefinition(e).isVoid?this._errors.push(Nt.create(e,t.sourceSpan,'Void elements do not have end tags "'+t.parts[1]+'"')):this._popElement(e)||this._errors.push(Nt.create(e,t.sourceSpan,'Unexpected closing tag "'+e+'". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags'))},t.prototype._popElement=function(t){for(var e=this._elementStack.length-1;e>=0;e--){var n=this._elementStack[e];if(n.name===t)return this._elementStack.splice(e,this._elementStack.length-e),!0;if(!this.getTagDefinition(n.name).closedByParent)return!1}return!1},t.prototype._consumeAttr=function(t){var e=ft(t.parts[0],t.parts[1]),n=t.sourceSpan.end,a="",r=void 0;if(this._peek.type===ht.ATTR_VALUE){var i=this._advance();a=i.parts[0],n=i.sourceSpan.end,r=i.sourceSpan}return new c(e,a,new w(t.sourceSpan.start,n),r)},t.prototype._getParentElement=function(){return this._elementStack.length>0?this._elementStack[this._elementStack.length-1]:null},t.prototype._getParentElementSkippingContainers=function(){for(var t=null,e=this._elementStack.length-1;e>=0;e--){if("ng-container"!==lt(this._elementStack[e].name)[1])return{parent:this._elementStack[e],container:t};t=this._elementStack[e]}return{parent:null,container:t}},t.prototype._addToParent=function(t){var e=this._getParentElement();null!==e?e.children.push(t):this._rootNodes.push(t)},t.prototype._insertBeforeContainer=function(t,e,n){if(e){if(t){var a=t.children.indexOf(e);t.children[a]=n}else this._rootNodes.push(n);n.children.push(e),this._elementStack.splice(this._elementStack.indexOf(e),0,n)}else this._addToParent(n),this._elementStack.push(n)},t.prototype._getElementFullName=function(t,e,n){return null===t&&null===(t=this.getTagDefinition(e).implicitNamespacePrefix)&&null!==n&&(t=dt(n.name)),ft(t,e)},t}();function Et(t,e){return t.length>0&&t[t.length-1]===e}var Lt=new(function(){function t(){this.closedByParent=!1,this.contentType=ct.PARSABLE_DATA,this.isVoid=!1,this.ignoreFirstLf=!1,this.canSelfClose=!0}return t.prototype.requireExtraParent=function(t){return!1},t.prototype.isClosedByChild=function(t){return!1},t}());function Pt(t){return Lt}var Mt=function(){function t(t){var e=void 0===t?{}:t,n=e.closedByChildren,a=e.requiredParents,r=e.implicitNamespacePrefix,i=e.contentType,s=void 0===i?ct.PARSABLE_DATA:i,o=e.closedByParent,u=void 0!==o&&o,c=e.isVoid,l=void 0!==c&&c,d=e.ignoreFirstLf,f=void 0!==d&&d,p=this;this.closedByChildren={},this.closedByParent=!1,this.canSelfClose=!1,n&&n.length>0&&n.forEach(function(t){return p.closedByChildren[t]=!0}),this.isVoid=l,this.closedByParent=u||l,a&&a.length>0&&(this.requiredParents={},this.parentToAdd=a[0],a.forEach(function(t){return p.requiredParents[t]=!0})),this.implicitNamespacePrefix=r||null,this.contentType=s,this.ignoreFirstLf=f}return t.prototype.requireExtraParent=function(t){if(!this.requiredParents)return!1;if(!t)return!0;var e=t.toLowerCase();return!("template"===e||"ng-template"===t)&&!0!==this.requiredParents[e]},t.prototype.isClosedByChild=function(t){return this.isVoid||t.toLowerCase()in this.closedByChildren},t}(),qt={base:new Mt({isVoid:!0}),meta:new Mt({isVoid:!0}),area:new Mt({isVoid:!0}),embed:new Mt({isVoid:!0}),link:new Mt({isVoid:!0}),img:new Mt({isVoid:!0}),input:new Mt({isVoid:!0}),param:new Mt({isVoid:!0}),hr:new Mt({isVoid:!0}),br:new Mt({isVoid:!0}),source:new Mt({isVoid:!0}),track:new Mt({isVoid:!0}),wbr:new Mt({isVoid:!0}),p:new Mt({closedByChildren:["address","article","aside","blockquote","div","dl","fieldset","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","main","nav","ol","p","pre","section","table","ul"],closedByParent:!0}),thead:new Mt({closedByChildren:["tbody","tfoot"]}),tbody:new Mt({closedByChildren:["tbody","tfoot"],closedByParent:!0}),tfoot:new Mt({closedByChildren:["tbody"],closedByParent:!0}),tr:new Mt({closedByChildren:["tr"],requiredParents:["tbody","tfoot","thead"],closedByParent:!0}),td:new Mt({closedByChildren:["td","th"],closedByParent:!0}),th:new Mt({closedByChildren:["td","th"],closedByParent:!0}),col:new Mt({requiredParents:["colgroup"],isVoid:!0}),svg:new Mt({implicitNamespacePrefix:"svg"}),math:new Mt({implicitNamespacePrefix:"math"}),li:new Mt({closedByChildren:["li"],closedByParent:!0}),dt:new Mt({closedByChildren:["dt","dd"]}),dd:new Mt({closedByChildren:["dt","dd"],closedByParent:!0}),rb:new Mt({closedByChildren:["rb","rt","rtc","rp"],closedByParent:!0}),rt:new Mt({closedByChildren:["rb","rt","rtc","rp"],closedByParent:!0}),rtc:new Mt({closedByChildren:["rb","rtc","rp"],closedByParent:!0}),rp:new Mt({closedByChildren:["rb","rt","rtc","rp"],closedByParent:!0}),optgroup:new Mt({closedByChildren:["optgroup"],closedByParent:!0}),option:new Mt({closedByChildren:["option","optgroup"],closedByParent:!0}),pre:new Mt({ignoreFirstLf:!0}),listing:new Mt({ignoreFirstLf:!0}),style:new Mt({contentType:ct.RAW_TEXT}),script:new Mt({contentType:ct.RAW_TEXT}),title:new Mt({contentType:ct.ESCAPABLE_RAW_TEXT}),textarea:new Mt({contentType:ct.ESCAPABLE_RAW_TEXT,ignoreFirstLf:!0})},jt=new Mt;function Ft(t){return qt[t.toLowerCase()]||jt}var zt=function(t){function e(e,n){var a=t.call(this)||this;return a.mapName=n,a.internalToPublic={},a.publicToNextId={},a.publicToInternal={},e.nodes.forEach(function(t){return t.visit(a)}),a}return Object(a.__extends)(e,t),e.prototype.toPublicName=function(t){return this.internalToPublic.hasOwnProperty(t)?this.internalToPublic[t]:null},e.prototype.toInternalName=function(t){return this.publicToInternal.hasOwnProperty(t)?this.publicToInternal[t]:null},e.prototype.visitText=function(t,e){return null},e.prototype.visitTagPlaceholder=function(e,n){this.visitPlaceholderName(e.startName),t.prototype.visitTagPlaceholder.call(this,e,n),this.visitPlaceholderName(e.closeName)},e.prototype.visitPlaceholder=function(t,e){this.visitPlaceholderName(t.name)},e.prototype.visitIcuPlaceholder=function(t,e){this.visitPlaceholderName(t.name)},e.prototype.visitPlaceholderName=function(t){if(t&&!this.internalToPublic.hasOwnProperty(t)){var e=this.mapName(t);if(this.publicToInternal.hasOwnProperty(e)){var n=this.publicToNextId[e];this.publicToNextId[e]=n+1,e=e+"_"+n}else this.publicToNextId[e]=1;this.internalToPublic[t]=e,this.publicToInternal[e]=t}},e}(_),Gt=new r.I18nSelectPipe,Yt=function(){function t(t,e){this.params=e,this.i18nPluralPipe=new r.I18nPluralPipe(new r.NgLocaleLocalization(t))}return t.prototype.visitElement=function(t,e){return Ft(t.name).isVoid?"<"+t.name+this.serializeNodes(t.attrs," ")+"/>":"<"+t.name+this.serializeNodes(t.attrs," ")+">"+this.serializeNodes(t.children)+""},t.prototype.visitAttribute=function(t,e){return t.name+'="'+t.value+'"'},t.prototype.visitText=function(t,e){return t.value},t.prototype.visitComment=function(t,e){return"\x3c!--"+t.value+"--\x3e"},t.prototype.visitExpansion=function(t,e){var n=this,a={};switch(t.cases.forEach(function(t){return a[t.value]=n.serializeNodes(t.expression)}),t.type){case"select":return Gt.transform(this.params[t.switchValue]||"",a);case"plural":return this.i18nPluralPipe.transform(this.params[t.switchValue],a)}throw new Error('Unknown expansion type "'+t.type+'"')},t.prototype.visitExpansionCase=function(t,e){return" "+t.value+" {"+this.serializeNodes(t.expression)+"}"},t.prototype.serializeNodes=function(t,e){var n=this;return void 0===e&&(e=""),0===t.length?"":e+t.map(function(t){return t.visit(n,null)}).join(e)},t}();function Vt(t){return t.id||function(t){var e,n,r=oe(t),i=function(t,e){for(var n=Array(t.length+3>>>2),a=0;a>5]|=128<<24-s%32,i[15+(s+64>>9<<4)]=s;for(var h=0;h>>4).toString(16)+(15&a).toString(16)}return e.toLowerCase()}(re([c,l,d,f,p]))}((e=t.nodes,e.map(function(t){return t.visit(Bt,null)})).join("")+"["+t.meaning+"]");var e}var Ht=function(){function t(){}return t.prototype.visitText=function(t,e){return t.value},t.prototype.visitContainer=function(t,e){var n=this;return"["+t.children.map(function(t){return t.visit(n)}).join(", ")+"]"},t.prototype.visitIcu=function(t,e){var n=this,a=Object.keys(t.cases).map(function(e){return e+" {"+t.cases[e].visit(n)+"}"});return"{"+t.expression+", "+t.type+", "+a.join(", ")+"}"},t.prototype.visitTagPlaceholder=function(t,e){var n=this;return t.isVoid?'':''+t.children.map(function(t){return t.visit(n)}).join(", ")+''},t.prototype.visitPlaceholder=function(t,e){return t.value?''+t.value+"":''},t.prototype.visitIcuPlaceholder=function(t,e){return''+t.value.visit(this)+""},t}(),Bt=new Ht,Ut=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.visitIcu=function(t,e){var n=this,a=Object.keys(t.cases).map(function(e){return e+" {"+t.cases[e].visit(n)+"}"});return"{"+t.type+", "+a.join(", ")+"}"},e}(Ht);function Wt(t,e,n,a){return t<20?[e&n|~e&a,1518500249]:t<40?[e^n^a,1859775393]:t<60?[e&n|e&a|n&a,2400959708]:[e^n^a,3395469782]}function Kt(t){var e=oe(t),n=Object(a.__read)([$t(e,0),$t(e,102072)],2),r=n[0],i=n[1];return 0!==r||0!==i&&1!==i||(r^=319790063,i^=-1801410264),[r,i]}function $t(t,e){var n,r,i=Object(a.__read)([2654435769,2654435769],2),s=i[0],o=i[1],u=t.length;for(n=0;n+12<=u;n+=12)s=Jt(s,ae(t,n,Xt.Little)),o=Jt(o,ae(t,n+4,Xt.Little)),e=Jt(e,ae(t,n+8,Xt.Little)),s=(r=Object(a.__read)(Zt([s,o,e]),3))[0],o=r[1],e=r[2];return s=Jt(s,ae(t,n,Xt.Little)),o=Jt(o,ae(t,n+4,Xt.Little)),e=Jt(e,u),Zt([s,o,e=Jt(e,ae(t,n+8,Xt.Little)<<8)])[2]}function Zt(t){var e=Object(a.__read)(t,3),n=e[0],r=e[1],i=e[2];return n=te(n,r),n=te(n,i),n^=i>>>13,r=te(r,i),r=te(r,n),r^=n<<8,i=te(i,n),i=te(i,r),i^=r>>>13,n=te(n,r),n=te(n,i),n^=i>>>12,r=te(r,i),r=te(r,n),r^=n<<16,i=te(i,n),i=te(i,r),i^=r>>>5,n=te(n,r),n=te(n,i),n^=i>>>3,r=te(r,i),r=te(r,n),r^=n<<10,i=te(i,n),i=te(i,r),[n,r,i^=r>>>15]}var Xt=function(){var t={Little:0,Big:1};return t[t.Little]="Little",t[t.Big]="Big",t}();function Jt(t,e){return Qt(t,e)[1]}function Qt(t,e){var n=(65535&t)+(65535&e),a=(t>>>16)+(e>>>16)+(n>>>16);return[a>>>16,a<<16|65535&n]}function te(t,e){var n=(65535&t)-(65535&e);return(t>>16)-(e>>16)+(n>>16)<<16|65535&n}function ee(t,e){return t<>>32-e}function ne(t,e){return e>=t.length?0:255&t.charCodeAt(e)}function ae(t,e,n){var a=0;if(n===Xt.Big)for(var r=0;r<4;r++)a+=ne(t,e+r)<<24-8*r;else for(r=0;r<4;r++)a+=ne(t,e+r)<<8*r;return a}function re(t){return t.reduce(function(t,e){return t+function(t){for(var e="",n=0;n<4;n++)e+=String.fromCharCode(t>>>8*(3-n)&255);return e}(e)},"")}function ie(t,e){for(var n="",a=Math.max(t.length,e.length),r=0,i=0;r=10?(i=1,n+=s-10):(i=0,n+=s)}return n}function se(t,e){for(var n="",a=e;0!==t;t>>>=1)1&t&&(n=ie(n,a)),a=ie(a,a);return n}function oe(t){for(var e="",n=0;n=55296&&a<=56319&&t.length>n+1){var r=t.charCodeAt(n+1);r>=56320&&r<=57343&&(n++,a=(a-55296<<10)+r-56320+65536)}a<=127?e+=String.fromCharCode(a):a<=2047?e+=String.fromCharCode(a>>6&31|192,63&a|128):a<=65535?e+=String.fromCharCode(a>>12|224,a>>6&63|128,63&a|128):a<=2097151&&(e+=String.fromCharCode(a>>18&7|240,a>>12&63|128,a>>6&63|128,63&a|128))}return e}function ue(t){var e=(new le).parse(t),n=e.msgIdToHtml,r=e.errors,i={},s=new de;if(Object.keys(n).forEach(function(t){var e=s.convert(n[t]),o=e.i18nNodes,u=e.errors;r.push.apply(r,Object(a.__spread)(u)),i[t]=o}),r.length)throw new Error("xliff parse errors:\n"+r.join("\n"));return i}var ce=Vt,le=function(){function t(){}return t.prototype.parse=function(t){this._unitMlString=null,this._msgIdToHtml={};var e=new At(Pt).parse(t,"",!1);return this._errors=e.errors,f(this,e.rootNodes,null),{msgIdToHtml:this._msgIdToHtml,errors:this._errors}},t.prototype.visitElement=function(t,e){switch(t.name){case"trans-unit":this._unitMlString=null;var n=t.attrs.find(function(t){return"id"===t.name});if(n){var a=n.value;this._msgIdToHtml.hasOwnProperty(a)?this._addError(t,"Duplicated translations for msg "+a):(f(this,t.children,null),"string"==typeof this._unitMlString?this._msgIdToHtml[a]=this._unitMlString:this._addError(t,"Message "+a+" misses a translation"))}else this._addError(t,' misses the "id" attribute');break;case"source":break;case"target":var r=t.startSourceSpan.start.file.content.slice(t.startSourceSpan.end.offset,t.endSourceSpan.start.offset);this._unitMlString=r;break;case"file":f(this,t.children,null);break;default:f(this,t.children,null)}},t.prototype.visitAttribute=function(t,e){},t.prototype.visitText=function(t,e){},t.prototype.visitComment=function(t,e){},t.prototype.visitExpansion=function(t,e){},t.prototype.visitExpansionCase=function(t,e){},t.prototype._addError=function(t,e){this._errors.push(new I(t.sourceSpan,e))},t}(),de=function(){function t(){}return t.prototype.convert=function(t){var e=new At(Pt).parse(t,"",!0);return this._errors=e.errors,{i18nNodes:this._errors.length>0||0===e.rootNodes.length?[]:f(this,e.rootNodes),errors:this._errors}},t.prototype.visitText=function(t,e){return new h(t.value,t.sourceSpan)},t.prototype.visitElement=function(t,e){if("x"===t.name){var n=t.attrs.find(function(t){return"id"===t.name});if(n)return new y("",n.value,t.sourceSpan);this._addError(t,' misses the "id" attribute')}else this._addError(t,"Unexpected tag");return null},t.prototype.visitExpansion=function(t,e){var n={};return f(this,t.cases).forEach(function(e){n[e.value]=new g(e.nodes,t.sourceSpan)}),new b(t.switchValue,t.type,n,t.sourceSpan)},t.prototype.visitExpansionCase=function(t,e){return{value:t.value,nodes:f(this,t.expression)}},t.prototype.visitComment=function(t,e){},t.prototype.visitAttribute=function(t,e){},t.prototype._addError=function(t,e){this._errors.push(new I(t.sourceSpan,e))},t}();function fe(t){var e=(new he).parse(t),n=e.msgIdToHtml,r=e.errors,i={},s=new ge;if(Object.keys(n).forEach(function(t){var e=s.convert(n[t]),o=e.i18nNodes,u=e.errors;r.push.apply(r,Object(a.__spread)(u)),i[t]=o}),r.length)throw new Error("xliff2 parse errors:\n"+r.join("\n"));return i}var pe=function(t){if(t.id)return t.id;var e=new Ut;return function(t,e){var n,r=Object(a.__read)(Kt(t),2),i=r[0],s=r[1];if(e){var o=Object(a.__read)(Kt(e),2),u=o[0],c=o[1];i=(n=Object(a.__read)(function(t,e){var n=Object(a.__read)(t,2),r=n[0],i=n[1],s=Object(a.__read)(e,2),o=s[0],u=s[1],c=Object(a.__read)(Qt(i,u),2),l=c[0],d=c[1];return[Jt(Jt(r,o),l),d]}(function(t,e){var n=Object(a.__read)(t,2),r=n[0],i=n[1];return[r<<1|i>>>31,i<<1|r>>>31]}([i,s]),[u,c]),2))[0],s=n[1]}return function(t){for(var e="",n="1",a=t.length-1;a>=0;a--)e=ie(e,se(ne(t,a),n)),n=se(256,n);return e.split("").reverse().join("")}(re([2147483647&i,s]))}(t.nodes.map(function(t){return t.visit(e,null)}).join(""),t.meaning)},he=function(){function t(){}return t.prototype.parse=function(t){this._unitMlString=null,this._msgIdToHtml={};var e=new At(Pt).parse(t,"",!1);return this._errors=e.errors,f(this,e.rootNodes,null),{msgIdToHtml:this._msgIdToHtml,errors:this._errors}},t.prototype.visitElement=function(t,e){switch(t.name){case"unit":this._unitMlString=null;var n=t.attrs.find(function(t){return"id"===t.name});if(n){var a=n.value;this._msgIdToHtml.hasOwnProperty(a)?this._addError(t,"Duplicated translations for msg "+a):(f(this,t.children,null),"string"==typeof this._unitMlString?this._msgIdToHtml[a]=this._unitMlString:this._addError(t,"Message "+a+" misses a translation"))}else this._addError(t,' misses the "id" attribute');break;case"source":break;case"target":var r=t.startSourceSpan.start.file.content.slice(t.startSourceSpan.end.offset,t.endSourceSpan.start.offset);this._unitMlString=r;break;case"xliff":var i=t.attrs.find(function(t){return"version"===t.name});if(i){var s=i.value;"2.0"!==s?this._addError(t,"The XLIFF file version "+s+" is not compatible with XLIFF 2.0 serializer"):f(this,t.children,null)}break;default:f(this,t.children,null)}},t.prototype.visitAttribute=function(t,e){},t.prototype.visitText=function(t,e){},t.prototype.visitComment=function(t,e){},t.prototype.visitExpansion=function(t,e){},t.prototype.visitExpansionCase=function(t,e){},t.prototype._addError=function(t,e){this._errors.push(new I(t.sourceSpan,e))},t}(),ge=function(){function t(){}return t.prototype.convert=function(t){var e=new At(Pt).parse(t,"",!0);return this._errors=e.errors,{i18nNodes:this._errors.length>0||0===e.rootNodes.length?[]:[].concat.apply([],Object(a.__spread)(f(this,e.rootNodes))),errors:this._errors}},t.prototype.visitText=function(t,e){return new h(t.value,t.sourceSpan)},t.prototype.visitElement=function(t,e){var n=this;switch(t.name){case"ph":var r=t.attrs.find(function(t){return"equiv"===t.name});if(r)return[new y("",r.value,t.sourceSpan)];this._addError(t,' misses the "equiv" attribute');break;case"pc":var i=t.attrs.find(function(t){return"equivStart"===t.name}),s=t.attrs.find(function(t){return"equivEnd"===t.name});if(i){if(s){var o=i.value,u=s.value,c=[];return c.concat.apply(c,Object(a.__spread)([new y("",o,t.sourceSpan)],t.children.map(function(t){return t.visit(n,null)}),[new y("",u,t.sourceSpan)]))}this._addError(t,' misses the "equivEnd" attribute')}else this._addError(t,' misses the "equivStart" attribute');break;default:this._addError(t,"Unexpected tag")}return null},t.prototype.visitExpansion=function(t,e){var n={};return f(this,t.cases).forEach(function(e){n[e.value]=new g(e.nodes,t.sourceSpan)}),new b(t.switchValue,t.type,n,t.sourceSpan)},t.prototype.visitExpansionCase=function(t,e){return{value:t.value,nodes:[].concat.apply([],Object(a.__spread)(f(this,t.expression)))}},t.prototype.visitComment=function(t,e){},t.prototype.visitAttribute=function(t,e){},t.prototype._addError=function(t,e){this._errors.push(new I(t.sourceSpan,e))},t}();function be(t){return t.toUpperCase().replace(/[^A-Z0-9_]/g,"_")}function me(t){var e=(new _e).parse(t),n=e.msgIdToHtml,a=e.errors;if(a.length)throw new Error("xtb parse errors:\n"+a.join("\n"));var r={},i=new xe;return Object.keys(n).forEach(function(t){var e,a;e=r,a=t,Object.defineProperty(e,a,{configurable:!0,enumerable:!0,get:function(){var r=function(){var e=i.convert(n[t]),a=e.i18nNodes,r=e.errors;if(r.length)throw new Error("xtb parse errors:\n"+r.join("\n"));return a}();return Object.defineProperty(e,a,{enumerable:!0,value:r}),r},set:function(t){throw new Error("Could not overwrite an XTB translation")}})}),r}var ye=Vt,ve=function(t){return new zt(t,be)},_e=function(){function t(){}return t.prototype.parse=function(t){this._bundleDepth=0,this._msgIdToHtml={};var e=new At(Pt).parse(t,"",!1);return this._errors=e.errors,f(this,e.rootNodes),{msgIdToHtml:this._msgIdToHtml,errors:this._errors}},t.prototype.visitElement=function(t,e){switch(t.name){case"translationbundle":this._bundleDepth++,this._bundleDepth>1&&this._addError(t," elements can not be nested"),f(this,t.children,null),this._bundleDepth--;break;case"translation":var n=t.attrs.find(function(t){return"id"===t.name});if(n){var a=n.value;if(this._msgIdToHtml.hasOwnProperty(a))this._addError(t,"Duplicated translations for msg "+a);else{var r=t.startSourceSpan.start.file.content.slice(t.startSourceSpan.end.offset,t.endSourceSpan.start.offset);this._msgIdToHtml[a]=r}}else this._addError(t,' misses the "id" attribute');break;default:this._addError(t,"Unexpected tag")}},t.prototype.visitAttribute=function(t,e){},t.prototype.visitText=function(t,e){},t.prototype.visitComment=function(t,e){},t.prototype.visitExpansion=function(t,e){},t.prototype.visitExpansionCase=function(t,e){},t.prototype._addError=function(t,e){this._errors.push(new I(t.sourceSpan,e))},t}(),xe=function(){function t(){}return t.prototype.convert=function(t){var e=new At(Pt).parse(t,"",!0);return this._errors=e.errors,{i18nNodes:this._errors.length>0||0===e.rootNodes.length?[]:f(this,e.rootNodes),errors:this._errors}},t.prototype.visitText=function(t,e){return new h(t.value,t.sourceSpan)},t.prototype.visitExpansion=function(t,e){var n={};return f(this,t.cases).forEach(function(e){n[e.value]=new g(e.nodes,t.sourceSpan)}),new b(t.switchValue,t.type,n,t.sourceSpan)},t.prototype.visitExpansionCase=function(t,e){return{value:t.value,nodes:f(this,t.expression)}},t.prototype.visitElement=function(t,e){if("ph"===t.name){var n=t.attrs.find(function(t){return"name"===t.name});if(n)return new y("",n.value,t.sourceSpan);this._addError(t,' misses the "name" attribute')}else this._addError(t,"Unexpected tag");return null},t.prototype.visitComment=function(t,e){},t.prototype.visitAttribute=function(t,e){},t.prototype._addError=function(t,e){this._errors.push(new I(t.sourceSpan,e))},t}(),Te=function(){return function(t,e,n,a){this.input=e,this.errLocation=n,this.ctxLocation=a,this.message="Parser Error: "+t+" "+n+" ["+e+"] in "+a}}(),we=function(){return function(t,e){this.start=t,this.end=e}}(),Se=function(){function t(t){this.span=t}return t.prototype.visit=function(t,e){return void 0===e&&(e=null),null},t.prototype.toString=function(){return"AST"},t}(),Oe=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.prefix=n,i.uninterpretedExpression=a,i.location=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitQuote(this,e)},e.prototype.toString=function(){return"Quote"},e}(Se),Ie=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){void 0===e&&(e=null)},e}(Se),Ce=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitImplicitReceiver(this,e)},e}(Se),ke=function(t){function e(e,n){var a=t.call(this,e)||this;return a.expressions=n,a}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitChain(this,e)},e}(Se),Ne=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.condition=n,i.trueExp=a,i.falseExp=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitConditional(this,e)},e}(Se),Re=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.receiver=n,r.name=a,r}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPropertyRead(this,e)},e}(Se),Ae=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.receiver=n,i.name=a,i.value=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPropertyWrite(this,e)},e}(Se),De=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.receiver=n,r.name=a,r}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitSafePropertyRead(this,e)},e}(Se),Ee=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.obj=n,r.key=a,r}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitKeyedRead(this,e)},e}(Se),Le=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.obj=n,i.key=a,i.value=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitKeyedWrite(this,e)},e}(Se),Pe=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.exp=n,i.name=a,i.args=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPipe(this,e)},e}(Se),Me=function(t){function e(e,n){var a=t.call(this,e)||this;return a.value=n,a}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitLiteralPrimitive(this,e)},e}(Se),qe=function(t){function e(e,n){var a=t.call(this,e)||this;return a.expressions=n,a}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitLiteralArray(this,e)},e}(Se),je=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.keys=n,r.values=a,r}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitLiteralMap(this,e)},e}(Se),Fe=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.strings=n,r.expressions=a,r}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitInterpolation(this,e)},e}(Se),ze=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.operation=n,i.left=a,i.right=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitBinary(this,e)},e}(Se),Ge=function(t){function e(e,n){var a=t.call(this,e)||this;return a.expression=n,a}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitPrefixNot(this,e)},e}(Se),Ye=function(t){function e(e,n){var a=t.call(this,e)||this;return a.expression=n,a}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitNonNullAssert(this,e)},e}(Se),Ve=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.receiver=n,i.name=a,i.args=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitMethodCall(this,e)},e}(Se),He=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.receiver=n,i.name=a,i.args=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitSafeMethodCall(this,e)},e}(Se),Be=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.target=n,r.args=a,r}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),t.visitFunctionCall(this,e)},e}(Se),Ue=function(t){function e(e,n,a,r){var i=t.call(this,new we(0,null==n?0:n.length))||this;return i.ast=e,i.source=n,i.location=a,i.errors=r,i}return Object(a.__extends)(e,t),e.prototype.visit=function(t,e){return void 0===e&&(e=null),this.ast.visit(t,e)},e.prototype.toString=function(){return this.source+" in "+this.location},e}(Se),We=function(){return function(t,e,n,a,r){this.span=t,this.key=e,this.keyIsVar=n,this.name=a,this.expression=r}}(),Ke=function(){var t={Character:0,Identifier:1,Keyword:2,String:3,Operator:4,Number:5,Error:6};return t[t.Character]="Character",t[t.Identifier]="Identifier",t[t.Keyword]="Keyword",t[t.String]="String",t[t.Operator]="Operator",t[t.Number]="Number",t[t.Error]="Error",t}(),$e=["var","let","as","null","undefined","true","false","if","else","this"],Ze=function(){function t(){}return t.prototype.tokenize=function(t){for(var e=new en(t),n=[],a=e.scanToken();null!=a;)n.push(a),a=e.scanToken();return n},t}(),Xe=function(){function t(t,e,n,a){this.index=t,this.type=e,this.numValue=n,this.strValue=a}return t.prototype.isCharacter=function(t){return this.type===Ke.Character&&this.numValue===t},t.prototype.isNumber=function(){return this.type===Ke.Number},t.prototype.isString=function(){return this.type===Ke.String},t.prototype.isOperator=function(t){return this.type===Ke.Operator&&this.strValue===t},t.prototype.isIdentifier=function(){return this.type===Ke.Identifier},t.prototype.isKeyword=function(){return this.type===Ke.Keyword},t.prototype.isKeywordLet=function(){return this.type===Ke.Keyword&&"let"===this.strValue},t.prototype.isKeywordAs=function(){return this.type===Ke.Keyword&&"as"===this.strValue},t.prototype.isKeywordNull=function(){return this.type===Ke.Keyword&&"null"===this.strValue},t.prototype.isKeywordUndefined=function(){return this.type===Ke.Keyword&&"undefined"===this.strValue},t.prototype.isKeywordTrue=function(){return this.type===Ke.Keyword&&"true"===this.strValue},t.prototype.isKeywordFalse=function(){return this.type===Ke.Keyword&&"false"===this.strValue},t.prototype.isKeywordThis=function(){return this.type===Ke.Keyword&&"this"===this.strValue},t.prototype.isError=function(){return this.type===Ke.Error},t.prototype.toNumber=function(){return this.type===Ke.Number?this.numValue:-1},t.prototype.toString=function(){switch(this.type){case Ke.Character:case Ke.Identifier:case Ke.Keyword:case Ke.Operator:case Ke.String:case Ke.Error:return this.strValue;case Ke.Number:return this.numValue.toString();default:return null}},t}();function Je(t,e){return new Xe(t,Ke.Character,e,String.fromCharCode(e))}function Qe(t,e){return new Xe(t,Ke.Operator,0,e)}var tn=new Xe(-1,Ke.Character,0,""),en=function(){function t(t){this.input=t,this.peek=0,this.index=-1,this.length=t.length,this.advance()}return t.prototype.advance=function(){this.peek=++this.index>=this.length?N:this.input.charCodeAt(this.index)},t.prototype.scanToken=function(){for(var t=this.input,e=this.length,n=this.peek,a=this.index;n<=P;){if(++a>=e){n=N;break}n=t.charCodeAt(a)}if(this.peek=n,this.index=a,a>=e)return null;if(nn(n))return this.scanIdentifier();if(ot(n))return this.scanNumber(a);var r=a;switch(n){case 46:return this.advance(),ot(this.peek)?this.scanNumber(r):Je(r,46);case 40:case 41:case rt:case 125:case 91:case 93:case 44:case 58:case Y:return this.scanCharacter(r,n);case j:case M:return this.scanString();case 35:case F:case z:case 42:case G:case 37:case 94:return this.scanOperator(r,String.fromCharCode(n));case 63:return this.scanComplexOperator(r,"?",46,".");case 60:case H:return this.scanComplexOperator(r,String.fromCharCode(n),V,"=");case 33:case V:return this.scanComplexOperator(r,String.fromCharCode(n),V,"=",V,"=");case 38:return this.scanComplexOperator(r,"&",38,"&");case 124:return this.scanComplexOperator(r,"|",124,"|");case it:for(;st(this.peek);)this.advance();return this.scanToken()}return this.advance(),this.error("Unexpected character ["+String.fromCharCode(n)+"]",0)},t.prototype.scanCharacter=function(t,e){return this.advance(),Je(t,e)},t.prototype.scanOperator=function(t,e){return this.advance(),Qe(t,e)},t.prototype.scanComplexOperator=function(t,e,n,a,r,i){this.advance();var s=e;return this.peek===n&&(this.advance(),s+=a),null!=r&&this.peek===r&&(this.advance(),s+=i),Qe(t,s)},t.prototype.scanIdentifier=function(){var t=this.index;for(this.advance();an(this.peek);)this.advance();var e=this.input.substring(t,this.index);return $e.indexOf(e)>-1?new Xe(t,Ke.Keyword,0,e):new Xe(t,Ke.Identifier,0,e)},t.prototype.scanNumber=function(t){var e,n=this.index===t;for(this.advance();;){if(ot(this.peek));else if(46===this.peek)n=!1;else{if(101!==(e=this.peek)&&69!==e)break;if(this.advance(),rn(this.peek)&&this.advance(),!ot(this.peek))return this.error("Invalid exponent",-1);n=!1}this.advance()}var a=this.input.substring(t,this.index),r=n?function(t){var e=parseInt(t,10);if(isNaN(e))throw new Error("Invalid integer literal when parsing "+t);return e}(a):parseFloat(a);return new Xe(t,Ke.Number,r,"")},t.prototype.scanString=function(){var t=this.index,e=this.peek;this.advance();for(var n="",a=this.index,r=this.input;this.peek!==e;)if(92===this.peek){n+=r.substring(a,this.index),this.advance();var i=void 0;if(this.peek=this.peek,117===this.peek){var s=r.substring(this.index+1,this.index+5);if(!/^[0-9a-f]+$/i.test(s))return this.error("Invalid unicode escape [\\u"+s+"]",0);i=parseInt(s,16);for(var o=0;o<5;o++)this.advance()}else i=sn(this.peek),this.advance();n+=String.fromCharCode(i),a=this.index}else{if(this.peek===N)return this.error("Unterminated quote",0);this.advance()}var u=r.substring(a,this.index);return this.advance(),new Xe(t,Ke.String,0,n+u)},t.prototype.error=function(t,e){var n=this.index+e;return function(t,e){return new Xe(n,Ke.Error,0,e)}(0,"Lexer Error: "+t+" at column "+n+" in expression ["+this.input+"]")},t}();function nn(t){return X<=t&&t<=at||W<=t&&t<=$||t===Z||t===q}function an(t){return ut(t)||ot(t)||t===Z||t===q}function rn(t){return t===z||t===F}function sn(t){switch(t){case Q:return A;case J:return E;case tt:return L;case et:return R;case nt:return D;default:return t}}var on=function(){return function(t,e,n){this.strings=t,this.expressions=e,this.offsets=n}}(),un=function(){return function(t,e,n){this.templateBindings=t,this.warnings=e,this.errors=n}}();function cn(t){var e=C(t.start)+"([\\s\\S]*?)"+C(t.end);return new RegExp(e,"g")}var ln=function(){function t(t){this._lexer=t,this.errors=[]}return t.prototype.parseAction=function(t,e,n){void 0===n&&(n=k),this._checkNoInterpolation(t,e,n);var a=this._stripComments(t),r=this._lexer.tokenize(this._stripComments(t)),i=new dn(t,e,r,a.length,!0,this.errors,t.length-a.length).parseChain();return new Ue(i,t,e,this.errors)},t.prototype.parseBinding=function(t,e,n){void 0===n&&(n=k);var a=this._parseBindingAst(t,e,n);return new Ue(a,t,e,this.errors)},t.prototype.parseSimpleBinding=function(t,e,n){void 0===n&&(n=k);var a=this._parseBindingAst(t,e,n),r=fn.check(a);return r.length>0&&this._reportError("Host binding expression cannot contain "+r.join(" "),t,e),new Ue(a,t,e,this.errors)},t.prototype._reportError=function(t,e,n,a){this.errors.push(new Te(t,e,n,a))},t.prototype._parseBindingAst=function(t,e,n){var a=this._parseQuote(t,e);if(null!=a)return a;this._checkNoInterpolation(t,e,n);var r=this._stripComments(t),i=this._lexer.tokenize(r);return new dn(t,e,i,r.length,!1,this.errors,t.length-r.length).parseChain()},t.prototype._parseQuote=function(t,e){if(null===t)return null;var n=t.indexOf(":");if(-1===n)return null;var a=t.substring(0,n).trim();if(!function(t){if(0===a.length)return!1;var e=new en(a);if(!nn(e.peek))return!1;for(e.advance();e.peek!==N;){if(!an(e.peek))return!1;e.advance()}return!0}())return null;var r=t.substring(n+1);return new Oe(new we(0,t.length),a,r,e)},t.prototype.parseTemplateBindings=function(t,e,n){var r=this._lexer.tokenize(e);if(t){var i=this._lexer.tokenize(t).map(function(t){return t.index=0,t});r.unshift.apply(r,Object(a.__spread)(i))}return new dn(e,n,r,e.length,!1,this.errors,0).parseTemplateBindings()},t.prototype.parseInterpolation=function(t,e,n){void 0===n&&(n=k);var a=this.splitInterpolation(t,e,n);if(null===a)return null;for(var r=[],i=0;i0?(u+=n.start.length,s.push(l),o.push(u),u+=l.length+n.end.length):(this._reportError("Blank expressions are not allowed in interpolated strings",t,"at column "+this._findInterpolationErrorColumn(r,c,n)+" in",e),s.push("$implict"),o.push(u))}return new on(i,s,o)},t.prototype.wrapLiteralPrimitive=function(t,e){return new Ue(new Me(new we(0,null===t?0:t.length),t),t,e,this.errors)},t.prototype._stripComments=function(t){var e=this._commentStart(t);return null!=e?t.substring(0,e).trim():t},t.prototype._commentStart=function(t){for(var e,n=null,a=0;a1&&this._reportError("Got interpolation ("+n.start+n.end+") where expression was expected",t,"at column "+this._findInterpolationErrorColumn(r,1,n)+" in",e)},t.prototype._findInterpolationErrorColumn=function(t,e,n){for(var a="",r=0;r":case"<=":case">=":this.advance();var n=this.parseAdditive();t=new ze(this.span(t.span.start),e,t,n);continue}break}return t},t.prototype.parseAdditive=function(){for(var t=this.parseMultiplicative();this.next.type===Ke.Operator;){var e=this.next.strValue;switch(e){case"+":case"-":this.advance();var n=this.parseMultiplicative();t=new ze(this.span(t.span.start),e,t,n);continue}break}return t},t.prototype.parseMultiplicative=function(){for(var t=this.parsePrefix();this.next.type===Ke.Operator;){var e=this.next.strValue;switch(e){case"*":case"%":case"/":this.advance();var n=this.parsePrefix();t=new ze(this.span(t.span.start),e,t,n);continue}break}return t},t.prototype.parsePrefix=function(){if(this.next.type===Ke.Operator){var t=this.inputIndex,e=this.next.strValue,n=void 0;switch(e){case"+":return this.advance(),this.parsePrefix();case"-":return this.advance(),n=this.parsePrefix(),new ze(this.span(t),e,new Me(new we(t,t),0),n);case"!":return this.advance(),n=this.parsePrefix(),new Ge(this.span(t),n)}}return this.parseCallChain()},t.prototype.parseCallChain=function(){for(var t=this.parsePrimary();;)if(this.optionalCharacter(46))t=this.parseAccessMemberOrMethodCall(t,!1);else if(this.optionalOperator("?."))t=this.parseAccessMemberOrMethodCall(t,!0);else if(this.optionalCharacter(91)){this.rbracketsExpected++;var e=this.parsePipe();if(this.rbracketsExpected--,this.expectCharacter(93),this.optionalOperator("=")){var n=this.parseConditional();t=new Le(this.span(t.span.start),t,e,n)}else t=new Ee(this.span(t.span.start),t,e)}else if(this.optionalCharacter(40)){this.rparensExpected++;var a=this.parseCallArguments();this.rparensExpected--,this.expectCharacter(41),t=new Be(this.span(t.span.start),t,a)}else{if(!this.optionalOperator("!"))return t;t=new Ye(this.span(t.span.start),t)}},t.prototype.parsePrimary=function(){var t=this.inputIndex;if(this.optionalCharacter(40)){this.rparensExpected++;var e=this.parsePipe();return this.rparensExpected--,this.expectCharacter(41),e}if(this.next.isKeywordNull())return this.advance(),new Me(this.span(t),null);if(this.next.isKeywordUndefined())return this.advance(),new Me(this.span(t),void 0);if(this.next.isKeywordTrue())return this.advance(),new Me(this.span(t),!0);if(this.next.isKeywordFalse())return this.advance(),new Me(this.span(t),!1);if(this.next.isKeywordThis())return this.advance(),new Ce(this.span(t));if(this.optionalCharacter(91)){this.rbracketsExpected++;var n=this.parseExpressionList(93);return this.rbracketsExpected--,this.expectCharacter(93),new qe(this.span(t),n)}if(this.next.isCharacter(rt))return this.parseLiteralMap();if(this.next.isIdentifier())return this.parseAccessMemberOrMethodCall(new Ce(this.span(t)),!1);if(this.next.isNumber()){var a=this.next.toNumber();return this.advance(),new Me(this.span(t),a)}if(this.next.isString()){var r=this.next.toString();return this.advance(),new Me(this.span(t),r)}return this.index>=this.tokens.length?(this.error("Unexpected end of expression: "+this.input),new Ie(this.span(t))):(this.error("Unexpected token "+this.next),new Ie(this.span(t)))},t.prototype.parseExpressionList=function(t){var e=[];if(!this.next.isCharacter(t))do{e.push(this.parsePipe())}while(this.optionalCharacter(44));return e},t.prototype.parseLiteralMap=function(){var t=[],e=[],n=this.inputIndex;if(this.expectCharacter(rt),!this.optionalCharacter(125)){this.rbracesExpected++;do{var a=this.next.isString(),r=this.expectIdentifierOrKeywordOrString();t.push({key:r,quoted:a}),this.expectCharacter(58),e.push(this.parsePipe())}while(this.optionalCharacter(44));this.rbracesExpected--,this.expectCharacter(125)}return new je(this.span(n),t,e)},t.prototype.parseAccessMemberOrMethodCall=function(t,e){void 0===e&&(e=!1);var n=t.span.start,a=this.expectIdentifierOrKeyword();if(this.optionalCharacter(40)){this.rparensExpected++;var r=this.parseCallArguments();this.expectCharacter(41),this.rparensExpected--;var i=this.span(n);return e?new He(i,t,a,r):new Ve(i,t,a,r)}if(e)return this.optionalOperator("=")?(this.error("The '?.' operator cannot be used in the assignment"),new Ie(this.span(n))):new De(this.span(n),t,a);if(this.optionalOperator("=")){if(!this.parseAction)return this.error("Bindings cannot contain assignments"),new Ie(this.span(n));var s=this.parseConditional();return new Ae(this.span(n),t,a,s)}return new Re(this.span(n),t,a)},t.prototype.parseCallArguments=function(){if(this.next.isCharacter(41))return[];var t=[];do{t.push(this.parsePipe())}while(this.optionalCharacter(44));return t},t.prototype.expectTemplateBindingKey=function(){var t="",e=!1;do{t+=this.expectIdentifierOrKeywordOrString(),(e=this.optionalOperator("-"))&&(t+="-")}while(e);return t.toString()},t.prototype.parseTemplateBindings=function(){for(var t=[],e=null;this.index":">")},t.prototype._hashClosingTag=function(t){return this._hashTag("/"+t,{},!1)},t.prototype._generateUniqueName=function(t){if(!this._placeHolderNameCounts.hasOwnProperty(t))return this._placeHolderNameCounts[t]=1,t;var e=this._placeHolderNameCounts[t];return this._placeHolderNameCounts[t]=e+1,t+"_"+e},t}(),gn=new ln(new Ze),bn=function(){function t(t,e){this._expressionParser=t,this._interpolationConfig=e}return t.prototype.toI18nMessage=function(t,e,n,a){this._isIcu=1===t.length&&t[0]instanceof o,this._icuDepth=0,this._placeholderRegistry=new hn,this._placeholderToContent={},this._placeholderToMessage={};var r=f(this,t,{});return new p(r,this._placeholderToContent,this._placeholderToMessage,e,n,a)},t.prototype.visitElement=function(t,e){var n=f(this,t.children),a={};t.attrs.forEach(function(t){a[t.name]=t.value});var r=Ft(t.name).isVoid,i=this._placeholderRegistry.getStartTagPlaceholderName(t.name,a,r);this._placeholderToContent[i]=t.sourceSpan?t.sourceSpan.toString():"";var s="";return r||(s=this._placeholderRegistry.getCloseTagPlaceholderName(t.name),this._placeholderToContent[s]=""),new m(t.name,a,i,s,n,r,t.sourceSpan)},t.prototype.visitAttribute=function(t,e){return this._visitTextWithInterpolation(t.value,t.sourceSpan)},t.prototype.visitText=function(t,e){return this._visitTextWithInterpolation(t.value,t.sourceSpan)},t.prototype.visitComment=function(t,e){return null},t.prototype.visitExpansion=function(e,n){var a=this;this._icuDepth++;var r={},i=new b(e.switchValue,e.type,r,e.sourceSpan);if(e.cases.forEach(function(t){r[t.value]=new g(t.expression.map(function(t){return t.visit(a,{})}),t.expSourceSpan)}),this._icuDepth--,this._isIcu||this._icuDepth>0){var s=this._placeholderRegistry.getUniquePlaceholder("VAR_"+e.type);return i.expressionPlaceholder=s,this._placeholderToContent[s]=e.switchValue,i}var o=this._placeholderRegistry.getPlaceholderName("ICU",e.sourceSpan.toString()),u=new t(this._expressionParser,this._interpolationConfig);return this._placeholderToMessage[o]=u.toI18nMessage([e],"","",""),new v(i,o,e.sourceSpan)},t.prototype.visitExpansionCase=function(t,e){throw new Error("Unreachable code")},t.prototype._visitTextWithInterpolation=function(t,e){var n=this._expressionParser.splitInterpolation(t,e.start.toString(),this._interpolationConfig);if(!n)return new h(t,e);for(var a=[],r=new g(a,e),i=this._interpolationConfig,s=i.start,o=i.end,u=0;u":"<"+a+" "+r+">"+t.children.map(function(t){return t.visit(n)}).join("")+""},t.prototype.visitIcuPlaceholder=function(t,e){return this.convertToText(this._srcMsg.placeholderToMessage[t.name])},t.prototype.convertToText=function(t){var e,n=this,a=this._digest(t),r=this._mapperFactory?this._mapperFactory(t):null;this._contextStack.push({msg:this._srcMsg,mapper:this._mapper}),this._srcMsg=t,this._i18nNodesByMsgId.hasOwnProperty(a)?(e=this._i18nNodesByMsgId[a],this._mapper=function(t){return r?r.toInternalName(t):t}):(this._missingTranslationStrategy===i.MissingTranslationStrategy.Error?this._addError(t.nodes[0],'Missing translation for message "'+a+'"'):this._console&&this._missingTranslationStrategy===i.MissingTranslationStrategy.Warning&&this._console.warn('Missing translation for message "'+a+'"'),e=t.nodes,this._mapper=function(t){return t});var s=e.map(function(t){return t.visit(n)}).join(""),o=this._contextStack.pop();return this._srcMsg=o.msg,this._mapper=o.mapper,s},t.prototype.convertToValue=function(t){var e=t.replace(this._interpolationConfig.start,"").replace(this._interpolationConfig.end,"");return-1!==this._paramKeys.indexOf(e)?this._params[e]:t},t.prototype._addError=function(t,e){this._errors.push(new I(t.sourceSpan,e))},t}(),Tn=function(){var t={Extract:0,Merge:1};return t[t.Extract]="Extract",t[t.Merge]="Merge",t}(),wn=function(){function t(t){void 0===t&&(t=[]),this._implicitTags=t,this.blockChildren=[]}return t.prototype.extract=function(t,e){return this.init(Tn.Extract,e),t.visit(this,null),this.inI18nBlock&&this._reportError(t,"Unclosed block"),new vn(this.messages,this.errors)},t.prototype.merge=function(t,e,n,a,r){void 0===r&&(r={}),this.init(Tn.Merge,n,a),this.translations=e,this.metadata=r;var i=t.visit(this,null);return this.inI18nBlock&&this._reportError(t,"Unclosed block"),new Rt(i.children,this.errors)},t.prototype.visitExpansionCase=function(t,e){var n=f(this,t.expression,e);if(this.mode===Tn.Merge)return new u(t.value,n,t.sourceSpan,t.valueSourceSpan,t.expSourceSpan)},t.prototype.visitExpansion=function(t,e){this.mayBeAddBlockChildren(t);var n=this.inIcu;this.inIcu||(this.isInTranslatableSection&&this.addMessage([t]),this.inIcu=!0);var a=f(this,t.cases,e);return this.mode===Tn.Merge&&(t=new o(t.switchValue,t.type,a,t.sourceSpan,t.switchValueSourceSpan)),this.inIcu=n,t},t.prototype.visitComment=function(t,e){},t.prototype.visitText=function(t,e){return this.isInTranslatableSection&&this.mayBeAddBlockChildren(t),t},t.prototype.visitElement=function(t,e){var n=this;this.mayBeAddBlockChildren(t),this.depth++;var a=this.inI18nNode,r=this.inImplicitNode,i=[],s=void 0,o=t.attrs.find(function(t){return"i18n"===t.name})||null,u=this._implicitTags.some(function(e){return t.name===e})&&!this.inIcu&&!this.isInTranslatableSection,c=!r&&u;if(this.inImplicitNode=r||u,this.isInTranslatableSection||this.inIcu)(o||c)&&this._reportError(t,"Could not mark an element as translatable inside a translatable section"),this.mode===Tn.Extract&&f(this,t.children);else{if(o||c){this.inI18nNode=!0;var d=this.addMessage(t.children,this.metadata);s=this.translateMessage(t,d)}if(this.mode===Tn.Extract){var p=o||c;p&&this.openTranslatableSection(t),f(this,t.children),p&&this._closeTranslatableSection(t,t.children)}}return this.mode===Tn.Merge&&(s||t.children).forEach(function(t){var a=t.visit(n,e);a&&!n.isInTranslatableSection&&(i=i.concat(a))}),this.depth--,this.inI18nNode=a,this.inImplicitNode=r,this.mode===Tn.Merge?new l(t.name,[],i,t.sourceSpan,t.startSourceSpan,t.endSourceSpan):null},t.prototype.visitAttribute=function(t,e){throw new Error("unreachable code")},t.prototype.init=function(t,e,n){void 0===n&&(n={}),this.mode=t,this.inI18nBlock=!1,this.inI18nNode=!1,this.depth=0,this.inIcu=!1,this.msgCountAtSectionStart=void 0,this.errors=[],this.messages=[],this.inImplicitNode=!1,this.createI18nMessage=function(t){var e=new bn(gn,t);return function(t,n,a,r){return e.toI18nMessage(t,n,a,r)}}(e),this.params=n},t.prototype.addMessage=function(t,e){var n=void 0===e?{}:e,a=n.meaning,r=n.description,i=n.id;if(0===t.length||1===t.length&&t[0]instanceof c&&!t[0].value)return null;var s=this.createI18nMessage(t,void 0===a?"":a,void 0===r?"":r,void 0===i?"":i);return this.messages.push(s),s},t.prototype.translateMessage=function(t,e){if(e&&this.mode===Tn.Merge){var n=this.translations.get(e,this.params);if(n)return n;this._reportError(t,'Translation unavailable for message id="'+this.translations.digest(e)+'"')}return[]},t.prototype.mayBeAddBlockChildren=function(t){this.inI18nBlock&&!this.inIcu&&this.depth===this.blockStartDepth&&this.blockChildren.push(t)},t.prototype.openTranslatableSection=function(t){this.isInTranslatableSection?this._reportError(t,"Unexpected section start"):this.msgCountAtSectionStart=this.messages.length},Object.defineProperty(t.prototype,"isInTranslatableSection",{get:function(){return void 0!==this.msgCountAtSectionStart},enumerable:!0,configurable:!0}),t.prototype._closeTranslatableSection=function(t,e){if(this.isInTranslatableSection){var n=this.msgCountAtSectionStart;if(1===e.reduce(function(t,e){return t+(e instanceof d?0:1)},0))for(var a=this.messages.length-1;a>=n;a--){var r=this.messages[a].nodes;if(!(1===r.length&&r[0]instanceof h)){this.messages.splice(a,1);break}}this.msgCountAtSectionStart=void 0}else this._reportError(t,"Unexpected section end")},t.prototype._reportError=function(t,e){this.errors.push(new I(t.sourceSpan,e))},t}(),Sn=new i.InjectionToken("MissingTranslationStrategy"),On=function(){return function(t,e,n,a){var r,s;void 0===a&&(a=i.MissingTranslationStrategy.Warning);var o=function(t){return null};switch(t=(t||"xlf").toLowerCase()){case"xtb":r=me,s=ye,o=ve;break;case"xliff2":case"xlf2":r=fe,s=pe;break;case"xliff":case"xlf":r=ue,s=ce;break;default:throw new Error("Unknown translations format "+t)}var u=new yn,c=_n.load(e,"i18n",s,o,r,a);return function(t,e){void 0===e&&(e={});var a="string"==typeof t?t:t.value,r={};"object"==typeof t&&(r.id=t.id,r.meaning=t.meaning,r.description=t.description);var i=u.parse(a,"",!0);if(i.errors.length)throw i.errors;return function(t,e,n){return t.map(function(t){return t.visit(new Yt(e,n),null)})}(u.mergeTranslations(i.rootNodes,c,e,r,["wrapper"]).rootNodes,n,e).join("")}}}()},JvlW:function(t,e,n){!function(t){"use strict";var e={ss:"sekund\u0117_sekund\u017ei\u0173_sekundes",m:"minut\u0117_minut\u0117s_minut\u0119",mm:"minut\u0117s_minu\u010di\u0173_minutes",h:"valanda_valandos_valand\u0105",hh:"valandos_valand\u0173_valandas",d:"diena_dienos_dien\u0105",dd:"dienos_dien\u0173_dienas",M:"m\u0117nuo_m\u0117nesio_m\u0117nes\u012f",MM:"m\u0117nesiai_m\u0117nesi\u0173_m\u0117nesius",y:"metai_met\u0173_metus",yy:"metai_met\u0173_metus"};function n(t,e,n,a){return e?r(n)[0]:a?r(n)[1]:r(n)[2]}function a(t){return t%10==0||t>10&&t<20}function r(t){return e[t].split("_")}function i(t,e,i,s){var o=t+" ";return 1===t?o+n(0,e,i[0],s):e?o+(a(t)?r(i)[1]:r(i)[0]):s?o+r(i)[1]:o+(a(t)?r(i)[1]:r(i)[2])}t.defineLocale("lt",{months:{format:"sausio_vasario_kovo_baland\u017eio_gegu\u017e\u0117s_bir\u017eelio_liepos_rugpj\u016b\u010dio_rugs\u0117jo_spalio_lapkri\u010dio_gruod\u017eio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegu\u017e\u0117_bir\u017eelis_liepa_rugpj\u016btis_rugs\u0117jis_spalis_lapkritis_gruodis".split("_"),isFormat:/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadien\u012f_pirmadien\u012f_antradien\u012f_tre\u010diadien\u012f_ketvirtadien\u012f_penktadien\u012f_\u0161e\u0161tadien\u012f".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_tre\u010diadienis_ketvirtadienis_penktadienis_\u0161e\u0161tadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_\u0160e\u0161".split("_"),weekdaysMin:"S_P_A_T_K_Pn_\u0160".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[\u0160iandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Pra\u0117jus\u012f] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prie\u0161 %s",s:function(t,e,n,a){return e?"kelios sekund\u0117s":a?"keli\u0173 sekund\u017ei\u0173":"kelias sekundes"},ss:i,m:n,mm:i,h:n,hh:i,d:n,dd:i,M:n,MM:i,y:n,yy:i},dayOfMonthOrdinalParse:/\d{1,2}-oji/,ordinal:function(t){return t+"-oji"},week:{dow:1,doy:4}})}(n("wd/R"))},JxMD:function(t,e,n){"use strict";var a=n("CcnG"),r=n("Ip0R"),i=n("xdbM");n("dgut"),n("Fgil"),n.d(e,"a",function(){return s}),n.d(e,"b",function(){return o});var s=a["\u0275crt"]({encapsulation:0,styles:[["canvas[_ngcontent-%COMP%]{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.chartjs-tooltip[_ngcontent-%COMP%]{opacity:0;position:absolute;background:rgba(0,0,0,.7);color:#fff;border-radius:3px;-webkit-transition:.1s;transition:all .1s ease;pointer-events:none;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif!important;-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]{-webkit-transform:translate(-10%,0);transform:translate(-10%,0)}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]::after{left:10%}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]{-webkit-transform:translate(-90%,0);transform:translate(-90%,0)}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]::after{left:90%}.chartjs-tooltip[_ngcontent-%COMP%]::after{content:' ';position:absolute;top:100%;left:50%;margin-left:-5px;border-width:5px;border-style:solid;border-color:#000 transparent transparent} .chartjs-tooltip-key{display:inline-block;width:10px;height:10px;margin-right:10px}.chart-container[_ngcontent-%COMP%]{margin:auto;cursor:pointer;overflow:visible;position:static!important}"]],data:{}});function o(t){return a["\u0275vid"](0,[a["\u0275qud"](402653184,1,{chartCanvasRef:0}),a["\u0275qud"](402653184,2,{chartTooltipRef:0}),(t()(),a["\u0275eld"](2,0,null,null,5,"div",[["class","chart-container"]],null,null,null,null,null)),a["\u0275did"](3,278528,null,0,r.NgStyle,[a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngStyle:[0,"ngStyle"]},null),(t()(),a["\u0275eld"](4,0,[[1,0],["sparkCanvas",1]],null,1,"canvas",[["baseChart",""]],null,null,null,null,null)),a["\u0275did"](5,737280,null,0,i.BaseChartDirective,[a.ElementRef],{datasets:[0,"datasets"],labels:[1,"labels"],options:[2,"options"],chartType:[3,"chartType"],colors:[4,"colors"]},null),(t()(),a["\u0275eld"](6,0,[[2,0],["sparkTooltip",1]],null,1,"div",[["class","chartjs-tooltip"]],null,null,null,null,null)),(t()(),a["\u0275eld"](7,0,null,null,0,"table",[],null,null,null,null,null))],function(t,e){var n=e.component;t(e,3,0,n.style),t(e,5,0,n.datasets,n.labels,n.options,"line",n.colors)},null)}},"K/tc":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("af",{months:"Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),weekdays:"Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),weekdaysShort:"Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),weekdaysMin:"So_Ma_Di_Wo_Do_Vr_Sa".split("_"),meridiemParse:/vm|nm/i,isPM:function(t){return/^nm$/i.test(t)},meridiem:function(t,e,n){return t<12?n?"vm":"VM":n?"nm":"NM"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Vandag om] LT",nextDay:"[M\xf4re om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gister om] LT",lastWeek:"[Laas] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oor %s",past:"%s gelede",s:"'n paar sekondes",ss:"%d sekondes",m:"'n minuut",mm:"%d minute",h:"'n uur",hh:"%d ure",d:"'n dag",dd:"%d dae",M:"'n maand",MM:"%d maande",y:"'n jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(t){return t+(1===t||8===t||t>=20?"ste":"de")},week:{dow:1,doy:4}})}()},K2E3:function(t,e,n){"use strict";var a=n("6ww4"),r=n("RDha"),i=function(t){r.extend(this,t),this.initialize.apply(this,arguments)};r.extend(i.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=r.clone(t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,r=e._start,i=e._view;return n&&1!==t?(i||(i=e._view={}),r||(r=e._start={}),function(t,e,n,r){var i,s,o,u,c,l,d,f,p,h=Object.keys(n);for(i=0,s=h.length;i0||(e.forEach(function(e){delete t[e]}),delete t._chartjs)}}t.DatasetController=function(t,e){this.initialize(t,e)},a.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=n.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),a=this.getDataset().data||[],r=n.data;for(t=0,e=a.length;tn&&this.insertElements(n,a-n)},insertElements:function(t,e){for(var n=0;n0?t.prototype.requestAsyncId.call(this,e,n,a):(e.actions.push(this),e.scheduled||(e.scheduled=(s=e.flush.bind(e,null),o=r++,i[o]=s,Promise.resolve().then(function(){return function(t){var e=i[t];e&&e()}(o)}),o)));var s,o},e.prototype.recycleAsyncId=function(e,n,a){if(void 0===a&&(a=0),null!==a&&a>0||null===a&&this.delay>0)return t.prototype.recycleAsyncId.call(this,e,n,a);0===e.actions.length&&(delete i[n],e.scheduled=void 0)},e}(n("h9Dq").a),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return a.__extends(e,t),e.prototype.flush=function(t){this.active=!0,this.scheduled=void 0;var e,n=this.actions,a=-1,r=n.length;t=t||n.shift();do{if(e=t.execute(t.state,t.delay))break}while(++a=2&&t<=4?e[1]:e[2]},translate:function(t,n,a){var r=e.words[a];return 1===a.length?n?r[0]:r[1]:t+" "+e.correctGrammaticalCase(t,r)}};t.defineLocale("me",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sjutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedjelje] [u] LT","[pro\u0161log] [ponedjeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srijede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"nekoliko sekundi",ss:e.translate,m:e.translate,mm:e.translate,h:e.translate,hh:e.translate,d:"dan",dd:e.translate,M:"mjesec",MM:e.translate,y:"godinu",yy:e.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n("wd/R"))},KVJa:function(t,e,n){"use strict";var a=n("CcnG");n("Z21x"),n("Ip0R"),n("sne2"),n.d(e,"a",function(){return r}),n.d(e,"b",function(){return i});var r=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function i(t){return a["\u0275vid"](0,[(t()(),a["\u0275ted"](-1,null,["\xa0\n"])),(t()(),a["\u0275eld"](1,0,null,null,1,"button",[["class","btn btn-sm btn-default tc_backButton"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.back()&&a),a},null,null)),(t()(),a["\u0275ted"](2,null,[" ","\n"]))],null,function(t,e){t(e,2,0,e.component.name)})}},KhEm:function(t,e,n){"use strict";n.d(e,"a",function(){return u}),n.d(e,"b",function(){return l});var a=n("mrSG"),r=n("K9Ia"),i=n("6blF"),s=(n("FFOo"),n("pugT")),o=n("yGWI"),u=function(t){function e(e,n){var a=t.call(this)||this;return a.source=e,a.subjectFactory=n,a._refCount=0,a._isComplete=!1,a}return a.__extends(e,t),e.prototype._subscribe=function(t){return this.getSubject().subscribe(t)},e.prototype.getSubject=function(){var t=this._subject;return t&&!t.isStopped||(this._subject=this.subjectFactory()),this._subject},e.prototype.connect=function(){var t=this._connection;return t||(this._isComplete=!1,(t=this._connection=new s.a).add(this.source.subscribe(new d(this.getSubject(),this))),t.closed&&(this._connection=null,t=s.a.EMPTY)),t},e.prototype.refCount=function(){return Object(o.a)()(this)},e}(i.a),c=u.prototype,l={operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:c._subscribe},_isComplete:{value:c._isComplete,writable:!0},getSubject:{value:c.getSubject},connect:{value:c.connect},refCount:{value:c.refCount}},d=function(t){function e(e,n){var a=t.call(this,e)||this;return a.connectable=n,a}return a.__extends(e,t),e.prototype._error=function(e){this._unsubscribe(),t.prototype._error.call(this,e)},e.prototype._complete=function(){this.connectable._isComplete=!0,this._unsubscribe(),t.prototype._complete.call(this)},e.prototype._unsubscribe=function(){var t=this.connectable;if(t){this.connectable=null;var e=t._connection;t._refCount=0,t._subject=null,t._connection=null,e&&e.unsubscribe()}},e}(r.b)},"L/V9":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a="function"==typeof Symbol?Symbol("rxSubscriber"):"@@rxSubscriber_"+Math.random()},L5sC:function(t,e,n){var a=n("mrSG").__decorate;Object.defineProperty(e,"__esModule",{value:!0});var r=n("CcnG");e.DataTableColumnCellTreeToggle=function(){return a([r.Directive({selector:"[ngx-datatable-tree-toggle]"})],function(t){this.template=t})}()},LceX:function(t,e,n){"use strict";n.d(e,"a",function(){return r}),n.d(e,"b",function(){return d}),n.d(e,"c",function(){return i}),n.d(e,"d",function(){return s}),n.d(e,"e",function(){return o}),n.d(e,"f",function(){return u}),n.d(e,"g",function(){return c}),n.d(e,"h",function(){return l});var a=n("sne2"),r=(n("eTJe"),n("n/D3"),n("V3my"),n("ZEkX"),function(){return function(){}}()),i={breadcrumbs:"Users"},s={breadcrumbs:a.a.CREATE},o={breadcrumbs:a.a.EDIT},u={breadcrumbs:"Roles"},c={breadcrumbs:a.a.CREATE},l={breadcrumbs:a.a.EDIT},d=function(){return function(){}}()},Loxo:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("uz",{months:"\u044f\u043d\u0432\u0430\u0440_\u0444\u0435\u0432\u0440\u0430\u043b_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440_\u043e\u043a\u0442\u044f\u0431\u0440_\u043d\u043e\u044f\u0431\u0440_\u0434\u0435\u043a\u0430\u0431\u0440".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u042f\u043a\u0448\u0430\u043d\u0431\u0430_\u0414\u0443\u0448\u0430\u043d\u0431\u0430_\u0421\u0435\u0448\u0430\u043d\u0431\u0430_\u0427\u043e\u0440\u0448\u0430\u043d\u0431\u0430_\u041f\u0430\u0439\u0448\u0430\u043d\u0431\u0430_\u0416\u0443\u043c\u0430_\u0428\u0430\u043d\u0431\u0430".split("_"),weekdaysShort:"\u042f\u043a\u0448_\u0414\u0443\u0448_\u0421\u0435\u0448_\u0427\u043e\u0440_\u041f\u0430\u0439_\u0416\u0443\u043c_\u0428\u0430\u043d".split("_"),weekdaysMin:"\u042f\u043a_\u0414\u0443_\u0421\u0435_\u0427\u043e_\u041f\u0430_\u0416\u0443_\u0428\u0430".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[\u0411\u0443\u0433\u0443\u043d \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",nextDay:"[\u042d\u0440\u0442\u0430\u0433\u0430] LT [\u0434\u0430]",nextWeek:"dddd [\u043a\u0443\u043d\u0438 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",lastDay:"[\u041a\u0435\u0447\u0430 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",lastWeek:"[\u0423\u0442\u0433\u0430\u043d] dddd [\u043a\u0443\u043d\u0438 \u0441\u043e\u0430\u0442] LT [\u0434\u0430]",sameElse:"L"},relativeTime:{future:"\u042f\u043a\u0438\u043d %s \u0438\u0447\u0438\u0434\u0430",past:"\u0411\u0438\u0440 \u043d\u0435\u0447\u0430 %s \u043e\u043b\u0434\u0438\u043d",s:"\u0444\u0443\u0440\u0441\u0430\u0442",ss:"%d \u0444\u0443\u0440\u0441\u0430\u0442",m:"\u0431\u0438\u0440 \u0434\u0430\u043a\u0438\u043a\u0430",mm:"%d \u0434\u0430\u043a\u0438\u043a\u0430",h:"\u0431\u0438\u0440 \u0441\u043e\u0430\u0442",hh:"%d \u0441\u043e\u0430\u0442",d:"\u0431\u0438\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u0431\u0438\u0440 \u043e\u0439",MM:"%d \u043e\u0439",y:"\u0431\u0438\u0440 \u0439\u0438\u043b",yy:"%d \u0439\u0438\u043b"},week:{dow:1,doy:7}})}()},LvDl:function(t,e,n){(function(t){var a;(function(){var r,i=200,s="Expected a function",o="__lodash_placeholder__",u=1,c=2,l=4,d=1,f=2,p=1,h=2,g=4,b=8,m=16,y=32,v=64,_=128,x=256,T=512,w=800,S=16,O=1/0,I=9007199254740991,C=1.7976931348623157e308,k=NaN,N=4294967295,R=N-1,A=N>>>1,D=[["ary",_],["bind",p],["bindKey",h],["curry",b],["curryRight",m],["flip",T],["partial",y],["partialRight",v],["rearg",x]],E="[object Arguments]",L="[object Array]",P="[object AsyncFunction]",M="[object Boolean]",q="[object Date]",j="[object DOMException]",F="[object Error]",z="[object Function]",G="[object GeneratorFunction]",Y="[object Map]",V="[object Number]",H="[object Null]",B="[object Object]",U="[object Proxy]",W="[object RegExp]",K="[object Set]",$="[object String]",Z="[object Symbol]",X="[object Undefined]",J="[object WeakMap]",Q="[object ArrayBuffer]",tt="[object DataView]",et="[object Float32Array]",nt="[object Float64Array]",at="[object Int8Array]",rt="[object Int16Array]",it="[object Int32Array]",st="[object Uint8Array]",ot="[object Uint8ClampedArray]",ut="[object Uint16Array]",ct="[object Uint32Array]",lt=/\b__p \+= '';/g,dt=/\b(__p \+=) '' \+/g,ft=/(__e\(.*?\)|\b__t\)) \+\n'';/g,pt=/&(?:amp|lt|gt|quot|#39);/g,ht=/[&<>"']/g,gt=RegExp(pt.source),bt=RegExp(ht.source),mt=/<%-([\s\S]+?)%>/g,yt=/<%([\s\S]+?)%>/g,vt=/<%=([\s\S]+?)%>/g,_t=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,xt=/^\w*$/,Tt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,wt=/[\\^$.*+?()[\]{}|]/g,St=RegExp(wt.source),Ot=/^\s+|\s+$/g,It=/^\s+/,Ct=/\s+$/,kt=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Nt=/\{\n\/\* \[wrapped with (.+)\] \*/,Rt=/,? & /,At=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Dt=/\\(\\)?/g,Et=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Lt=/\w*$/,Pt=/^[-+]0x[0-9a-f]+$/i,Mt=/^0b[01]+$/i,qt=/^\[object .+?Constructor\]$/,jt=/^0o[0-7]+$/i,Ft=/^(?:0|[1-9]\d*)$/,zt=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Gt=/($^)/,Yt=/['\n\r\u2028\u2029\\]/g,Vt="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",Ht="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Bt="["+Ht+"]",Ut="["+Vt+"]",Wt="\\d+",Kt="[a-z\\xdf-\\xf6\\xf8-\\xff]",$t="[^\\ud800-\\udfff"+Ht+Wt+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",Zt="\\ud83c[\\udffb-\\udfff]",Xt="[^\\ud800-\\udfff]",Jt="(?:\\ud83c[\\udde6-\\uddff]){2}",Qt="[\\ud800-\\udbff][\\udc00-\\udfff]",te="[A-Z\\xc0-\\xd6\\xd8-\\xde]",ee="(?:"+Kt+"|"+$t+")",ne="(?:"+te+"|"+$t+")",ae="(?:"+Ut+"|"+Zt+")?",re="[\\ufe0e\\ufe0f]?"+ae+"(?:\\u200d(?:"+[Xt,Jt,Qt].join("|")+")[\\ufe0e\\ufe0f]?"+ae+")*",ie="(?:"+["[\\u2700-\\u27bf]",Jt,Qt].join("|")+")"+re,se="(?:"+[Xt+Ut+"?",Ut,Jt,Qt,"[\\ud800-\\udfff]"].join("|")+")",oe=RegExp("['\u2019]","g"),ue=RegExp(Ut,"g"),ce=RegExp(Zt+"(?="+Zt+")|"+se+re,"g"),le=RegExp([te+"?"+Kt+"+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?="+[Bt,te,"$"].join("|")+")",ne+"+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?="+[Bt,te+ee,"$"].join("|")+")",te+"?"+ee+"+(?:['\u2019](?:d|ll|m|re|s|t|ve))?",te+"+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",Wt,ie].join("|"),"g"),de=RegExp("[\\u200d\\ud800-\\udfff"+Vt+"\\ufe0e\\ufe0f]"),fe=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,pe=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],he=-1,ge={};ge[et]=ge[nt]=ge[at]=ge[rt]=ge[it]=ge[st]=ge[ot]=ge[ut]=ge[ct]=!0,ge[E]=ge[L]=ge[Q]=ge[M]=ge[tt]=ge[q]=ge[F]=ge[z]=ge[Y]=ge[V]=ge[B]=ge[W]=ge[K]=ge[$]=ge[J]=!1;var be={};be[E]=be[L]=be[Q]=be[tt]=be[M]=be[q]=be[et]=be[nt]=be[at]=be[rt]=be[it]=be[Y]=be[V]=be[B]=be[W]=be[K]=be[$]=be[Z]=be[st]=be[ot]=be[ut]=be[ct]=!0,be[F]=be[z]=be[J]=!1;var me={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},ye=parseFloat,ve=parseInt,_e="object"==typeof global&&global&&global.Object===Object&&global,xe="object"==typeof self&&self&&self.Object===Object&&self,Te=_e||xe||Function("return this")(),we=e&&!e.nodeType&&e,Se=we&&"object"==typeof t&&t&&!t.nodeType&&t,Oe=Se&&Se.exports===we,Ie=Oe&&_e.process,Ce=function(){try{return Se&&Se.require&&Se.require("util").types||Ie&&Ie.binding&&Ie.binding("util")}catch(t){}}(),ke=Ce&&Ce.isArrayBuffer,Ne=Ce&&Ce.isDate,Re=Ce&&Ce.isMap,Ae=Ce&&Ce.isRegExp,De=Ce&&Ce.isSet,Ee=Ce&&Ce.isTypedArray;function Le(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}function Pe(t,e,n,a){for(var r=-1,i=null==t?0:t.length;++r-1}function ze(t,e,n){for(var a=-1,r=null==t?0:t.length;++a-1;);return n}function cn(t,e){for(var n=t.length;n--&&$e(e,t[n],0)>-1;);return n}var ln=tn({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),dn=tn({"&":"&","<":"<",">":">",'"':""","'":"'"});function fn(t){return"\\"+me[t]}function pn(t){return de.test(t)}function hn(t){var e=-1,n=Array(t.size);return t.forEach(function(t,a){n[++e]=[a,t]}),n}function gn(t,e){return function(n){return t(e(n))}}function bn(t,e){for(var n=-1,a=t.length,r=0,i=[];++n",""":'"',"'":"'"}),Tn=function t(e){var n,a=(e=null==e?Te:Tn.defaults(Te.Object(),e,Tn.pick(Te,pe))).Array,Vt=e.Date,Ht=e.Error,Bt=e.Function,Ut=e.Math,Wt=e.Object,Kt=e.RegExp,$t=e.String,Zt=e.TypeError,Xt=a.prototype,Jt=Wt.prototype,Qt=e["__core-js_shared__"],te=Bt.prototype.toString,ee=Jt.hasOwnProperty,ne=0,ae=(n=/[^.]+$/.exec(Qt&&Qt.keys&&Qt.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"",re=Jt.toString,ie=te.call(Wt),se=Te._,ce=Kt("^"+te.call(ee).replace(wt,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),de=Oe?e.Buffer:r,me=e.Symbol,_e=e.Uint8Array,xe=de?de.allocUnsafe:r,we=gn(Wt.getPrototypeOf,Wt),Se=Wt.create,Ie=Jt.propertyIsEnumerable,Ce=Xt.splice,Ue=me?me.isConcatSpreadable:r,tn=me?me.iterator:r,wn=me?me.toStringTag:r,Sn=function(){try{var t=Ti(Wt,"defineProperty");return t({},"",{}),t}catch(e){}}(),On=e.clearTimeout!==Te.clearTimeout&&e.clearTimeout,In=Vt&&Vt.now!==Te.Date.now&&Vt.now,Cn=e.setTimeout!==Te.setTimeout&&e.setTimeout,kn=Ut.ceil,Nn=Ut.floor,Rn=Wt.getOwnPropertySymbols,An=de?de.isBuffer:r,Dn=e.isFinite,En=Xt.join,Ln=gn(Wt.keys,Wt),Pn=Ut.max,Mn=Ut.min,qn=Vt.now,jn=e.parseInt,Fn=Ut.random,zn=Xt.reverse,Gn=Ti(e,"DataView"),Yn=Ti(e,"Map"),Vn=Ti(e,"Promise"),Hn=Ti(e,"Set"),Bn=Ti(e,"WeakMap"),Un=Ti(Wt,"create"),Wn=Bn&&new Bn,Kn={},$n=Ki(Gn),Zn=Ki(Yn),Xn=Ki(Vn),Jn=Ki(Hn),Qn=Ki(Bn),ta=me?me.prototype:r,ea=ta?ta.valueOf:r,na=ta?ta.toString:r;function aa(t){if(fo(t)&&!to(t)&&!(t instanceof oa)){if(t instanceof sa)return t;if(ee.call(t,"__wrapped__"))return $i(t)}return new sa(t)}var ra=function(){function t(){}return function(e){if(!lo(e))return{};if(Se)return Se(e);t.prototype=e;var n=new t;return t.prototype=r,n}}();function ia(){}function sa(t,e){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!e,this.__index__=0,this.__values__=r}function oa(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=N,this.__views__=[]}function ua(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e=e?t:e)),t}function wa(t,e,n,a,i,s){var o,d=e&u,f=e&c,p=e&l;if(n&&(o=i?n(t,a,i,s):n(t)),o!==r)return o;if(!lo(t))return t;var h=to(t);if(h){if(o=function(t){var e=t.length,n=new t.constructor(e);return e&&"string"==typeof t[0]&&ee.call(t,"index")&&(n.index=t.index,n.input=t.input),n}(t),!d)return zr(t,o)}else{var g=Oi(t),b=g==z||g==G;if(ro(t))return Lr(t,d);if(g==B||g==E||b&&!i){if(o=f||b?{}:Ci(t),!d)return f?function(t,e){return Gr(t,Si(t),e)}(t,function(e,n){return e&&Gr(t,Vo(t),e)}(o)):function(t,e){return Gr(t,wi(t),e)}(t,va(o,t))}else{if(!be[g])return i?t:{};o=function(t,e,n){var a,r,i=t.constructor;switch(e){case Q:return Pr(t);case M:case q:return new i(+t);case tt:return function(t,e){var n=e?Pr(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)}(t,n);case et:case nt:case at:case rt:case it:case st:case ot:case ut:case ct:return Mr(t,n);case Y:return new i;case V:case $:return new i(t);case W:return(r=new(a=t).constructor(a.source,Lt.exec(a))).lastIndex=a.lastIndex,r;case K:return new i;case Z:return ea?Wt(ea.call(t)):{}}}(t,g,d)}}s||(s=new fa);var m=s.get(t);if(m)return m;s.set(t,o),mo(t)?t.forEach(function(a){o.add(wa(a,e,n,a,t,s))}):po(t)&&t.forEach(function(a,r){o.set(r,wa(a,e,n,r,t,s))});var y=h?r:(p?f?gi:hi:f?Vo:Yo)(t);return Me(y||t,function(a,r){y&&(a=t[r=a]),ba(o,r,wa(a,e,n,r,t,s))}),o}function Sa(t,e,n){var a=n.length;if(null==t)return!a;for(t=Wt(t);a--;){var i=n[a],s=t[i];if(s===r&&!(i in t)||!(0,e[i])(s))return!1}return!0}function Oa(t,e,n){if("function"!=typeof t)throw new Zt(s);return Gi(function(){t.apply(r,n)},e)}function Ia(t,e,n,a){var r=-1,s=Fe,o=!0,u=t.length,c=[],l=e.length;if(!u)return c;n&&(e=Ge(e,rn(n))),a?(s=ze,o=!1):e.length>=i&&(s=on,o=!1,e=new da(e));t:for(;++r-1},ca.prototype.set=function(t,e){var n=this.__data__,a=ma(n,t);return a<0?(++this.size,n.push([t,e])):n[a][1]=e,this},la.prototype.clear=function(){this.size=0,this.__data__={hash:new ua,map:new(Yn||ca),string:new ua}},la.prototype.delete=function(t){var e=_i(this,t).delete(t);return this.size-=e?1:0,e},la.prototype.get=function(t){return _i(this,t).get(t)},la.prototype.has=function(t){return _i(this,t).has(t)},la.prototype.set=function(t,e){var n=_i(this,t),a=n.size;return n.set(t,e),this.size+=n.size==a?0:1,this},da.prototype.add=da.prototype.push=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this},da.prototype.has=function(t){return this.__data__.has(t)},fa.prototype.clear=function(){this.__data__=new ca,this.size=0},fa.prototype.delete=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n},fa.prototype.get=function(t){return this.__data__.get(t)},fa.prototype.has=function(t){return this.__data__.has(t)},fa.prototype.set=function(t,e){var n=this.__data__;if(n instanceof ca){var a=n.__data__;if(!Yn||a.length0&&n(o)?e>1?Da(o,e-1,n,a,r):Ye(r,o):a||(r[r.length]=o)}return r}var Ea=Br(),La=Br(!0);function Pa(t,e){return t&&Ea(t,e,Yo)}function Ma(t,e){return t&&La(t,e,Yo)}function qa(t,e){return je(e,function(e){return oo(t[e])})}function ja(t,e){for(var n=0,a=(e=Rr(e,t)).length;null!=t&&ne}function Ya(t,e){return null!=t&&ee.call(t,e)}function Va(t,e){return null!=t&&e in Wt(t)}function Ha(t,e,n){for(var i=n?ze:Fe,s=t[0].length,o=t.length,u=o,c=a(o),l=1/0,d=[];u--;){var f=t[u];u&&e&&(f=Ge(f,rn(e))),l=Mn(f.length,l),c[u]=!n&&(e||s>=120&&f.length>=120)?new da(u&&f):r}f=t[0];var p=-1,h=c[0];t:for(;++p=o?u:u*("desc"==n[a]?-1:1)}return t.index-e.index}(t,e,n)});a--;)t[a]=t[a].value;return t}(Qa(t,function(t,n,r){return{criteria:Ge(e,function(e){return e(t)}),index:++a,value:t}}))}function ir(t,e,n){for(var a=-1,r=e.length,i={};++a-1;)o!==t&&Ce.call(o,u,1),Ce.call(t,u,1);return t}function or(t,e){for(var n=t?e.length:0,a=n-1;n--;){var r=e[n];if(n==a||r!==i){var i=r;Ni(r)?Ce.call(t,r,1):Tr(t,r)}}return t}function ur(t,e){return t+Nn(Fn()*(e-t+1))}function cr(t,e){var n="";if(!t||e<1||e>I)return n;do{e%2&&(n+=t),(e=Nn(e/2))&&(t+=t)}while(e);return n}function lr(t,e){return Yi(qi(t,e,hu),t+"")}function dr(t,e,n,a){if(!lo(t))return t;for(var i=-1,s=(e=Rr(e,t)).length,o=s-1,u=t;null!=u&&++ii?0:i+e),(n=n>i?i:n)<0&&(n+=i),i=e>n?0:n-e>>>0,e>>>=0;for(var s=a(i);++r>>1,s=t[i];null!==s&&!vo(s)&&(n?s<=e:s=i){var l=e?null:si(t);if(l)return mn(l);o=!1,r=on,c=new da}else c=e?[]:u;t:for(;++a=a?t:hr(t,e,n)}var Er=On||function(t){return Te.clearTimeout(t)};function Lr(t,e){if(e)return t.slice();var n=t.length,a=xe?xe(n):new t.constructor(n);return t.copy(a),a}function Pr(t){var e=new t.constructor(t.byteLength);return new _e(e).set(new _e(t)),e}function Mr(t,e){var n=e?Pr(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.length)}function qr(t,e){if(t!==e){var n=t!==r,a=null===t,i=t==t,s=vo(t),o=e!==r,u=null===e,c=e==e,l=vo(e);if(!u&&!l&&!s&&t>e||s&&o&&c&&!u&&!l||a&&o&&c||!n&&c||!i)return 1;if(!a&&!s&&!l&&t1?n[i-1]:r,o=i>2?n[2]:r;for(s=t.length>3&&"function"==typeof s?(i--,s):r,o&&Ri(n[0],n[1],o)&&(s=i<3?r:s,i=1),e=Wt(e);++a-1?i[s?e[o]:o]:r}}function Zr(t){return pi(function(e){var n=e.length,a=n,i=sa.prototype.thru;for(t&&e.reverse();a--;){var o=e[a];if("function"!=typeof o)throw new Zt(s);if(i&&!u&&"wrapper"==mi(o))var u=new sa([],!0)}for(a=u?a:n;++a1&&b.reverse(),f&&lu))return!1;var l=s.get(t);if(l&&s.get(e))return l==e;var p=-1,h=!0,g=n&f?new da:r;for(s.set(t,e),s.set(e,t);++p-1&&t%1==0&&t1?"& ":"")+e[a],e=e.join(n>2?", ":" "),t.replace(kt,"{\n/* [wrapped with "+e+"] */\n")}(a,function(t,e){return Me(D,function(n){var a="_."+n[0];e&n[1]&&!Fe(t,a)&&t.push(a)}),t.sort()}(function(t){var e=t.match(Nt);return e?e[1].split(Rt):[]}(a),n)))}function Hi(t){var e=0,n=0;return function(){var a=qn(),i=S-(a-n);if(n=a,i>0){if(++e>=w)return arguments[0]}else e=0;return t.apply(r,arguments)}}function Bi(t,e){var n=-1,a=t.length,i=a-1;for(e=e===r?a:e;++n1?t[e-1]:r;return n="function"==typeof n?(t.pop(),n):r,gs(t,n)});function Ts(t){var e=aa(t);return e.__chain__=!0,e}function ws(t,e){return e(t)}var Ss=pi(function(t){var e=t.length,n=e?t[0]:0,a=this.__wrapped__,i=function(e){return xa(e,t)};return!(e>1||this.__actions__.length)&&a instanceof oa&&Ni(n)?((a=a.slice(n,+n+(e?1:0))).__actions__.push({func:ws,args:[i],thisArg:r}),new sa(a,this.__chain__).thru(function(t){return e&&!t.length&&t.push(r),t})):this.thru(i)}),Os=Yr(function(t,e,n){ee.call(t,n)?++t[n]:_a(t,n,1)}),Is=$r(Qi),Cs=$r(ts);function ks(t,e){return(to(t)?Me:Ca)(t,vi(e,3))}function Ns(t,e){return(to(t)?function(t,e){for(var n=null==t?0:t.length;n--&&!1!==e(t[n],n,t););return t}:ka)(t,vi(e,3))}var Rs=Yr(function(t,e,n){ee.call(t,n)?t[n].push(e):_a(t,n,[e])}),As=lr(function(t,e,n){var r=-1,i="function"==typeof e,s=no(t)?a(t.length):[];return Ca(t,function(t){s[++r]=i?Le(e,t,n):Ba(t,e,n)}),s}),Ds=Yr(function(t,e,n){_a(t,n,e)});function Es(t,e){return(to(t)?Ge:Qa)(t,vi(e,3))}var Ls=Yr(function(t,e,n){t[n?0:1].push(e)},function(){return[[],[]]}),Ps=lr(function(t,e){if(null==t)return[];var n=e.length;return n>1&&Ri(t,e[0],e[1])?e=[]:n>2&&Ri(e[0],e[1],e[2])&&(e=[e[0]]),rr(t,Da(e,1),[])}),Ms=In||function(){return Te.Date.now()};function qs(t,e,n){return e=n?r:e,ui(t,_,r,r,r,r,e=t&&null==e?t.length:e)}function js(t,e){var n;if("function"!=typeof e)throw new Zt(s);return t=Oo(t),function(){return--t>0&&(n=e.apply(this,arguments)),t<=1&&(e=r),n}}var Fs=lr(function(t,e,n){var a=p;if(n.length){var r=bn(n,yi(Fs));a|=y}return ui(t,a,e,n,r)}),zs=lr(function(t,e,n){var a=p|h;if(n.length){var r=bn(n,yi(zs));a|=y}return ui(e,a,t,n,r)});function Gs(t,e,n){var a,i,o,u,c,l,d=0,f=!1,p=!1,h=!0;if("function"!=typeof t)throw new Zt(s);function g(e){var n=a,s=i;return a=i=r,d=e,u=t.apply(s,n)}function b(t){var n=t-l;return l===r||n>=e||n<0||p&&t-d>=o}function m(){var t=Ms();if(b(t))return y(t);c=Gi(m,function(t){var n=e-(t-l);return p?Mn(n,o-(t-d)):n}(t))}function y(t){return c=r,h&&a?g(t):(a=i=r,u)}function v(){var t=Ms(),n=b(t);if(a=arguments,i=this,l=t,n){if(c===r)return function(t){return d=t,c=Gi(m,e),f?g(t):u}(l);if(p)return Er(c),c=Gi(m,e),g(l)}return c===r&&(c=Gi(m,e)),u}return e=Co(e)||0,lo(n)&&(f=!!n.leading,o=(p="maxWait"in n)?Pn(Co(n.maxWait)||0,e):o,h="trailing"in n?!!n.trailing:h),v.cancel=function(){c!==r&&Er(c),d=0,a=l=i=c=r},v.flush=function(){return c===r?u:y(Ms())},v}var Ys=lr(function(t,e){return Oa(t,1,e)}),Vs=lr(function(t,e,n){return Oa(t,Co(e)||0,n)});function Hs(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new Zt(s);var n=function(){var a=arguments,r=e?e.apply(this,a):a[0],i=n.cache;if(i.has(r))return i.get(r);var s=t.apply(this,a);return n.cache=i.set(r,s)||i,s};return n.cache=new(Hs.Cache||la),n}function Bs(t){if("function"!=typeof t)throw new Zt(s);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}Hs.Cache=la;var Us=Ar(function(t,e){var n=(e=1==e.length&&to(e[0])?Ge(e[0],rn(vi())):Ge(Da(e,1),rn(vi()))).length;return lr(function(a){for(var r=-1,i=Mn(a.length,n);++r=e}),Qs=Ua(function(){return arguments}())?Ua:function(t){return fo(t)&&ee.call(t,"callee")&&!Ie.call(t,"callee")},to=a.isArray,eo=ke?rn(ke):function(t){return fo(t)&&za(t)==Q};function no(t){return null!=t&&co(t.length)&&!oo(t)}function ao(t){return fo(t)&&no(t)}var ro=An||Cu,io=Ne?rn(Ne):function(t){return fo(t)&&za(t)==q};function so(t){if(!fo(t))return!1;var e=za(t);return e==F||e==j||"string"==typeof t.message&&"string"==typeof t.name&&!go(t)}function oo(t){if(!lo(t))return!1;var e=za(t);return e==z||e==G||e==P||e==U}function uo(t){return"number"==typeof t&&t==Oo(t)}function co(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=I}function lo(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function fo(t){return null!=t&&"object"==typeof t}var po=Re?rn(Re):function(t){return fo(t)&&Oi(t)==Y};function ho(t){return"number"==typeof t||fo(t)&&za(t)==V}function go(t){if(!fo(t)||za(t)!=B)return!1;var e=we(t);if(null===e)return!0;var n=ee.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&te.call(n)==ie}var bo=Ae?rn(Ae):function(t){return fo(t)&&za(t)==W},mo=De?rn(De):function(t){return fo(t)&&Oi(t)==K};function yo(t){return"string"==typeof t||!to(t)&&fo(t)&&za(t)==$}function vo(t){return"symbol"==typeof t||fo(t)&&za(t)==Z}var _o=Ee?rn(Ee):function(t){return fo(t)&&co(t.length)&&!!ge[za(t)]},xo=ai(Ja),To=ai(function(t,e){return t<=e});function wo(t){if(!t)return[];if(no(t))return yo(t)?_n(t):zr(t);if(tn&&t[tn])return function(t){for(var e,n=[];!(e=t.next()).done;)n.push(e.value);return n}(t[tn]());var e=Oi(t);return(e==Y?hn:e==K?mn:Xo)(t)}function So(t){return t?(t=Co(t))===O||t===-O?(t<0?-1:1)*C:t==t?t:0:0===t?t:0}function Oo(t){var e=So(t),n=e%1;return e==e?n?e-n:e:0}function Io(t){return t?Ta(Oo(t),0,N):0}function Co(t){if("number"==typeof t)return t;if(vo(t))return k;if(lo(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=lo(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(Ot,"");var n=Mt.test(t);return n||jt.test(t)?ve(t.slice(2),n?2:8):Pt.test(t)?k:+t}function ko(t){return Gr(t,Vo(t))}function No(t){return null==t?"":_r(t)}var Ro=Vr(function(t,e){if(Li(e)||no(e))Gr(e,Yo(e),t);else for(var n in e)ee.call(e,n)&&ba(t,n,e[n])}),Ao=Vr(function(t,e){Gr(e,Vo(e),t)}),Do=Vr(function(t,e,n,a){Gr(e,Vo(e),t,a)}),Eo=Vr(function(t,e,n,a){Gr(e,Yo(e),t,a)}),Lo=pi(xa),Po=lr(function(t,e){t=Wt(t);var n=-1,a=e.length,i=a>2?e[2]:r;for(i&&Ri(e[0],e[1],i)&&(a=1);++n1),e}),Gr(t,gi(t),n),a&&(n=wa(n,u|c|l,di));for(var r=e.length;r--;)Tr(n,e[r]);return n}),Wo=pi(function(t,e){return null==t?{}:function(t,e){return ir(t,e,function(e,n){return jo(t,n)})}(t,e)});function Ko(t,e){if(null==t)return{};var n=Ge(gi(t),function(t){return[t]});return e=vi(e),ir(t,n,function(t,n){return e(t,n[0])})}var $o=oi(Yo),Zo=oi(Vo);function Xo(t){return null==t?[]:sn(t,Yo(t))}var Jo=Wr(function(t,e,n){return e=e.toLowerCase(),t+(n?Qo(e):e)});function Qo(t){return ou(No(t).toLowerCase())}function tu(t){return(t=No(t))&&t.replace(zt,ln).replace(ue,"")}var eu=Wr(function(t,e,n){return t+(n?"-":"")+e.toLowerCase()}),nu=Wr(function(t,e,n){return t+(n?" ":"")+e.toLowerCase()}),au=Ur("toLowerCase"),ru=Wr(function(t,e,n){return t+(n?"_":"")+e.toLowerCase()}),iu=Wr(function(t,e,n){return t+(n?" ":"")+ou(e)}),su=Wr(function(t,e,n){return t+(n?" ":"")+e.toUpperCase()}),ou=Ur("toUpperCase");function uu(t,e,n){return t=No(t),(e=n?r:e)===r?function(t){return fe.test(t)}(t)?function(t){return t.match(le)||[]}(t):function(t){return t.match(At)||[]}(t):t.match(e)||[]}var cu=lr(function(t,e){try{return Le(t,r,e)}catch(n){return so(n)?n:new Ht(n)}}),lu=pi(function(t,e){return Me(e,function(e){e=Wi(e),_a(t,e,Fs(t[e],t))}),t});function du(t){return function(){return t}}var fu=Zr(),pu=Zr(!0);function hu(t){return t}function gu(t){return Za("function"==typeof t?t:wa(t,u))}var bu=lr(function(t,e){return function(n){return Ba(n,t,e)}}),mu=lr(function(t,e){return function(n){return Ba(t,n,e)}});function yu(t,e,n){var a=Yo(e),r=qa(e,a);null!=n||lo(e)&&(r.length||!a.length)||(n=e,e=t,t=this,r=qa(e,Yo(e)));var i=!(lo(n)&&"chain"in n&&!n.chain),s=oo(t);return Me(r,function(n){var a=e[n];t[n]=a,s&&(t.prototype[n]=function(){var e=this.__chain__;if(i||e){var n=t(this.__wrapped__);return(n.__actions__=zr(this.__actions__)).push({func:a,args:arguments,thisArg:t}),n.__chain__=e,n}return a.apply(t,Ye([this.value()],arguments))})}),t}function vu(){}var _u=ti(Ge),xu=ti(qe),Tu=ti(Be);function wu(t){return Ai(t)?Qe(Wi(t)):function(t){return function(e){return ja(e,t)}}(t)}var Su=ni(),Ou=ni(!0);function Iu(){return[]}function Cu(){return!1}var ku,Nu=Qr(function(t,e){return t+e},0),Ru=ii("ceil"),Au=Qr(function(t,e){return t/e},1),Du=ii("floor"),Eu=Qr(function(t,e){return t*e},1),Lu=ii("round"),Pu=Qr(function(t,e){return t-e},0);return aa.after=function(t,e){if("function"!=typeof e)throw new Zt(s);return t=Oo(t),function(){if(--t<1)return e.apply(this,arguments)}},aa.ary=qs,aa.assign=Ro,aa.assignIn=Ao,aa.assignInWith=Do,aa.assignWith=Eo,aa.at=Lo,aa.before=js,aa.bind=Fs,aa.bindAll=lu,aa.bindKey=zs,aa.castArray=function(){if(!arguments.length)return[];var t=arguments[0];return to(t)?t:[t]},aa.chain=Ts,aa.chunk=function(t,e,n){e=(n?Ri(t,e,n):e===r)?1:Pn(Oo(e),0);var i=null==t?0:t.length;if(!i||e<1)return[];for(var s=0,o=0,u=a(kn(i/e));si?0:i+n),(a=a===r||a>i?i:Oo(a))<0&&(a+=i),a=n>a?0:Io(a);n>>0)?(t=No(t))&&("string"==typeof e||null!=e&&!bo(e))&&!(e=_r(e))&&pn(t)?Dr(_n(t),0,n):t.split(e,n):[]},aa.spread=function(t,e){if("function"!=typeof t)throw new Zt(s);return e=null==e?0:Pn(Oo(e),0),lr(function(n){var a=n[e],r=Dr(n,0,e);return a&&Ye(r,a),Le(t,this,r)})},aa.tail=function(t){var e=null==t?0:t.length;return e?hr(t,1,e):[]},aa.take=function(t,e,n){return t&&t.length?hr(t,0,(e=n||e===r?1:Oo(e))<0?0:e):[]},aa.takeRight=function(t,e,n){var a=null==t?0:t.length;return a?hr(t,(e=a-(e=n||e===r?1:Oo(e)))<0?0:e,a):[]},aa.takeRightWhile=function(t,e){return t&&t.length?Sr(t,vi(e,3),!1,!0):[]},aa.takeWhile=function(t,e){return t&&t.length?Sr(t,vi(e,3)):[]},aa.tap=function(t,e){return e(t),t},aa.throttle=function(t,e,n){var a=!0,r=!0;if("function"!=typeof t)throw new Zt(s);return lo(n)&&(a="leading"in n?!!n.leading:a,r="trailing"in n?!!n.trailing:r),Gs(t,e,{leading:a,maxWait:e,trailing:r})},aa.thru=ws,aa.toArray=wo,aa.toPairs=$o,aa.toPairsIn=Zo,aa.toPath=function(t){return to(t)?Ge(t,Wi):vo(t)?[t]:zr(Ui(No(t)))},aa.toPlainObject=ko,aa.transform=function(t,e,n){var a=to(t),r=a||ro(t)||_o(t);if(e=vi(e,4),null==n){var i=t&&t.constructor;n=r?a?new i:[]:lo(t)&&oo(i)?ra(we(t)):{}}return(r?Me:Pa)(t,function(t,a,r){return e(n,t,a,r)}),n},aa.unary=function(t){return qs(t,1)},aa.union=ds,aa.unionBy=fs,aa.unionWith=ps,aa.uniq=function(t){return t&&t.length?xr(t):[]},aa.uniqBy=function(t,e){return t&&t.length?xr(t,vi(e,2)):[]},aa.uniqWith=function(t,e){return e="function"==typeof e?e:r,t&&t.length?xr(t,r,e):[]},aa.unset=function(t,e){return null==t||Tr(t,e)},aa.unzip=hs,aa.unzipWith=gs,aa.update=function(t,e,n){return null==t?t:wr(t,e,Nr(n))},aa.updateWith=function(t,e,n,a){return a="function"==typeof a?a:r,null==t?t:wr(t,e,Nr(n),a)},aa.values=Xo,aa.valuesIn=function(t){return null==t?[]:sn(t,Vo(t))},aa.without=bs,aa.words=uu,aa.wrap=function(t,e){return Ws(Nr(e),t)},aa.xor=ms,aa.xorBy=ys,aa.xorWith=vs,aa.zip=_s,aa.zipObject=function(t,e){return Cr(t||[],e||[],ba)},aa.zipObjectDeep=function(t,e){return Cr(t||[],e||[],dr)},aa.zipWith=xs,aa.entries=$o,aa.entriesIn=Zo,aa.extend=Ao,aa.extendWith=Do,yu(aa,aa),aa.add=Nu,aa.attempt=cu,aa.camelCase=Jo,aa.capitalize=Qo,aa.ceil=Ru,aa.clamp=function(t,e,n){return n===r&&(n=e,e=r),n!==r&&(n=(n=Co(n))==n?n:0),e!==r&&(e=(e=Co(e))==e?e:0),Ta(Co(t),e,n)},aa.clone=function(t){return wa(t,l)},aa.cloneDeep=function(t){return wa(t,u|l)},aa.cloneDeepWith=function(t,e){return wa(t,u|l,e="function"==typeof e?e:r)},aa.cloneWith=function(t,e){return wa(t,l,e="function"==typeof e?e:r)},aa.conformsTo=function(t,e){return null==e||Sa(t,e,Yo(e))},aa.deburr=tu,aa.defaultTo=function(t,e){return null==t||t!=t?e:t},aa.divide=Au,aa.endsWith=function(t,e,n){t=No(t),e=_r(e);var a=t.length,i=n=n===r?a:Ta(Oo(n),0,a);return(n-=e.length)>=0&&t.slice(n,i)==e},aa.eq=Zs,aa.escape=function(t){return(t=No(t))&&bt.test(t)?t.replace(ht,dn):t},aa.escapeRegExp=function(t){return(t=No(t))&&St.test(t)?t.replace(wt,"\\$&"):t},aa.every=function(t,e,n){var a=to(t)?qe:Na;return n&&Ri(t,e,n)&&(e=r),a(t,vi(e,3))},aa.find=Is,aa.findIndex=Qi,aa.findKey=function(t,e){return We(t,vi(e,3),Pa)},aa.findLast=Cs,aa.findLastIndex=ts,aa.findLastKey=function(t,e){return We(t,vi(e,3),Ma)},aa.floor=Du,aa.forEach=ks,aa.forEachRight=Ns,aa.forIn=function(t,e){return null==t?t:Ea(t,vi(e,3),Vo)},aa.forInRight=function(t,e){return null==t?t:La(t,vi(e,3),Vo)},aa.forOwn=function(t,e){return t&&Pa(t,vi(e,3))},aa.forOwnRight=function(t,e){return t&&Ma(t,vi(e,3))},aa.get=qo,aa.gt=Xs,aa.gte=Js,aa.has=function(t,e){return null!=t&&Ii(t,e,Ya)},aa.hasIn=jo,aa.head=ns,aa.identity=hu,aa.includes=function(t,e,n,a){t=no(t)?t:Xo(t),n=n&&!a?Oo(n):0;var r=t.length;return n<0&&(n=Pn(r+n,0)),yo(t)?n<=r&&t.indexOf(e,n)>-1:!!r&&$e(t,e,n)>-1},aa.indexOf=function(t,e,n){var a=null==t?0:t.length;if(!a)return-1;var r=null==n?0:Oo(n);return r<0&&(r=Pn(a+r,0)),$e(t,e,r)},aa.inRange=function(t,e,n){return e=So(e),n===r?(n=e,e=0):n=So(n),function(t,e,n){return t>=Mn(e,n)&&t=-I&&t<=I},aa.isSet=mo,aa.isString=yo,aa.isSymbol=vo,aa.isTypedArray=_o,aa.isUndefined=function(t){return t===r},aa.isWeakMap=function(t){return fo(t)&&Oi(t)==J},aa.isWeakSet=function(t){return fo(t)&&"[object WeakSet]"==za(t)},aa.join=function(t,e){return null==t?"":En.call(t,e)},aa.kebabCase=eu,aa.last=ss,aa.lastIndexOf=function(t,e,n){var a=null==t?0:t.length;if(!a)return-1;var i=a;return n!==r&&(i=(i=Oo(n))<0?Pn(a+i,0):Mn(i,a-1)),e==e?function(t,e,n){for(var a=n+1;a--;)if(t[a]===e)return a;return a}(t,e,i):Ke(t,Xe,i,!0)},aa.lowerCase=nu,aa.lowerFirst=au,aa.lt=xo,aa.lte=To,aa.max=function(t){return t&&t.length?Ra(t,hu,Ga):r},aa.maxBy=function(t,e){return t&&t.length?Ra(t,vi(e,2),Ga):r},aa.mean=function(t){return Je(t,hu)},aa.meanBy=function(t,e){return Je(t,vi(e,2))},aa.min=function(t){return t&&t.length?Ra(t,hu,Ja):r},aa.minBy=function(t,e){return t&&t.length?Ra(t,vi(e,2),Ja):r},aa.stubArray=Iu,aa.stubFalse=Cu,aa.stubObject=function(){return{}},aa.stubString=function(){return""},aa.stubTrue=function(){return!0},aa.multiply=Eu,aa.nth=function(t,e){return t&&t.length?ar(t,Oo(e)):r},aa.noConflict=function(){return Te._===this&&(Te._=se),this},aa.noop=vu,aa.now=Ms,aa.pad=function(t,e,n){t=No(t);var a=(e=Oo(e))?vn(t):0;if(!e||a>=e)return t;var r=(e-a)/2;return ei(Nn(r),n)+t+ei(kn(r),n)},aa.padEnd=function(t,e,n){t=No(t);var a=(e=Oo(e))?vn(t):0;return e&&ae){var a=t;t=e,e=a}if(n||t%1||e%1){var i=Fn();return Mn(t+i*(e-t+ye("1e-"+((i+"").length-1))),e)}return ur(t,e)},aa.reduce=function(t,e,n){var a=to(t)?Ve:en,r=arguments.length<3;return a(t,vi(e,4),n,r,Ca)},aa.reduceRight=function(t,e,n){var a=to(t)?He:en,r=arguments.length<3;return a(t,vi(e,4),n,r,ka)},aa.repeat=function(t,e,n){return e=(n?Ri(t,e,n):e===r)?1:Oo(e),cr(No(t),e)},aa.replace=function(){var t=arguments,e=No(t[0]);return t.length<3?e:e.replace(t[1],t[2])},aa.result=function(t,e,n){var a=-1,i=(e=Rr(e,t)).length;for(i||(i=1,t=r);++aI)return[];var n=N,a=Mn(t,N);e=vi(e),t-=N;for(var r=an(a,e);++n=s)return t;var u=n-vn(a);if(u<1)return a;var c=o?Dr(o,0,u).join(""):t.slice(0,u);if(i===r)return c+a;if(o&&(u+=c.length-u),bo(i)){if(t.slice(u).search(i)){var l,d=c;for(i.global||(i=Kt(i.source,No(Lt.exec(i))+"g")),i.lastIndex=0;l=i.exec(d);)var f=l.index;c=c.slice(0,f===r?u:f)}}else if(t.indexOf(_r(i),u)!=u){var p=c.lastIndexOf(i);p>-1&&(c=c.slice(0,p))}return c+a},aa.unescape=function(t){return(t=No(t))&>.test(t)?t.replace(pt,xn):t},aa.uniqueId=function(t){var e=++ne;return No(t)+e},aa.upperCase=su,aa.upperFirst=ou,aa.each=ks,aa.eachRight=Ns,aa.first=ns,yu(aa,(ku={},Pa(aa,function(t,e){ee.call(aa.prototype,e)||(ku[e]=t)}),ku),{chain:!1}),aa.VERSION="4.17.14",Me(["bind","bindKey","curry","curryRight","partial","partialRight"],function(t){aa[t].placeholder=aa}),Me(["drop","take"],function(t,e){oa.prototype[t]=function(n){n=n===r?1:Pn(Oo(n),0);var a=this.__filtered__&&!e?new oa(this):this.clone();return a.__filtered__?a.__takeCount__=Mn(n,a.__takeCount__):a.__views__.push({size:Mn(n,N),type:t+(a.__dir__<0?"Right":"")}),a},oa.prototype[t+"Right"]=function(e){return this.reverse()[t](e).reverse()}}),Me(["filter","map","takeWhile"],function(t,e){var n=e+1,a=1==n||3==n;oa.prototype[t]=function(t){var e=this.clone();return e.__iteratees__.push({iteratee:vi(t,3),type:n}),e.__filtered__=e.__filtered__||a,e}}),Me(["head","last"],function(t,e){var n="take"+(e?"Right":"");oa.prototype[t]=function(){return this[n](1).value()[0]}}),Me(["initial","tail"],function(t,e){var n="drop"+(e?"":"Right");oa.prototype[t]=function(){return this.__filtered__?new oa(this):this[n](1)}}),oa.prototype.compact=function(){return this.filter(hu)},oa.prototype.find=function(t){return this.filter(t).head()},oa.prototype.findLast=function(t){return this.reverse().find(t)},oa.prototype.invokeMap=lr(function(t,e){return"function"==typeof t?new oa(this):this.map(function(n){return Ba(n,t,e)})}),oa.prototype.reject=function(t){return this.filter(Bs(vi(t)))},oa.prototype.slice=function(t,e){t=Oo(t);var n=this;return n.__filtered__&&(t>0||e<0)?new oa(n):(t<0?n=n.takeRight(-t):t&&(n=n.drop(t)),e!==r&&(n=(e=Oo(e))<0?n.dropRight(-e):n.take(e-t)),n)},oa.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},oa.prototype.toArray=function(){return this.take(N)},Pa(oa.prototype,function(t,e){var n=/^(?:filter|find|map|reject)|While$/.test(e),a=/^(?:head|last)$/.test(e),i=aa[a?"take"+("last"==e?"Right":""):e],s=a||/^find/.test(e);i&&(aa.prototype[e]=function(){var e=this.__wrapped__,o=a?[1]:arguments,u=e instanceof oa,c=o[0],l=u||to(e),d=function(t){var e=i.apply(aa,Ye([t],o));return a&&f?e[0]:e};l&&n&&"function"==typeof c&&1!=c.length&&(u=l=!1);var f=this.__chain__,p=s&&!f,h=u&&!this.__actions__.length;if(!s&&l){e=h?e:new oa(this);var g=t.apply(e,o);return g.__actions__.push({func:ws,args:[d],thisArg:r}),new sa(g,f)}return p&&h?t.apply(this,o):(g=this.thru(d),p?a?g.value()[0]:g.value():g)})}),Me(["pop","push","shift","sort","splice","unshift"],function(t){var e=Xt[t],n=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",a=/^(?:pop|shift)$/.test(t);aa.prototype[t]=function(){var t=arguments;if(a&&!this.__chain__){var r=this.value();return e.apply(to(r)?r:[],t)}return this[n](function(n){return e.apply(to(n)?n:[],t)})}}),Pa(oa.prototype,function(t,e){var n=aa[e];if(n){var a=n.name+"";ee.call(Kn,a)||(Kn[a]=[]),Kn[a].push({name:e,func:n})}}),Kn[Xr(r,h).name]=[{name:"wrapper",func:r}],oa.prototype.clone=function(){var t=new oa(this.__wrapped__);return t.__actions__=zr(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=zr(this.__iteratees__),t.__takeCount__=this.__takeCount__,t.__views__=zr(this.__views__),t},oa.prototype.reverse=function(){if(this.__filtered__){var t=new oa(this);t.__dir__=-1,t.__filtered__=!0}else(t=this.clone()).__dir__*=-1;return t},oa.prototype.value=function(){var t=this.__wrapped__.value(),e=this.__dir__,n=to(t),a=e<0,r=n?t.length:0,i=function(t,e,n){for(var a=-1,r=n.length;++a=this.__values__.length;return{done:t,value:t?r:this.__values__[this.__index__++]}},aa.prototype.plant=function(t){for(var e,n=this;n instanceof ia;){var a=$i(n);a.__index__=0,a.__values__=r,e?i.__wrapped__=a:e=a;var i=a;n=n.__wrapped__}return i.__wrapped__=t,e},aa.prototype.reverse=function(){var t=this.__wrapped__;if(t instanceof oa){var e=t;return this.__actions__.length&&(e=new oa(this)),(e=e.reverse()).__actions__.push({func:ws,args:[ls],thisArg:r}),new sa(e,this.__chain__)}return this.thru(ls)},aa.prototype.toJSON=aa.prototype.valueOf=aa.prototype.value=function(){return Or(this.__wrapped__,this.__actions__)},aa.prototype.first=aa.prototype.head,tn&&(aa.prototype[tn]=function(){return this}),aa}();Te._=Tn,(a=(function(){return Tn}).call(e,n,e,t))===r||(t.exports=a)}).call(this)}).call(this,n("YuTi")(t))},Lwhh:function(t,e,n){var a=n("mrSG").__decorate;Object.defineProperty(e,"__esModule",{value:!0});var r=n("CcnG");e.DataTableColumnHeaderDirective=function(){return a([r.Directive({selector:"[ngx-datatable-header-template]"})],function(t){this.template=t})}()},"M/6F":function(t,e,n){"use strict";var a=n("CcnG"),r=n("IZUe"),i=n("MdoF"),s=n("lTVp"),o=n("Ip0R");n("NDi4"),n.d(e,"a",function(){return u}),n.d(e,"b",function(){return l});var u=a["\u0275crt"]({encapsulation:0,styles:[[".error-panel-alert-icon[_ngcontent-%COMP%]{vertical-align:top;padding-right:15px}.error-panel-alert-title[_ngcontent-%COMP%]{font-weight:700}"]],data:{}});function c(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,2,"button",[["autofocus",""],["class","btn btn-sm btn-default tc_backButton"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.backAction.emit()&&a),a},null,null)),a["\u0275did"](2,4210688,null,0,r.a,[a.ElementRef],null,null),(t()(),a["\u0275ted"](-1,null,["Back"]))],null,null)}function l(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,11,"alert",[["type","danger"]],null,null,null,i.c,i.b)),a["\u0275did"](1,114688,null,0,s.a,[s.b,a.ChangeDetectorRef],{type:[0,"type"]},null),(t()(),a["\u0275eld"](2,0,null,0,9,"table",[],null,null,null,null,null)),(t()(),a["\u0275eld"](3,0,null,null,8,"tbody",[],null,null,null,null,null)),(t()(),a["\u0275eld"](4,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,1,"td",[["class","error-panel-alert-icon"],["rowspan","2"]],null,null,null,null,null)),(t()(),a["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-3x fa-times-circle alert-danger"]],null,null,null,null,null)),(t()(),a["\u0275eld"](7,0,null,null,1,"td",[["class","error-panel-alert-title"]],null,null,null,null,null)),(t()(),a["\u0275ted"](8,null,[" "," "])),(t()(),a["\u0275eld"](9,0,null,null,2,"tr",[],null,null,null,null,null)),(t()(),a["\u0275eld"](10,0,null,null,1,"td",[["class","error-panel-alert-text"]],null,null,null,null,null)),a["\u0275ncd"](null,0),(t()(),a["\u0275and"](16777216,null,null,1,null,c)),a["\u0275did"](13,16384,null,0,o.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"danger"),t(e,13,0,n.backAction.observers.length>0)},function(t,e){t(e,8,0,e.component.title)})}},M9eX:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("DtyJ"),o=(n("czA5"),n("ahDk"));e.ResizeableDirective=function(){function t(t,e){this.renderer=e,this.resizeEnabled=!0,this.resize=new i.EventEmitter,this.resizing=!1,this.element=t.nativeElement}return t.prototype.ngAfterViewInit=function(){var t=this.renderer,e=t.createElement("span");t.addClass(e,this.resizeEnabled?"resize-handle":"resize-handle--not-resizable"),t.appendChild(this.element,e)},t.prototype.ngOnDestroy=function(){this._destroySubscription()},t.prototype.onMouseup=function(){this.resizing=!1,this.subscription&&!this.subscription.closed&&(this._destroySubscription(),this.resize.emit(this.element.clientWidth))},t.prototype.onMousedown=function(t){var e=this,n=t.target.classList.contains("resize-handle"),a=this.element.clientWidth,r=t.screenX;if(n){t.stopPropagation(),this.resizing=!0;var i=s.fromEvent(document,"mouseup");this.subscription=i.subscribe(function(t){return e.onMouseup()});var u=s.fromEvent(document,"mousemove").pipe(o.takeUntil(i)).subscribe(function(t){return e.move(t,a,r)});this.subscription.add(u)}},t.prototype.move=function(t,e,n){var a=e+(t.screenX-n);(!this.minWidth||a>=this.minWidth)&&(!this.maxWidth||a<=this.maxWidth)&&(this.element.style.width=a+"px")},t.prototype._destroySubscription=function(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)},a([i.Input(),r("design:type",Boolean)],t.prototype,"resizeEnabled",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"minWidth",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"maxWidth",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"resize",void 0),a([i.HostListener("mousedown",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onMousedown",null),a([i.Directive({selector:"[resizeable]",host:{"[class.resizeable]":"resizeEnabled"}})],t)}()},MGBS:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("mrSG"),r=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return a.__extends(e,t),e.prototype.notifyNext=function(t,e,n,a,r){this.destination.next(e)},e.prototype.notifyError=function(t,e){this.destination.error(t)},e.prototype.notifyComplete=function(t){this.destination.complete()},e}(n("FFOo").a)},MaEZ:function(t,e){t.exports='\n \n \n \n Toggle navigation\n Zobraz./skr\xfdt navigaci\n \n \n Dashboard\n P\u0159ehled\n \n \n Cluster\n Klastr\n \n \n Hosts\n Stroje\n \n \n Monitors\n Monitory\n \n \n OSDs\n OSD\n \n \n Configuration\n Nastaven\xed\n \n \n CRUSH map\n CRUSH mapa\n \n \n Manager modules\n Moduly spr\xe1vy\n \n \n Logs\n Z\xe1znamy ud\xe1lost\xed\n \n \n Alerts\n V\xfdstrahy\n \n \n Silences\n Silences\n \n \n Pools\n Fondy\n \n \n Block\n Blok\n \n \n Images\n Obrazy\n \n \n Mirroring\n Zrcadlen\xed\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n Souborov\xe9 syst\xe9my\n \n \n Object Gateway\n Objektov\xe1 br\xe1na\n \n \n Daemons\n Procesy slu\u017eeb\n \n \n Users\n U\u017eivatel\xe9\n \n \n Buckets\n N\xe1doby\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Z\xedsk\xe1vaj\xed se data\n pro\n \n \n . \u010cekejte\u2026\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Zobrazuj\xed se data\n z mezipam\u011bti\n pro \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Neda\u0159\xed se na\u010d\xedst dat \n pro\n \n \n .\n Zkontrolujte zdrav\xed klastru.\n \n \n \n Back\n Zp\u011bt\n \n \n Select a Language\n Vyberte jazyk\n \n \n Loading panel data...\n Na\u010d\xedt\xe1n\xed \xfadaj\u016f panelu\u2026\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Nahl\xe9dn\u011bte do\n dokumentace\n , kde naleznete jak\n nastavit a zapnout funkci monitorov\xe1n\xed.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Grafana p\u0159ehled neexistuje. Pod\xedvejte se do\n dokumentace\n jak\n p\u0159idat p\u0159ehledy do Grafany.\n \n \n \n Grafana Time Picker\n Grafana Time Picker\n \n \n Reset Settings\n Resetovat nastaven\xed\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n Data se nepoda\u0159ilo na\u010d\xedst\n \n \n selected\n vybr\xe1no\n X selected\n \n \n found\n nalezeno\n X found\n \n \n total\n celkem\n X total\n \n \n Edit\n Upravit\n \n \n Name\n N\xe1zev\n \n \n Description\n Popis\n \n \n Long description\n Podrobn\u011bj\u0161\xed popis\n \n \n Default\n V\xfdchoz\xed\n \n \n Daemon default\n V\xfdchoz\xed pro proces slu\u017eby\n \n \n Services\n Slu\u017eby\n \n \n Values\n Hodnoty\n \n \n The entered value is too high! It must not be greater than \n .\n \n Zadan\xe1 hodnota je p\u0159\xedli\u0161 vysok\xe1! Nem\u016f\u017ee b\xfdt vy\u0161\u0161\xed ne\u017e \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Zadan\xe1 hodnota je p\u0159\xedli\u0161 n\xedzk\xe1! Nem\u016f\u017ee b\xfdt ni\u017e\u0161\xed ne\u017e \n .\n \n \n \n Save\n Ulo\u017eit\n \n \n CRUSH map viewer\n prohl\xed\u017ee\u010d CRUSH mapy\n \n \n Hosts List\n Seznam stroj\u016f\n \n \n Overall Performance\n Celkov\xe1 v\xfdkonnost\n \n \n No entries found\n Nenalezeny \u017e\xe1dn\xe9 polo\u017eky\n \n \n Cluster Logs\n Z\xe1znamy ud\xe1lost\xed v klastra\n \n \n Audit Logs\n Auditn\xed z\xe1znamy ud\xe1lost\xed\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n Na\u010d\xedt\xe1n\xed nastaven\xed\u2026\n \n \n The configuration could not be loaded.\n Toto nastaven\xed se nepoda\u0159ilo na\u010d\xedst.\n \n \n Edit Manager module\n Upravit modul spr\xe1vy\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n Zadan\xe1 hodnota nen\xed platn\xe9 UUID, nap\u0159.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n Je t\u0159eba, aby zadan\xe1 hodnota byla platnou IP adresou.\n \n \n This field is required.\n Tuto kolonku je t\u0159eba vyplnit.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n The entered value is too high! It must be lower or equal to \n .\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n The entered value is too low! It must be greater or equal to \n .\n \n \n \n The entered value needs to be a number.\n Je t\u0159eba, aby zadan\xe1 hodnota byla \u010d\xedslo.\n \n \n The entered value needs to be a number or decimal.\n Je t\u0159eba, aby zadan\xe1 hodnota byla \u010d\xedslo nebo des\xedtkov\xe9.\n \n \n Update\n Aktualizovat\n \n \n Status\n Stav\n \n \n Cluster ID\n Identif. kastru\n \n \n monmap modified\n mapa monitor\u016f zm\u011bn\u011bna\n \n \n monmap epoch\n monmap epocha\n \n \n quorum con\n kv\xf3rum spojen\xed\n \n \n quorum mon\n kv\xf3rum monitor\n \n \n required con\n vy\u017eadov\xe1no spojen\xed\n \n \n required mon\n vy\u017eadov\xe1no monitor\u016f\n \n \n In Quorum\n V kv\xf3ru\n \n \n Not In Quorum\n Nen\xed v kv\xf3ru\n \n \n Cancel\n Storno\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n Opravdu chcete ozna\u010den\xe9 \n \n ?\n \n \n \n Yes, I am sure.\n Ano, opravdu to chci.\n \n \n Cluster-wide OSD Flags\n P\u0159\xedznaky OSD pro cel\xfd klastr\n \n \n Submit\n Odeslat\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Pokro\u010dil\xe9\u2026\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n Priorita obnoven\xed OSD\n \n \n Priority\n Priorita\n \n \n Customize priority values\n P\u0159izp\u016fsobit hodnoty priority\n \n \n This field is required!\n Tuto kolonku je t\u0159eba vyplnit!\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n Zadan\xe1 hodnota je p\u0159\xedli\u0161 vysok\xe1, je t\u0159eba, aby nebyla vy\u0161\u0161\xed ne\u017e \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Zadan\xe1 hodnota je p\u0159\xedli\u0161 n\xedzk\xe1! Je t\u0159eba, aby byla ni\u017e\u0161\xed ne\u017e \n .\n \n \n \n Reweight OSD\n Znovu vyv\xe1\u017eit OSD\n \n \n The value needs to be between 0 and 1.\n Je t\u0159eba, aby hodnota byla mezi 0 a 1.\n \n \n Reweight\n Znovu vyv\xe1\u017eit\n \n \n OSDs \n Scrub\n \n OSD \n kontrola\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, vybrat, 1 {Deep } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Chyst\xe1te se pou\u017e\xedt kontrolu na\n scrub to\n OSD \n \n \n .\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, vybrat, 1 {deep } }\n \n \n OSDs List\n Seznam OSD\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n Pokud budete pokra\u010dovat, \n OSD \n \n \n \n \n bude ozna\u010deno\n \n \n \n The OSD is not safe to destroy!\n OSD nen\xed mo\u017en\xe9 bezpe\u010dn\u011b zlikvidovat!\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n Pokud budete pokra\u010dovat,\n OSD \n \n bude \n \n \n .\n \n \n \n Details\n Podrobnosti\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Hodnota\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Zav\u0159\xedt\n \n \n Delete\n Smazat\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Zdrav\xed\n \n \n Statistics\n Statistiky\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Ohledn\u011b nastaven\xed a zapnut\xed funkce spr\xe1vy NFS Ganesha nahl\xe9dn\u011bte do \n dokumentace\n \n \n \n \n Clients\n Klienti\n \n \n Any client can access\n P\u0159istupovat m\u016f\u017ee libovoln\xfd klient\n \n \n Addresses\n Adresy\n \n \n Required field\n Vy\u017eadovan\xe1 kolonka\n \n \n Must contain one or more comma-separated values\n Je t\u0159eba, aby obsahovalo jednu nebo v\xedce \u010d\xe1rkou odd\u011blovan\xfdch hodnot\n \n \n For example:\n Nap\u0159\xedklad:\n \n \n Access Type\n Typ p\u0159\xedstupu\n \n \n Squash\n Squash\n \n \n Add clients\n P\u0159idat klienty\n \n \n Loading...\n Na\u010d\xedt\xe1n\xed\u2026\n \n \n -- No cluster available --\n -- \u017d\xe1dn\xfd klastr k dispozici --\n \n \n -- Select the cluster --\n -- Vyberte klastr --\n \n \n Add daemon\n P\u0159idat proces slu\u017eby\n \n \n Storage Backend\n Podp\u016frn\xe1 vrstva \xfalo\u017ei\u0161t\u011b\n \n \n -- No data pools available --\n -- \u017d\xe1dn\xe9 fondy k dispozici --\n \n \n -- Select the storage backend --\n -- Vyberte podp\u016frnou vrstvu \xfalo\u017ei\u0161t\u011b --\n \n \n Object Gateway User\n U\u017eivatel objektov\xe9 br\xe1ny\n \n \n -- No users available --\n -- \u017d\xe1dn\xed u\u017eivatel\xe9 k dispozici --\n \n \n -- Select the object gateway user --\n -- Vyberte u\u017eivatele br\xe1ny objekt\u016f --\n \n \n CephFS User ID\n Identif. u\u017eivatele CephFS\n \n \n -- No clients available --\n -- \u017d\xe1dn\xed klienti k dispozici --\n \n \n -- Select the cephx client --\n -- Vyberte cephx klienta --\n \n \n CephFS Name\n N\xe1zev CephFS\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n Security Label\n \n \n Enable security label\n Enable security label\n \n \n CephFS Path\n Popis um\xedst\u011bn\xed CephFS\n \n \n Path need to start with a \'/\' and can be followed by a word\n Je t\u0159eba, aby popis um\xedst\u011bn\xed za\u010d\xednal na \u201e/\u201c, za kter\xfdm n\xe1sleduje slovo\n \n \n New directory will be created\n Bude vytvo\u0159ena nov\xe1 slo\u017eka\n \n \n Path\n Popis um\xedst\u011bn\xed\n \n \n Path can only be a single \'/\' or a word\n Popis um\xedst\u011bn\xed m\u016f\u017ee b\xfdt pouze jedin\xe9 \u201e/\u201c nebo slovo\n \n \n New bucket will be created\n Bude vytvo\u0159ena nov\xe1 n\xe1doba\n \n \n NFS Protocol\n NFS protokol\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n NFS \u0161t\xedtek\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Alternativn\xed p\u0159\xedstup pro \n NFS v3\n p\u0159ipojen\xed (nem\u016f\u017ee za\u010d\xednat na /).\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n By using different Tag options, the same Path may be exported multiple times.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n By using different Pseudo options, the same Path may be exported multiple times.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- \u017d\xe1dn\xfd typ p\u0159\xedstupu k dispozici --\n \n \n -- Select the access type --\n -- Vyberte typ p\u0159\xedstupu --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- No squash available --\n \n \n --Select what kind of user id squashing is performed --\n --Select what kind of user id squashing is performed --\n \n \n Transport Protocol\n Transportn\xed protokol\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n V\xedtejte v Ceph!\n The welcome message on the login page\n \n \n Username is required\n Je t\u0159eba vyplnit u\u017eivatelsk\xe9 jm\xe9no\n \n \n Password is required\n Je t\u0159eba vyplnit heslo\n \n \n Login\n P\u0159ihl\xe1sit\n \n \n Sorry, the user does not exist in Ceph.\n Je n\xe1m l\xedto, u\u017eivatel v Ceph neexistuje.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Vr\xe1tit se na \n P\u0159ihla\u0161ovac\xed str\xe1nku\n . Budete odhl\xe1\u0161eni od poskytovatele identity kdy\u017e se pokus\xedte znovu p\u0159ihl\xe1sit.\n \n \n \n Forbidden\n Odep\u0159eno\n \n \n Sorry, you are not allowed to see what you were looking for.\n Omlouv\xe1me se, ale nem\xe1te opr\xe1vn\u011bn\xed zobrazit to, po \u010dem se poohl\xed\u017e\xedte.\n \n \n Sorry, we could not find what you were looking for\n Omlouv\xe1me se, nepoda\u0159ilo se naj\xedt to, po \u010dem se poohl\xed\u017e\xedte\n \n \n Remove all\n Odebrat v\u0161e\n \n \n Recent Notifications\n Ned\xe1vn\xe1 ozn\xe1men\xed\n \n \n There are no background tasks.\n Nejsou zde \u017e\xe1dn\xe9 \xfalohy na pozad\xed.\n \n \n Background Tasks\n \xdalohy na pozad\xed\n \n \n Help\n N\xe1pov\u011bda\n \n \n Documentation\n Dokumentace\n \n \n API\n Aplika\u010dn\xed program. rozhran\xed\n \n \n About\n O aplikaci\n \n \n Dashboard Settings\n Nastaven\xed p\u0159ehledu\n \n \n User management\n Spr\xe1va u\u017eivatel\u016f\n \n \n Logged in user\n P\u0159ihl\xe1\u0161en\xfd u\u017eivatel\n \n \n Signed in as\n \n \n \n \n P\u0159ihl\xe1\u0161eni jako\n \n \n \n \n \n \n Sign out\n Odhl\xe1sit\n \n \n Name...\n N\xe1zev\u2026\n \n \n The chosen name is already in use.\n Zvolen\xfd n\xe1zev u\u017e je pou\u017e\xedv\xe1n.\n \n \n Description...\n Popis\u2026\n \n \n Permissions\n Opr\xe1vn\u011bn\xed\n \n \n Roles\n Role\n \n \n Username\n U\u017eivatelsk\xe9 jm\xe9no\n \n \n Password\n Heslo\n \n \n Confirm password\n Potvrzen\xed zad\xe1n\xed hesla\n \n \n Password confirmation doesn\'t match the password.\n Zad\xe1n\xed hesla se neshoduj\xed.\n \n \n Full name\n Cel\xe9 jm\xe9no\n \n \n Email\n E-mail\n \n \n Invalid email.\n Neplatn\xfd e-mail.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Chyst\xe1te se odebrat opr\xe1vn\u011bn\xed \u201eu\u017eivatel \u010d\xedst/aktualizovat\u201c sv\xe9mu vlastn\xedmu \xfa\u010dtu.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Pokud budete pokra\u010dovat, nebudete nad\xe1le schopn\xed p\u0159id\xe1vat nebo nebo odeb\xedrat role \u017e\xe1dn\xe9mu z u\u017eivatel\u016f.\n \n \n Are you sure you want to continue?\n Opravdu chcete pokra\u010dovat?\n \n \n Performance counters not available\n V\xfdkonnostn\xed \u010d\xedta\u010de nejsou k dispozici\n \n \n Attributes (OSD map)\n Atributy (OSD mapa)\n \n \n Metadata not available\n Metadata nejsou k dispozici\n \n \n Metadata\n Metadata\n \n \n Performance counter\n V\xfdkonnostn\xed \u010d\xedta\u010d\n \n \n Histogram not available: \n \n \n Histogram nen\xed k dispozici: \n \n \n \n \n Writes\n Z\xe1pisy\n \n \n Reads\n \u010cten\xed\n \n \n Histogram\n Histogram\n \n \n Performance Details\n Podrobnosti o v\xfdkonnosti\n \n \n Current values\n St\xe1vaj\xedc\xed hodnoty\n \n \n Type\n Typ\n \n \n Min\n Min\n \n \n Max\n Max\n \n \n Flags\n P\u0159\xedznaky\n \n \n Source\n Zdroj\n \n \n Level\n \xdarove\u0148\n \n \n Can be updated at runtime (editable)\n Je mo\u017en\xe9 aktualizovat za provozu (upraviteln\xe9)\n \n \n Tags\n \u0160t\xedtky\n \n \n Enum values\n Vy\u010d\xedslit hodnoty\n \n \n See also\n Viz tak\xe9\n \n \n Cluster Status\n Stav klastru\n \n \n Manager Daemons\n Procesy slu\u017eby spr\xe1vy\n \n \n Object Gateways\n Objektov\xe9 br\xe1ny\n \n \n Metadata Servers\n Metadata servery\n \n \n iSCSI Gateways\n iSCSI br\xe1ny\n \n \n Client IOPS\n vst/v\xfdst. klienta\n \n \n Client Throughput\n Propustnost klienta\n \n \n Client Read/Write\n \u010cten\xed/z\xe1pis klienta\n \n \n Recovery Throughput\n Propustnost zotaven\xed\n \n \n Scrub\n Kontrola\n \n \n Performance\n V\xfdkonnost\n \n \n Raw Capacity\n Hol\xe1 kapacita\n \n \n Objects\n Objekty\n \n \n PGs per OSD\n Skupin um\xedst\u011bn\xed na OSD\n \n \n PG Status\n Stav skupiny um\xedst\u011bn\xed\n \n \n Capacity\n Kapacita\n \n \n \n \n See \n Logs\n for more details.\n \n Dal\u0161\xed podrobnosti \n \n naleznete v \n z\xe1znamech ud\xe1lost\xed\n .\n \n \n \n Ranks\n Hodnocen\xed\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Klienti: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n P\u0159esunout obraz do ko\u0161e\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n Pro p\u0159esunut\xed \n \n /\n \n do ko\u0161e,\n klikn\u011bte na \n P\u0159esunout obraz\n . Voliteln\u011b je mo\u017en\xe9 zvolit datum skon\u010den\xed platnosti.\n \n \n \n Protection expires at\n Platnost ochrany skon\u010d\xed v\n \n \n NOT PROTECTED\n NECHR\xc1N\u011aNO\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Chybn\xfd form\xe1t data. Pou\u017eijte \u201eRRRR-MM-DD HH:mm:ss\u201c.\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n Platnost ochrany u\u017e skon\u010dila. Zvolte budouc\xed datum nebo nevypl\u0148ujte.\n \n \n Move Image\n P\u0159esunout obraz\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n P\u0159ehled\n \n \n Targets\n C\xedle\n \n \n Discovery Authentication\n Ov\u011b\u0159ov\xe1n\xed pro objevov\xe1n\xed\n \n \n User\n U\u017eivatele\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n U\u017eivatel pro vz\xe1jemn\xe9 ov\u011b\u0159en\xed\n \n \n Mutual Password\n Heslo pro vz\xe1jemn\xe9 ov\u011b\u0159en\xed\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Pod\xedvejte se do \n dokumentace\n \n jak nastavit a zapnout funkci spr\xe1vy iSCSI c\xedl\u016f.\n \n \n \n Available information:\n Informace k dispozici:\n \n \n iSCSI Targets not available\n iSCSI c\xedl nen\xed k dispozici\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n K dispozici pouze pro RBD obrazy se zapnut\xfdm \n fast-diff\n \n \n \n \n Pool\n Fond\n \n \n Data Pool\n Datov\xfd fond\n \n \n Created\n Vytvo\u0159eno\n \n \n Size\n Velikost\n \n \n Object size\n Velikost objektu\n \n \n Features\n Funkce\n \n \n Provisioned\n Poskytov\xe1no\n \n \n N/A\n N/A\n \n \n Total provisioned\n Celkem poskytov\xe1no\n \n \n Striping unit\n Prou\u017ekovac\xed jednotka\n \n \n Striping count\n Po\u010det prou\u017ekov\xe1n\xed\n \n \n Parent\n Nad\u0159azen\xe9\n \n \n Block name prefix\n P\u0159edpona n\xe1zvu bloku\n \n \n Order\n Po\u0159ad\xed\n \n \n Snapshots\n Zachycen\xe9 stavy\n \n \n Image\n Obraz\n \n \n This setting overrides the global value\n Toto nastaven\xed p\u0159ebije glob\xe1ln\xed hodnotu\n \n \n Global\n Glob\xe1ln\xed\n \n \n This is the global value. No value for this option has been set for this image.\n Toto je glob\xe1ln\xed hodnota. Pro tento obraz nebyla u t\xe9to volby nastavena \u017e\xe1dn\xe1 hodnota.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \u201e/\u201c a \u201e@\u201c nejsou dovoleny.\n \n \n -- No rbd pools available --\n -- \u017d\xe1dn\xe9 rbd fondy k dispozici --\n \n \n -- Select a pool --\n -- Vybrat fond --\n \n \n Use a dedicated data pool\n Pou\u017e\xedt vyhrazen\xfd datov\xfd fond\n \n \n Data pool\n Datov\xfd fond\n \n \n Dedicated pool that stores the object-data of the RBD.\n Vyhrazen\xfd fond kter\xfd uchov\xe1v\xe1 objektov\xe1 data RBD.\n \n \n e.g., 10GiB\n nap\u0159. 10 GiB\n \n \n You have to increase the size.\n Je t\u0159eba zv\u011bt\u0161it.\n \n \n Advanced\n Pokro\u010dil\xe9\n \n \n Striping\n Prou\u017ekov\xe1n\xed\n \n \n Stripe unit\n Jednotka prou\u017eku\n \n \n -- Select stripe unit --\n -- Vybrat jednotku prou\u017eku --\n \n \n This field is required because stripe count is defined!\n Tuto kolonku je t\u0159eba vyplnit, proto\u017ee je definov\xe1n po\u010det prou\u017ek\u016f!\n \n \n Stripe unit is greater than object size.\n Jednotka prou\u017eku je vy\u0161\u0161\xed ne\u017e velikost objektu.\n \n \n Stripe count\n Po\u010det prou\u017ek\u016f\n \n \n This field is required because stripe unit is defined!\n Tuto kolonku je t\u0159eba vyplnit, proto\u017ee je definov\xe1na jednotka prou\u017eku!\n \n \n Stripe count must be greater than 0.\n Je t\u0159eba, aby po\u010det prou\u017ek\u016f byl v\u011bt\u0161\xed ne\u017e nula.\n \n \n \n RBD Snapshot\n \n \n RBD zachycen\xfd stav\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, vybrat, skute\u010dn\xe9 {Rename} ostatn\xed {Create} }\n \n \n \n Snapshot\n \n \n zachycen\xfd stav\n \n \n \n PROTECTED\n CHR\xc1N\u011aNO\n \n \n UNPROTECTED\n NECHR\xc1N\u011aNO\n \n \n You are about to rollback\n Chyst\xe1te se vr\xe1tit zp\u011bt\n \n \n Purge Trash\n Vysypat ko\u0161\n \n \n To purge, select one or All images and click\n Pro vy\u010di\u0161t\u011bn\xed, vyberte jeden nebo v\u0161echny obrazy a klikn\u011bte na\n \n \n Pool:\n Fond:\n \n \n Pool name...\n N\xe1zev fondu\u2026\n \n \n All\n V\u0161e\n \n \n Restore Image\n Obnovit obraz\n \n \n To restore\n Pro obnoven\xed\n \n \n type the image\'s new name and click\n zadejte nov\xfd n\xe1zev pro obraz a klikn\u011bte na\n \n \n New Name\n Nov\xfd n\xe1zev\n \n \n Expired at\n Platnost skon\u010dila v\n \n \n Protected until\n Chr\xe1n\u011bno do\n \n \n This image is protected until \n .\n \n Tento obraz je chr\xe1n\u011bn do\n .\n \n \n \n Trash\n Ko\u0161\n \n \n iSCSI Topology\n Topologie iSCSI\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n M\u011bnit tyto parametry z jejich v\xfdchoz\xedch hodnot obvykle nen\xed pot\u0159eba.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Nastaven\xed\n \n \n Backstore\n Backstore\n \n \n Confirm\n Potvrdit\n \n \n Advanced Settings\n Pokro\u010dil\xe1 nastaven\xed\n \n \n Target IQN\n IQN c\xedle\n \n \n IQN has wrong pattern.\n IQN nem\xe1 spr\xe1vn\xfd form\xe1t.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n IQN m\xe1 n\xe1sleduj\xedc\xed formu z\xe1pisu \u201eiqn.$rok-$m\u011bs\xedc.$adresaObr\xe1cen\u011b:$ur\u010den\xfdN\xe1zev\'\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Nap\u0159\xedklad: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n Dal\u0161\xed informace\n \n \n This target has modified advanced settings.\n Tento c\xedl m\xe1 zm\u011bn\u011bn\xe1 pokro\u010dil\xe1 nastaven\xed.\n \n \n Portals\n Port\xe1ly\n \n \n At least \n gateways are required.\n \n Je t\u0159eba alespo\u0148 \n bran.\n \n \n \n Add portal\n P\u0159idat port\xe1l\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Tento obraz m\xe1 zm\u011bn\u011bn\xe1 nastaven\xed.\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n P\u0159idat obraz\n \n \n ACL authentication\n ACL ov\u011b\u0159ov\xe1n\xed\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Inici\xe1tory\n \n \n Initiator\n Inici\xe1tor\n \n \n Client IQN\n IQN klienta\n \n \n Initiator IQN needs to be unique.\n Je t\u0159eba, aby se IQN inici\xe1toru neopakovalo.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Je t\u0159eba, aby u\u017eivatelsk\xe1 jm\xe9na m\u011bla d\xe9lku 8 a\u017e 64 znak\u016f a\n mohou obsahovat pouze p\xedsmena a znaky \u201e.\u201c, \u201e@\u201c, \u201e-\u201c, \u201e_\u201c nebo \u201e:\u201c.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n Inici\xe1tor spad\xe1 do skupiny. Obrazy budou nastaveny ve skupin\u011b.\n \n \n No items added.\n Nep\u0159id\xe1ny \u017e\xe1dn\xe9 polo\u017eky.\n \n \n Add initiator\n P\u0159idat inici\xe1tor\n \n \n Groups\n Skupiny\n \n \n Group\n Skupina\n \n \n Add group\n P\u0159idat skupinu\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n Nastaven\xed RBD\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Odebrat hodnotu m\xedstn\xedmu nastaven\xed. Nam\xedsto n\xed bude pou\u017eita hodnota nad\u0159azen\xe9ho nastaven\xed.\n \n \n The mininum value is 0\n Minim\xe1ln\xed hodnota je 0\n \n \n Issues\n probl\xe9my\n \n \n Syncing\n Synchronizuje se\n \n \n Ready\n P\u0159ipraveno\n \n \n Edit pool mirror mode\n Upravit re\u017eim zrcadlen\xed fondu\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n Pro \xfapravu re\u017eimu zrcadlen\xed pro fond\xa0\n \n \n , vyberte ze seznamu nov\xfd re\u017eim a klikn\u011bte na\xa0\n Aktualizovat\n .\n \n \n \n Mode\n Re\u017eim\n \n \n Peer clusters must be removed prior to disabling mirror.\n P\u0159ed vypnut\xedm zrcadlen\xed je t\u0159eba odebrat klastry-prot\u011bj\u0161ky.\n \n \n \n \n pool mirror peer\n \n \n \n prot\u011bj\u0161ek zrcadlen\xed fondu\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Edit} other {Add} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n atributy\n prot\u011bj\u0161ku zrcadlen\xed pro fond \n \n \n a klikn\u011bte na \n Odeslat\n .\n \n \n \n Cluster Name\n N\xe1zev klastru\n \n \n The cluster name is not valid.\n N\xe1zev klastru nen\xed platn\xfd\n \n \n CephX ID\n CephX identif.\n \n \n CephX ID...\n CephX identif. \u2026\n \n \n The CephX ID is not valid.\n CephX identif. nen\xed platn\xfd.\n \n \n Monitor Addresses\n Adresy monitor\u016f\n \n \n Comma-delimited addresses...\n \u010c\xe1rkou odd\u011blovan\xe9 adresy\u2026\n \n \n The monitory address is not valid.\n Adresa monitoru nen\xed platn\xe1.\n \n \n CephX Key\n CephX kl\xed\u010d\n \n \n Base64-encoded key...\n Kl\xed\u010d v base64 k\xf3dov\xe1n\xed\u2026\n \n \n CephX key must be base64 encoded.\n Je t\u0159eba, aby CephX kl\xed\u010d byl v k\xf3dov\xe1n\xed base64.\n \n \n Pools List\n Seznam fond\u016f\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n N\xe1zev m\u016f\u017ee b\xfdt tvo\u0159en pouze p\xedsmeny a \u010d\xedslicemi, d\xe1le je\u0161t\u011b spojovn\xedky a podtr\u017e\xedtky.\n \n \n The chosen erasure code profile name is already in use.\n Zvolen\xfd n\xe1zev pro profil mazac\xedho k\xf3du je u\u017e pou\u017e\xedv\xe1n.\n \n \n Plugin\n Z\xe1suvn\xfd modul\n \n \n Data chunks (k)\n Shluky dat (k)\n \n \n Must be equal to or greater than 2.\n Je t\u0159eba, aby bylo 2 a v\xedce.\n \n \n Coding chunks (m)\n Shluky k\xf3dov\xe1n\xed (m)\n \n \n Must be equal to or greater than 1.\n Je t\u0159eba, aby bylo 1 a v\xedce.\n \n \n Durability estimator (c)\n Odhadov\xe1n\xed odolnosti (c)\n \n \n Locality (l)\n Um\xedst\u011bn\xed (l)\n \n \n Crush failure domain\n Dom\xe9na selh\xe1n\xed crush\n \n \n Crush Locality\n Lokalita crush\n \n \n None\n \u017d\xe1dn\xe9\n \n \n Technique\n Technika\n \n \n Packetsize\n Velikostpaketu\n \n \n Crush root\n Ko\u0159en crush\n \n \n Crush device class\n T\u0159\xedda crush za\u0159\xedzen\xed\n \n \n any\n libovoln\xe9\n \n \n Directory\n Slo\u017eka\n \n \n The chosen Ceph pool name is already in use.\n Zvolen\xfd n\xe1zev pro Ceph fond je u\u017e pou\u017e\xedv\xe1n.\n \n \n Pool type\n Typ fondul\n \n \n -- Select a pool type --\n -- Vybrat typ fondu --\n \n \n Placement groups\n Skupiny um\xedst\u011bn\xed\n \n \n At least one placement group is needed!\n Je t\u0159eba alespo\u0148 jedn\xe9 skupiny um\xedst\u011bn\xed!\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n V\xe1\u0161 klastr nem\u016f\u017ee obslou\u017eit tolik skupin um\xedst\u011bn\xed. P\u0159epo\u010d\xedtejte pot\u0159ebn\xe9 mno\u017estv\xed skupin um\xedst\u011bn\xed.\n \n \n Calculation help\n N\xe1pov\u011bda k v\xfdpo\u010dtu\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n \n \n Crush ruleset\n Sada pravidel crush\n \n \n -- Select a crush rule --\n -- Vybrat crush pravidlo --\n \n \n Crush rule\n Crush pravidlo\n \n \n Crush steps\n Crush kroky\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n Pravidlo nem\u016f\u017ee b\xfdt uplatn\u011bno na st\xe1vaj\xedc\xed klastr proto\u017ee m\xe1\n p\u0159\xedli\u0161 m\xe1lo OSD aby splnil minimum OSD vy\u017eadovan\xfdch t\xedmto pravidlem.\n \n \n Replicated size\n Replikovan\xe1 velikost\n \n \n Minimum: \n \n \n Nejm\xe9n\u011b: \n \n \n \n \n Maximum: \n \n \n Nejv\xedce: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n Zadan\xe1 velikost je mimo rozsah. Platn\xe9 hodnoty jsou od \n do \n .\n \n \n \n Erasure code profile\n Profil mazac\xedho k\xf3du\n \n \n -- No erasure code profile available --\n -- \u017d\xe1dn\xfd profil mazac\xedho k\xf3du --\n \n \n -- Select an erasure code profile --\n -- Vyberte profil mazac\xedho k\xf3du --\n \n \n EC Overwrites\n EC p\u0159ebit\xed\n \n \n Applications\n Aplikace\n \n \n Compression\n Komprese\n \n \n Algorithm\n Algoritmus\n \n \n -- No erasure compression algorithm available --\n -- \u017d\xe1dn\xfd algoritmus komprese maz\xe1n\xed --\n \n \n Minimum blob size\n Minim\xe1ln\xed velikost blobu\n \n \n e.g., 128KiB\n nap\u0159. 128 KiB\n \n \n Value should be greater than 0\n Hodnota by m\u011bla b\xfdt vy\u0161\u0161\xed ne\u017e nula\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Nejvy\u0161\u0161\xed velikost blobu\n \n \n e.g., 512KiB\n nap\u0159. 512 KiB\n \n \n Value should be greater than the minimum blob size\n Hodnota by m\u011bla b\xfdt vy\u0161\u0161\xed ne\u017e nejni\u017e\u0161\xed velikost blobu\n \n \n Ratio\n Pom\u011br\n \n \n Compression ratio\n Kompresn\xed pom\u011br\n \n \n Value should be between 0.0 and 1.0\n Hodnota by m\u011bla b\xfdt z rozmez\xed 0.0 a\u017e 1.0\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n Nen\xed mo\u017en\xe9 vytvo\u0159it RBD fond, kter\xfd m\xe1 v n\xe1zvu \u201e/\u201c.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n Zm\u011b\u0148te n\xe1zev nebo ze seznamu pou\u017eit\xed odeberte \u201erbd\u201c\n \n \n Cache Tiers Details\n Podrobnosti o stupn\xedch mezipam\u011bti\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Pod\xedvejte se do \n dokumentace\n \n jak nastavit a zapnout funkci spr\xe1vy br\xe1ny objekt\u016f.\n \n \n \n Daemons List\n Seznam proces\u016f slu\u017eeb\n \n \n Performance Counters\n V\xfdkonnostn\xed \u010d\xedta\u010de\n \n \n Loading bucket data...\n Na\u010d\xedt\xe1n\xed dat n\xe1doby\u2026\n \n \n The bucket data could not be loaded.\n Data n\xe1doby se nepoda\u0159ilo na\u010d\xedst.\n \n \n Id\n Identif.\n \n \n The value is not valid.\n Hodnota nen\xed platn\xe1.\n \n \n Owner\n Vlastn\xedk\n \n \n -- Select a user --\n -- Vybrat u\u017eivatele --\n \n \n ID\n Identif.\n \n \n Index type\n Typ rejst\u0159\xedku\n \n \n Placement rule\n Pravidlo um\xedst\u011bn\xed\n \n \n Marker\n Ozna\u010dova\u010d\n \n \n Maximum marker\n Nejvy\u0161\u0161\xed ozna\u010dova\u010d\n \n \n Version\n Verze\n \n \n Master version\n Hlavn\xed verze\n \n \n Modification time\n Okam\u017eik \xfapravy\n \n \n Zonegroup\n Skupinaz\xf3ny\n \n \n Bucket quota\n Kv\xf3ta n\xe1doby\n \n \n Enabled\n Zapnuto\n \n \n Maximum size\n Nejvy\u0161\u0161\xed velikost\n \n \n Unlimited\n Neomezeno\n \n \n Maximum objects\n Nejv\xfd\u0161e objekt\u016f\n \n \n -- Select a username --\n -- Vybrat u\u017eivatelsk\xe9 jm\xe9no --\n \n \n Auto-generate key\n Automaticky vytvo\u0159it kl\xed\u010d\n \n \n Access key\n P\u0159\xedstupov\xfd kl\xed\u010d\n \n \n Secret key\n Tajn\xfd kl\xed\u010d\n \n \n Email address\n E-mailov\xe1 adresa\n \n \n Suspended\n Pozastaveno\n \n \n System\n Syst\xe9m\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n \n \n Maximum buckets\n Nejv\xfd\u0161e n\xe1dob\n \n \n Subusers\n D\xedl\u010d\xed u\u017eivatel\xe9\n \n \n Capabilities\n Schopnosti\n \n \n User quota\n Kv\xf3ta u\u017eivatele\n \n \n Show\n Zobrazit\n \n \n Keys\n Kl\xed\u010de\n \n \n -- Select a type --\n -- Vybrat typ --\n \n \n Permission\n Opr\xe1vn\u011bn\xed\n \n \n -- Select a permission --\n -- Vybrat opr\xe1vn\u011bn\xed --\n \n \n Subuser\n D\xedl\u010d\xed u\u017eivatel\n \n \n The chosen subuser ID is already in use.\n Zvolen\xfd identifik\xe1tor d\xedl\u010d\xedho u\u017eivatele u\u017e je pou\u017e\xedv\xe1n.\n \n \n read, write\n \u010d\xedst, zapisovat\n \n \n full\n pln\xe9\n \n \n Swift key\n Swift kl\xed\u010d\n \n \n Auto-generate secret\n Automaticky vytvo\u0159it tajemstv\xed\n \n \n Loading user data...\n Na\u010d\xedt\xe1n\xed \xfadaj\u016f u\u017eivatele\u2026\n \n \n The user data could not be loaded.\n \xdadaje u\u017eivatele se nepoda\u0159ilo na\u010d\xedst.\n \n \n The chosen user ID is already in use.\n Zvolen\xfd identif. u\u017eivatele u\u017e je pou\u017e\xedv\xe1n.\n \n \n This is not a valid email address.\n Toto nen\xed platn\xe1 e-mailov\xe1 adresa.\n \n \n The chosen email address is already in use.\n Zvolen\xe1 e-mailov\xe1 adresa u\u017e je pou\u017e\xedv\xe1na.\n \n \n Max. buckets\n Nejv\xfd\u0161e n\xe1dob\n \n \n The entered value must be >= 0.\n Je t\u0159eba, aby zadan\xe1 hodnota byla 0 a vy\u0161\u0161\xed.\n \n \n S3 key\n S3 kl\xed\u010d\n \n \n There are no subusers.\n Nejsou zde \u017e\xe1dn\xed d\xedl\u010d\xed u\u017eivatel\xe9.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n Nejsou zde \u017e\xe1dn\xe9 kl\xed\u010de.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n Nejsou zde \u017e\xe1dn\xe9 schopnosti.\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Neomezen\xe1 velikost\n \n \n Max. size\n Nejvy\u0161\u0161\xed velikost\n \n \n Unlimited objects\n Neomezen\xe9 objekty\n \n \n Max. objects\n Nejv\xfd\u0161e objekt\u016f\n \n \n Current\n St\xe1vaj\xedc\xed\n \n \n Updated discovery authentication\n Aktualizov\xe1no ov\u011b\u0159ov\xe1n\xed pro objevov\xe1n\xed\n \n \n There are no portals available.\n Nejsou k dispozici \u017e\xe1dn\xe9 port\xe1ly.\n \n \n There are no images available.\n Nejsou k dispozici \u017e\xe1dn\xe9 obrazy.\n \n \n There are no images available. Please make sure you add an image to the target.\n Nejsou k dispozici \u017e\xe1dn\xe9 obrazy. Ov\u011b\u0159te, \u017ee jste c\xedli p\u0159idali obraz.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n Nejsou k dispozici \u017e\xe1dn\xe9 inici\xe1tory. Ov\u011b\u0159te, \u017ee jste c\xedli p\u0159idali inici\xe1tor.\n \n \n target\n target\n \n \n Target\n C\xedl\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n Stav\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Bajt\u016f \u010dten\xed\n \n \n Write Bytes\n Bajt\u016f z\xe1pis\n \n \n Read Ops\n Operac\xed/s \u010dten\xed\n \n \n Write Ops\n Operac\xed/s z\xe1pis\n \n \n A/O Since\n A/O od\n \n \n Instance\n Instance\n \n \n Hostname\n N\xe1zev stroje\n \n \n Issue\n Probl\xe9m\n \n \n Progress\n Ukazatel postupu\n \n \n Disabled\n Vypnuto\n \n \n Edit Mode\n Upravit re\u017eim\n \n \n Add Peer\n P\u0159idat prot\u011bj\u0161ek\n \n \n Edit Peer\n Upravit prot\u011bj\u0161ek\n \n \n Delete Peer\n Smazat prot\u011bj\u0161ek\n \n \n Leader\n Vedouc\xed\n \n \n # Local\n Po\u010det m\xedstn\xedch\n \n \n # Remote\n Po\u010det vzd\xe1len\xfdch\n \n \n mirror peer\n zrcadlit prot\u011bj\u0161ek\n \n \n Key\n Kl\xed\u010d\n \n \n RBD\n RBD\n \n \n Deep flatten\n Hlubok\xe9 zplo\u0161t\u011bn\xed\n \n \n Layering\n Vrstven\xed\n \n \n Exclusive lock\n V\xfdhradn\xed z\xe1mek\n \n \n Object map (requires exclusive-lock)\n Mapa objekt\u016f (vy\u017eaduje v\xfdhradn\xed z\xe1mek)\n \n \n Journaling (requires exclusive-lock)\n \u017durn\xe1lov\xe1n\xed (vy\u017eaduje v\xfdhradn\xed z\xe1mek)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Vr\xe1cen\xed zachycen\xe9ho stavu RBD zp\u011bt\n \n \n Rollback\n Vr\xe1cen\xed zp\u011bt\n \n \n RBD snapshot\n Zachycen\xfd stav RBD\n \n \n Deleted At\n Smaz\xe1no v\n \n \n id\n identif.\n \n \n type\n typ\n \n \n state\n stav\n \n \n version\n verze\n \n \n Host\n Stroj\n \n \n root\n ko\u0159en\n \n \n Rank\n Hodnocen\xed\n \n \n Daemon\n Proces slu\u017eby\n \n \n Activity\n Aktivita\n \n \n Dentries\n Struktury slo\u017eek\n \n \n Inodes\n I-uzl\u016f\n \n \n Usage\n Vyu\u017eit\xed\n \n \n Standby daemons\n Procesy slu\u017eeb v pohotovosti\n \n \n The value can be updated at runtime.\n Hodnotu je mo\u017en\xe9 aktualizovat za chodu.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n Procesy slu\u017eeb / klienti nez\xedsk\xe1vaj\xed tuto hodnotu\n z datab\xe1ze nastaven\xed monitoru. Nen\xed umo\u017en\u011bno nastavit tuto volbu\n prost\u0159ednictv\xedm \u201eceph config set \u2026\'. Tato volba by m\u011bla b\xfdt nastavena\n z p\u0159\xedkazov\xe9ho \u0159\xe1dku.\n \n \n Option takes effect only during daemon startup.\n Volba se uplatn\xed pouze p\u0159i spou\u0161t\u011bn\xed procesu slu\u017eby.\n \n \n Option only affects cluster creation.\n Volba ovlivn\xed pouze vytv\xe1\u0159en\xed klastru.\n \n \n Option only affects daemon creation.\n Volba ovlivn\xed pouze vytvo\u0159en\xed procesu slu\u017eby.\n \n \n Updated config option \n \n \n Aktualizov\xe1na volba nastaven\xed \n \n \n \n \n Service\n Slu\u017eba\n \n \n Current value\n St\xe1vaj\xedc\xed hodnota\n \n \n Editable\n Upraviteln\xe9\n \n \n Updated options for module "\n ".\n \n Aktualizov\xe1na volba pro modul \u201e\n \u201c\n \n \n \n Enable\n Zapnout\n \n \n Disable\n Vypnout\n \n \n Reconnecting, please wait ...\n Op\u011btovn\xe9 p\u0159ipojov\xe1n\xed, \u010dekejte\u2026\n \n \n Public Address\n Ve\u0159ejn\xe1 adresa\n \n \n Open Sessions\n Otev\u0159en\xe9 relace\n \n \n No In\n Po\u010det do\n \n \n OSDs that were previously marked out will not be marked back in when they start\n OSD kter\xe9 byly d\u0159\xedve odzna\u010deny nebudou ozna\u010deny nazp\u011bt kdy\u017e spust\xed\n \n \n No Out\n Po\u010det ven\n \n \n OSDs will not automatically be marked out after the configured interval\n OSD nebudou automaticky odzna\u010deny po nastaven\xe9m intervalu\n \n \n No Up\n Po\u010det aktivn\xedch\n \n \n OSDs are not allowed to start\n OSD nen\xed dovoleno spu\u0161t\u011bn\xed\n \n \n No Down\n Po\u010det neaktivn\xedch\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n Hl\xe1\u0161en\xed o selh\xe1n\xed OSD jsou ignorov\xe1ny, jako nap\u0159\xedklad \u017ee monitory OSD neozna\u010d\xed jako nedostupn\xe9\n \n \n Pause\n Pozastavit\n \n \n Pauses reads and writes\n Pozastavit \u010dten\xed a z\xe1pisy\n \n \n No Scrub\n \u017d\xe1dn\xe1 kontrola\n \n \n Scrubbing is disabled\n Kontrola je vypnut\xe1\n \n \n No Deep Scrub\n \u017d\xe1dn\xe1 hloubkov\xe1 kontrola\n \n \n Deep Scrubbing is disabled\n Hloubkov\xe1 kontrola je vypnut\xe1\n \n \n No Backfill\n \u017d\xe1dn\xe9 zasyp\xe1v\xe1n\xed\n \n \n Backfilling of PGs is suspended\n Zasyp\xe1v\xe1n\xed skupin um\xedst\u011bn\xed je pozastaveno\n \n \n No Recover\n \u017d\xe1dn\xe9 obnoven\xed\n \n \n Recovery of PGs is suspended\n Obnovov\xe1n\xed skupin um\xedst\u011bn\xed je pozastaveno\n \n \n Bitwise Sort\n Bitov\xe9 t\u0159\xedd\u011bn\xed\n \n \n Use bitwise sort\n T\u0159\xeddit podle bit\u016f\n \n \n Purged Snapdirs\n Vy\u010di\u0161t\u011bn\xe9 slo\u017eky zachycen\xfdch stav\u016f\n \n \n OSDs have converted snapsets\n OSD maj\xed p\u0159eveden\xe9 sady zachycen\xfdch stav\u016f\n \n \n Recovery Deletes\n Smaz\xe1no p\u0159i zotavov\xe1n\xed\n \n \n Deletes performed during recovery instead of peering\n Maz\xe1n\xed proveden\xe1 p\u0159i obnovov\xe1n\xed nam\xedsto peeringu\n \n \n PG Log Hard Limit\n Nep\u0159ekro\u010diteln\xfd limit z\xe1znamu ud\xe1lost\xed PG\n \n \n Puts a hard limit on pg log length\n Zapne nep\u0159ekro\u010diteln\xfd limit na d\xe9lku z\xe1znamu ud\xe1lost\xed v pg\n \n \n Updated OSD Flags\n Aktualizov\xe1ny OSD p\u0159\xedznaky\n \n \n out\n ven\n \n \n in\n dovnit\u0159\n \n \n down\n nedostupn\xe9\n \n \n Mark\n Zna\u010dka\n \n \n OSD lost\n OSD ztraceno\n \n \n marked lost\n ozna\u010deno jako ztracen\xe9\n \n \n Purge\n Vy\u010distit\n \n \n OSD\n OSD\n \n \n purged\n vy\u010di\u0161t\u011bno\n \n \n destroy\n zlikvidovat\n \n \n destroyed\n zlikvidov\xe1no\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n skupiny um\xedst\u011bn\xed\n \n \n Read bytes\n P\u0159e\u010dteno bajt\u016f\n \n \n Writes bytes\n Zaps\xe1no bajt\u016f\n \n \n Read ops\n Operac\xed/s \u010dten\xed\n \n \n Write ops\n Operac\xed/s z\xe1pis\n \n \n Mark OSD \n \n \n Ozna\u010dit OSD \n \n \n \n \n Mark \n \n \n Ozna\u010dit \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n Max Backfills\n \n \n Recovery Max Active\n Recovery Max Active\n \n \n Recovery Max Single Start\n Recovery Max Single Start\n \n \n Recovery Sleep\n Recovery Sleep\n \n \n Custom\n U\u017eivatelsky ur\u010den\xe9\n \n \n Updated OSD recovery speed priority "\n "\n \n Aktualizov\xe1na rychlost zotaven\xed OSD \u201e\n \u201c\n \n \n \n \n was initialized in the following OSD: \n \n \n \n bylo inicializov\xe1no v n\xe1sleduj\xedc\xedm OSD: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n \xdaloha\n \n \n Severity\n Z\xe1va\u017enost\n \n \n Started\n Zah\xe1jeno\n \n \n URL\n URL adresa\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Aktualizov\xe1no\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n Pou\u017eito\n \n \n Avail.\n K dispozici\n \n \n Clean\n \u010cist\xe9\n \n \n Working\n Pracuj\xedc\xed\n \n \n Warning\n Varov\xe1n\xed\n \n \n Unknown\n Nezn\xe1m\xe9\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n aktivn\xed\n \n \n no filesystems\n \u017e\xe1dn\xe9 souborov\xe9 syst\xe9my\n \n \n active\n aktivn\xed\n \n \n standby\n v pohotovosti\n \n \n n/a\n n/a\n \n \n active daemon\n aktivn\xed proces slu\u017eby\n \n \n quorum\n kv\xf3rum\n \n \n The NFS Ganesha service is not configured.\n Slu\u017eba NFS Ganesha nen\xed nastavena.\n \n \n Transport\n Transport\n \n \n CephFS User\n CephFS u\u017eivatel\n \n \n CephFS Filesystem\n Souborov\xfd syst\xe9m CephFS\n \n \n (inherited from global config)\n (p\u0159evzato z glob\xe1ln\xedho nastaven\xed)\n \n \n inherited from global config\n p\u0159evzato z glob\xe1ln\xedho nastaven\xed\n \n \n -- Select what kind of user id squashing is performed --\n -- Select what kind of user id squashing is performed --\n \n \n There are no daemons available.\n Nejsou k dispozici \u017e\xe1dn\xe9 procesy slu\u017eeb.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Re\u017eim mezipam\u011bti\n \n \n Min Evict Age\n Min Evict Age\n \n \n Min Flush Age\n Min Flush Age\n \n \n Target Max Bytes\n Nejv\xfd\u0161e bajt\u016f c\xedle\n \n \n Target Max Objects\n Nejv\xfd\u0161e objekt\u016f c\xedle\n \n \n No applications added\n Nebyla p\u0159id\xe1na \u017e\xe1dn\xe1 aplikace\n \n \n Applications limit reached\n Dosa\u017een limit aplikac\xed\n \n \n A pool can only have up to four applications definitions.\n Fond m\u016f\u017ee m\xedt nejv\xfd\u0161e \u010dty\u0159i definice aplikac\xed.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n Pou\u017eiteln\xe9 znaky \u201e_a-zA-Z0-9\u201c\n \n \n Maximum length is 128 characters\n Nejvy\u0161\u0161\xed d\xe9lka je 128 znak\u016f\n \n \n Filter or add applications\n Filtrovat nebo p\u0159idat aplikace\n \n \n Add application\n P\u0159idat aplikaci\n \n \n pool\n pool\n \n \n erasure code profile\n profil mazac\xedho k\xf3du\n \n \n Replica Size\n Velikost repliky\n \n \n Last Change\n Nejnov\u011bj\u0161\xed zm\u011bna\n \n \n Erasure Coded Profile\n Maz\xe1n\xedm k\xf3dovan\xfd profil\n \n \n Crush Ruleset\n Sada crush pravidel\n \n \n Write bytes\n Zaps\xe1no bajt\u016f\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n n\xe1doba\n \n \n Updated Object Gateway bucket "\n "\n \n Aktualizov\xe1na n\xe1doba objektov\xe9 br\xe1ny \u201e\n \u201c\n \n \n \n Created Object Gateway bucket "\n "\n \n Vytvo\u0159ena n\xe1doba objektov\xe9 br\xe1ny \u201e\n \u201c\n \n \n \n buckets\n n\xe1doby\n \n \n capability\n capability\n \n \n user\n u\u017eivatel\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Aktualizov\xe1n u\u017eivatel objektov\xe9 br\xe1ny \u201e\n \u201c\n \n \n \n Created Object Gateway user "\n "\n \n Vytvo\u0159en u\u017eivatel objektov\xe9 br\xe1ny \u201e\n \u201c\n \n \n \n users\n u\u017eivatel\xe9\n \n \n Swift Key\n Swift Key\n \n \n Scope\n Rozsah\n \n \n Read\n \u010cten\xed\n \n \n Create\n Vytvo\u0159it\n \n \n role\n role\n \n \n Created role \'\n \'\n \n Vytvo\u0159ena role \u201e\n \u201c\n \n \n \n Updated role \'\n \'\n \n Aktualizov\xe1na role \u201e\n \u201c\n \n \n \n System Role\n Syst\xe9mov\xe1 role\n \n \n Deleted role \'\n \'\n \n Smaz\xe1na role \u201e\n \u201c\n \n \n \n Created user "\n "\n \n Vytvo\u0159en u\u017eivatel \u201e\n \u201c\n \n \n \n Update user\n Aktualizovat u\u017eivatele\n \n \n Continue\n Pokra\u010dovat\n \n \n You were automatically logged out because your roles have been changed.\n Byli jste automaticky odhl\xe1\u0161eni proto\u017ee va\u0161e role byly zm\u011bn\u011bny.\n \n \n Updated user "\n "\n \n Aktualizov\xe1n u\u017eivatel \u201e\n \u201c\n \n \n \n Deleted user "\n "\n \n Smaz\xe1n u\u017eivatel \u201e\n \u201c\n \n \n \n Failed to delete user "\n "\n \n Nepoda\u0159ilo se smazat u\u017eivatele \u201e\n \u201c\n \n \n \n You are currently logged in as "\n ".\n \n Nyn\xed jste p\u0159ihl\xe1\u0161en\xed jako \u201e\n \u201c.\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Ka\u017ed\xfd objekt je rozd\u011blen v \u010d\xe1stech shluk\u016f dat, ka\u017ed\xe9 ulo\u017een\xe9 na jin\xe9m OSD.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Po\u010d\xedtat k\xf3dovac\xed shluky pro ka\u017ed\xfd objekt a ukl\xe1dat je na r\u016fzn\xfdch OSD.\n Po\u010det k\xf3dovac\xedch shluk\u016f je tak\xe9 po\u010det OSD, kter\xe9 mohou vypadnou, ani\u017e dojde ke ztr\xe1t\u011b dat.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Z\xe1suvn\xfd modul jerasure je nejobecn\u011bj\u0161\xed a nejp\u0159izp\u016fsobiv\u011bj\u0161\xed,\n je tak\xe9 v\xfdchoz\xed pro Ceph fondy k\xf3dovan\xe9 maz\xe1n\xedm.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n Z\xe1suvn\xfd modul isa obaluje knihovnu ISA. Funguje pouze na procesorech Intel.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n N\xe1zev crush n\xe1doby slou\u017e\xedc\xed jako prvn\xed krok CRUSH pravidla.\n Nap\u0159\xedklad krok vz\xedt v\xfdchoz\xed.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Omezit um\xedst\u011bn\xed na za\u0159\xedzen\xed ur\u010dit\xe9 t\u0159\xeddy\n (nap\u0159., ssd nebo hdd), pomoc\xed n\xe1zvu crush t\u0159\xeddy za\u0159\xedzen\xed v CRUSH map\u011b.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n Nastavit slo\u017eku ze kter\xe9 na\u010d\xedtat z\xe1suvn\xfd modul mazac\xedho k\xf3du.\n \n \n Allows all operations\n Umo\u017enit v\u0161echny operace\n \n \n Allows only operations that do not modify the server\n Umo\u017enit pouze operace kter\xe9 neuprav\xed server\n \n \n Does not allow read or write operations, but allows any other operation\n Neumo\u017e\u0148uje operace \u010dten\xed \u010di z\xe1pisu, ale umo\u017e\u0148uje ostatn\xed\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n Neumo\u017e\u0148uje \u010dten\xed, z\xe1pis nebo jinou operaci kter\xe1 upravuje atributy souboru nebo obsah slo\u017eky\n \n \n Allows no access at all\n Neumo\u017enit v\u016fbec \u017e\xe1dn\xfd p\u0159\xedstup\n \n \n -- Select the priority --\n -- Vyberte prioritu --\n \n \n Low\n N\xedzk\xe1\n \n \n High\n Vysok\xe1\n \n \n Last 5 minutes\n Uplynul\xfdch 5 minut\n \n \n Last 15 minutes\n Uplynul\xfdch 15 minut\n \n \n Last 30 minutes\n Uplynul\xfdch 30 minut\n \n \n Last 1 hour (Default)\n Uplynul\xe1 1 hodina (v\xfdchoz\xed)\n \n \n Last 3 hours\n Uplynul\xe9 3 hodiny\n \n \n Last 6 hours\n Uplynul\xfdch 6 hodin\n \n \n Last 12 hours\n Uplynul\xfdch 12 hodin\n \n \n Last 24 hours\n Uplynul\xfdch 24 hodin\n \n \n Yesterday\n V\u010dera\n \n \n Today\n Dnes\n \n \n Today so far\n Dnes doposud\n \n \n Day before yesterday\n V\u010derej\u0161ek\n \n \n Last 2 days\n Uplynul\xe9 2 dny\n \n \n This day last week\n Tento den minul\xfd t\xfdden\n \n \n Previous week\n P\u0159edchoz\xed t\xfdden\n \n \n This week\n Tento t\xfdden\n \n \n This week so far\n Tento t\xfdden doposud\n \n \n Last 7 days\n Uplynul\xfdch 7 dn\u016f\n \n \n Previous month\n P\u0159edchoz\xed m\u011bs\xedc\n \n \n This month\n Tento m\u011bs\xedc\n \n \n This month so far\n Tento m\u011bs\xedc doposud\n \n \n Last 30 days\n Uplynul\xfdch 30 dn\u016f\n \n \n Last 90 days\n Uplynul\xfdch 90 dn\u016f\n \n \n Last 6 months\n Uplynul\xfdch 6 m\u011bs\xedc\u016f\n \n \n Last 1 year\n Uplynul\xfd 1 rok\n \n \n Previous year\n P\u0159edchoz\xed rok\n \n \n This year\n Tento rok\n \n \n This year so far\n Tento rok doposud\n \n \n Last 2 years\n Uplynul\xe9 2 roky\n \n \n Last 5 years\n Uplynul\xfdch 5 let\n \n \n Information\n Informace\n \n \n No items selected.\n Nevybr\xe1ny \u017e\xe1dn\xe9 polo\u017eky.\n \n \n Deselect item to select again\n Aby polo\u017eku bylo mo\u017en\xe9 znovu vybrat, je t\u0159eba nejprve zru\u0161it jej\xed v\xfdb\u011br\n \n \n Selection limit reached\n Dosa\u017een limit v\xfdb\u011bru\n \n \n Filter tags\n Filtrovat \u0161t\xedtky\n \n \n Add badge\n P\u0159idat odznak\n \n \n There are no items available.\n Nejsou k dispozici \u017e\xe1dn\xe9 polo\u017eky.\n \n \n Add\n P\u0159idat\n \n \n Remove\n Remove\n \n \n Clone\n Klonovat\n \n \n Copy\n Kop\xedrovat\n \n \n Deep Scrub\n Hloubkov\xe1 kontrola\n \n \n Destroy\n Zlikvidovat\n \n \n Flatten\n Zplo\u0161tit\n \n \n Mark Down\n Ozna\u010dit\n \n \n Mark In\n Ozna\u010dit\n \n \n Mark Lost\n Ozna\u010dit ztracen\xe9\n \n \n Mark Out\n Odzna\u010dit\n \n \n Protect\n Ochr\xe1nit\n \n \n Rename\n P\u0159ejmenovat\n \n \n Restore\n Obnovit\n \n \n Move to Trash\n P\u0159esunout do ko\u0161e\n \n \n Unprotect\n Zru\u0161it ochranu\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Smaz\xe1no\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Naklonov\xe1no\n \n \n Copied\n Zkop\xedrov\xe1no\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n Ano\n \n \n No\n Ne\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Kvalita slu\u017eby\n \n \n BPS Limit\n BPS Limit\n \n \n The desired limit of IO bytes per second.\n Po\u017eadovan\xfd limit vst./v\xfdstup. bajt\u016f za sekundu.\n \n \n IOPS Limit\n IOPS Limit\n \n \n The desired limit of IO operations per second.\n Po\u017eadovan\xfd limit vst./v\xfdstup. operac\xed za sekundu.\n \n \n Read BPS Limit\n Read BPS Limit\n \n \n The desired limit of read bytes per second.\n Po\u017eadovan\xfd limit \u010dten\xed bajt\u016f za sekundu.\n \n \n Read IOPS Limit\n Read IOPS Limit\n \n \n The desired limit of read operations per second.\n Po\u017eadovan\xfd limit operac\xed \u010dten\xed za sekundu.\n \n \n Write BPS Limit\n Write BPS Limit\n \n \n The desired limit of write bytes per second.\n Po\u017eadovan\xfd limit z\xe1pisu bajt\u016f za sekundu.\n \n \n Write IOPS Limit\n Write IOPS Limit\n \n \n The desired limit of write operations per second.\n Po\u017eadovan\xfd limit operac\xed \u010dten\xed za sekundu.\n \n \n BPS Burst\n BPS d\xe1vka\n \n \n The desired burst limit of IO bytes.\n The desired burst limit of IO bytes.\n \n \n IOPS Burst\n IOPS Burst\n \n \n The desired burst limit of IO operations.\n Po\u017eadovan\xfd limit d\xe1vky vst./v\xfdstup. operac\xed.\n \n \n Read BPS Burst\n Read BPS Burst\n \n \n The desired burst limit of read bytes.\n Po\u017eadovan\xfd limit d\xe1vky bajt\u016f \u010dten\xed.\n \n \n Read IOPS Burst\n Read IOPS Burst\n \n \n The desired burst limit of read operations.\n Po\u017eadovan\xfd limit d\xe1vky \u010dten\xed bajt\u016f.\n \n \n Write BPS Burst\n Write BPS Burst\n \n \n The desired burst limit of write bytes.\n Po\u017eadovan\xfd limit bajt\u016f d\xe1vky z\xe1pisu.\n \n \n Write IOPS Burst\n Write IOPS Burst\n \n \n The desired burst limit of write operations.\n Po\u017eadovan\xfd limit d\xe1vky operace z\xe1pisu.\n \n \n Failed to \n \n \n \n Nepoda\u0159ilo se \n \n \n \n \n \n Executing\n Vykon\xe1v\xe1 se\n \n \n execute\n vykonat\n \n \n Executed\n Vykon\xe1no\n \n \n unknown task\n nezn\xe1m\xfd \xfakol\n \n \n Creating\n Vytv\xe1\u0159\xed se\n \n \n create\n vytvo\u0159it\n \n \n Updating\n Aktualizuje se\n \n \n update\n aktualizovat\n \n \n Deleting\n Ma\u017ee se\n \n \n delete\n smazat\n \n \n RBD \'\n \'\n \n RBD \u201e\n \u201c\n \n \n \n RBD snapshot \'\n \'\n \n RBD zachycen\xfd stav \u201e\n \u201c\n \n \n \n mirror mode for pool \'\n \'\n \n re\u017eim zrcadlen\xed pro fond \u201e\n \u201c\n \n \n \n mirror peer for pool \'\n \'\n \n prot\u011bj\u0161ek zrcadlen\xed pro fond \u201e\n \u201c\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n N\xe1zev u\u017e je pou\u017e\xedv\xe1n \n .\n \n \n \n Name is already used by \n .\n \n N\xe1zev u\u017e je pou\u017e\xedv\xe1n \n .\n \n \n \n Name is already used by \n .\n \n N\xe1zev u\u017e je pou\u017e\xedv\xe1n \n .\n \n \n \n \n contains snapshots.\n \n \n obsahuje zachycen\xe9 stavy.\n \n \n \n Cloning\n Klonuje se\n \n \n clone\n klonovat\n \n \n Snapshot of \n must be protected.\n \n Je t\u0159eba, aby zachycen\xfd stav \n byl chr\xe1n\u011bn\xfd.\n \n \n \n Copying\n Kop\xedruje se\n \n \n copy\n zkop\xedrovat\n \n \n Flattening\n Zplo\u0161t\u011bn\xed\n \n \n flatten\n zplo\u0161tit\n \n \n Flattened\n Zplo\u0161t\u011bno\n \n \n Name is already used by \n .\n \n N\xe1zev u\u017e je pou\u017e\xedv\xe1n pro \n .\n \n \n \n Cannot unprotect \n because it contains child images.\n \n Nen\xed mo\u017en\xe9 zru\u0161it ochranu \n , proto\u017ee obsahuje pod\u0159\xedzen\xe9 obrazy.\n \n \n \n Cannot delete \n because it\'s protected.\n \n \n nen\xed mo\u017en\xe9 smazat, proto\u017ee je chr\xe1n\u011bn\xe9.\n \n \n \n Rolling back\n Bere se zp\u011bt\n \n \n rollback\n vz\xedt zp\u011bt\n \n \n Rolled back\n Vzato zp\u011bt\n \n \n Moving\n P\u0159esouv\xe1 se\n \n \n move\n p\u0159esunout\n \n \n Moved\n P\u0159esunuto\n \n \n image \'\n \' to trash\n \n obraz \u201e\n \u201c do ko\u0161e\n \n \n \n Could not find image.\n Obraz se neda\u0159\xed naj\xedt.\n \n \n Restoring\n Obnovuje se\n \n \n restore\n obnovit\n \n \n Restored\n Obnoveno\n \n \n image \'\n \' into \'\n \'\n \n obraz \u201e\n \u201c do \u201e\n \u201c\n \n \n \n Image name \'\n \' is already in use.\n \n N\xe1zev \u201e\n \u201c u\u017e je pou\u017e\xedv\xe1n pro jin\xfd obraz.\n \n \n \n image \'\n \'\n \n obraz \u201e\n \u201c\n \n \n \n Purging\n \u010cist\xed se\n \n \n purge\n vy\u010distit\n \n \n Purged\n Vy\u010di\u0161t\u011bno\n \n \n all pools\n v\u0161echny fondy\n \n \n images from \n \n \n obrazy z \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n Zrcadlen\xed nelze vypnout proto\u017ee obsahuje prot\u011bj\u0161ek.\n \n \n pool \'\n \'\n \n fond \u201e\n \u201c\n \n \n \n erasure code profile \'\n \'\n \n profil mazac\xedho k\xf3du \u201e\n \u201c\n \n \n \n target \'\n \'\n \n c\xedl \u201e\n \u201c\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},McSo:function(t,e,n){"use strict";function a(t){return null!==t&&"object"==typeof t}n.d(e,"a",function(){return a})},MdoF:function(t,e,n){"use strict";n.d(e,"b",function(){return s}),n.d(e,"c",function(){return c}),n.d(e,"a",function(){return d});var a=n("CcnG"),r=n("lTVp"),i=n("Ip0R"),s=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"button",[["aria-label","Close"],["class","close"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.close()&&a),a},null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["\xd7"])),(t()(),a["\u0275eld"](3,0,null,null,1,"span",[["class","sr-only"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Close"]))],null,null)}function u(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"div",[["role","alert"]],null,null,null,null,null)),a["\u0275did"](1,278528,null,0,i.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,o)),a["\u0275did"](3,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),a["\u0275ncd"](null,0)],function(t,e){var n=e.component;t(e,1,0,"alert alert-"+n.type,n.classes),t(e,3,0,n.dismissible)},null)}function c(t){return a["\u0275vid"](2,[(t()(),a["\u0275and"](16777216,null,null,1,null,u)),a["\u0275did"](1,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,1,0,e.component.isOpen)},null)}function l(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"alert",[],null,null,null,c,s)),a["\u0275did"](1,114688,null,0,r.a,[r.b,a.ChangeDetectorRef],null,null)],function(t,e){t(e,1,0)},null)}var d=a["\u0275ccf"]("alert,bs-alert",r.a,l,{type:"type",dismissible:"dismissible",dismissOnTimeout:"dismissOnTimeout",isOpen:"isOpen"},{onClose:"onClose",onClosed:"onClosed"},["*"])},Mfce:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG");n("czA5"),e.DataTableRowWrapperComponent=function(){function t(t,e){this.cd=t,this.differs=e,this.rowContextmenu=new i.EventEmitter(!1),this.groupContext={group:this.row,expanded:this.expanded,rowIndex:this.rowIndex},this.rowContext={row:this.row,expanded:this.expanded,rowIndex:this.rowIndex},this._expanded=!1,this.rowDiffer=e.find({}).create()}return Object.defineProperty(t.prototype,"rowIndex",{get:function(){return this._rowIndex},set:function(t){this._rowIndex=t,this.rowContext.rowIndex=t,this.groupContext.rowIndex=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"expanded",{get:function(){return this._expanded},set:function(t){this._expanded=t,this.groupContext.expanded=t,this.rowContext.expanded=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),t.prototype.ngDoCheck=function(){this.rowDiffer.diff(this.row)&&(this.rowContext.row=this.row,this.groupContext.group=this.row,this.cd.markForCheck())},t.prototype.onContextmenu=function(t){this.rowContextmenu.emit({event:t,row:this.row})},t.prototype.getGroupHeaderStyle=function(){var t={};return t.transform="translate3d("+this.offsetX+"px, 0px, 0px)",t["backface-visibility"]="hidden",t.width=this.innerWidth,t},a([i.Input(),r("design:type",Number)],t.prototype,"innerWidth",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"rowDetail",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"groupHeader",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"offsetX",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"detailRowHeight",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"row",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"groupedRows",void 0),a([i.Output(),r("design:type",Object)],t.prototype,"rowContextmenu",void 0),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"rowIndex",null),a([i.Input(),r("design:type",Boolean),r("design:paramtypes",[Boolean])],t.prototype,"expanded",null),a([i.HostListener("contextmenu",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onContextmenu",null),a([i.Component({selector:"datatable-row-wrapper",changeDetection:i.ChangeDetectionStrategy.OnPush,template:'\n
\n \n \n
\n \n \n \n \n \n \n ',host:{class:"datatable-row-wrapper"}})],t)}()},MgB7:function(t,e,n){"use strict";function a(t,e,n){var a,r,i;n=n||{};var s=null,o=0;function u(){o=!1===n.leading?0:+new Date,s=null,i=t.apply(a,r)}return function(){var c=+new Date;o||!1!==n.leading||(o=c);var l=e-(c-o);return a=this,r=arguments,l<=0?(clearTimeout(s),s=null,o=c,i=t.apply(a,r)):s||!1===n.trailing||(s=setTimeout(u,l)),i}}Object.defineProperty(e,"__esModule",{value:!0}),e.throttle=a,e.throttleable=function(t,e){return function(n,r,i){return{configurable:!0,enumerable:i.enumerable,get:function(){return Object.defineProperty(this,r,{configurable:!0,enumerable:i.enumerable,value:a(i.value,t,e)}),this[r]}}}}},MuvH:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("CcnG"),r=n("t/Na"),i=n("pL04"),s=function(){function t(t){this.http=t}return t.prototype.getConfigData=function(){return this.http.get("api/cluster_conf/")},t.prototype.get=function(t){return this.http.get("api/cluster_conf/"+t)},t.prototype.filter=function(t){return this.http.get("api/cluster_conf/filter?names="+t.join(","))},t.prototype.create=function(t){return this.http.post("api/cluster_conf/",t)},t.prototype.delete=function(t,e){return this.http.delete("api/cluster_conf/"+t+"?section="+e)},t.prototype.bulkCreate=function(t){return this.http.put("api/cluster_conf/",t)},t.ngInjectableDef=a.defineInjectable({factory:function(){return new t(a.inject(r.c))},token:t,providedIn:i.a}),t}()},MwfX:function(t,e,n){"use strict";n.d(e,"a",function(){return d}),n.d(e,"b",function(){return f});var a=n("mrSG"),r=n("zo3G"),i=n("26FU"),s=n("6blF"),o=n("mZXl"),u=n("dC0D"),c=n("67Y/"),l=n("ad02"),d=function(t){function e(e,n,a){var i=t.call(this,e)||this;return n.pipe(Object(o.b)(r.a)).pipe(Object(u.a)(function(t,e){return e?a(t,e):t},e)).subscribe(function(t){return i.next(t)}),i}return Object(a.__extends)(e,t),e}(i.a),f=function(t){function e(e,n,a){var r=t.call(this)||this;return r._dispatcher=e,r._reducer=n,r.source=a,r}return Object(a.__extends)(e,t),e.prototype.select=function(t){return this.source.pipe(Object(c.a)(t)).pipe(Object(l.a)())},e.prototype.lift=function(t){var n=new e(this._dispatcher,this._reducer,this);return n.operator=t,n},e.prototype.dispatch=function(t){this._dispatcher.next(t)},e.prototype.next=function(t){this._dispatcher.next(t)},e.prototype.error=function(t){this._dispatcher.error(t)},e.prototype.complete=function(){},e}(s.a)},Mxhz:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("CcnG"),r=n("t/Na"),i=n("pL04"),s=function(){function t(t){this.http=t}return t.prototype.list=function(){return this.http.get("api/user")},t.prototype.delete=function(t){return this.http.delete("api/user/"+t)},t.prototype.get=function(t){return this.http.get("api/user/"+t)},t.prototype.create=function(t){return this.http.post("api/user",t)},t.prototype.update=function(t){return this.http.put("api/user/"+t.username,t)},t.ngInjectableDef=a.defineInjectable({factory:function(){return new t(a.inject(r.c))},token:t,providedIn:i.a}),t}()},NDi4:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("CcnG"),r=function(){return function(){this.title="Error",this.backAction=new a.EventEmitter}}()},NEZu:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(t,e,n,a){this.customColors={backgroundColor:void 0,borderColor:void 0},this.checkOffset=!1,this.chartEl=t.nativeElement,this.getStyleLeft=n,this.getStyleTop=a,this.tooltipEl=e.nativeElement}return t.prototype.customTooltips=function(t){var e=this;if(0!==t.opacity){if(this.tooltipEl.classList.remove("above","below","no-transform"),this.tooltipEl.classList.add(t.yAlign?t.yAlign:"no-transform"),t.body){var n=t.title||[],a=t.body.map(function(t){return t.lines}),r="";n.forEach(function(t){r+=""+e.getTitle(t)+""}),r+="",a.forEach(function(n,a){var i=t.labelColors[a],s="background:"+(e.customColors.backgroundColor||i.backgroundColor);s+="; border-color:"+(e.customColors.borderColor||i.borderColor),r+=''+e.getBody(n)+""}),r+="",this.tooltipEl.querySelector("table").innerHTML=r}var i=this.chartEl.offsetTop,s=this.chartEl.offsetLeft;if(this.checkOffset){var o=t.width/2;this.tooltipEl.classList.remove("transform-left"),this.tooltipEl.classList.remove("transform-right"),t.caretX-o<0?this.tooltipEl.classList.add("transform-left"):t.caretX+o>this.chartEl.width&&this.tooltipEl.classList.add("transform-right")}this.tooltipEl.style.left=this.getStyleLeft(t,s),this.tooltipEl.style.top=this.getStyleTop(t,i),this.tooltipEl.style.opacity=1,this.tooltipEl.style.fontFamily=t._fontFamily,this.tooltipEl.style.fontSize=t.fontSize,this.tooltipEl.style.fontStyle=t._fontStyle,this.tooltipEl.style.padding=t.yPadding+"px "+t.xPadding+"px"}else this.tooltipEl.style.opacity=0},t.prototype.getBody=function(t){return t},t.prototype.getTitle=function(t){return t},t}()},NJnL:function(t,e,n){"use strict";n.d(e,"a",function(){return G});var a=n("mrSG"),r=n("CcnG"),i=n("Ip0R"),s=n("K9Ia"),o=n("p0ib"),u=n("bne5"),c=n("F/XL"),l=n("tHPV");function d(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function f(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function p(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=d(t),n=e.overflowX,a=e.overflowY;return/(auto|scroll|overlay)/.test(String(e.overflow)+String(a)+String(n))?t:p(f(t))}var h="undefined"!=typeof window&&"undefined"!=typeof document,g=h&&!(!window.MSInputMethodContext||!document.documentMode),b=h&&!(!window.MSInputMethodContext||!/MSIE 10/.test(navigator.userAgent));function m(t){return 11===t?g:10===t?b:g||b}function y(t){if(!t)return document.documentElement;for(var e,n=m(10)?document.body:null,a=t.offsetParent||null;a===n&&t.nextElementSibling&&e!==t.nextElementSibling;)a=(e=t.nextElementSibling).offsetParent;var r=a&&a.nodeName;return r&&"BODY"!==r&&"HTML"!==r?-1!==["TH","TD","TABLE"].indexOf(a.nodeName)&&"static"===d(a,"position")?y(a):a:e?e.ownerDocument.documentElement:document.documentElement}function v(t){return null!==t.parentNode?v(t.parentNode):t}function _(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,a=n?t:e,r=n?e:t,i=document.createRange();i.setStart(a,0),i.setEnd(r,0);var s,o,u=i.commonAncestorContainer;if(t!==u&&e!==u||a.contains(r))return"BODY"===(o=(s=u).nodeName)||"HTML"!==o&&y(s.firstElementChild)!==s?y(u):u;var c=v(t);return c.host?_(c.host,e):_(t,v(e).host)}function x(t,e){var n="x"===e?"Left":"Top",a="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+a+"Width"])}function T(t,e,n,a){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],m(10)?parseInt(n["offset"+t],10)+parseInt(a["margin"+("Height"===t?"Top":"Left")],10)+parseInt(a["margin"+("Height"===t?"Bottom":"Right")],10):0)}function w(t){var e=t.body,n=t.documentElement,a=m(10)&&getComputedStyle(n);return{height:T("Height",e,n,a),width:T("Width",e,n,a)}}function S(t,e){void 0===e&&(e="top");var n="top"===e?"scrollTop":"scrollLeft",a=t.nodeName;return"BODY"===a||"HTML"===a?(t.ownerDocument.scrollingElement||t.ownerDocument.documentElement)[n]:t[n]}function O(t){return Object(a.__assign)({},t,{right:t.left+t.width,bottom:t.top+t.height})}function I(t){var e={};try{if(m(10)){e=t.getBoundingClientRect();var n=S(t,"top"),a=S(t,"left");e.top+=n,e.left+=a,e.bottom+=n,e.right+=a}else e=t.getBoundingClientRect()}catch(c){return}var r={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},i="HTML"===t.nodeName?w(t.ownerDocument):{},s=t.offsetWidth-(i.width||t.clientWidth||r.right-r.left),o=t.offsetHeight-(i.height||t.clientHeight||r.bottom-r.top);if(s||o){var u=d(t);s-=x(u,"x"),o-=x(u,"y"),r.width-=s,r.height-=o}return O(r)}function C(t,e,n){void 0===n&&(n=!1);var a=m(10),r="HTML"===e.nodeName,i=I(t),s=I(e),o=p(t),u=d(e),c=parseFloat(u.borderTopWidth),l=parseFloat(u.borderLeftWidth);n&&r&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var f=O({top:i.top-s.top-c,left:i.left-s.left-l,width:i.width,height:i.height});if(f.marginTop=0,f.marginLeft=0,!a&&r){var h=parseFloat(u.marginTop),g=parseFloat(u.marginLeft);f.top-=c-h,f.bottom-=c-h,f.left-=l-g,f.right-=l-g,f.marginTop=h,f.marginLeft=g}return(a&&!n?e.contains(o):e===o&&"BODY"!==o.nodeName)&&(f=function(t,e,n){void 0===n&&(n=!1);var a=S(e,"top"),r=S(e,"left"),i=n?-1:1;return t.top+=a*i,t.bottom+=a*i,t.left+=r*i,t.right+=r*i,t}(f,e)),f}function k(t){if(!t||!t.parentElement||m())return document.documentElement;for(var e=t.parentElement;e&&"none"===d(e,"transform");)e=e.parentElement;return e||document.documentElement}function N(t,e,n,a,r){void 0===n&&(n=0),void 0===r&&(r=!1);var i={top:0,left:0},s=r?k(t):_(t,e);if("viewport"===a)i=function(t,e){void 0===e&&(e=!1);var n=s.ownerDocument.documentElement,a=C(s,n),r=Math.max(n.clientWidth,window.innerWidth||0),i=Math.max(n.clientHeight,window.innerHeight||0),o=e?0:S(n),u=e?0:S(n,"left");return O({top:o-Number(a.top)+Number(a.marginTop),left:u-Number(a.left)+Number(a.marginLeft),width:r,height:i})}(0,r);else{var o=void 0;"scrollParent"===a?"BODY"===(o=p(f(e))).nodeName&&(o=t.ownerDocument.documentElement):o="window"===a?t.ownerDocument.documentElement:a;var u=C(o,s,r);if("HTML"!==o.nodeName||function t(e){var n=e.nodeName;return"BODY"!==n&&"HTML"!==n&&("fixed"===d(e,"position")||t(f(e)))}(s))i=u;else{var c=w(t.ownerDocument),l=c.height,h=c.width;i.top+=u.top-u.marginTop,i.bottom=Number(l)+Number(u.top),i.left+=u.left-u.marginLeft,i.right=Number(h)+Number(u.left)}}return i.left+=n,i.top+=n,i.right-=n,i.bottom-=n,i}function R(t,e,n,r,i,s,o){if(void 0===i&&(i=["top","bottom","right","left"]),void 0===s&&(s="viewport"),void 0===o&&(o=0),-1===t.indexOf("auto"))return t;var u=N(n,r,o,s),c={top:{width:u.width,height:e.top-u.top},right:{width:u.right-e.right,height:u.height},bottom:{width:u.width,height:u.bottom-e.bottom},left:{width:e.left-u.left,height:u.height}},l=Object.keys(c).map(function(t){return Object(a.__assign)({key:t},c[t],{area:(e=c[t],e.width*e.height)});var e}).sort(function(t,e){return e.area-t.area}),d=l.filter(function(t){return t.width>=n.clientWidth&&t.height>=n.clientHeight}),f=(d=d.filter(function(t){return i.some(function(e){return e===t.key})})).length>0?d[0].key:l[0].key,p=t.split(" ")[1];return n.className=n.className.replace(/bs-tooltip-auto/g,"bs-tooltip-"+f),f+(p?"-"+p:"")}function A(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),a=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:Number(t.offsetWidth)+a,height:Number(t.offsetHeight)+n}}function D(t,e,n){return void 0===n&&(n=null),C(e,n?k(t):_(t,e),n)}function E(t,e,n){var a,r=n.split(" ")[0],i=A(t),s={width:i.width,height:i.height},o=-1!==["right","left"].indexOf(r),u=o?"top":"left",c=o?"left":"top",l=o?"height":"width",d=o?"width":"height";return s[u]=e[u]+e[l]/2-i[l]/2,s[c]=r===c?e[c]-i[d]:e[(a={left:"right",right:"left",bottom:"top",top:"bottom"},c.replace(/left|right|bottom|top/g,function(t){return a[t]}))],s}function L(t,e){return t&&t.modifiers&&t.modifiers[e]&&t.modifiers[e].enabled}function P(t,e,n){Object.keys(e).forEach(function(a){var r,i="";-1!==["width","height","top","right","bottom","left"].indexOf(a)&&""!==(r=e[a])&&!isNaN(parseFloat(r))&&isFinite(r)&&(i="px"),n?n.setStyle(t,a,""+String(e[a])+i):t.style[a]=String(e[a])+i})}function M(t){var e,n=t.offsets.target,a=t.instance.target.querySelector(".arrow");if(!a)return t;var r=-1!==["left","right"].indexOf(t.placement),i=r?"height":"width",s=r?"Top":"Left",o=s.toLowerCase(),u=r?"left":"top",c=r?"bottom":"right",l=A(a)[i];t.offsets.host[c]-ln[c]&&(n[o]+=Number(t.offsets.host[o])+Number(l)-Number(n[c])),n=O(n);var f=Number(t.offsets.host[o])+Number(t.offsets.host[i]/2-l/2),p=d(t.instance.target),h=parseFloat(p["margin"+s]),g=parseFloat(p["border"+s+"Width"]),b=f-n[o]-h-g;return b=Math.max(Math.min(n[i]-l,b),0),t.offsets.arrow=((e={})[o]=Math.round(b),e[u]="",e),t.instance.arrow=a,t}function q(t){if(t.offsets.target=O(t.offsets.target),!L(t.options,"flip"))return t.offsets.target=Object(a.__assign)({},t.offsets.target,E(t.instance.target,t.offsets.host,t.placement)),t;var e=N(t.instance.target,t.instance.host,0,"viewport",!1),n=t.placement.split(" ")[0],r=t.placement.split(" ")[1]||"",i=R("auto",t.offsets.host,t.instance.target,t.instance.host,t.options.allowedPositions),s=[n,i];return s.forEach(function(i,o){if(n!==i||s.length===o+1)return t;var u="left"===(n=t.placement.split(" ")[0])&&Math.floor(t.offsets.target.right)>Math.floor(t.offsets.host.left)||"right"===n&&Math.floor(t.offsets.target.left)Math.floor(t.offsets.host.top)||"bottom"===n&&Math.floor(t.offsets.target.top)Math.floor(e.right),d=Math.floor(t.offsets.target.top)Math.floor(e.bottom),p="left"===n&&c||"right"===n&&l||"top"===n&&d||"bottom"===n&&f,h=-1!==["top","bottom"].indexOf(n),g=h&&"left"===r&&c||h&&"right"===r&&l||!h&&"left"===r&&d||!h&&"right"===r&&f;(u||p||g)&&((u||p)&&(n=s[o+1]),g&&(r=function(t){return"right"===t?"left":"left"===t?"right":t}(r)),t.placement=n+(r?" "+r:""),t.offsets.target=Object(a.__assign)({},t.offsets.target,E(t.instance.target,t.offsets.host,t.placement)))}),t}function j(t){if(!L(t.options,"preventOverflow"))return t;var e=t.instance.target.style,n=e.top,r=e.left,i=e.transform;e.top="",e.left="",e.transform="";var s=N(t.instance.target,t.instance.host,0,"scrollParent",!1);e.top=n,e.left=r,e.transform=i;var o,u={primary:function(e){var n,a=t.offsets.target[e];return t.offsets.target[e]s[e]&&(r=Math.min(t.offsets.target[a],s[e]-("right"===e?t.offsets.target.width:t.offsets.target.height))),(n={})[a]=r,n}};return["left","right","top","bottom"].forEach(function(e){o=-1!==["left","top"].indexOf(e)?"primary":"secondary",t.offsets.target=Object(a.__assign)({},t.offsets.target,u[o](e))}),t}function F(t){var e,n,r=t.placement,i=r.split(" ")[0],s=r.split(" ")[1];if(s){var o=t.offsets,u=o.host,c=o.target,l=-1!==["bottom","top"].indexOf(i),d=l?"left":"top",f=l?"width":"height",p={start:(e={},e[d]=u[d],e),end:(n={},n[d]=u[d]+u[f]-c[f],n)};t.offsets.target=Object(a.__assign)({},c,p[s])}return t}var z=new(function(){function t(){}return t.prototype.position=function(t,e,n){return void 0===n&&(n=!0),this.offset(t,e,!1)},t.prototype.offset=function(t,e,n){return void 0===n&&(n=!0),D(e,t)},t.prototype.positionElements=function(t,e,n,a,r){return[q,F,j,M].reduce(function(t,e){return e(t)},function(t,e,n,a){var r=D(t,e);n.match(/^(auto)*\s*(left|right|top|bottom)*$/)||n.match(/^(left|right|top|bottom)*\s*(start|end)*$/)||(n="auto");var i=!!n.match(/auto/g),s=n.match(/auto\s(left|right|top|bottom)/)?n.split(" ")[1]||"auto":n;return{options:a,instance:{target:t,host:e,arrow:null},offsets:{target:E(t,r,s),host:r,arrow:null},positionFixed:!1,placement:s=R(s,r,t,e,a?a.allowedPositions:void 0),placementAuto:i}}(e,t,n,r))},t}()),G=function(){function t(t,e){var n=this;this.update$$=new s.a,this.positionElements=new Map,this.isDisabled=!1,Object(i.isPlatformBrowser)(e)&&(this.triggerEvent$=Object(o.a)(Object(u.a)(window,"scroll"),Object(u.a)(window,"resize"),Object(c.a)(0,l.a),this.update$$),this.triggerEvent$.subscribe(function(){n.isDisabled||n.positionElements.forEach(function(e){var a,r,i,s,o,u,c,l;a=Y(e.target),r=Y(e.element),i=e.attachment,s=e.appendToBody,o=n.options,u=t.createRenderer(null,null),P(r,{"will-change":"transform",top:"0px",left:"0px",transform:"translate3d("+(l=function(t){return{width:t.offsets.target.width,height:t.offsets.target.height,left:Math.floor(t.offsets.target.left),top:Math.round(t.offsets.target.top),bottom:Math.round(t.offsets.target.bottom),right:Math.floor(t.offsets.target.right)}}(c=z.positionElements(a,r,i,s,o))).left+"px, "+l.top+"px, 0px)"},u),c.instance.arrow&&P(c.instance.arrow,c.offsets.arrow,u),function(t,e){var n=t.instance.target,a=n.className;t.placementAuto&&(-1!==(a=(a=(a=a.replace(/bs-popover-auto/g,"bs-popover-"+t.placement)).replace(/bs-tooltip-auto/g,"bs-tooltip-"+t.placement)).replace(/\sauto/g," "+t.placement)).indexOf("popover")&&-1===a.indexOf("popover-auto")&&(a+=" popover-auto"),-1!==a.indexOf("tooltip")&&-1===a.indexOf("tooltip-auto")&&(a+=" tooltip-auto")),a=a.replace(/left|right|top|bottom/g,""+t.placement.split(" ")[0]),e?e.setAttribute(n,"class",a):n.className=a}(c,u)})}))}return t.prototype.position=function(t){this.addPositionElement(t)},Object.defineProperty(t.prototype,"event$",{get:function(){return this.triggerEvent$},enumerable:!0,configurable:!0}),t.prototype.disable=function(){this.isDisabled=!0},t.prototype.enable=function(){this.isDisabled=!1},t.prototype.addPositionElement=function(t){this.positionElements.set(Y(t.element),t)},t.prototype.calcPosition=function(){this.update$$.next()},t.prototype.deletePositionElement=function(t){this.positionElements.delete(Y(t))},t.prototype.setOptions=function(t){this.options=t},t}();function Y(t){return"string"==typeof t?document.querySelector(t):t instanceof r.ElementRef?t.nativeElement:t}},NUGo:function(t,e,n){"use strict";var a=n("CcnG"),r=n("Ip0R"),i=n("ZYCi"),s=n("xtZt"),o=n("lqqz");n("S7zO"),n.d(e,"a",function(){return u}),n.d(e,"b",function(){return g});var u=a["\u0275crt"]({encapsulation:0,styles:[[".dropdown-menu[_ngcontent-%COMP%] > .disabled[_ngcontent-%COMP%] > a[_ngcontent-%COMP%]{pointer-events:auto;cursor:default!important}"]],data:{}});function c(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,7,null,null,null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,6,"button",[["class","btn btn-sm btn-primary"],["type","button"]],null,[[null,"click"]],function(t,e,n){var r=!0,i=t.component;return"click"===e&&(r=!1!==a["\u0275nov"](t,4).onClick()&&r),"click"===e&&(r=!1!==i.useClickAction(t.context.ngIf)&&r),r},null,null)),a["\u0275did"](2,278528,null,0,r.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a["\u0275pod"](3,{disabled:0}),a["\u0275did"](4,16384,null,0,i.m,[i.l,i.a,[8,null],a.Renderer2,a.ElementRef],{preserveFragment:[0,"preserveFragment"],routerLink:[1,"routerLink"]},null),(t()(),a["\u0275eld"](5,0,null,null,0,"i",[],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275eld"](6,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](7,null,["",""]))],function(t,e){var n=e.component,a=t(e,3,0,n.disableSelectionAction(e.context.ngIf));t(e,2,0,"btn btn-sm btn-primary",a),t(e,4,0,e.context.ngIf.preserveFragment?"":null,n.useRouterLink(e.context.ngIf))},function(t,e){t(e,5,0,a["\u0275inlineInterpolate"](1,"fa fa-fw ",e.context.ngIf.icon,"")),t(e,7,0,e.context.ngIf.name)})}function l(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.component.onlyDropDown)})}function d(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"span",[["class","sr-only"]],null,null,null,null,null))],null,null)}function f(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,6,"button",[["class","btn btn-sm btn-primary dropdown-toggle dropdown-toggle-split"],["dropdownToggle",""],["type","button"]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var r=!0;return"click"===e&&(r=!1!==a["\u0275nov"](t,1).onClick()&&r),r},null,null)),a["\u0275did"](1,147456,null,0,s.g,[a.ChangeDetectorRef,s.c,a.ElementRef,a.Renderer2,s.f],null,null),(t()(),a["\u0275and"](16777216,null,null,1,null,l)),a["\u0275did"](3,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](4,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,d)),a["\u0275did"](6,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,n.onlyDropDown),t(e,6,0,!n.onlyDropDown)},function(t,e){t(e,0,0,!0,a["\u0275nov"](e,1).isDisabled,a["\u0275nov"](e,1).isOpen)})}function p(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,8,null,null,null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,7,"li",[["data-toggle","tooltip"],["role","menuitem"]],[[8,"title",0]],null,null,null,null)),a["\u0275did"](2,278528,null,0,r.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a["\u0275pod"](3,{disabled:0}),(t()(),a["\u0275eld"](4,0,null,null,4,"a",[["class","dropdown-item"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var r=!0,i=t.component;return"click"===e&&(r=!1!==a["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&r),"click"===e&&(r=!1!==i.useClickAction(t.context.$implicit)&&r),r},null,null)),a["\u0275did"](5,671744,null,0,i.o,[i.l,i.a,r.LocationStrategy],{preserveFragment:[0,"preserveFragment"],routerLink:[1,"routerLink"]},null),(t()(),a["\u0275eld"](6,0,null,null,0,"i",[],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275eld"](7,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](8,null,["",""]))],function(t,e){var n=e.component,r=a["\u0275inlineInterpolate"](1,"",n.toClassName(e.context.$implicit.name),""),i=t(e,3,0,n.disableSelectionAction(e.context.$implicit));t(e,2,0,r,i),t(e,5,0,e.context.$implicit.preserveFragment?"":null,n.useRouterLink(e.context.$implicit))},function(t,e){t(e,1,0,a["\u0275inlineInterpolate"](1,"",e.component.useDisableDesc(e.context.$implicit),"")),t(e,4,0,a["\u0275nov"](e,5).target,a["\u0275nov"](e,5).href),t(e,6,0,a["\u0275inlineInterpolate"](1,"fa fa-fw ",e.context.$implicit.icon,"")),t(e,8,0,e.context.$implicit.name)})}function h(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"ul",[["class","dropdown-menu"],["role","menu"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,p)),a["\u0275did"](2,278528,null,0,r.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.component.dropDownActions)},null)}function g(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,16777216,null,null,8,"div",[["class","btn-group"],["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),a["\u0275prd"](512,null,s.f,s.f,[]),a["\u0275did"](2,212992,null,0,s.c,[a.ElementRef,a.Renderer2,a.ViewContainerRef,o.a,s.a,s.f],null,null),(t()(),a["\u0275and"](16777216,null,null,1,null,c)),a["\u0275did"](4,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,f)),a["\u0275did"](6,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,h)),a["\u0275did"](8,16384,null,0,s.d,[s.f,a.ViewContainerRef,a.TemplateRef],null,null)],function(t,e){var n=e.component;t(e,2,0),t(e,4,0,n.getCurrentButton()),t(e,6,0,n.showDropDownActions())},function(t,e){t(e,0,0,a["\u0275nov"](e,2).dropup,a["\u0275nov"](e,2).isOpen,a["\u0275nov"](e,2).isOpen&&a["\u0275nov"](e,2).isBs4)})}},Nia1:function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("3/HP")),a(n("FLvf")),a(n("2V7f")),a(n("fktO")),a(n("QHrR")),a(n("i3PA"))},O5R2:function(t,e,n){"use strict";n.r(e);var a=n("6blF"),r=n("VnD/");a.a.prototype.filter=function(t,e){return Object(r.a)(t,e)(this)}},ODdm:function(t,e,n){"use strict";t.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},OIYi:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}})}()},OLbh:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("gIcY"),r=function(){function t(t){this.modalRef=t,this.boundCancel=this.cancel.bind(this),this.confirmationForm=new a.k({})}return t.prototype.ngOnInit=function(){this.bodyContext=this.bodyContext||{},this.bodyContext.$implicit=this.bodyData},t.prototype.cancel=function(){this.modalRef.hide(),this.onCancel&&this.onCancel()},t.prototype.stopLoadingSpinner=function(){this.confirmationForm.setErrors({cdSubmitButton:!0})},t}()},"OWV/":function(t,e){t.exports='\n \n \n \n Toggle navigation\n Alternar navega\xe7\xe3o\n \n \n Dashboard\n Painel de controle\n \n \n Cluster\n Cluster\n \n \n Hosts\n Hosts\n \n \n Monitors\n Monitores\n \n \n OSDs\n OSDs\n \n \n Configuration\n Configura\xe7\xe3o\n \n \n CRUSH map\n Mapa CRUSH\n \n \n Manager modules\n M\xf3dulos do gerenciador\n \n \n Logs\n Registros\n \n \n Alerts\n Alertas\n \n \n Silences\n Silences\n \n \n Pools\n Pools\n \n \n Block\n Bloco\n \n \n Images\n Imagens\n \n \n Mirroring\n Espelhamento\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n Sistemas de arquivos\n \n \n Object Gateway\n Gateway de Objetos\n \n \n Daemons\n Daemons\n \n \n Users\n Usu\xe1rios\n \n \n Buckets\n Compartimentos\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Recuperando dados\n de\n \n \n . Aguarde...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Exibindo dados armazenados em cache anteriormente\n \n para \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n N\xe3o foi poss\xedvel carregar os dados\n de\n \n \n .\n Verifique a sa\xfade do cluster.\n \n \n \n Back\n Voltar\n \n \n Select a Language\n Selecionar Idioma\n \n \n Loading panel data...\n Carregando dados do painel...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Consulte a\n documenta\xe7\xe3o\n sobre como\n configurar e habilitar a funcionalidade de monitoramento.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n O Painel de Controle do Grafana n\xe3o existe. Consulte a\n documenta\xe7\xe3o\n sobre como\n adicionar pain\xe9is de controle ao Grafana.\n \n \n \n Grafana Time Picker\n Seletor de Hor\xe1rio do Grafana\n \n \n Reset Settings\n Redefinir Configura\xe7\xf5es\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n Falha ao carregar dados.\n \n \n selected\n selecionado(s)\n X selected\n \n \n found\n encontrado(s)\n X found\n \n \n total\n total\n X total\n \n \n Edit\n Editar\n \n \n Name\n Nome\n \n \n Description\n Descri\xe7\xe3o\n \n \n Long description\n Descri\xe7\xe3o extensa\n \n \n Default\n Padr\xe3o\n \n \n Daemon default\n Padr\xe3o do daemon\n \n \n Services\n Servi\xe7os\n \n \n Values\n Valores\n \n \n The entered value is too high! It must not be greater than \n .\n \n O valor inserido \xe9 muito alto! Ele n\xe3o pode ser maior do que \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n O valor inserido \xe9 muito baixo! Ele n\xe3o deve ser menor do que \n .\n \n \n \n Save\n Salvar\n \n \n CRUSH map viewer\n Visualizador de mapa CRUSH\n \n \n Hosts List\n Lista de Hosts\n \n \n Overall Performance\n Desempenho Geral\n \n \n No entries found\n Nenhuma entrada encontrada\n \n \n Cluster Logs\n Registros do Cluster\n \n \n Audit Logs\n Registros de Auditoria\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n Carregando configura\xe7\xe3o...\n \n \n The configuration could not be loaded.\n N\xe3o foi poss\xedvel carregar a configura\xe7\xe3o.\n \n \n Edit Manager module\n Editar m\xf3dulo do gerenciador\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n O valor inserido n\xe3o \xe9 um UUID v\xe1lido. Ex.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n O valor inserido precisa ser um endere\xe7o IP v\xe1lido.\n \n \n This field is required.\n Este campo \xe9 obrigat\xf3rio.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n O valor inserido \xe9 muito alto! Ele deve ser menor ou igual a \n .\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n O valor inserido \xe9 muito baixo! Ele deve ser maior ou igual a \n .\n \n \n \n The entered value needs to be a number.\n O valor inserido precisa ser um n\xfamero.\n \n \n The entered value needs to be a number or decimal.\n O valor inserido precisa ser um n\xfamero ou decimal.\n \n \n Update\n Atualizar\n \n \n Status\n Status\n \n \n Cluster ID\n ID do Cluster\n \n \n monmap modified\n monmap modificado\n \n \n monmap epoch\n \xe9poca de monmap\n \n \n quorum con\n quorum con\n \n \n quorum mon\n quorum mon\n \n \n required con\n con obrigat\xf3rio\n \n \n required mon\n mon obrigat\xf3rio\n \n \n In Quorum\n No Quorum\n \n \n Not In Quorum\n N\xe3o est\xe1 no Quorum\n \n \n Cancel\n Cancelar\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n Deseja realmente \n o(a) \n selecionado(a)?\n \n \n \n Yes, I am sure.\n Sim, desejo.\n \n \n Cluster-wide OSD Flags\n Flags OSD de todo o Cluster\n \n \n Submit\n Enviar\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Avan\xe7ado...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n Prioridade de Recupera\xe7\xe3o de OSD\n \n \n Priority\n Prioridade\n \n \n Customize priority values\n Personalizar valores de prioridade\n \n \n This field is required!\n Este campo \xe9 obrigat\xf3rio!\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n O valor inserido \xe9 muito alto! Ele n\xe3o pode ser maior do que \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n O valor inserido \xe9 muito baixo! Ele n\xe3o deve ser menor do que \n .\n \n \n \n Reweight OSD\n Reponderar OSD\n \n \n The value needs to be between 0 and 1.\n O valor precisa ser entre 0 e 1.\n \n \n Reweight\n Reponderar\n \n \n OSDs \n Scrub\n \n Remo\xe7\xe3o de OSDs \n \n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {Profundo } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Voc\xea est\xe1 prestes a aplicar uma \n remo\xe7\xe3o ao\n OSD \n \n \n .\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {profundo} }\n \n \n OSDs List\n Lista de OSDs\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \n OSD \n \n ser\xe1 marcado como\n \n \n se voc\xea continuar.\n \n \n \n The OSD is not safe to destroy!\n N\xe3o \xe9 seguro destruir o OSD!\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \n OSD \n \n ser\xe1\n \n \n se voc\xea continuar.\n \n \n \n Details\n Detalhes\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Valor\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Fechar\n \n \n Delete\n Excluir\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Sa\xfade\n \n \n Statistics\n Estat\xedsticas\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Consulte a \n documenta\xe7\xe3o\n \n sobre como configurar e habilitar a funcionalidade de gerenciamento do NFS Ganesha.\n \n \n \n Clients\n Clientes\n \n \n Any client can access\n Qualquer cliente pode acessar\n \n \n Addresses\n Endere\xe7os\n \n \n Required field\n Campo obrigat\xf3rio\n \n \n Must contain one or more comma-separated values\n Deve conter um ou mais valores separados por v\xedrgula\n \n \n For example:\n Por exemplo:\n \n \n Access Type\n Tipo de Acesso\n \n \n Squash\n Executar Squash\n \n \n Add clients\n Adicionar clientes\n \n \n Loading...\n Carregando...\n \n \n -- No cluster available --\n -- N\xe3o h\xe1 clusters dispon\xedveis --\n \n \n -- Select the cluster --\n -- Selecionar cluster --\n \n \n Add daemon\n Adicionar daemon\n \n \n Storage Backend\n Backend de Armazenamento\n \n \n -- No data pools available --\n -- N\xe3o h\xe1 pools de dados dispon\xedveis --\n \n \n -- Select the storage backend --\n -- Selecionar backend de armazenamento --\n \n \n Object Gateway User\n Usu\xe1rio do Gateway de Objetos\n \n \n -- No users available --\n -- N\xe3o h\xe1 usu\xe1rios dispon\xedveis --\n \n \n -- Select the object gateway user --\n -- Selecionar usu\xe1rio do gateway de objetos --\n \n \n CephFS User ID\n ID de Usu\xe1rio do CephFS\n \n \n -- No clients available --\n -- N\xe3o h\xe1 clientes dispon\xedveis --\n \n \n -- Select the cephx client --\n -- Selecionar cliente do cephx --\n \n \n CephFS Name\n Nome do CephFS\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n R\xf3tulo de Seguran\xe7a\n \n \n Enable security label\n Habilitar r\xf3tulo de seguran\xe7a\n \n \n CephFS Path\n Caminho do CephFS\n \n \n Path need to start with a \'/\' and can be followed by a word\n O caminho precisa come\xe7ar com \'/\' e pode ser seguido de uma palavra\n \n \n New directory will be created\n Novo diret\xf3rio ser\xe1 criado\n \n \n Path\n Caminho\n \n \n Path can only be a single \'/\' or a word\n O caminho pode ser apenas uma \'/\' ou uma palavra\n \n \n New bucket will be created\n Novo compartimento ser\xe1 criado\n \n \n NFS Protocol\n Protocolo NFS\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n Tag NFS\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Acesso alternativo \xe0s montagens do \n NFS v3\n (n\xe3o deve ter / \xe0 esquerda).\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n Clientes n\xe3o podem montar subdiret\xf3rios (ou seja, se Tag = foo, o cliente n\xe3o poder\xe1 montar foo/baz).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n Ao usar op\xe7\xf5es diferentes de Tag, o mesmo Caminho pode ser exportado v\xe1rias vezes.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n A posi\xe7\xe3o que esta exporta\xe7\xe3o de \n NFS v4\n ocupa\n no \n Pseudo FS\n (deve ser exclusiva).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n Ao usar op\xe7\xf5es diferentes de Pseudo, o mesmo Caminho pode ser exportado v\xe1rias vezes.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- N\xe3o h\xe1 tipos de acesso dispon\xedveis --\n \n \n -- Select the access type --\n -- Selecionar tipo de acesso --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- N\xe3o h\xe1 squashes dispon\xedveis --\n \n \n --Select what kind of user id squashing is performed --\n --Selecionar que tipo de squash de ID de usu\xe1rio ser\xe1 executado --\n \n \n Transport Protocol\n Protocolo de Transporte\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Bem-vindo ao Ceph!\n The welcome message on the login page\n \n \n Username is required\n Nome de usu\xe1rio \xe9 obrigat\xf3rio\n \n \n Password is required\n Senha \xe9 obrigat\xf3ria\n \n \n Login\n Login\n \n \n Sorry, the user does not exist in Ceph.\n O usu\xe1rio n\xe3o existe no Ceph.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Retorne \xe0 \n P\xe1gina de Login\n . Seu logout ser\xe1 efetuado do Provedor de Identidade quando voc\xea repetir o login.\n \n \n \n Forbidden\n Proibido\n \n \n Sorry, you are not allowed to see what you were looking for.\n Voc\xea n\xe3o tem permiss\xe3o para ver o que est\xe1 procurando.\n \n \n Sorry, we could not find what you were looking for\n N\xe3o foi poss\xedvel localizar o que voc\xea est\xe1 procurando\n \n \n Remove all\n Remover tudo\n \n \n Recent Notifications\n Notifica\xe7\xf5es Recentes\n \n \n There are no background tasks.\n N\xe3o h\xe1 tarefas em segundo plano.\n \n \n Background Tasks\n Tarefas em Segundo Plano\n \n \n Help\n Ajuda\n \n \n Documentation\n Documenta\xe7\xe3o\n \n \n API\n API\n \n \n About\n Sobre\n \n \n Dashboard Settings\n Configura\xe7\xf5es do Painel de Controle\n \n \n User management\n Gerenciamento de usu\xe1rios\n \n \n Logged in user\n Usu\xe1rio que efetuou login\n \n \n Signed in as\n \n \n \n \n Efetuar login como\n \n \n \n \n \n \n Sign out\n Efetuar logout\n \n \n Name...\n Nome...\n \n \n The chosen name is already in use.\n O nome escolhido j\xe1 est\xe1 em uso.\n \n \n Description...\n Descri\xe7\xe3o...\n \n \n Permissions\n Permiss\xf5es\n \n \n Roles\n Fun\xe7\xf5es\n \n \n Username\n Nome de usu\xe1rio\n \n \n Password\n Senha\n \n \n Confirm password\n Confirmar senha\n \n \n Password confirmation doesn\'t match the password.\n A confirma\xe7\xe3o de senha n\xe3o corresponde \xe0 senha.\n \n \n Full name\n Nome completo\n \n \n Email\n E-mail\n \n \n Invalid email.\n E-mail inv\xe1lido.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Voc\xea est\xe1 prestes a remover as permiss\xf5es de "leitura/atualiza\xe7\xe3o de usu\xe1rio" do seu pr\xf3prio usu\xe1rio.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Se voc\xea continuar, n\xe3o poder\xe1 mais adicionar ou remover fun\xe7\xf5es de nenhum usu\xe1rio.\n \n \n Are you sure you want to continue?\n Deseja realmente continuar?\n \n \n Performance counters not available\n Contadores de desempenho n\xe3o dispon\xedveis\n \n \n Attributes (OSD map)\n Atributos (mapa OSD)\n \n \n Metadata not available\n Metadados n\xe3o dispon\xedveis\n \n \n Metadata\n Metadados\n \n \n Performance counter\n Contador de desempenho\n \n \n Histogram not available: \n \n \n Histograma n\xe3o dispon\xedvel: \n \n \n \n \n Writes\n Grava\xe7\xf5es\n \n \n Reads\n Leituras\n \n \n Histogram\n Histograma\n \n \n Performance Details\n Detalhes de Desempenho\n \n \n Current values\n Valores atuais\n \n \n Type\n Tipo\n \n \n Min\n M\xedn.\n \n \n Max\n M\xe1x.\n \n \n Flags\n Flags\n \n \n Source\n Origem\n \n \n Level\n N\xedvel\n \n \n Can be updated at runtime (editable)\n Pode ser atualizado em tempo de execu\xe7\xe3o (edit\xe1vel)\n \n \n Tags\n Tags\n \n \n Enum values\n Valores de enum\n \n \n See also\n Consulte tamb\xe9m\n \n \n Cluster Status\n Status do Cluster\n \n \n Manager Daemons\n Daemons do Gerenciador\n \n \n Object Gateways\n Gateways de Objetos\n \n \n Metadata Servers\n Servidores de Metadados\n \n \n iSCSI Gateways\n Gateways iSCSI\n \n \n Client IOPS\n IOPS do Cliente\n \n \n Client Throughput\n Throughput do Cliente\n \n \n Client Read/Write\n Leitura/Grava\xe7\xe3o do Cliente\n \n \n Recovery Throughput\n Throughput de Recupera\xe7\xe3o\n \n \n Scrub\n Remo\xe7\xe3o\n \n \n Performance\n Desempenho\n \n \n Raw Capacity\n Capacidade Bruta\n \n \n Objects\n Objetos\n \n \n PGs per OSD\n PGs por OSD\n \n \n PG Status\n Status do PG\n \n \n Capacity\n Capacidade\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n Consulte os \n Registros\n para obter mais detalhes.\n \n \n \n Ranks\n Posi\xe7\xf5es\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Clientes: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n Mover imagem para o lixo\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n Para mover \n \n /\n \n para o lixo,\n clique em \n Mover Imagem\n . Se preferir, escolha uma data de vencimento.\n \n \n \n Protection expires at\n Vencimento da prote\xe7\xe3o em\n \n \n NOT PROTECTED\n N\xc3O PROTEGIDO\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Formato de data incorreto. Use "AAAA-MM-DD HH:mm:ss".\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n A prote\xe7\xe3o j\xe1 venceu. Escolha uma data no futuro ou deixe-a vazia.\n \n \n Move Image\n Mover Imagem\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n Vis\xe3o geral\n \n \n Targets\n Destinos\n \n \n Discovery Authentication\n Autentica\xe7\xe3o de Descoberta\n \n \n User\n Usu\xe1rio\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Os nomes de usu\xe1rio devem ter entre 8 e 64 caracteres e\n apenas podem conter letras, \'.\', \'@\', \'-\', \'_\' ou \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n Usu\xe1rio M\xfatuo\n \n \n Mutual Password\n Senha M\xfatua\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Consulte a \n documenta\xe7\xe3o\n \n sobre como configurar e habilitar a funcionalidade de gerenciamento de Destinos iSCSI.\n \n \n \n Available information:\n Informa\xe7\xf5es dispon\xedveis:\n \n \n iSCSI Targets not available\n Destinos iSCSI n\xe3o dispon\xedveis\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n Dispon\xedvel apenas para imagens RBD com \n diff r\xe1pido\n habilitado\n \n \n \n Pool\n Pool\n \n \n Data Pool\n Pool de Dados\n \n \n Created\n Criado\n \n \n Size\n Tamanho\n \n \n Object size\n Tamanho do objeto\n \n \n Features\n Recursos\n \n \n Provisioned\n Aprovisionado\n \n \n N/A\n N/A\n \n \n Total provisioned\n Total aprovisionado\n \n \n Striping unit\n Unidade de distribui\xe7\xe3o\n \n \n Striping count\n Total de distribui\xe7\xf5es\n \n \n Parent\n Pai\n \n \n Block name prefix\n Prefixo do nome do bloco\n \n \n Order\n Ordem\n \n \n Snapshots\n Instant\xe2neos\n \n \n Image\n Imagem\n \n \n This setting overrides the global value\n Esta configura\xe7\xe3o substitui o valor global\n \n \n Global\n Global\n \n \n This is the global value. No value for this option has been set for this image.\n Este \xe9 o valor global. Nenhum valor para esta op\xe7\xe3o foi definido para esta imagem.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \'/\' e \'@\' n\xe3o s\xe3o permitidos.\n \n \n -- No rbd pools available --\n -- N\xe3o h\xe1 pools de RBD dispon\xedveis --\n \n \n -- Select a pool --\n -- Selecionar pool --\n \n \n Use a dedicated data pool\n Usar pool de dados dedicado\n \n \n Data pool\n Pool de dados\n \n \n Dedicated pool that stores the object-data of the RBD.\n Pool dedicado que armazena os dados de objetos do RBD.\n \n \n e.g., 10GiB\n ex. 10 GiB\n \n \n You have to increase the size.\n Voc\xea precisa aumentar o tamanho.\n \n \n Advanced\n Avan\xe7ado\n \n \n Striping\n Distribui\xe7\xe3o\n \n \n Stripe unit\n Unidade de distribui\xe7\xe3o\n \n \n -- Select stripe unit --\n -- Selecionar unidade de distribui\xe7\xe3o --\n \n \n This field is required because stripe count is defined!\n Este campo \xe9 obrigat\xf3rio porque o total de distribui\xe7\xf5es foi definido!\n \n \n Stripe unit is greater than object size.\n A unidade de distribui\xe7\xe3o \xe9 maior do que o tamanho do objeto.\n \n \n Stripe count\n Total de distribui\xe7\xf5es\n \n \n This field is required because stripe unit is defined!\n Este campo \xe9 obrigat\xf3rio porque a unidade de distribui\xe7\xe3o foi definida!\n \n \n Stripe count must be greater than 0.\n O total de distribui\xe7\xf5es deve ser maior do que 0.\n \n \n \n RBD Snapshot\n \n \n Instant\xe2neo do RBD\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Renomear} other {Criar} }\n \n \n \n Snapshot\n \n \n Instant\xe2neo\n \n \n \n PROTECTED\n PROTEGIDO\n \n \n UNPROTECTED\n N\xc3O PROTEGIDO\n \n \n You are about to rollback\n Voc\xea est\xe1 prestes a fazer rollback\n \n \n Purge Trash\n Purgar Lixo\n \n \n To purge, select one or All images and click\n Para purgar, selecione uma ou Todas as imagens e clique em\n \n \n Pool:\n Pool:\n \n \n Pool name...\n Nome do pool...\n \n \n All\n Tudo\n \n \n Restore Image\n Restaurar Imagem\n \n \n To restore\n Para restaurar\n \n \n type the image\'s new name and click\n digite o novo nome da imagem e clique em\n \n \n New Name\n Novo Nome\n \n \n Expired at\n Venceu em\n \n \n Protected until\n Protegido at\xe9\n \n \n This image is protected until \n .\n \n Esta imagem est\xe1 protegida at\xe9 \n .\n \n \n \n Trash\n Lixo\n \n \n iSCSI Topology\n Topologia iSCSI\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n N\xe3o costuma ser necess\xe1rio mudar o valor padr\xe3o destes par\xe2metros.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Configura\xe7\xf5es\n \n \n Backstore\n Backstore\n \n \n Confirm\n Confirmar\n \n \n Advanced Settings\n Configura\xe7\xf5es Avan\xe7adas\n \n \n Target IQN\n IQN de Destino\n \n \n IQN has wrong pattern.\n IQN tem padr\xe3o incorreto.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n Um IQN tem a seguinte nota\xe7\xe3o \'iqn.$year-$month.$reversedAddress:$definedName\'\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Por exemplo: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n Mais informa\xe7\xf5es\n \n \n This target has modified advanced settings.\n Este destino tem configura\xe7\xf5es avan\xe7adas modificadas.\n \n \n Portals\n Portais\n \n \n At least \n gateways are required.\n \n Pelo menos \n gateways s\xe3o necess\xe1rios.\n \n \n \n Add portal\n Adicionar portal\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Esta imagem tem configura\xe7\xf5es modificadas.\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n Adicionar imagem\n \n \n ACL authentication\n Autentica\xe7\xe3o ACL\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Iniciadores\n \n \n Initiator\n Iniciador\n \n \n Client IQN\n IQN do Cliente\n \n \n Initiator IQN needs to be unique.\n O IQN do Iniciador precisa ser exclusivo.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Os nomes de usu\xe1rio devem ter entre 8 e 64 caracteres e\n apenas podem conter letras, \'.\', \'@\', \'-\', \'_\' ou \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n O iniciador pertence a um grupo. As imagens ser\xe3o configuradas no grupo.\n \n \n No items added.\n Nenhum item adicionado.\n \n \n Add initiator\n Adicionar iniciador\n \n \n Groups\n Grupos\n \n \n Group\n Grupo\n \n \n Add group\n Adicionar grupo\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n Configura\xe7\xe3o de RBD\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Remova o valor de configura\xe7\xe3o local. No lugar dele, o valor de configura\xe7\xe3o pai ser\xe1 herdado e usado.\n \n \n The mininum value is 0\n O valor m\xednimo \xe9 0\n \n \n Issues\n Problemas\n \n \n Syncing\n Sincronizando\n \n \n Ready\n Pronto\n \n \n Edit pool mirror mode\n Editar modo de espelho do pool\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n Para editar o modo de espelho do pool\xa0\n \n \n , selecione o novo modo na lista e clique em\xa0\n Atualizar\n .\n \n \n \n Mode\n Modo\n \n \n Peer clusters must be removed prior to disabling mirror.\n Clusters de peer devem ser removidos antes de desabilitar o espelho.\n \n \n \n \n pool mirror peer\n \n \n \n peer de espelho do pool\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Editar} other {Adicionar} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n os atributos\n de peer de espelho do pool \n \n \n e clique em \n Enviar\n .\n \n \n \n Cluster Name\n Nome do Cluster\n \n \n The cluster name is not valid.\n O nome do cluster n\xe3o \xe9 v\xe1lido.\n \n \n CephX ID\n ID do CephX\n \n \n CephX ID...\n ID do CephX...\n \n \n The CephX ID is not valid.\n O ID do CephX n\xe3o \xe9 v\xe1lido.\n \n \n Monitor Addresses\n Endere\xe7os do Monitor\n \n \n Comma-delimited addresses...\n Endere\xe7os delimitados por v\xedrgula...\n \n \n The monitory address is not valid.\n O endere\xe7o de monitoria n\xe3o \xe9 v\xe1lido.\n \n \n CephX Key\n Chave do CephX\n \n \n Base64-encoded key...\n Chave codificada com base64...\n \n \n CephX key must be base64 encoded.\n A chave do CephX deve ser codificada com base64.\n \n \n Pools List\n Lista de Pools\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n O nome pode conter apenas caracteres alfanum\xe9ricos, tra\xe7os e sublinhados.\n \n \n The chosen erasure code profile name is already in use.\n O nome do perfil de c\xf3digo de elimina\xe7\xe3o escolhido j\xe1 est\xe1 em uso.\n \n \n Plugin\n Plug-in\n \n \n Data chunks (k)\n Pacotes de dados (k)\n \n \n Must be equal to or greater than 2.\n Deve ser igual ou maior do que 2.\n \n \n Coding chunks (m)\n Pacotes de codifica\xe7\xe3o (m)\n \n \n Must be equal to or greater than 1.\n Deve ser igual ou maior do que 1.\n \n \n Durability estimator (c)\n Estimador de durabilidade (c)\n \n \n Locality (l)\n Localidade (l)\n \n \n Crush failure domain\n Dom\xednio de falha do Crush\n \n \n Crush Locality\n Localidade do Crush\n \n \n None\n Nenhum\n \n \n Technique\n T\xe9cnica\n \n \n Packetsize\n Tamanho do pacote\n \n \n Crush root\n Raiz do Crush\n \n \n Crush device class\n Classe do dispositivo do Crush\n \n \n any\n qualquer\n \n \n Directory\n Diret\xf3rio\n \n \n The chosen Ceph pool name is already in use.\n O nome do pool do Ceph escolhido j\xe1 est\xe1 em uso.\n \n \n Pool type\n Tipo de pool\n \n \n -- Select a pool type --\n -- Selecionar tipo de pool --\n \n \n Placement groups\n Grupos de posicionamento\n \n \n At least one placement group is needed!\n Pelo menos um grupo de posicionamento \xe9 necess\xe1rio!\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n Seu cluster n\xe3o pode processar tantos PGs. Recalcule a quantidade de PG necess\xe1ria.\n \n \n Calculation help\n Ajuda no c\xe1lculo\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n As configura\xe7\xf5es de PGs atuais foram calculadas para voc\xea. Verifique\n se os valores atendem \xe0s suas necessidades antes de enviar.\n \n \n Crush ruleset\n Conjunto de regras do Crush\n \n \n -- Select a crush rule --\n -- Selecionar regra de crush --\n \n \n Crush rule\n Regra de Crush\n \n \n Crush steps\n Etapas do Crush\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n Imposs\xedvel usar a regra no cluster atual porque ela tem\n poucos OSDs para atender ao OSD m\xednimo necess\xe1rio para esta regra.\n \n \n Replicated size\n Tamanho replicado\n \n \n Minimum: \n \n \n M\xednimo: \n \n \n \n \n Maximum: \n \n \n M\xe1ximo: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n O tamanho especificado est\xe1 fora da faixa. Um valor de\n a \n \xe9 v\xe1lido.\n \n \n \n Erasure code profile\n Perfil do c\xf3digo de elimina\xe7\xe3o\n \n \n -- No erasure code profile available --\n -- N\xe3o h\xe1 perfis de c\xf3digo de elimina\xe7\xe3o dispon\xedveis --\n \n \n -- Select an erasure code profile --\n -- Selecionar perfil do c\xf3digo de elimina\xe7\xe3o --\n \n \n EC Overwrites\n Sobregrava\xe7\xf5es de EC\n \n \n Applications\n Aplicativos\n \n \n Compression\n Compacta\xe7\xe3o\n \n \n Algorithm\n Algoritmo\n \n \n -- No erasure compression algorithm available --\n -- N\xe3o h\xe1 algoritmos de compacta\xe7\xe3o de elimina\xe7\xe3o dispon\xedveis --\n \n \n Minimum blob size\n Tamanho m\xednimo do blob\n \n \n e.g., 128KiB\n ex. 128 KiB\n \n \n Value should be greater than 0\n O valor deve ser maior do que 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Tamanho m\xe1ximo do blob\n \n \n e.g., 512KiB\n ex. 512 KiB\n \n \n Value should be greater than the minimum blob size\n O valor deve ser maior do que o tamanho m\xednimo do blob\n \n \n Ratio\n Taxa\n \n \n Compression ratio\n Taxa de compacta\xe7\xe3o\n \n \n Value should be between 0.0 and 1.0\n O valor deve ser entre 0.0 e 1.0\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n Imposs\xedvel criar um pool de RBD com \'/\' no nome.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n Altere o nome ou remova o \'rbd\' da lista de aplicativos.\n \n \n Cache Tiers Details\n Detalhes das Camadas do Cache\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Consulte a \n documenta\xe7\xe3o\n \n sobre como configurar e habilitar a funcionalidade de gerenciamento do Gateway de Objetos.\n \n \n \n Daemons List\n Lista de Daemons\n \n \n Performance Counters\n Contadores de Desempenho\n \n \n Loading bucket data...\n Carregando dados do compartimento...\n \n \n The bucket data could not be loaded.\n N\xe3o foi poss\xedvel carregar os dados do compartimento.\n \n \n Id\n ID\n \n \n The value is not valid.\n O valor n\xe3o \xe9 v\xe1lido.\n \n \n Owner\n Propriet\xe1rio\n \n \n -- Select a user --\n -- Selecionar usu\xe1rio --\n \n \n ID\n ID\n \n \n Index type\n Tipo de \xedndice\n \n \n Placement rule\n Regra de posicionamento\n \n \n Marker\n Marcador\n \n \n Maximum marker\n Marcador m\xe1ximo\n \n \n Version\n Vers\xe3o\n \n \n Master version\n Vers\xe3o master\n \n \n Modification time\n Hor\xe1rio da modifica\xe7\xe3o\n \n \n Zonegroup\n Grupo de zonas\n \n \n Bucket quota\n Cota do compartimento\n \n \n Enabled\n Habilitado\n \n \n Maximum size\n Tamanho m\xe1ximo\n \n \n Unlimited\n Ilimitado\n \n \n Maximum objects\n M\xe1ximo de objetos\n \n \n -- Select a username --\n -- Selecionar nome de usu\xe1rio --\n \n \n Auto-generate key\n Gerar chave automaticamente\n \n \n Access key\n Chave de acesso\n \n \n Secret key\n Chave secreta\n \n \n Email address\n Endere\xe7o de e-mail\n \n \n Suspended\n Suspenso\n \n \n System\n Sistema\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {N\xe3o} 1 {Sim} }\n \n \n Maximum buckets\n M\xe1ximo de compartimentos\n \n \n Subusers\n Subusu\xe1rios\n \n \n Capabilities\n Recursos\n \n \n User quota\n Cota do usu\xe1rio\n \n \n Show\n Mostrar\n \n \n Keys\n Chaves\n \n \n -- Select a type --\n -- Selecionar tipo --\n \n \n Permission\n Permiss\xe3o\n \n \n -- Select a permission --\n -- Selecionar permiss\xe3o --\n \n \n Subuser\n Subusu\xe1rio\n \n \n The chosen subuser ID is already in use.\n O ID de subusu\xe1rio escolhido j\xe1 est\xe1 em uso.\n \n \n read, write\n leitura, grava\xe7\xe3o\n \n \n full\n completo\n \n \n Swift key\n Chave Swift\n \n \n Auto-generate secret\n Gerar segredo automaticamente\n \n \n Loading user data...\n Carregando dados do usu\xe1rio...\n \n \n The user data could not be loaded.\n N\xe3o foi poss\xedvel carregar os dados do usu\xe1rio.\n \n \n The chosen user ID is already in use.\n O ID de usu\xe1rio escolhido j\xe1 est\xe1 em uso.\n \n \n This is not a valid email address.\n Este n\xe3o \xe9 um endere\xe7o de e-mail v\xe1lido.\n \n \n The chosen email address is already in use.\n O endere\xe7o de e-mail escolhido j\xe1 est\xe1 em uso.\n \n \n Max. buckets\n M\xe1x. de compartimentos\n \n \n The entered value must be >= 0.\n O valor inserido deve ser >= 0.\n \n \n S3 key\n Chave S3\n \n \n There are no subusers.\n N\xe3o h\xe1 subusu\xe1rios.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n N\xe3o h\xe1 chaves.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n N\xe3o h\xe1 recursos.\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Tamanho ilimitado\n \n \n Max. size\n Tamanho m\xe1x.\n \n \n Unlimited objects\n Objetos ilimitados\n \n \n Max. objects\n M\xe1x. de objetos\n \n \n Current\n Atual\n \n \n Updated discovery authentication\n Autentica\xe7\xe3o de descoberta atualizada\n \n \n There are no portals available.\n N\xe3o h\xe1 portais dispon\xedveis.\n \n \n There are no images available.\n N\xe3o h\xe1 imagens dispon\xedveis.\n \n \n There are no images available. Please make sure you add an image to the target.\n N\xe3o h\xe1 imagens dispon\xedveis. Adicione uma imagem ao destino.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n N\xe3o h\xe1 iniciadores dispon\xedveis. Adicione um iniciador ao destino.\n \n \n target\n target\n \n \n Target\n Destino\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n Estado\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Bytes de Leitura\n \n \n Write Bytes\n Bytes de Grava\xe7\xe3o\n \n \n Read Ops\n Op. de Leitura\n \n \n Write Ops\n Op. de Grava\xe7\xe3o\n \n \n A/O Since\n A/O Desde\n \n \n Instance\n Inst\xe2ncia\n \n \n Hostname\n Nome de host\n \n \n Issue\n Problema\n \n \n Progress\n Andamento\n \n \n Disabled\n Desabilitado\n \n \n Edit Mode\n Modo de Edi\xe7\xe3o\n \n \n Add Peer\n Adicionar Peer\n \n \n Edit Peer\n Editar Peer\n \n \n Delete Peer\n Excluir Peer\n \n \n Leader\n Leader\n \n \n # Local\n N\xba Local\n \n \n # Remote\n N\xba Remoto\n \n \n mirror peer\n espelhar peer\n \n \n Key\n Chave\n \n \n RBD\n RBD\n \n \n Deep flatten\n Nivelamento profundo\n \n \n Layering\n Disposi\xe7\xe3o em camadas\n \n \n Exclusive lock\n Bloqueio exclusivo\n \n \n Object map (requires exclusive-lock)\n Mapa de objetos (requer bloqueio exclusivo)\n \n \n Journaling (requires exclusive-lock)\n Registro em di\xe1rio (requer bloqueio exclusivo)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Rollback de instant\xe2neo do RBD\n \n \n Rollback\n Fazer Rollback\n \n \n RBD snapshot\n Instant\xe2neo do RBD\n \n \n Deleted At\n Exclu\xeddo \xe0(s)\n \n \n id\n ID\n \n \n type\n tipo\n \n \n state\n estado\n \n \n version\n vers\xe3o\n \n \n Host\n Host\n \n \n root\n raiz\n \n \n Rank\n Posi\xe7\xe3o\n \n \n Daemon\n Daemon\n \n \n Activity\n Atividade\n \n \n Dentries\n Dentries\n \n \n Inodes\n Inodes\n \n \n Usage\n Uso\n \n \n Standby daemons\n Daemons de standby\n \n \n The value can be updated at runtime.\n \xc9 poss\xedvel atualizar o valor em temo de execu\xe7\xe3o.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n Daemons/clientes n\xe3o extraem este valor do\n banco de dados de configura\xe7\xe3o do monitor. A configura\xe7\xe3o desta op\xe7\xe3o n\xe3o \xe9 permitida por meio de \'ceph config\n set ...\'. Essa op\xe7\xe3o deve ser configurada por meio do ceph.conf ou da\n linha de comando.\n \n \n Option takes effect only during daemon startup.\n A op\xe7\xe3o entra em vigor apenas durante a inicializa\xe7\xe3o do daemon.\n \n \n Option only affects cluster creation.\n A op\xe7\xe3o afeta apenas a cria\xe7\xe3o do cluster.\n \n \n Option only affects daemon creation.\n A op\xe7\xe3o afeta apenas a cria\xe7\xe3o do daemon.\n \n \n Updated config option \n \n \n Op\xe7\xe3o de configura\xe7\xe3o \n atualizada\n \n \n \n Service\n Servi\xe7o\n \n \n Current value\n Valor atual\n \n \n Editable\n Edit\xe1vel\n \n \n Updated options for module "\n ".\n \n Op\xe7\xf5es atualizadas para o m\xf3dulo &quot;\n &quot;.\n \n \n \n Enable\n Habilitar\n \n \n Disable\n Desabilitar\n \n \n Reconnecting, please wait ...\n Reconectando, aguarde...\n \n \n Public Address\n Endere\xe7o P\xfablico\n \n \n Open Sessions\n Sess\xf5es Abertas\n \n \n No In\n N\xe3o Entrada\n \n \n OSDs that were previously marked out will not be marked back in when they start\n Os OSDs que j\xe1 foram marcados como sa\xedda n\xe3o ser\xe3o remarcados como entrada ao serem iniciados\n \n \n No Out\n N\xe3o Sa\xedda\n \n \n OSDs will not automatically be marked out after the configured interval\n Os OSDs n\xe3o ser\xe3o automaticamente marcados como sa\xedda ap\xf3s o intervalo configurado\n \n \n No Up\n N\xe3o Ativo\n \n \n OSDs are not allowed to start\n Os OSDs n\xe3o podem ser iniciados\n \n \n No Down\n N\xe3o Inativo\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n Os relat\xf3rios de falha de OSD est\xe3o sendo ignorados, portanto, os monitores n\xe3o marcar\xe3o os OSDs como inativos\n \n \n Pause\n Pausar\n \n \n Pauses reads and writes\n Pausa leituras e grava\xe7\xf5es\n \n \n No Scrub\n Sem Remo\xe7\xe3o\n \n \n Scrubbing is disabled\n Remo\xe7\xe3o desabilitada\n \n \n No Deep Scrub\n Sem Remo\xe7\xe3o Profunda\n \n \n Deep Scrubbing is disabled\n Remo\xe7\xe3o Profunda desabilitada\n \n \n No Backfill\n Sem Provisionamento\n \n \n Backfilling of PGs is suspended\n Provisionamento de PGs suspenso\n \n \n No Recover\n Sem Recupera\xe7\xe3o\n \n \n Recovery of PGs is suspended\n Recupera\xe7\xe3o de PGs suspensa\n \n \n Bitwise Sort\n Classifica\xe7\xe3o Bit a Bit\n \n \n Use bitwise sort\n Usar classifica\xe7\xe3o bit a bit\n \n \n Purged Snapdirs\n Snapdirs Purgados\n \n \n OSDs have converted snapsets\n OSDs converteram snapsets\n \n \n Recovery Deletes\n Exclus\xf5es de Recupera\xe7\xe3o\n \n \n Deletes performed during recovery instead of peering\n Exclus\xf5es realizadas durante a recupera\xe7\xe3o, e n\xe3o o emparelhamento\n \n \n PG Log Hard Limit\n Limite F\xedsico do Registro de PG\n \n \n Puts a hard limit on pg log length\n Atribui um limite f\xedsico ao tamanho do registro de PG\n \n \n Updated OSD Flags\n Flags OSD Atualizadas\n \n \n out\n sa\xedda\n \n \n in\n entrada\n \n \n down\n inativo\n \n \n Mark\n Marcar\n \n \n OSD lost\n OSD perdido\n \n \n marked lost\n marcado como perdido\n \n \n Purge\n Purgar\n \n \n OSD\n OSD\n \n \n purged\n purgado\n \n \n destroy\n destruir\n \n \n destroyed\n destru\xeddo\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n PGs\n \n \n Read bytes\n Bytes de leitura\n \n \n Writes bytes\n Bytes de grava\xe7\xe3o\n \n \n Read ops\n Op. de leitura\n \n \n Write ops\n Op. de grava\xe7\xe3o\n \n \n Mark OSD \n \n \n Marcar OSD como \n \n \n \n \n Mark \n \n \n Marcar como \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n M\xe1x. de Provisionamentos\n \n \n Recovery Max Active\n M\xe1x. Recupera\xe7\xe3o Ativo\n \n \n Recovery Max Single Start\n M\xe1x. Recupera\xe7\xe3o Inicializa\xe7\xe3o \xdanica\n \n \n Recovery Sleep\n Suspens\xe3o de Recupera\xe7\xe3o\n \n \n Custom\n Personalizado\n \n \n Updated OSD recovery speed priority "\n "\n \n Prioridade de velocidade de recupera\xe7\xe3o de OSD &quot;\n &quot atualizada;\n \n \n \n \n was initialized in the following OSD: \n \n \n \n foi inicializado no seguinte OSD: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n Tarefa\n \n \n Severity\n Gravidade\n \n \n Started\n Iniciado\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Atualizado\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n Usado\n \n \n Avail.\n Disp.\n \n \n Clean\n Limpar\n \n \n Working\n Em funcionamento\n \n \n Warning\n Aviso\n \n \n Unknown\n Desconhecido\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n ativo\n \n \n no filesystems\n sem sistemas de arquivos\n \n \n active\n ativo\n \n \n standby\n standby\n \n \n n/a\n n/a\n \n \n active daemon\n daemon ativo\n \n \n quorum\n quorum\n \n \n The NFS Ganesha service is not configured.\n O servi\xe7o NFS Ganesha n\xe3o est\xe1 configurado.\n \n \n Transport\n Transporte\n \n \n CephFS User\n Usu\xe1rio do CephFS\n \n \n CephFS Filesystem\n Sistema de Arquivos do CephFS\n \n \n (inherited from global config)\n (herdado da configura\xe7\xe3o global)\n \n \n inherited from global config\n herdado da configura\xe7\xe3o global\n \n \n -- Select what kind of user id squashing is performed --\n -- Selecionar que tipo de squash de ID de usu\xe1rio ser\xe1 executado --\n \n \n There are no daemons available.\n N\xe3o h\xe1 daemons dispon\xedveis.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Modo de Cache\n \n \n Min Evict Age\n Tempo M\xedn. Expuls\xe3o\n \n \n Min Flush Age\n Tempo M\xedn. Descarregamento\n \n \n Target Max Bytes\n M\xe1x. de Bytes de Destino\n \n \n Target Max Objects\n M\xe1x. de Objetos de Destino\n \n \n No applications added\n Nenhum aplicativo adicionado\n \n \n Applications limit reached\n Limite de aplicativos atingido\n \n \n A pool can only have up to four applications definitions.\n Um pool apenas pode ter at\xe9 quatro defini\xe7\xf5es de aplicativos.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n Caracteres permitidos: \'_a-zA-Z0-9\'\n \n \n Maximum length is 128 characters\n Tamanho m\xe1ximo de 128 caracteres\n \n \n Filter or add applications\n Filtrar ou adicionar aplicativos\n \n \n Add application\n Adicionar aplicativo\n \n \n pool\n pool\n \n \n erasure code profile\n perfil de c\xf3digo de elimina\xe7\xe3o\n \n \n Replica Size\n Tamanho da R\xe9plica\n \n \n Last Change\n \xdaltima Altera\xe7\xe3o\n \n \n Erasure Coded Profile\n Perfil Codificado para Elimina\xe7\xe3o\n \n \n Crush Ruleset\n Conjunto de Regras do Crush\n \n \n Write bytes\n Bytes de grava\xe7\xe3o\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n compartimento\n \n \n Updated Object Gateway bucket "\n "\n \n Compartimento do Gateway de Objetos &quot;\n &quot; atualizado\n \n \n \n Created Object Gateway bucket "\n "\n \n Compartimento do Gateway de Objetos &quot;\n &quot; criado\n \n \n \n buckets\n compartimentos\n \n \n capability\n capability\n \n \n user\n usu\xe1rio\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Usu\xe1rio do Gateway de Objetos &quot;\n &quot; atualizado\n \n \n \n Created Object Gateway user "\n "\n \n Usu\xe1rio do Gateway de Objetos &quot;\n &quot; criado\n \n \n \n users\n usu\xe1rios\n \n \n Swift Key\n Swift Key\n \n \n Scope\n Escopo\n \n \n Read\n Leitura\n \n \n Create\n Criar\n \n \n role\n role\n \n \n Created role \'\n \'\n \n Fun\xe7\xe3o \'\n \' criada\n \n \n \n Updated role \'\n \'\n \n Fun\xe7\xe3o \'\n \' atualizada\n \n \n \n System Role\n Fun\xe7\xe3o do Sistema\n \n \n Deleted role \'\n \'\n \n Fun\xe7\xe3o \'\n \' exclu\xedda\n \n \n \n Created user "\n "\n \n Usu\xe1rio &quot;\n &quot; criado\n \n \n \n Update user\n Atualizar usu\xe1rio\n \n \n Continue\n Continuar\n \n \n You were automatically logged out because your roles have been changed.\n Voc\xea foi automaticamente desconectado porque suas fun\xe7\xf5es foram alteradas.\n \n \n Updated user "\n "\n \n Usu\xe1rio &quot;\n &quot; atualizado\n \n \n \n Deleted user "\n "\n \n Usu\xe1rio &quot;\n &quot; exclu\xeddo\n \n \n \n Failed to delete user "\n "\n \n Falha ao excluir o usu\xe1rio &quot;\n &quot;\n \n \n \n You are currently logged in as "\n ".\n \n No momento, voc\xea est\xe1 conectado como &quot;\n &quot;.\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Cada objeto \xe9 dividido em partes de pacotes de dados, cada uma armazenada em um OSD diferente.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Calcule os pacotes de codifica\xe7\xe3o de cada objeto e armazene-os em diferentes OSDs.\n O n\xfamero de pacotes de codifica\xe7\xe3o \xe9 tamb\xe9m o n\xfamero de OSDs que podem ficar inativos sem perda de dados.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n O plug-in jerasure \xe9 o mais gen\xe9rico e flex\xedvel,\n al\xe9m de ser o padr\xe3o para pools codificados para elimina\xe7\xe3o do Ceph.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n A t\xe9cnica mais flex\xedvel \xe9 reed_sol_van: ela \xe9 suficiente para definir k\n e m. A t\xe9cnica cauchy_good pode ser mais r\xe1pida, mas voc\xea precisa escolher o tamanho do pacote\n com cuidado. Todos os reed_sol_r6_op, liberation, blaum_roth e liber8tion s\xe3o equivalentes ao RAID6\n no sentido de que s\xf3 podem ser configurados com m=2.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n A codifica\xe7\xe3o ser\xe1 feita em pacotes de tamanho de bytes um de cada vez.\n A escolha do tamanho do pacote certo \xe9 dif\xedcil.\n A documenta\xe7\xe3o do jerasure cont\xe9m informa\xe7\xf5es completas sobre este t\xf3pico.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n Com o plug-in jerasure, quando um objeto codificado para elimina\xe7\xe3o \xe9 armazenado em\n v\xe1rios OSDs, a recupera\xe7\xe3o ap\xf3s a perda de um OSD requer a leitura de todos os outros.\n Por exemplo, se o jerasure for configurado com k=8 e m=4, a perda de um OSD exigir\xe1 a leitura\n dos outros onze para fazer o reparo.\n\n O plug-in de c\xf3digo de elimina\xe7\xe3o lrc cria pacotes locais de paridade para conseguir recuperar usando\n menos OSDs. Por exemplo, se o lrc for configurado com k=8, m=4 e l=4, ele criar\xe1\n um pacote de paridade adicional para cada quatro OSDs. Quando um \xfanico OSD \xe9 perdido, ele pode ser\n recuperado apenas com quatro OSDs, em vez de onze.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Agrupe os pacotes de codifica\xe7\xe3o e dados em conjuntos de localidades com tamanho. Por exemplo,\n no caso de k=4 e m=2, quando locality=3, dois grupos de tr\xeas s\xe3o criados. Cada conjunto pode\n ser recuperado sem a leitura dos pacotes do outro conjunto.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n O tipo do compartimento de crush em que cada conjunto de pacotes definido\n por l ser\xe1 armazenado. Por exemplo, se isso for definido como rack, cada grupo de pacotes l ser\xe1\n colocado em um rack diferente. Isso \xe9 usado para criar uma etapa da regra CRUSH, como a etapa de escolha do\n rack. Se isso n\xe3o for definido, esse tipo de agrupamento n\xe3o ser\xe1 feito.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n O plug-in isa encapsula a biblioteca ISA. Ele apenas \xe9 executado em processadores Intel.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n O plug-in ISA vem em dois formatos de Reed Solomon.\n Se reed_sol_van for definido, ele ser\xe1 Vandermonde, se cauchy for definido, ele ser\xe1 Cauchy.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n O plug-in shec encapsula a biblioteca m\xfaltipla SHEC.\n Ele permite ao ceph recuperar dados com mais efici\xeancia do que os c\xf3digos de Reed Solomon.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n O n\xfamero de pacotes de paridade, em que cada um inclui cada pacote de dados em sua\n faixa de c\xe1lculo. O n\xfamero \xe9 usado como estimador de durabilidade. Por exemplo, se c=2,\n 2 OSDs podem ficar inativos sem perda de dados.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n O nome do compartimento de crush usado para a primeira etapa da regra CRUSH.\n Por exemplo, a etapa assumir o padr\xe3o.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n Verifique se n\xe3o h\xe1 dois pacotes em um compartimento com o mesmo dom\xednio de\n falha. Por exemplo, se o dom\xednio de falha for um host, n\xe3o armazene dois pacotes no mesmo\n host. Isso \xe9 usado para criar uma etapa da regra CRUSH, como a etapa de escolha do host folha.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Restrinja o posicionamento a dispositivos de uma classe espec\xedfica\n (ex. ssd ou hdd), usando nomes de classe de dispositivo crush no mapa CRUSH.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n Defina o nome do diret\xf3rio do qual o plug-in de c\xf3digo de elimina\xe7\xe3o \xe9 carregado.\n \n \n Allows all operations\n Permite todas as opera\xe7\xf5es\n \n \n Allows only operations that do not modify the server\n Permite apenas as opera\xe7\xf5es que n\xe3o modificam o servidor\n \n \n Does not allow read or write operations, but allows any other operation\n N\xe3o permite opera\xe7\xf5es de leitura ou grava\xe7\xe3o, mas permite qualquer outra opera\xe7\xe3o\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n N\xe3o permite leitura, grava\xe7\xe3o ou qualquer opera\xe7\xe3o que modifica os atributos do arquivo ou o conte\xfado do diret\xf3rio\n \n \n Allows no access at all\n N\xe3o permite nenhum tipo de acesso\n \n \n -- Select the priority --\n -- Selecionar prioridade --\n \n \n Low\n Baixa\n \n \n High\n Alta\n \n \n Last 5 minutes\n \xdaltimos 5 minutos\n \n \n Last 15 minutes\n \xdaltimos 15 minutos\n \n \n Last 30 minutes\n \xdaltimos 30 minutos\n \n \n Last 1 hour (Default)\n \xdaltima 1 hora (Padr\xe3o)\n \n \n Last 3 hours\n \xdaltimas 3 horas\n \n \n Last 6 hours\n \xdaltimas 6 horas\n \n \n Last 12 hours\n \xdaltimas 12 horas\n \n \n Last 24 hours\n \xdaltimas 24 horas\n \n \n Yesterday\n Ontem\n \n \n Today\n Hoje\n \n \n Today so far\n At\xe9 agora hoje\n \n \n Day before yesterday\n Antes de ontem\n \n \n Last 2 days\n \xdaltimos 2 dias\n \n \n This day last week\n Este dia na semana passada\n \n \n Previous week\n Semana anterior\n \n \n This week\n Esta semana\n \n \n This week so far\n At\xe9 agora nesta semana\n \n \n Last 7 days\n \xdaltimos 7 dias\n \n \n Previous month\n M\xeas anterior\n \n \n This month\n Este m\xeas\n \n \n This month so far\n At\xe9 agora neste m\xeas\n \n \n Last 30 days\n \xdaltimos 30 dias\n \n \n Last 90 days\n \xdaltimos 90 dias\n \n \n Last 6 months\n \xdaltimos 6 meses\n \n \n Last 1 year\n \xdaltimo ano\n \n \n Previous year\n Ano anterior\n \n \n This year\n Este ano\n \n \n This year so far\n At\xe9 agora neste ano\n \n \n Last 2 years\n \xdaltimos 2 anos\n \n \n Last 5 years\n \xdaltimos 5 anos\n \n \n Information\n Informa\xe7\xf5es\n \n \n No items selected.\n Nenhum item selecionado.\n \n \n Deselect item to select again\n Desmarcar item para selecionar novamente\n \n \n Selection limit reached\n Limite de sele\xe7\xe3o atingido\n \n \n Filter tags\n Tags de filtro\n \n \n Add badge\n Adicionar selo\n \n \n There are no items available.\n N\xe3o h\xe1 itens dispon\xedveis.\n \n \n Add\n Adicionar\n \n \n Remove\n Remove\n \n \n Clone\n Clonar\n \n \n Copy\n Copiar\n \n \n Deep Scrub\n Remo\xe7\xe3o Profunda\n \n \n Destroy\n Destruir\n \n \n Flatten\n Nivelar\n \n \n Mark Down\n Marcar como Inativo\n \n \n Mark In\n Marcar como Entrada\n \n \n Mark Lost\n Marcar como Perdido\n \n \n Mark Out\n Marcar como Sa\xedda\n \n \n Protect\n Proteger\n \n \n Rename\n Renomear\n \n \n Restore\n Restaurar\n \n \n Move to Trash\n Mover para Lixo\n \n \n Unprotect\n Cancelar prote\xe7\xe3o\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Exclu\xeddo\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Clonado\n \n \n Copied\n Copiado\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n Sim\n \n \n No\n N\xe3o\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Qualidade do Servi\xe7o\n \n \n BPS Limit\n Limite de BPS\n \n \n The desired limit of IO bytes per second.\n O limite de bytes por segundo de E/S desejado.\n \n \n IOPS Limit\n Limite de IOPS\n \n \n The desired limit of IO operations per second.\n O limite de opera\xe7\xf5es por segundo de E/S desejado.\n \n \n Read BPS Limit\n Limite de BPS de Leitura\n \n \n The desired limit of read bytes per second.\n O limite de bytes por segundo de leitura desejado.\n \n \n Read IOPS Limit\n Limite de IOPS de Leitura\n \n \n The desired limit of read operations per second.\n O limite de opera\xe7\xf5es por segundo de leitura desejado.\n \n \n Write BPS Limit\n Limite de BPS de Grava\xe7\xe3o\n \n \n The desired limit of write bytes per second.\n O limite de bytes por segundo de grava\xe7\xe3o desejado.\n \n \n Write IOPS Limit\n Limite de IOPS de Grava\xe7\xe3o\n \n \n The desired limit of write operations per second.\n O limite de opera\xe7\xf5es por segundo de grava\xe7\xe3o desejado.\n \n \n BPS Burst\n Intermit\xeancia de BPS\n \n \n The desired burst limit of IO bytes.\n O limite de bytes de E/S de intermit\xeancia desejado.\n \n \n IOPS Burst\n Intermit\xeancia de IOPS\n \n \n The desired burst limit of IO operations.\n O limite de opera\xe7\xf5es de E/S de intermit\xeancia desejado.\n \n \n Read BPS Burst\n Intermit\xeancia de BPS de Leitura\n \n \n The desired burst limit of read bytes.\n O limite de bytes de leitura de intermit\xeancia desejado.\n \n \n Read IOPS Burst\n Intermit\xeancia de IOPS de Leitura\n \n \n The desired burst limit of read operations.\n O limite de opera\xe7\xf5es de leitura de intermit\xeancia desejado.\n \n \n Write BPS Burst\n Intermit\xeancia de BPS de Grava\xe7\xe3o\n \n \n The desired burst limit of write bytes.\n O limite de bytes de grava\xe7\xe3o de intermit\xeancia desejado.\n \n \n Write IOPS Burst\n Intermit\xeancia de IOPS de Grava\xe7\xe3o\n \n \n The desired burst limit of write operations.\n O limite de opera\xe7\xf5es de grava\xe7\xe3o de intermit\xeancia desejado.\n \n \n Failed to \n \n \n \n Falha ao \n \n \n \n \n \n Executing\n Executando\n \n \n execute\n executar\n \n \n Executed\n Executado\n \n \n unknown task\n tarefa desconhecida\n \n \n Creating\n Criando\n \n \n create\n criar\n \n \n Updating\n Atualizando\n \n \n update\n atualizar\n \n \n Deleting\n Excluindo\n \n \n delete\n excluir\n \n \n RBD \'\n \'\n \n RBD \'\n \'\n \n \n \n RBD snapshot \'\n \'\n \n Instant\xe2neo do RBD \'\n \'\n \n \n \n mirror mode for pool \'\n \'\n \n modo de espelho para o pool \'\n \'\n \n \n \n mirror peer for pool \'\n \'\n \n espelhar peer para o pool \'\n \'\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n Nome j\xe1 foi usado por \n .\n \n \n \n Name is already used by \n .\n \n Nome j\xe1 foi usado por \n .\n \n \n \n Name is already used by \n .\n \n Nome j\xe1 foi usado por \n .\n \n \n \n \n contains snapshots.\n \n \n cont\xe9m instant\xe2neos.\n \n \n \n Cloning\n Clonando\n \n \n clone\n clonar\n \n \n Snapshot of \n must be protected.\n \n O instant\xe2neo de \n deve ser protegido.\n \n \n \n Copying\n Copiando\n \n \n copy\n copiar\n \n \n Flattening\n Nivelando\n \n \n flatten\n nivelar\n \n \n Flattened\n Nivelado\n \n \n Name is already used by \n .\n \n Nome j\xe1 foi usado por \n .\n \n \n \n Cannot unprotect \n because it contains child images.\n \n Imposs\xedvel cancelar a prote\xe7\xe3o de \n porque h\xe1 imagens filho.\n \n \n \n Cannot delete \n because it\'s protected.\n \n Imposs\xedvel excluir \n porque est\xe1 protegido.\n \n \n \n Rolling back\n Fazendo rollback\n \n \n rollback\n rollback\n \n \n Rolled back\n Rollback feito\n \n \n Moving\n Movendo\n \n \n move\n mover\n \n \n Moved\n Movido\n \n \n image \'\n \' to trash\n \n imagem \'\n \' para jogar no lixo\n \n \n \n Could not find image.\n Imagem n\xe3o encontrada.\n \n \n Restoring\n Restaurando\n \n \n restore\n restaurar\n \n \n Restored\n Restaurado\n \n \n image \'\n \' into \'\n \'\n \n imagem \'\n \' para \'\n \'\n \n \n \n Image name \'\n \' is already in use.\n \n Nome da imagem \'\n \' j\xe1 est\xe1 em uso.\n \n \n \n image \'\n \'\n \n imagem \'\n \'\n \n \n \n Purging\n Purgando\n \n \n purge\n purgar\n \n \n Purged\n Purgado\n \n \n all pools\n todos os pools\n \n \n images from \n \n \n imagens de \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n Imposs\xedvel desabilitar espelhamento porque ele cont\xe9m um peer.\n \n \n pool \'\n \'\n \n pool \'\n \'\n \n \n \n erasure code profile \'\n \'\n \n perfil de c\xf3digo de elimina\xe7\xe3o \'\n \'\n \n \n \n target \'\n \'\n \n destino \'\n \'\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},OXbD:function(t,e,n){"use strict";var a=n("CDJp"),r=n("K2E3"),i=n("RDha"),s=a.global.defaultColor;function o(t){var e=this._view;return!!e&&Math.abs(t-e.x)=t.left&&1.01*t.right>=n.x&&n.y>=t.top&&1.01*t.bottom>=n.y)&&(r.strokeStyle=e.borderColor||s,r.lineWidth=i.valueOrDefault(e.borderWidth,a.global.elements.point.borderWidth),r.fillStyle=e.backgroundColor||s,i.canvas.drawPoint(r,o,c,l,d,u))}})},OZfm:function(t,e,n){"use strict";n.d(e,"a",function(){return s}),n.d(e,"b",function(){return o}),n.d(e,"c",function(){return u}),n.d(e,"d",function(){return c});var a=n("lqqz"),r=n("rpEJ"),i=n("NJnL"),s=function(){return function(){this.adaptivePosition=!0,this.placement="top",this.triggers="click",this.outsideClick=!1}}(),o=function(){function t(t){Object.assign(this,t)}return Object.defineProperty(t.prototype,"isBs3",{get:function(){return Object(r.d)()},enumerable:!0,configurable:!0}),t}(),u=function(){function t(t,e,n,a,r,i){this._positionService=i,this.outsideClick=!1,this.containerClass="",this._isInited=!1,this._popover=r.createLoader(e,a,n).provide({provide:s,useValue:t}),Object.assign(this,t),this.onShown=this._popover.onShown,this.onHidden=this._popover.onHidden,"undefined"!=typeof window&&e.nativeElement.addEventListener("click",function(){try{e.nativeElement.focus()}catch(t){return}})}return Object.defineProperty(t.prototype,"isOpen",{get:function(){return this._popover.isShown},set:function(t){t?this.show():this.hide()},enumerable:!0,configurable:!0}),t.prototype.show=function(){!this._popover.isShown&&this.popover&&(this._positionService.setOptions({modifiers:{flip:{enabled:this.adaptivePosition},preventOverflow:{enabled:this.adaptivePosition}}}),this._popover.attach(o).to(this.container).position({attachment:this.placement}).show({content:this.popover,context:this.popoverContext,placement:this.placement,title:this.popoverTitle,containerClass:this.containerClass}),this.adaptivePosition||(this._positionService.calcPosition(),this._positionService.deletePositionElement(this._popover._componentRef.location)),this.isOpen=!0)},t.prototype.hide=function(){this.isOpen&&(this._popover.hide(),this.isOpen=!1)},t.prototype.toggle=function(){if(this.isOpen)return this.hide();this.show()},t.prototype.ngOnInit=function(){var t=this;this._isInited||(this._isInited=!0,this._popover.listen({triggers:this.triggers,outsideClick:this.outsideClick,show:function(){return t.show()}}))},t.prototype.ngOnDestroy=function(){this._popover.dispose()},t}(),c=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[s,a.a,i.a]}},t}()},Oaa7:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")},week:{dow:1,doy:4}})}()},Ob0Z:function(t,e,n){!function(t){"use strict";var e={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},n={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};function a(t,e,n,a){var r="";if(e)switch(n){case"s":r="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926";break;case"ss":r="%d \u0938\u0947\u0915\u0902\u0926";break;case"m":r="\u090f\u0915 \u092e\u093f\u0928\u093f\u091f";break;case"mm":r="%d \u092e\u093f\u0928\u093f\u091f\u0947";break;case"h":r="\u090f\u0915 \u0924\u093e\u0938";break;case"hh":r="%d \u0924\u093e\u0938";break;case"d":r="\u090f\u0915 \u0926\u093f\u0935\u0938";break;case"dd":r="%d \u0926\u093f\u0935\u0938";break;case"M":r="\u090f\u0915 \u092e\u0939\u093f\u0928\u093e";break;case"MM":r="%d \u092e\u0939\u093f\u0928\u0947";break;case"y":r="\u090f\u0915 \u0935\u0930\u094d\u0937";break;case"yy":r="%d \u0935\u0930\u094d\u0937\u0947"}else switch(n){case"s":r="\u0915\u093e\u0939\u0940 \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"ss":r="%d \u0938\u0947\u0915\u0902\u0926\u093e\u0902";break;case"m":r="\u090f\u0915\u093e \u092e\u093f\u0928\u093f\u091f\u093e";break;case"mm":r="%d \u092e\u093f\u0928\u093f\u091f\u093e\u0902";break;case"h":r="\u090f\u0915\u093e \u0924\u093e\u0938\u093e";break;case"hh":r="%d \u0924\u093e\u0938\u093e\u0902";break;case"d":r="\u090f\u0915\u093e \u0926\u093f\u0935\u0938\u093e";break;case"dd":r="%d \u0926\u093f\u0935\u0938\u093e\u0902";break;case"M":r="\u090f\u0915\u093e \u092e\u0939\u093f\u0928\u094d\u092f\u093e";break;case"MM":r="%d \u092e\u0939\u093f\u0928\u094d\u092f\u093e\u0902";break;case"y":r="\u090f\u0915\u093e \u0935\u0930\u094d\u0937\u093e";break;case"yy":r="%d \u0935\u0930\u094d\u0937\u093e\u0902"}return r.replace(/%d/i,t)}t.defineLocale("mr",{months:"\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u090f\u092a\u094d\u0930\u093f\u0932_\u092e\u0947_\u091c\u0942\u0928_\u091c\u0941\u0932\u0948_\u0911\u0917\u0938\u094d\u091f_\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930_\u0911\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930_\u0921\u093f\u0938\u0947\u0902\u092c\u0930".split("_"),monthsShort:"\u091c\u093e\u0928\u0947._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a._\u090f\u092a\u094d\u0930\u093f._\u092e\u0947._\u091c\u0942\u0928._\u091c\u0941\u0932\u0948._\u0911\u0917._\u0938\u092a\u094d\u091f\u0947\u0902._\u0911\u0915\u094d\u091f\u094b._\u0928\u094b\u0935\u094d\u0939\u0947\u0902._\u0921\u093f\u0938\u0947\u0902.".split("_"),monthsParseExact:!0,weekdays:"\u0930\u0935\u093f\u0935\u093e\u0930_\u0938\u094b\u092e\u0935\u093e\u0930_\u092e\u0902\u0917\u0933\u0935\u093e\u0930_\u092c\u0941\u0927\u0935\u093e\u0930_\u0917\u0941\u0930\u0942\u0935\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930_\u0936\u0928\u093f\u0935\u093e\u0930".split("_"),weekdaysShort:"\u0930\u0935\u093f_\u0938\u094b\u092e_\u092e\u0902\u0917\u0933_\u092c\u0941\u0927_\u0917\u0941\u0930\u0942_\u0936\u0941\u0915\u094d\u0930_\u0936\u0928\u093f".split("_"),weekdaysMin:"\u0930_\u0938\u094b_\u092e\u0902_\u092c\u0941_\u0917\u0941_\u0936\u0941_\u0936".split("_"),longDateFormat:{LT:"A h:mm \u0935\u093e\u091c\u0924\u093e",LTS:"A h:mm:ss \u0935\u093e\u091c\u0924\u093e",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e",LLLL:"dddd, D MMMM YYYY, A h:mm \u0935\u093e\u091c\u0924\u093e"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u0909\u0926\u094d\u092f\u093e] LT",nextWeek:"dddd, LT",lastDay:"[\u0915\u093e\u0932] LT",lastWeek:"[\u092e\u093e\u0917\u0940\u0932] dddd, LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u0927\u094d\u092f\u0947",past:"%s\u092a\u0942\u0930\u094d\u0935\u0940",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},preparse:function(t){return t.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0930\u093e\u0924\u094d\u0930\u0940|\u0938\u0915\u093e\u0933\u0940|\u0926\u0941\u092a\u093e\u0930\u0940|\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0930\u093e\u0924\u094d\u0930\u0940"===e?t<4?t:t+12:"\u0938\u0915\u093e\u0933\u0940"===e?t:"\u0926\u0941\u092a\u093e\u0930\u0940"===e?t>=10?t:t+12:"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"\u0930\u093e\u0924\u094d\u0930\u0940":t<10?"\u0938\u0915\u093e\u0933\u0940":t<17?"\u0926\u0941\u092a\u093e\u0930\u0940":t<20?"\u0938\u093e\u092f\u0902\u0915\u093e\u0933\u0940":"\u0930\u093e\u0924\u094d\u0930\u0940"},week:{dow:0,doy:6}})}(n("wd/R"))},OjkT:function(t,e,n){!function(t){"use strict";var e={1:"\u0967",2:"\u0968",3:"\u0969",4:"\u096a",5:"\u096b",6:"\u096c",7:"\u096d",8:"\u096e",9:"\u096f",0:"\u0966"},n={"\u0967":"1","\u0968":"2","\u0969":"3","\u096a":"4","\u096b":"5","\u096c":"6","\u096d":"7","\u096e":"8","\u096f":"9","\u0966":"0"};t.defineLocale("ne",{months:"\u091c\u0928\u0935\u0930\u0940_\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u0930\u0940_\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f\u0932_\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908_\u0905\u0917\u0937\u094d\u091f_\u0938\u0947\u092a\u094d\u091f\u0947\u092e\u094d\u092c\u0930_\u0905\u0915\u094d\u091f\u094b\u092c\u0930_\u0928\u094b\u092d\u0947\u092e\u094d\u092c\u0930_\u0921\u093f\u0938\u0947\u092e\u094d\u092c\u0930".split("_"),monthsShort:"\u091c\u0928._\u092b\u0947\u092c\u094d\u0930\u0941._\u092e\u093e\u0930\u094d\u091a_\u0905\u092a\u094d\u0930\u093f._\u092e\u0908_\u091c\u0941\u0928_\u091c\u0941\u0932\u093e\u0908._\u0905\u0917._\u0938\u0947\u092a\u094d\u091f._\u0905\u0915\u094d\u091f\u094b._\u0928\u094b\u092d\u0947._\u0921\u093f\u0938\u0947.".split("_"),monthsParseExact:!0,weekdays:"\u0906\u0907\u0924\u092c\u093e\u0930_\u0938\u094b\u092e\u092c\u093e\u0930_\u092e\u0919\u094d\u0917\u0932\u092c\u093e\u0930_\u092c\u0941\u0927\u092c\u093e\u0930_\u092c\u093f\u0939\u093f\u092c\u093e\u0930_\u0936\u0941\u0915\u094d\u0930\u092c\u093e\u0930_\u0936\u0928\u093f\u092c\u093e\u0930".split("_"),weekdaysShort:"\u0906\u0907\u0924._\u0938\u094b\u092e._\u092e\u0919\u094d\u0917\u0932._\u092c\u0941\u0927._\u092c\u093f\u0939\u093f._\u0936\u0941\u0915\u094d\u0930._\u0936\u0928\u093f.".split("_"),weekdaysMin:"\u0906._\u0938\u094b._\u092e\u0902._\u092c\u0941._\u092c\u093f._\u0936\u0941._\u0936.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"A\u0915\u094b h:mm \u092c\u091c\u0947",LTS:"A\u0915\u094b h:mm:ss \u092c\u091c\u0947",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947",LLLL:"dddd, D MMMM YYYY, A\u0915\u094b h:mm \u092c\u091c\u0947"},preparse:function(t){return t.replace(/[\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u0966]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0930\u093e\u0924\u093f|\u092c\u093f\u0939\u093e\u0928|\u0926\u093f\u0909\u0901\u0938\u094b|\u0938\u093e\u0901\u091d/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0930\u093e\u0924\u093f"===e?t<4?t:t+12:"\u092c\u093f\u0939\u093e\u0928"===e?t:"\u0926\u093f\u0909\u0901\u0938\u094b"===e?t>=10?t:t+12:"\u0938\u093e\u0901\u091d"===e?t+12:void 0},meridiem:function(t,e,n){return t<3?"\u0930\u093e\u0924\u093f":t<12?"\u092c\u093f\u0939\u093e\u0928":t<16?"\u0926\u093f\u0909\u0901\u0938\u094b":t<20?"\u0938\u093e\u0901\u091d":"\u0930\u093e\u0924\u093f"},calendar:{sameDay:"[\u0906\u091c] LT",nextDay:"[\u092d\u094b\u0932\u093f] LT",nextWeek:"[\u0906\u0909\u0901\u0926\u094b] dddd[,] LT",lastDay:"[\u0939\u093f\u091c\u094b] LT",lastWeek:"[\u0917\u090f\u0915\u094b] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s\u092e\u093e",past:"%s \u0905\u0917\u093e\u0921\u093f",s:"\u0915\u0947\u0939\u0940 \u0915\u094d\u0937\u0923",ss:"%d \u0938\u0947\u0915\u0947\u0923\u094d\u0921",m:"\u090f\u0915 \u092e\u093f\u0928\u0947\u091f",mm:"%d \u092e\u093f\u0928\u0947\u091f",h:"\u090f\u0915 \u0918\u0923\u094d\u091f\u093e",hh:"%d \u0918\u0923\u094d\u091f\u093e",d:"\u090f\u0915 \u0926\u093f\u0928",dd:"%d \u0926\u093f\u0928",M:"\u090f\u0915 \u092e\u0939\u093f\u0928\u093e",MM:"%d \u092e\u0939\u093f\u0928\u093e",y:"\u090f\u0915 \u092c\u0930\u094d\u0937",yy:"%d \u092c\u0930\u094d\u0937"},week:{dow:0,doy:6}})}(n("wd/R"))},Oxv6:function(t,e,n){!function(t){"use strict";var e={0:"-\u0443\u043c",1:"-\u0443\u043c",2:"-\u044e\u043c",3:"-\u044e\u043c",4:"-\u0443\u043c",5:"-\u0443\u043c",6:"-\u0443\u043c",7:"-\u0443\u043c",8:"-\u0443\u043c",9:"-\u0443\u043c",10:"-\u0443\u043c",12:"-\u0443\u043c",13:"-\u0443\u043c",20:"-\u0443\u043c",30:"-\u044e\u043c",40:"-\u0443\u043c",50:"-\u0443\u043c",60:"-\u0443\u043c",70:"-\u0443\u043c",80:"-\u0443\u043c",90:"-\u0443\u043c",100:"-\u0443\u043c"};t.defineLocale("tg",{months:"\u044f\u043d\u0432\u0430\u0440_\u0444\u0435\u0432\u0440\u0430\u043b_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440_\u043e\u043a\u0442\u044f\u0431\u0440_\u043d\u043e\u044f\u0431\u0440_\u0434\u0435\u043a\u0430\u0431\u0440".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d_\u0438\u044e\u043b_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u044f\u043a\u0448\u0430\u043d\u0431\u0435_\u0434\u0443\u0448\u0430\u043d\u0431\u0435_\u0441\u0435\u0448\u0430\u043d\u0431\u0435_\u0447\u043e\u0440\u0448\u0430\u043d\u0431\u0435_\u043f\u0430\u043d\u04b7\u0448\u0430\u043d\u0431\u0435_\u04b7\u0443\u043c\u044a\u0430_\u0448\u0430\u043d\u0431\u0435".split("_"),weekdaysShort:"\u044f\u0448\u0431_\u0434\u0448\u0431_\u0441\u0448\u0431_\u0447\u0448\u0431_\u043f\u0448\u0431_\u04b7\u0443\u043c_\u0448\u043d\u0431".split("_"),weekdaysMin:"\u044f\u0448_\u0434\u0448_\u0441\u0448_\u0447\u0448_\u043f\u0448_\u04b7\u043c_\u0448\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0418\u043c\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextDay:"[\u041f\u0430\u0433\u043e\u04b3 \u0441\u043e\u0430\u0442\u0438] LT",lastDay:"[\u0414\u0438\u0440\u04ef\u0437 \u0441\u043e\u0430\u0442\u0438] LT",nextWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u043e\u044f\u043d\u0434\u0430 \u0441\u043e\u0430\u0442\u0438] LT",lastWeek:"dddd[\u0438] [\u04b3\u0430\u0444\u0442\u0430\u0438 \u0433\u0443\u0437\u0430\u0448\u0442\u0430 \u0441\u043e\u0430\u0442\u0438] LT",sameElse:"L"},relativeTime:{future:"\u0431\u0430\u044a\u0434\u0438 %s",past:"%s \u043f\u0435\u0448",s:"\u044f\u043a\u0447\u0430\u043d\u0434 \u0441\u043e\u043d\u0438\u044f",m:"\u044f\u043a \u0434\u0430\u049b\u0438\u049b\u0430",mm:"%d \u0434\u0430\u049b\u0438\u049b\u0430",h:"\u044f\u043a \u0441\u043e\u0430\u0442",hh:"%d \u0441\u043e\u0430\u0442",d:"\u044f\u043a \u0440\u04ef\u0437",dd:"%d \u0440\u04ef\u0437",M:"\u044f\u043a \u043c\u043e\u04b3",MM:"%d \u043c\u043e\u04b3",y:"\u044f\u043a \u0441\u043e\u043b",yy:"%d \u0441\u043e\u043b"},meridiemParse:/\u0448\u0430\u0431|\u0441\u0443\u0431\u04b3|\u0440\u04ef\u0437|\u0431\u0435\u0433\u043e\u04b3/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0448\u0430\u0431"===e?t<4?t:t+12:"\u0441\u0443\u0431\u04b3"===e?t:"\u0440\u04ef\u0437"===e?t>=11?t:t+12:"\u0431\u0435\u0433\u043e\u04b3"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"\u0448\u0430\u0431":t<11?"\u0441\u0443\u0431\u04b3":t<16?"\u0440\u04ef\u0437":t<19?"\u0431\u0435\u0433\u043e\u04b3":"\u0448\u0430\u0431"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0443\u043c|\u044e\u043c)/,ordinal:function(t){return t+(e[t]||e[t%10]||e[t>=100?100:null])},week:{dow:1,doy:7}})}(n("wd/R"))},P6uZ:function(t,e,n){"use strict";n.d(e,"a",function(){return c});var a=n("3fWJ"),r=n("VnD/"),i=n("t9fZ"),s=n("HJBe"),o=n("tNVB"),u=n("mChF");function c(t,e){var n=arguments.length>=2;return function(c){return c.pipe(t?Object(r.a)(function(e,n){return t(e,n,c)}):u.a,Object(i.a)(1),n?Object(s.a)(e):Object(o.a)(function(){return new a.a}))}}},P8lu:function(t,e,n){"use strict";n.d(e,"a",function(){return h});var a=n("mrSG"),r=n("t/Na"),i=n("LvDl"),s=n("VNr4"),o=n("F/XL"),u=n("psW0"),c=n("aGNc"),l=n("9Z1F"),d=n("xTzq"),f=n("CcnG"),p=n("pL04"),h=function(){function t(t){this.http=t,this.url="api/rgw/user"}return t.prototype.list=function(){var t=this;return this.enumerate().pipe(Object(u.a)(function(e){return e.length>0?Object(s.a)(e.map(function(e){return t.get(e)})):Object(o.a)([])}))},t.prototype.enumerate=function(){return this.http.get(this.url)},t.prototype.enumerateEmail=function(){return this.http.get(this.url+"/get_emails")},t.prototype.get=function(t){return this.http.get(this.url+"/"+t)},t.prototype.getQuota=function(t){return this.http.get(this.url+"/"+t+"/quota")},t.prototype.create=function(t){var e=new r.h;return i.keys(t).forEach(function(n){e=e.append(n,t[n])}),this.http.post(this.url,null,{params:e})},t.prototype.update=function(t,e){var n=new r.h;return i.keys(e).forEach(function(t){n=n.append(t,e[t])}),this.http.put(this.url+"/"+t,null,{params:n})},t.prototype.updateQuota=function(t,e){var n=new r.h;return i.keys(e).forEach(function(t){n=n.append(t,e[t])}),this.http.put(this.url+"/"+t+"/quota",null,{params:n})},t.prototype.delete=function(t){return this.http.delete(this.url+"/"+t)},t.prototype.createSubuser=function(t,e){var n=new r.h;return i.keys(e).forEach(function(t){n=n.append(t,e[t])}),this.http.post(this.url+"/"+t+"/subuser",null,{params:n})},t.prototype.deleteSubuser=function(t,e){return this.http.delete(this.url+"/"+t+"/subuser/"+e)},t.prototype.addCapability=function(t,e,n){var a=new r.h;return a=(a=a.append("type",e)).append("perm",n),this.http.post(this.url+"/"+t+"/capability",null,{params:a})},t.prototype.deleteCapability=function(t,e,n){var a=new r.h;return a=(a=a.append("type",e)).append("perm",n),this.http.delete(this.url+"/"+t+"/capability",{params:a})},t.prototype.addS3Key=function(t,e){var n=new r.h;return n=n.append("key_type","s3"),i.keys(e).forEach(function(t){n=n.append(t,e[t])}),this.http.post(this.url+"/"+t+"/key",null,{params:n})},t.prototype.deleteS3Key=function(t,e){var n=new r.h;return n=(n=n.append("key_type","s3")).append("access_key",e),this.http.delete(this.url+"/"+t+"/key",{params:n})},t.prototype.exists=function(t){return this.get(t).pipe(Object(c.a)(!0),Object(l.a)(function(t){return i.isFunction(t.preventDefault)&&t.preventDefault(),Object(o.a)(!1)}))},t.prototype.emailExists=function(t){return t=decodeURIComponent(t),this.enumerateEmail().pipe(Object(u.a)(function(e){var n=i.indexOf(e,t);return Object(o.a)(-1!==n)}))},t.ngInjectableDef=f.defineInjectable({factory:function(){return new t(f.inject(r.c))},token:t,providedIn:p.a}),t=a.__decorate([d.a,a.__metadata("design:paramtypes",[r.c])],t)}()},PA2r:function(t,e,n){!function(t){"use strict";var e="leden_\xfanor_b\u0159ezen_duben_kv\u011bten_\u010derven_\u010dervenec_srpen_z\xe1\u0159\xed_\u0159\xedjen_listopad_prosinec".split("_"),n="led_\xfano_b\u0159e_dub_kv\u011b_\u010dvn_\u010dvc_srp_z\xe1\u0159_\u0159\xedj_lis_pro".split("_"),a=[/^led/i,/^\xfano/i,/^b\u0159e/i,/^dub/i,/^kv\u011b/i,/^(\u010dvn|\u010derven$|\u010dervna)/i,/^(\u010dvc|\u010dervenec|\u010dervence)/i,/^srp/i,/^z\xe1\u0159/i,/^\u0159\xedj/i,/^lis/i,/^pro/i],r=/^(leden|\xfanor|b\u0159ezen|duben|kv\u011bten|\u010dervenec|\u010dervence|\u010derven|\u010dervna|srpen|z\xe1\u0159\xed|\u0159\xedjen|listopad|prosinec|led|\xfano|b\u0159e|dub|kv\u011b|\u010dvn|\u010dvc|srp|z\xe1\u0159|\u0159\xedj|lis|pro)/i;function i(t){return t>1&&t<5&&1!=~~(t/10)}function s(t,e,n,a){var r=t+" ";switch(n){case"s":return e||a?"p\xe1r sekund":"p\xe1r sekundami";case"ss":return e||a?r+(i(t)?"sekundy":"sekund"):r+"sekundami";case"m":return e?"minuta":a?"minutu":"minutou";case"mm":return e||a?r+(i(t)?"minuty":"minut"):r+"minutami";case"h":return e?"hodina":a?"hodinu":"hodinou";case"hh":return e||a?r+(i(t)?"hodiny":"hodin"):r+"hodinami";case"d":return e||a?"den":"dnem";case"dd":return e||a?r+(i(t)?"dny":"dn\xed"):r+"dny";case"M":return e||a?"m\u011bs\xedc":"m\u011bs\xedcem";case"MM":return e||a?r+(i(t)?"m\u011bs\xedce":"m\u011bs\xedc\u016f"):r+"m\u011bs\xedci";case"y":return e||a?"rok":"rokem";case"yy":return e||a?r+(i(t)?"roky":"let"):r+"lety"}}t.defineLocale("cs",{months:e,monthsShort:n,monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(leden|ledna|\xfanora|\xfanor|b\u0159ezen|b\u0159ezna|duben|dubna|kv\u011bten|kv\u011btna|\u010dervenec|\u010dervence|\u010derven|\u010dervna|srpen|srpna|z\xe1\u0159\xed|\u0159\xedjen|\u0159\xedjna|listopadu|listopad|prosinec|prosince)/i,monthsShortStrictRegex:/^(led|\xfano|b\u0159e|dub|kv\u011b|\u010dvn|\u010dvc|srp|z\xe1\u0159|\u0159\xedj|lis|pro)/i,monthsParse:a,longMonthsParse:a,shortMonthsParse:a,weekdays:"ned\u011ble_pond\u011bl\xed_\xfater\xfd_st\u0159eda_\u010dtvrtek_p\xe1tek_sobota".split("_"),weekdaysShort:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),weekdaysMin:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[z\xedtra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v ned\u011bli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve st\u0159edu v] LT";case 4:return"[ve \u010dtvrtek v] LT";case 5:return"[v p\xe1tek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[v\u010dera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou ned\u011bli v] LT";case 1:case 2:return"[minul\xe9] dddd [v] LT";case 3:return"[minulou st\u0159edu v] LT";case 4:case 5:return"[minul\xfd] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"p\u0159ed %s",s:s,ss:s,m:s,mm:s,h:s,hh:s,d:s,dd:s,M:s,MM:s,y:s,yy:s},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n("wd/R"))},PCNd:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},"PEr+":function(t,e,n){"use strict";var a=n("CcnG"),r=n("Ip0R"),i=n("EEJc"),s=n("ajRT"),o=n("gIcY"),u=n("IZUe"),c=n("ANnk"),l=n("f/UV"),d=n("aexS"),f=n("gp3X"),p=n("sb0X"),h=n("KVJa"),g=n("Z21x"),b=n("sne2"),m=n("0+/T"),y=n("DQlY");n.d(e,"a",function(){return A});var v=a["\u0275crt"]({encapsulation:0,styles:[[".modal-body[_ngcontent-%COMP%] .question[_ngcontent-%COMP%]{margin-top:1em}.modal-body[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{font-weight:700}.modal-body[_ngcontent-%COMP%] .question[_ngcontent-%COMP%] .checkbox[_ngcontent-%COMP%]{padding-top:7px}"]],data:{}});function _(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function x(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function T(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,5,"p",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["Are you sure that you want to "," "])),a["\u0275ppd"](2,1),(t()(),a["\u0275eld"](3,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),a["\u0275ted"](4,null,["",""])),(t()(),a["\u0275ted"](-1,null,["?"]))],null,function(t,e){var n=e.component,r=a["\u0275unv"](e,1,0,t(e,2,0,a["\u0275nov"](e.parent.parent,0),n.actionDescription));t(e,1,0,r),t(e,4,0,n.itemNames[0])})}function w(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),a["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,2,0,e.context.$implicit)})}function S(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"p",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["Are you sure that you want to "," the selected items?"])),a["\u0275ppd"](2,1),(t()(),a["\u0275eld"](3,0,null,null,2,"ul",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,w)),a["\u0275did"](5,278528,null,0,r.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,5,0,e.component.itemNames)},function(t,e){var n=e.component,r=a["\u0275unv"](e,1,0,t(e,2,0,a["\u0275nov"](e.parent.parent,0),n.actionDescription));t(e,1,0,r)})}function O(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,T)),a["\u0275did"](2,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(t()(),a["\u0275and"](0,[["manyNames",2]],null,0,null,S))],function(t,e){t(e,2,0,1===e.component.itemNames.length,a["\u0275nov"](e,3))},null)}function I(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"p",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["Are you sure that you want to "," the selected ","?"])),a["\u0275ppd"](2,1)],null,function(t,e){var n=e.component,r=a["\u0275unv"](e,1,0,t(e,2,0,a["\u0275nov"](e.parent,0),n.actionDescription));t(e,1,0,r,n.itemDescription)})}function C(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function k(t){return a["\u0275vid"](0,[(t()(),a["\u0275ted"](0,null,[" "," ","\n"])),a["\u0275ppd"](1,1)],null,function(t,e){var n=e.component,r=a["\u0275unv"](e,0,0,t(e,1,0,a["\u0275nov"](e.parent,1),n.actionDescription));t(e,0,0,r,n.itemDescription)})}function N(t){return a["\u0275vid"](0,[a["\u0275pid"](0,r.LowerCasePipe,[]),a["\u0275pid"](0,r.TitleCasePipe,[]),a["\u0275qud"](402653184,1,{submitButton:0}),(t()(),a["\u0275eld"](3,0,null,null,38,"cd-modal",[],null,null,null,i.c,i.b)),a["\u0275did"](4,49152,[["modal",4]],0,s.a,[],{modalRef:[0,"modalRef"]},null),(t()(),a["\u0275eld"](5,0,null,0,2,null,null,null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,_)),a["\u0275did"](7,540672,null,0,r.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(t()(),a["\u0275eld"](8,0,null,1,33,null,null,null,null,null,null,null)),(t()(),a["\u0275eld"](9,0,null,null,32,"form",[["name","deletionForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var r=!0;return"submit"===e&&(r=!1!==a["\u0275nov"](t,11).onSubmit(n)&&r),"reset"===e&&(r=!1!==a["\u0275nov"](t,11).onReset()&&r),r},null,null)),a["\u0275did"](10,16384,null,0,o.D,[],null,null),a["\u0275did"](11,540672,[["formDir",4]],0,o.l,[[8,null],[8,null]],{form:[0,"form"]},null),a["\u0275prd"](2048,null,o.d,null,[o.l]),a["\u0275did"](13,16384,null,0,o.s,[[4,o.d]],null,null),(t()(),a["\u0275eld"](14,0,null,null,20,"div",[["class","modal-body"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,x)),a["\u0275did"](16,540672,null,0,r.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),(t()(),a["\u0275eld"](17,0,null,null,17,"div",[["class","question"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,O)),a["\u0275did"](19,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(t()(),a["\u0275and"](0,[["noNames",2]],null,0,null,I)),(t()(),a["\u0275eld"](21,0,null,null,13,"div",[["class","form-group"]],null,null,null,null,null)),a["\u0275did"](22,278528,null,0,r.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a["\u0275pod"](23,{"has-error":0}),(t()(),a["\u0275eld"](24,0,null,null,10,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),a["\u0275eld"](25,0,null,null,7,"input",[["autofocus",""],["formControlName","confirmation"],["id","confirmation"],["name","confirmation"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var r=!0;return"change"===e&&(r=!1!==a["\u0275nov"](t,26).onChange(n.target.checked)&&r),"blur"===e&&(r=!1!==a["\u0275nov"](t,26).onTouched()&&r),r},null,null)),a["\u0275did"](26,16384,null,0,o.c,[a.Renderer2,a.ElementRef],null,null),a["\u0275prd"](1024,null,o.p,function(t){return[t]},[o.c]),a["\u0275did"](28,671744,null,0,o.j,[[3,o.d],[8,null],[8,null],[6,o.p],[2,o.F]],{name:[0,"name"]},null),a["\u0275prd"](2048,null,o.q,null,[o.j]),a["\u0275did"](30,16384,null,0,o.r,[[4,o.q]],null,null),a["\u0275did"](31,4210688,null,0,u.a,[a.ElementRef],null,null),a["\u0275did"](32,4210688,null,0,c.a,[[2,l.a],d.a,a.ElementRef],null,null),(t()(),a["\u0275eld"](33,0,null,null,1,"label",[["for","confirmation"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Yes, I am sure."])),(t()(),a["\u0275eld"](35,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),a["\u0275eld"](36,0,null,null,3,"cd-submit-button",[],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.callSubmitAction()&&a),a},f.b,f.a)),a["\u0275did"](37,114688,[[1,4],["submitButton",4]],0,p.a,[a.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(t()(),a["\u0275and"](16777216,null,0,1,null,C)),a["\u0275did"](39,540672,null,0,r.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(t()(),a["\u0275eld"](40,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,h.b,h.a)),a["\u0275did"](41,49152,null,0,g.a,[r.Location,b.b],{name:[0,"name"],back:[1,"back"]},null),(t()(),a["\u0275and"](0,[["deletionHeading",2]],null,0,null,k))],function(t,e){var n=e.component;t(e,4,0,n.modalRef),t(e,7,0,a["\u0275nov"](e,42)),t(e,11,0,n.deletionForm),t(e,16,0,n.bodyContext,n.bodyTemplate),t(e,19,0,n.itemNames,a["\u0275nov"](e,20));var r=t(e,23,0,n.deletionForm.showError("confirmation",a["\u0275nov"](e,11)));t(e,22,0,"form-group",r),t(e,28,0,"confirmation"),t(e,37,0,n.deletionForm),t(e,39,0,a["\u0275nov"](e,42)),t(e,41,0,"Cancel",n.modalRef.hide)},function(t,e){t(e,9,0,a["\u0275nov"](e,13).ngClassUntouched,a["\u0275nov"](e,13).ngClassTouched,a["\u0275nov"](e,13).ngClassPristine,a["\u0275nov"](e,13).ngClassDirty,a["\u0275nov"](e,13).ngClassValid,a["\u0275nov"](e,13).ngClassInvalid,a["\u0275nov"](e,13).ngClassPending),t(e,25,0,a["\u0275nov"](e,30).ngClassUntouched,a["\u0275nov"](e,30).ngClassTouched,a["\u0275nov"](e,30).ngClassPristine,a["\u0275nov"](e,30).ngClassDirty,a["\u0275nov"](e,30).ngClassValid,a["\u0275nov"](e,30).ngClassInvalid,a["\u0275nov"](e,30).ngClassPending)})}function R(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"cd-deletion-modal",[],null,null,null,N,v)),a["\u0275did"](1,114688,null,0,m.a,[y.a],null,null)],function(t,e){t(e,1,0)},null)}var A=a["\u0275ccf"]("cd-deletion-modal",m.a,R,{},{},[])},PNOi:function(t,e,n){var a=n("mrSG").__decorate;Object.defineProperty(e,"__esModule",{value:!0});var r=n("CcnG");e.ProgressBarComponent=function(){return a([r.Component({selector:"datatable-progress",template:'\n
\n
\n
\n
\n
\n ',changeDetection:r.ChangeDetectionStrategy.OnPush})],function(){})}()},PeUW:function(t,e,n){!function(t){"use strict";var e={1:"\u0be7",2:"\u0be8",3:"\u0be9",4:"\u0bea",5:"\u0beb",6:"\u0bec",7:"\u0bed",8:"\u0bee",9:"\u0bef",0:"\u0be6"},n={"\u0be7":"1","\u0be8":"2","\u0be9":"3","\u0bea":"4","\u0beb":"5","\u0bec":"6","\u0bed":"7","\u0bee":"8","\u0bef":"9","\u0be6":"0"};t.defineLocale("ta",{months:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),monthsShort:"\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf_\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf_\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd_\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd_\u0bae\u0bc7_\u0b9c\u0bc2\u0ba9\u0bcd_\u0b9c\u0bc2\u0bb2\u0bc8_\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd_\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bc6\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b85\u0b95\u0bcd\u0b9f\u0bc7\u0bbe\u0baa\u0bb0\u0bcd_\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd_\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd".split("_"),weekdays:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bcd\u0bb1\u0bc1\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0b9f\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8_\u0b9a\u0ba9\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb4\u0bae\u0bc8".split("_"),weekdaysShort:"\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1_\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd_\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd_\u0baa\u0bc1\u0ba4\u0ba9\u0bcd_\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd_\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf_\u0b9a\u0ba9\u0bbf".split("_"),weekdaysMin:"\u0b9e\u0bbe_\u0ba4\u0bbf_\u0b9a\u0bc6_\u0baa\u0bc1_\u0bb5\u0bbf_\u0bb5\u0bc6_\u0b9a".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, HH:mm",LLLL:"dddd, D MMMM YYYY, HH:mm"},calendar:{sameDay:"[\u0b87\u0ba9\u0bcd\u0bb1\u0bc1] LT",nextDay:"[\u0ba8\u0bbe\u0bb3\u0bc8] LT",nextWeek:"dddd, LT",lastDay:"[\u0ba8\u0bc7\u0bb1\u0bcd\u0bb1\u0bc1] LT",lastWeek:"[\u0b95\u0b9f\u0ba8\u0bcd\u0ba4 \u0bb5\u0bbe\u0bb0\u0bae\u0bcd] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0b87\u0bb2\u0bcd",past:"%s \u0bae\u0bc1\u0ba9\u0bcd",s:"\u0b92\u0bb0\u0bc1 \u0b9a\u0bbf\u0bb2 \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",ss:"%d \u0bb5\u0bbf\u0ba8\u0bbe\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",m:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0bae\u0bcd",mm:"%d \u0ba8\u0bbf\u0bae\u0bbf\u0b9f\u0b99\u0bcd\u0b95\u0bb3\u0bcd",h:"\u0b92\u0bb0\u0bc1 \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",hh:"%d \u0bae\u0ba3\u0bbf \u0ba8\u0bc7\u0bb0\u0bae\u0bcd",d:"\u0b92\u0bb0\u0bc1 \u0ba8\u0bbe\u0bb3\u0bcd",dd:"%d \u0ba8\u0bbe\u0b9f\u0bcd\u0b95\u0bb3\u0bcd",M:"\u0b92\u0bb0\u0bc1 \u0bae\u0bbe\u0ba4\u0bae\u0bcd",MM:"%d \u0bae\u0bbe\u0ba4\u0b99\u0bcd\u0b95\u0bb3\u0bcd",y:"\u0b92\u0bb0\u0bc1 \u0bb5\u0bb0\u0bc1\u0b9f\u0bae\u0bcd",yy:"%d \u0b86\u0ba3\u0bcd\u0b9f\u0bc1\u0b95\u0bb3\u0bcd"},dayOfMonthOrdinalParse:/\d{1,2}\u0bb5\u0ba4\u0bc1/,ordinal:function(t){return t+"\u0bb5\u0ba4\u0bc1"},preparse:function(t){return t.replace(/[\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0be6]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0baf\u0bbe\u0bae\u0bae\u0bcd|\u0bb5\u0bc8\u0b95\u0bb1\u0bc8|\u0b95\u0bbe\u0bb2\u0bc8|\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd|\u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1|\u0bae\u0bbe\u0bb2\u0bc8/,meridiem:function(t,e,n){return t<2?" \u0baf\u0bbe\u0bae\u0bae\u0bcd":t<6?" \u0bb5\u0bc8\u0b95\u0bb1\u0bc8":t<10?" \u0b95\u0bbe\u0bb2\u0bc8":t<14?" \u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd":t<18?" \u0b8e\u0bb1\u0bcd\u0baa\u0bbe\u0b9f\u0bc1":t<22?" \u0bae\u0bbe\u0bb2\u0bc8":" \u0baf\u0bbe\u0bae\u0bae\u0bcd"},meridiemHour:function(t,e){return 12===t&&(t=0),"\u0baf\u0bbe\u0bae\u0bae\u0bcd"===e?t<2?t:t+12:"\u0bb5\u0bc8\u0b95\u0bb1\u0bc8"===e||"\u0b95\u0bbe\u0bb2\u0bc8"===e?t:"\u0ba8\u0ba3\u0bcd\u0baa\u0b95\u0bb2\u0bcd"===e&&t>=10?t:t+12},week:{dow:0,doy:6}})}(n("wd/R"))},Phjn:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("psW0");function r(t,e){return Object(a.a)(t,e,1)}},PpIw:function(t,e,n){!function(t){"use strict";var e={1:"\u0ce7",2:"\u0ce8",3:"\u0ce9",4:"\u0cea",5:"\u0ceb",6:"\u0cec",7:"\u0ced",8:"\u0cee",9:"\u0cef",0:"\u0ce6"},n={"\u0ce7":"1","\u0ce8":"2","\u0ce9":"3","\u0cea":"4","\u0ceb":"5","\u0cec":"6","\u0ced":"7","\u0cee":"8","\u0cef":"9","\u0ce6":"0"};t.defineLocale("kn",{months:"\u0c9c\u0ca8\u0cb5\u0cb0\u0cbf_\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cbf_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5\u0cac\u0cb0\u0ccd_\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd".split("_"),monthsShort:"\u0c9c\u0ca8_\u0cab\u0cc6\u0cac\u0ccd\u0cb0_\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd_\u0c8f\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd_\u0cae\u0cc6\u0cd5_\u0c9c\u0cc2\u0ca8\u0ccd_\u0c9c\u0cc1\u0cb2\u0cc6\u0cd6_\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd_\u0cb8\u0cc6\u0caa\u0ccd\u0c9f\u0cc6\u0c82_\u0c85\u0c95\u0ccd\u0c9f\u0cc6\u0cc2\u0cd5_\u0ca8\u0cb5\u0cc6\u0c82_\u0ca1\u0cbf\u0cb8\u0cc6\u0c82".split("_"),monthsParseExact:!0,weekdays:"\u0cad\u0cbe\u0ca8\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae\u0cb5\u0cbe\u0cb0_\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0_\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0_\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0_\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0".split("_"),weekdaysShort:"\u0cad\u0cbe\u0ca8\u0cc1_\u0cb8\u0cc6\u0cc2\u0cd5\u0cae_\u0cae\u0c82\u0c97\u0cb3_\u0cac\u0cc1\u0ca7_\u0c97\u0cc1\u0cb0\u0cc1_\u0cb6\u0cc1\u0c95\u0ccd\u0cb0_\u0cb6\u0ca8\u0cbf".split("_"),weekdaysMin:"\u0cad\u0cbe_\u0cb8\u0cc6\u0cc2\u0cd5_\u0cae\u0c82_\u0cac\u0cc1_\u0c97\u0cc1_\u0cb6\u0cc1_\u0cb6".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c87\u0c82\u0ca6\u0cc1] LT",nextDay:"[\u0ca8\u0cbe\u0cb3\u0cc6] LT",nextWeek:"dddd, LT",lastDay:"[\u0ca8\u0cbf\u0ca8\u0ccd\u0ca8\u0cc6] LT",lastWeek:"[\u0c95\u0cc6\u0cc2\u0ca8\u0cc6\u0caf] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0ca8\u0c82\u0ca4\u0cb0",past:"%s \u0cb9\u0cbf\u0c82\u0ca6\u0cc6",s:"\u0c95\u0cc6\u0cb2\u0cb5\u0cc1 \u0c95\u0ccd\u0cb7\u0ca3\u0c97\u0cb3\u0cc1",ss:"%d \u0cb8\u0cc6\u0c95\u0cc6\u0c82\u0ca1\u0cc1\u0c97\u0cb3\u0cc1",m:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",mm:"%d \u0ca8\u0cbf\u0cae\u0cbf\u0cb7",h:"\u0c92\u0c82\u0ca6\u0cc1 \u0c97\u0c82\u0c9f\u0cc6",hh:"%d \u0c97\u0c82\u0c9f\u0cc6",d:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca6\u0cbf\u0ca8",dd:"%d \u0ca6\u0cbf\u0ca8",M:"\u0c92\u0c82\u0ca6\u0cc1 \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",MM:"%d \u0ca4\u0cbf\u0c82\u0c97\u0cb3\u0cc1",y:"\u0c92\u0c82\u0ca6\u0cc1 \u0cb5\u0cb0\u0ccd\u0cb7",yy:"%d \u0cb5\u0cb0\u0ccd\u0cb7"},preparse:function(t){return t.replace(/[\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0ce6]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf|\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6|\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8|\u0cb8\u0c82\u0c9c\u0cc6/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"===e?t<4?t:t+12:"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6"===e?t:"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8"===e?t>=10?t:t+12:"\u0cb8\u0c82\u0c9c\u0cc6"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf":t<10?"\u0cac\u0cc6\u0cb3\u0cbf\u0c97\u0ccd\u0c97\u0cc6":t<17?"\u0cae\u0ca7\u0ccd\u0caf\u0cbe\u0cb9\u0ccd\u0ca8":t<20?"\u0cb8\u0c82\u0c9c\u0cc6":"\u0cb0\u0cbe\u0ca4\u0ccd\u0cb0\u0cbf"},dayOfMonthOrdinalParse:/\d{1,2}(\u0ca8\u0cc6\u0cd5)/,ordinal:function(t){return t+"\u0ca8\u0cc6\u0cd5"},week:{dow:0,doy:6}})}(n("wd/R"))},Q3dv:function(t,e){t.exports='\n \n \n \n Toggle navigation\n \ub124\ube44\uac8c\uc774\uc158 \uc804\ud658\n \n \n Dashboard\n \ud604\ud669\ud310\n \n \n Cluster\n \ud074\ub7ec\uc2a4\ud130\n \n \n Hosts\n \ud638\uc2a4\ud2b8\ub4e4\n \n \n Monitors\n \ubaa8\ub2c8\ud130\ub4e4\n \n \n OSDs\n OSD\ub4e4\n \n \n Configuration\n \uc124\uc815\n \n \n CRUSH map\n \ud06c\ub7ec\uc26c\ub9f5\n \n \n Manager modules\n \uba54\ub2c8\uc800 \ubaa8\ub4c8\ub4e4\n \n \n Logs\n \ub85c\uadf8\ub4e4\n \n \n Alerts\n \uacbd\uace0\ub4e4\n \n \n Silences\n Silences\n \n \n Pools\n \ud480\ub4e4\n \n \n Block\n \ube14\ub7ed\n \n \n Images\n \uc774\ubbf8\uc9c0\ub4e4\n \n \n Mirroring\n \ubbf8\ub7ec\ub9c1\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n \ud30c\uc77c\uc2dc\uc2a4\ud15c\ub4e4\n \n \n Object Gateway\n \uc624\ube0c\uc81d\ud2b8\uac8c\uc774\ud2b8\uc6e8\uc774\n \n \n Daemons\n \ub370\ubaac\ub4e4\n \n \n Users\n \uc0ac\uc6a9\uc790\n \n \n Buckets\n \ubc84\ud0b7\ub4e4\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Retrieving data\n for\n \n \n . Please wait...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Displaying previously cached data\n \n for \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n \n \n Back\n \ub4a4\ub85c\n \n \n Select a Language\n \uc5b8\uc5b4\uc120\ud0dd\n \n \n Loading panel data...\n \ud328\ub110 \ub370\uc774\ud0c0 \ub85c\ub529 \uc911...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n \n \n Grafana Time Picker\n \uadf8\ub77c\ud30c\ub098 \ud0c0\uc784 \ud53d\ucee4\n \n \n Reset Settings\n \uc124\uc815 \ucd08\uae30\ud654\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n \ub370\uc774\ud0c0 \ub85c\ub529 \uc2e4\ud3d0\n \n \n selected\n \uc120\ud0dd\ub41c\n X selected\n \n \n found\n \ubc1c\uacac\ub41c\n X found\n \n \n total\n \uc804\uccb4\n X total\n \n \n Edit\n \ud3b8\uc9d1\n \n \n Name\n \uc774\ub984\n \n \n Description\n \uc124\uba85\n \n \n Long description\n \uc790\uc138\ud55c \uc124\uba85\n \n \n Default\n \uae30\ubcf8\uac12\n \n \n Daemon default\n \ub370\ubaa8 \uae30\ubcf8\uac12\n \n \n Services\n \uc11c\ube44\uc2a4\ub4e4\n \n \n Values\n \uac12\ub4e4\n \n \n The entered value is too high! It must not be greater than \n .\n \n \uc785\ub825\uac12\uc774 \ub108\ubb34 \ud07d\ub2c8\ub2e4! \uadf8\uac83\uc740 \n \ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \uc785\ub825\ub41c \uac12\uc774 \ub108\ubb34 \uc791\uc2b5\ub2c8\ub2e4.! \uadf8\uac83\uc740 \n \uc791\uc544\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n Save\n \uc800\uc7a5\ud558\uae30\n \n \n CRUSH map viewer\n \ud06c\ub7ec\uc26c\ub9f5 \ubcf4\uae30\n \n \n Hosts List\n \ud638\uc2a4\ud2b8 \ubaa9\ub85d\ub4e4\n \n \n Overall Performance\n \ud1b5\ud569 \uc131\ub2a5\uce58\n \n \n No entries found\n \ud56d\ubaa9\ub4e4\uc744 \ucc3e\uc744 \uc218 \uc5c6\uc74c\n \n \n Cluster Logs\n \ud074\ub7ec\uc2a4\ud130 \ub85c\uadf8\ub4e4\n \n \n Audit Logs\n \uac10\uc0ac \ub85c\uadf8\ub4e4\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n \uc124\uc815 \ub85c\ub529 \uc911\n \n \n The configuration could not be loaded.\n \uc124\uc815\uc744 \ub85c\ub4dc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n Edit Manager module\n \uad00\ub9ac\ubaa8\ub4c8 \ud3b8\uc9d1\ud558\uae30\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \uc785\ub825\ub41c \uac12\uc774 \uc720\ud6a8\ud55c UUID\uac00 \uc544\ub2d9\ub2c8\ub2e4, \uc608.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n \uc785\ub825\ub41c \uac12\uc740 \uc720\ud6a8\ud55c IP\uc8fc\uc18c \uc5ec\uc57c \ud569\ub2c8\ub2e4.\n \n \n This field is required.\n \uc774 \ud544\ub4dc\ub294 \ud544\uc218\uc801\uc785\ub2c8\ub2e4.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n \uc785\ub825\uac12\uc774 \ub108\ubb34 \ud07d\ub2c8\ub2e4! \uadf8\uac83\uc740 \ubc18\ub4dc\uc2dc \n \uc791\uac70\ub098 \uac19\uc544\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n \uc785\ub825\ub41c \uac12\uc774 \ub108\ubb34 \uc791\uc2b5\ub2c8\ub2e4! \uadf8\uac83\uc740 \n \ubcf4\ub2e4 \ud06c\uac70\ub098 \uac19\uc544\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n The entered value needs to be a number.\n \uc785\ub825\ub41c \uac12\uc740 \uc801\uc5b4\ub3c4 \ud558\ub098\uc758 \uc22b\uc790\ub97c \ud544\uc694\ub85c \ud569\ub2c8\ub2e4.\n \n \n The entered value needs to be a number or decimal.\n \uc785\ub825 \ub41c \uac12\uc740 \uc22b\uc790 \ub610\ub294 \uc2ed\uc9c4\uc218\uc5ec\uc57c \ud569\ub2c8\ub2e4.\n \n \n Update\n \uac31\uc2e0\n \n \n Status\n \uc0c1\ud0dc\n \n \n Cluster ID\n \ud074\ub7ec\uc2a4\ud130 ID\n \n \n monmap modified\n \ubaac\ub9f5 \ubcc0\uacbd\uc2dc\uac04\n \n \n monmap epoch\n \ubaac\ub9f5 \ubcc0\uacbd\ubc88\ud638\n \n \n quorum con\n \uc815\uc871\uc218 \uc77c\uce58\ubc88\ud638\n \n \n quorum mon\n \uc815\uc871\uc218 \ubaa8\ub2c8\ud130\uc0c1\ud0dc\n \n \n required con\n \uc694\uad6c\ub418\ub294 \uc77c\uce58\ubc88\ud638\n \n \n required mon\n \uc694\uad6c\ub418\ub294 \ubaa8\ub2c8\ud130\uc0c1\ud0dc\n \n \n In Quorum\n \uc815\uc871\uc218\uc5d0 \ud3ec\ud568\n \n \n Not In Quorum\n \uc815\uc871\uc218 \ubbf8\ud3ec\ud568\n \n \n Cancel\n \ucde8\uc18c\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n \uc120\ud0dd\ub41c \n \ub85c \n \uc744 \ud558\ub294 \uac83\uc774 \ud655\uc2e4\ud569\ub2c8\uae4c?\n \n \n \n Yes, I am sure.\n \uc608, \ud655\uc2e4\ud569\ub2c8\ub2e4.\n \n \n Cluster-wide OSD Flags\n \ud074\ub7ec\uc2a4\ud130-\uc218\uc900\uc758 OSD \ud50c\ub808\uadf8\ub4e4\n \n \n Submit\n \uc81c\ucd9c\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n \uc790\uc138\ud55c \uc635\uc158...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n OSD \ubcf5\uad6c \uc6b0\uc120\uc21c\uc704\n \n \n Priority\n \uc6b0\uc120\uc21c\uc704\n \n \n Customize priority values\n \uc6b0\uc120 \uc21c\uc704 \uac12 \ub9de\ucda4 \uc124\uc815\n \n \n This field is required!\n \uc774 \ud544\ub4dc\ub294 \uc694\uad6c\ub429\ub2c8\ub2e4!\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n \uc785\ub825\ub41c \uac12\uc774 \ub108\ubb34 \ud07d\ub2c8\ub2e4! \uadf8\uac83\uc740 \n \ubcf4\ub2e4 \ud06c\uc9c0 \uc54a\uc544\uc57c \ud569\ub2c8\ub2e4..\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \uc785\ub825\ub41c \uac12\uc774 \ub108\ubb34 \uc791\uc2b5\ub2c8\ub2e4! \uadf8\uac83\uc740 \n \ubcf4\ub2e4 \uc791\uc544\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n Reweight OSD\n OSD \uc7ac-\uc870\uc815\n \n \n The value needs to be between 0 and 1.\n \uac12\uc740 0\uacfc 1\uc0ac\uc774\uc5b4\uc57c \ud569\ub2c8\ub2e4.\n \n \n Reweight\n \uc7ac-\uc870\uc815\n \n \n OSDs \n Scrub\n \n OSD\ub4e4 \n \uccad\uc18c\ud558\uae30\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, \uc120\ud0dd, 1 {\uae4a\uc774 } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n OSD \n \n \n \uc744 \uccad\uc18c\ud558\uae30 \uc704\ud574, \ub2f9\uc2e0\uc740 \n \uc744 \uc801\uc6a9\ud558\ub824\uace0 \ud569\ub2c8\ub2e4.\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, \uc120\ud0dd, 1 {\uae4a\uc774 } }\n \n \n OSDs List\n OSD \ubaa9\ub85d\ub4e4\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \uacc4\uc18d\uc9c4\ud589\ud558\uba74 \n OSD \n \n \ub294 \n \n \n \ub85c \ud45c\uc2dc\ub429\ub2c8\ub2e4.\n \n \n \n The OSD is not safe to destroy!\n OSD\ub294 \ud30c\uad34\ud558\uae30\uc5d0 \uc548\uc804\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4!\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \uacc4\uc18d\uc9c4\ud589\ud558\uba74 \n OSD \n \n \ub294\n \n \n \uac00 \ub420 \uac83\uc785\ub2c8\ub2e4.\n \n \n \n Details\n \uc138\ubd80\uc124\uba85\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n \uac12\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n \ub2eb\uae30\n \n \n Delete\n \uc0ad\uc81c\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n \uac74\uac15\uc0c1\ud0dc\n \n \n Statistics\n \ud1b5\uacc4\ub4e4\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n \n \n Clients\n \ud074\ub77c\uc774\uc5b8\ud2b8\ub4e4\n \n \n Any client can access\n \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc811\uadfc\uac00\ub2a5\n \n \n Addresses\n \uc8fc\uc18c\ub4e4\n \n \n Required field\n \ud544\uc218 \uc785\ub825\ub780\n \n \n Must contain one or more comma-separated values\n \ubc18\ub4dc\uc2dc \ud558\ub098 \uc774\uc0c1\uc758 \uc27c\ud45c\ub85c \uad6c\ubd84 \ub41c \uac12\uc744 \ud3ec\ud568\ud574\uc57c \ud568\n \n \n For example:\n \uc608\ub97c\ub4e4\uba74:\n \n \n Access Type\n \uc811\uadfc\ud615\ud0dc\n \n \n Squash\n Squash\n \n \n Add clients\n \ud074\ub77c\uc774\uc5b8\ud2b8\ub4e4 \ucd94\uac00\n \n \n Loading...\n \ub85c\ub529\uc911...\n \n \n -- No cluster available --\n -- \uc0ac\uc6a9\uac00\ub2a5 \ud074\ub7ec\uc2a4\ud130 \uc5c6\uc74c --\n \n \n -- Select the cluster --\n -- \ud074\ub7ec\uc2a4\ud130 \uc120\ud0dd --\n \n \n Add daemon\n \ub370\ubaac \ucd94\uac00\ud558\uae30\n \n \n Storage Backend\n \uc2a4\ud1a0\ub9ac\uc9c0 \ubc31\uc5d4\ub4dc\n \n \n -- No data pools available --\n -- \uc774\uc6a9\uac00\ub2a5\ud55c \ub370\uc774\ud0c0\ud480 \uc5c6\uc74c --\n \n \n -- Select the storage backend --\n -- \uc2a4\ud1a0\ub9ac\uc9c0 \ubc31\uc5d4\ub4dc \uc120\ud0dd --\n \n \n Object Gateway User\n \uac1d\uccb4 \uac8c\uc774\ud2b8\uc6e8\uc774 \uc0ac\uc6a9\uc790\n \n \n -- No users available --\n -- \uc0ac\uc6a9\uac00\ub2a5\ud55c \uc0ac\uc6a9\uc790\ub4e4 \uc5c6\uc74c --\n \n \n -- Select the object gateway user --\n -- \uac1d\uccb4 \uac8c\uc774\ud2b8\uc6e8\uc774 \uc0ac\uc6a9\uc790 \uc120\ud0dd --\n \n \n CephFS User ID\n CephFS \uc0ac\uc6a9\uc790 ID\n \n \n -- No clients available --\n -- \uc0ac\uc6a9\uac00\ub2a5\ud55c \ud074\ub77c\uc774\uc5b8\ud2b8 \uc5c6\uc74c --\n \n \n -- Select the cephx client --\n -- cephx \ud074\ub77c\uc774\uc5b8\ud2b8 \uc120\ud0dd --\n \n \n CephFS Name\n CephFS \uc774\ub984\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n \ubcf4\uc548 \ub808\uc774\ube14\n \n \n Enable security label\n \ubcf4\uc548 \ub808\uc774\ube14 \uc0ac\uc6a9\n \n \n CephFS Path\n CephFS \uacbd\ub85c\n \n \n Path need to start with a \'/\' and can be followed by a word\n \uacbd\ub85c\ub294 \'/\'\ub85c \uc2dc\uc791\ud574\uc57c\ud558\uba70 \uadf8 \ub4a4\uc5d0 \ub2e8\uc5b4\uac00 \uc62c \uc218 \uc788\uc2b5\ub2c8\ub2e4\n \n \n New directory will be created\n \uc0c8\ub85c\uc6b4 \ub514\ub809\ud1a0\ub9ac\uac00 \ub9cc\ub4e4\uc5b4 \uc9c8 \uac83\uc785\ub2c8\ub2e4\n \n \n Path\n \uacbd\ub85c\n \n \n Path can only be a single \'/\' or a word\n \uacbd\ub85c\ub294 \ud558\ub098\uc758 \'/\' \ub610\ub294 \ud558\ub098\uc758 \ub2e8\uc5b4 \uc77c \uc218 \uc788\uc2b5\ub2c8\ub2e4\n \n \n New bucket will be created\n \uc0c8\ub85c\uc6b4 \ubc84\ud0b7\uc774 \ub9cc\ub4e4\uc5b4 \uc9c8 \uac83\uc785\ub2c8\ub2e4\n \n \n NFS Protocol\n NFS \ud504\ub85c\ud1a0\ucf5c\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n NFS \ud0dc\ud06c\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n \n NFS v3\n \ub9c8\uc6b4\ud2b8\ub4e4\uc744 \uc704\ud55c \ub300\uccb4 \uc811\uadfc (/\uac00 \uc55e\uc5d0 \uc640\uc57c \ud568).\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \ud558\uc704 \ub514\ub809\ud1a0\ub9ac\ub97c \ub9c8\uc6b4\ud2b8 \ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4 (\uc989, Tag = foo \uc778 \uacbd\uc6b0 \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 foo / baz\ub97c \ub9c8\uc6b4\ud2b8\ud558\uc9c0 \ubabb\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n \ub2e4\ub978 \ud0dc\uadf8 \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \uac19\uc740 \uacbd\ub85c\ub97c \uc5ec\ub7ec \ubc88 \ub0b4\ubcf4\ub0bc \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n \ub2e4\ub978 Pseudo \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \ub3d9\uc77c\ud55c \uacbd\ub85c\ub97c \uc5ec\ub7ec \ubc88 \ub0b4\ubcf4\ub0bc \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- \uc0ac\uc6a9\uac00\ub2a5\ud55c \uc811\uadfc\ud615\ud0dc \uc5c6\uc74c --\n \n \n -- Select the access type --\n -- \uc811\uadfc\ud615\ud0dc \uc120\ud0dd --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- \uc0ac\uc6a9\uac00\ub2a5\ud55c squash \uc5c6\uc74c --\n \n \n --Select what kind of user id squashing is performed --\n -- \uc5b4\ub5a4 \uc885\ub958\uc758 \uc0ac\uc6a9\uc790 ID \uc2a4\ucffc\uc2dc\uac00 \uc218\ud589\ub418\ub294\uc9c0 \uc120\ud0dd\ud558\uc138\uc694 --\n \n \n Transport Protocol\n \uc804\uc1a1\ud504\ub85c\ud1a0\ucf5c\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Ceph \uc0ac\uc6a9\uc744 \ud658\uc601\ud569\ub2c8\ub2e4.\n The welcome message on the login page\n \n \n Username is required\n \uc0ac\uc6a9\uc790\uc774\ub984\uc774 \ud544\uc694\ud569\ub2c8\ub2e4\n \n \n Password is required\n \uc554\ud638\uac00 \ud544\uc694\ud569\ub2c8\ub2e4\n \n \n Login\n \ub85c\uadf8\uc778\n \n \n Sorry, the user does not exist in Ceph.\n \ubbf8\uc548\ud569\ub2c8\ub2e4. \uc0ac\uc6a9\uc790\uac00 Ceph\ub0b4\uc5d0 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n \n \n Forbidden\n \uae08\uc9c0\ub428\n \n \n Sorry, you are not allowed to see what you were looking for.\n \ubbf8\uc548\ud569\ub2c8\ub2e4. \ub2f9\uc2e0\uc774 \uc694\uccad\ud560 \uac83\uc744 \uc5f4\ub78c\ud558\ub294 \uac83\uc774 \ud5c8\ub77d\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n Sorry, we could not find what you were looking for\n \ubbf8\uc548\ud569\ub2c8\ub2e4. \ub2f9\uc2e0\uc774 \uc694\uccad\ud560 \uac83\uc744 \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n Remove all\n \ubaa8\ub4e0 \uac83 \uc81c\uac70\n \n \n Recent Notifications\n \ucd5c\uadfc \uc54c\ub9bc\ub4e4\n \n \n There are no background tasks.\n \ubc31\uadf8\ub77c\uc6b4\ub4dc \uc791\uc5c5\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n Background Tasks\n \ubc31\uadf8\ub77c\uc6b4\ub4dc \uc791\uc5c5\ub4e4\n \n \n Help\n \ub3c4\uc6c0\ub9d0\n \n \n Documentation\n \ubb38\uc11c\n \n \n API\n API\n \n \n About\n \ub300\ud558\uc5ec\n \n \n Dashboard Settings\n \ub300\uc26c\ubcf4\ub4dc \uc124\uc815\n \n \n User management\n \uc0ac\uc6a9\uc790 \uad00\ub9ac\n \n \n Logged in user\n \ub85c\uadf8\uc778\ub41c \uc0ac\uc6a9\uc790\n \n \n Signed in as\n \n \n \n \n \n \n \n \n\ub85c\uc368 \uc2b9\uc778\ub428\n \n \n \n Sign out\n \ub85c\uadf8\uc544\uc6c3\n \n \n Name...\n \uc774\ub984...\n \n \n The chosen name is already in use.\n \uc120\ud0dd\ud55c \uc774\ub984\uc774 \uc774\ubbf8 \uc0ac\uc6a9\uc911\uc785\ub2c8\ub2e4.\n \n \n Description...\n \uc138\ubd80\uc124\uba85...\n \n \n Permissions\n \uad8c\ud55c\ub4e4\n \n \n Roles\n \uc5ed\ud560\ub4e4\n \n \n Username\n \uc0ac\uc6a9\uc790\uba85\n \n \n Password\n \uc554\ud638\n \n \n Confirm password\n \uc554\ud638 \ud655\uc778\n \n \n Password confirmation doesn\'t match the password.\n \uc554\ud638 \ud655\uc778\uc774 \uc554\ud638\uc640 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n Full name\n \uc804\uccb4 \uc774\ub984\n \n \n Email\n \uc804\uc790\uc6b0\ud3b8\n \n \n Invalid email.\n \uc720\ud6a8\ud558\uc9c0\uc54a\ub294 \uc804\uc790\uc6b0\ud3b8.\n \n \n You are about to remove "user read / update" permissions from your own user.\n \ub2f9\uc2e0\uc758 \uc0ac\uc6a9\uc790\ub85c\ubd80\ud130 "\uc0ac\uc6a9\uc790 \uc77d\uae30 / \uc5c5\ub370\uc774\ud2b8"\uad8c\ud55c\uc744 \uc81c\uac70\ud558\ub824\uace0\ud569\ub2c8\ub2e4.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n \uacc4\uc18d\ud558\uba74 \ubaa8\ub4e0 \uc0ac\uc6a9\uc790\uc5d0\uac8c \uc5ed\ud560\uc744 \ucd94\uac00\ud558\uac70\ub098 \uc81c\uac70 \ud560 \uc218 \uc5c6\uac8c\ub429\ub2c8\ub2e4.\n \n \n Are you sure you want to continue?\n \uacc4\uc18d \uc9c4\ud589\ud558\uae30\ub97c \uc6d0\ud558\uc2ed\ub2c8\uae4c?\n \n \n Performance counters not available\n \uc131\ub2a5 \uce74\uc6b4\ud130\ub4e4\uc744 \uc0ac\uc6a9 \ud560 \uc218 \uc5c6\uc74c\n \n \n Attributes (OSD map)\n \uc18d\uc131\ub4e4 (OSD \ub9f5)\n \n \n Metadata not available\n \uba54\ud0c0\ub370\uc774\ud0c0 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc74c\n \n \n Metadata\n \uba54\ud0c0\ub370\uc774\ud0c0\n \n \n Performance counter\n \uc131\ub2a5 \uce74\uc6b4\ud130\n \n \n Histogram not available: \n \n \n \ud788\uc2a4\ud1a0\uadf8\ub7a8\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc74c: \n \n \n \n \n Writes\n \uc4f0\uae30\n \n \n Reads\n \uc77d\uae30\n \n \n Histogram\n \ud788\uc2a4\ud1a0\uadf8\ub7a8\n \n \n Performance Details\n \uc131\ub2a5 \uc138\ubd80\uc815\ubcf4\ub4e4\n \n \n Current values\n \ud604\uc7ac \uac12\ub4e4\n \n \n Type\n \ud615\ud0dc\n \n \n Min\n \ucd5c\uc18c\n \n \n Max\n \ucd5c\ub300\n \n \n Flags\n \ud50c\ub808\uadf8\ub4e4\n \n \n Source\n \uc18c\uc2a4\n \n \n Level\n \uc218\uc900\n \n \n Can be updated at runtime (editable)\n \uc218\ud589\uc2dc\uac04\uc5d0 \uac31\uc2e0\uac00\ub2a5\ud568(\ud3b8\uc9d1\uac00\ub2a5)\n \n \n Tags\n \ud14c\ud06c\ub4e4\n \n \n Enum values\n \uc5f4\uac70\ud615 \uac12\ub4e4\n \n \n See also\n \ucd94\uac00\ub85c \ub354\ubcf4\uae30\n \n \n Cluster Status\n \ud074\ub7ec\uc2a4\ud130 \uc0c1\ud0dc\n \n \n Manager Daemons\n \uad00\ub9ac\uc790 \ub370\ubaac\ub4e4\n \n \n Object Gateways\n \uc624\ube0c\uc81d\ud2b8 \uac8c\uc774\ud2b8\uc6e8\uc774\ub4e4\n \n \n Metadata Servers\n \uba54\ud0c0\ub370\uc774\ud0c0 \uc11c\ubc84\ub4e4\n \n \n iSCSI Gateways\n iSCSI \uac8c\uc774\ud2b8\uc6e8\uc774\ub4e4\n \n \n Client IOPS\n \ud074\ub77c\uc774\uc5b8\ud2b8 IOPS\n \n \n Client Throughput\n \ud074\ub77c\uc774\uc5b8\ud2b8 \ucc98\ub9ac\ub7c9\n \n \n Client Read/Write\n \ud074\ub77c\uc774\uc5b8\ud2b8 \uc77d\uae30/\uc4f0\uae30\n \n \n Recovery Throughput\n \ubcf5\uad6c \ucc98\ub9ac\ub7c9\n \n \n Scrub\n \uc138\uc815\uc791\uc5c5\n \n \n Performance\n \uc131\ub2a5\n \n \n Raw Capacity\n \uc6d0\uc2dc\uc6a9\ub7c9\n \n \n Objects\n \uc624\ube0c\uc81d\ud2b8\ub4e4\n \n \n PGs per OSD\n OSD\ub2f9 PG\ub4e4\n \n \n PG Status\n PG \uc0c1\ud0dc\ub4e4\n \n \n Capacity\n \uc6a9\ub7c9\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n \ub354 \uc790\uc138\ud55c \ub0b4\uc6a9\uc744 \uc704\ud574 \n \ub85c\uadf8\n \ubcf4\uc2ed\uc2dc\uc624.\n \n \n \n Ranks\n \uc21c\uc704\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n \ud074\ub77c\uc774\uc5b8\ud2b8\ub4e4: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n \uc774\ubbf8\uc9c0\ub97c \ud734\uc9c0\ud1b5\uc5d0 \uc774\ub3d9\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n \ud734\uc9c0\ud1b5\uc73c\ub85c \n \n /\n \n \uc62e\uae30\uae30 \uc704\ud574, \n \uc120\ud0dd, \n \uc774\ubbf8\uc9c0 \uc62e\uae30\uc138\uc694. \uc120\ud0dd\uc801\uc73c\ub85c, \ud3d0\uae30\ub0a0\uc9dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n \n Protection expires at\n \ubcf4\ud638\uac00 \ub9cc\ub8cc\ub418\ub294 \n \n \n NOT PROTECTED\n \ubcf4\ud638\ub418\uc9c0 \uc54a\uc74c\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n \ub0a0\uc9dc \ud615\uc2dd \uc624\ub958. "YYYY-MM-DD HH:mm:ss" \ud615\uc2dd\uc73c\ub85c \uc9c0\uc815\ud558\uc138\uc694.\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n \ubcf4\ud638\uae30\uac04\uc774 \uc774\ubbf8 \ub9cc\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ub354 \ubbf8\ub798\uc758 \ub0a0\uc9dc\ub97c \uc120\ud0dd\ud558\uac70\ub098 \uacf5\ub780\uc73c\ub85c \ub0a8\uaca8\ub450\uc138\uc694.\n \n \n Move Image\n \uc774\ubbf8\uc9c0 \uc62e\uae30\uae30\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n \uac1c\uad00\n \n \n Targets\n \ud0c0\uac9f\ub4e4\n \n \n Discovery Authentication\n \uc778\uc99d \ud0d0\uc0c9\n \n \n User\n \uc0ac\uc6a9\uc790\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \uc0ac\uc6a9\uc790\uc774\ub984\uc740 8~64\uc790\uae4c\uc9c0 \uae38\uc774\uc758 \ubb38\uc790\ub4e4\uc744 \uac00\uc838\uc57c \ud558\uba70 \uadf8\ub9ac\uace0, \uc624\uc9c1 , \'.\', \'@\', \'-\', \'_\', \':\' \ub4f1\uc758 \ud2b9\uc218 \ubb38\uc790\ub4e4\ub9cc\uc744 \ud3ec\ud568\uac00\ub2a5\ud569\ub2c8\ub2e4.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n \uacf5\ub3d9 \uc0ac\uc6a9\uc790\n \n \n Mutual Password\n \uacf5\ud1b5 \uc554\ud638\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n iSCSI \ud0c0\uac9f\ub4e4 \uad00\ub9ac \uae30\ub2a5\ub4e4\uc744 \uc124\uc815\ud558\uace0 \ucf1c\uae30\uc704\ud574\uc11c \n \ubb38\uc11c\n \ubd80\ubd84\uc744 \ucc38\uc870\ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.\n \n \n \n Available information:\n \uc774\uc6a9\uac00\ub2a5\ud55c \uc815\ubcf4:\n \n \n iSCSI Targets not available\n iSCSI \ud0c0\uac9f\uc774 \uc774\uc6a9 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4.\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n \uc624\uc9c1 \n fast-diff\n \uc124\uc815\ub41c RBD \uc774\ubbf8\uc9c0\ub4e4\uacfc \ud568\uaed8 \uc0ac\uc6a9\uac00\ub2a5\ud569\ub2c8\ub2e4.\n \n \n \n Pool\n \ud480\n \n \n Data Pool\n \ub370\uc774\ud0c0 \ud480\n \n \n Created\n \uc0dd\uc131\ub41c\n \n \n Size\n \ud06c\uae30\n \n \n Object size\n \uac1d\uccb4\ud06c\uae30\n \n \n Features\n \ud2b9\uc9d5\ub4e4\n \n \n Provisioned\n \uc900\ube44\ub41c\n \n \n N/A\n \uc774\uc6a9\ubd88\uac00\n \n \n Total provisioned\n \uc900\ube44\ub41c \ucd1d\uacc4\n \n \n Striping unit\n \uc2a4\ud2b8\ub77c\uc774\ud551 \ub2e8\uc704\n \n \n Striping count\n \uc2a4\ud2b8\ub77c\uc774\ud551 \ud69f\uc218\n \n \n Parent\n \uc0c1\uc704\n \n \n Block name prefix\n \ube14\ub85d \uc774\ub984 \uc811\ub450\uc0ac\n \n \n Order\n \uc21c\uc11c\n \n \n Snapshots\n \uc2a4\ub0c5\uc0bf\n \n \n Image\n \uc774\ubbf8\uc9c0\n \n \n This setting overrides the global value\n \uc774 \uc124\uc815\uc740 \uc804\uc5ed \uac12\uc744 \ub36e\uc5b4\uc501\ub2c8\ub2e4.\n \n \n Global\n \uae00\ub85c\ubc8c\n \n \n This is the global value. No value for this option has been set for this image.\n \uc774\uac83\uc740 \uc804\uc5ed \uac12\uc785\ub2c8\ub2e4. \uc774 \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud574 \uc774 \uc635\uc158\uc758 \uac12\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \'/\' \uc640 \'@\' \ubb38\uc790\ub294 \uc0ac\uc6a9\ubd88\uac00\uc785\ub2c8\ub2e4.\n \n \n -- No rbd pools available --\n -- \uc774\uc6a9\uac00\ub2a5\ud55c rbd\ud480 \uc5c6\uc74c --\n \n \n -- Select a pool --\n -- \ud480 \uc120\ud0dd --\n \n \n Use a dedicated data pool\n \uc804\uc6a9 \ub370\uc774\ud0c0 \ud480\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc138\uc694\n \n \n Data pool\n \ub370\uc774\ud0c0 \ud480\n \n \n Dedicated pool that stores the object-data of the RBD.\n RBD\uc758 \uac1d\uccb4-\ub370\uc774\ud0c0\ub97c \uc800\uc7a5\ud558\uace0 \uc788\ub294 \uc804\uc6a9 \ud480\n \n \n e.g., 10GiB\n \uc608., 100 GiB\n \n \n You have to increase the size.\n \uc0ac\uc774\uc988\ub97c \uc99d\uac00\uc2dc\ucf1c\uc57c \ud569\ub2c8\ub2e4.\n \n \n Advanced\n \uc790\uc138\ud55c\n \n \n Striping\n \ubd84\uc0b0\uc800\uc7a5\n \n \n Stripe unit\n \ubd84\uc0b0\uc800\uc7a5\ub2e8\uc704\n \n \n -- Select stripe unit --\n -- \ubd84\uc0b0\uc800\uc7a5\ub2e8\uc704 \uc120\ud0dd --\n \n \n This field is required because stripe count is defined!\n \ubd84\uc0b0\uc800\uc7a5 \uac1c\uc218\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc73c\ubbc0\ub85c \uc774 \ud544\ub4dc\ub294 \ud544\uc218\uc785\ub2c8\ub2e4!\n \n \n Stripe unit is greater than object size.\n \ubd84\uc0b0\uc800\uc7a5\ub2e8\uc704\ub294 \uac1d\uccb4\ud06c\uae30\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4.\n \n \n Stripe count\n \ubd84\uc0b0\uc800\uc7a5 \uac2f\uc218\n \n \n This field is required because stripe unit is defined!\n \ubd84\uc0b0\uc800\uc7a5 \ub2e8\uc704\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc73c\ubbc0\ub85c \uc774 \ud544\ub4dc\ub294 \ud544\uc218\uc785\ub2c8\ub2e4!\n \n \n Stripe count must be greater than 0.\n \ubd84\uc0b0\uc800\uc7a5 \uac2f\uc218\ub294 \ubc18\ub4dc\uc2dc 0\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n RBD Snapshot\n \n \n RBD \uc2a4\ub0c5\uc0f7\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Rename} other {Create} }\n \n \n \n Snapshot\n \n \n \uc2a4\ub0c5\uc0f7\n \n \n \n PROTECTED\n \ubcf4\ud638\ub428\n \n \n UNPROTECTED\n \ubcf4\ud638\uc548\ub428\n \n \n You are about to rollback\n \ub864\ubc31\ud558\ub824\uace0 \ud569\ub2c8\ub2e4.\n \n \n Purge Trash\n \ud734\uc9c0\ud1b5 \ube44\uc6b0\uae30\n \n \n To purge, select one or All images and click\n \ube44\uc6b0\uae30 \uc704\ud574, \ud558\ub098 \ub610\ub294 \ubaa8\ub4e0 \uc774\ubbf8\uc9c0\ub4e4\uc744 \uc120\ud0dd\ud558\uace0 \ud074\ub9ad\ud558\uc138\uc694.\n \n \n Pool:\n \ud480:\n \n \n Pool name...\n \ud480 \uc774\ub984:\n \n \n All\n \ubaa8\ub4e0\n \n \n Restore Image\n \uc774\ubbf8\uc9c0 \ubcf5\uad6c\ud558\uae30\n \n \n To restore\n \ubcf5\uad6c\ub97c \uc704\ud574\n \n \n type the image\'s new name and click\n \uc774\ubbf8\uc9c0\ub4e4\uc758 \uc0c8\ub85c\uc6b4 \uc774\ub984\uc744 \uc785\ub825\ud558\uace0 \ud074\ub9ad\ud558\uc138\uc694\n \n \n New Name\n \uc0c8\ub85c\uc6b4 \uc774\ub984\n \n \n Expired at\n \ud3d0\uae30\ub420\n \n \n Protected until\n \uae4c\uc9c0 \ubcf4\ud638\ub428\n \n \n This image is protected until \n .\n \n \uc774 \uc774\ubbf8\uc9c0\ub294 \n \uae4c\uc9c0 \ubcf4\ud638\ub429\ub2c8\ub2e4.\n \n \n \n Trash\n \ud734\uc9c0\ud1b5\n \n \n iSCSI Topology\n iSCSI \ud1a0\ud3f4\ub85c\uc9c0\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n \uae30\ubcf8\uc124\uc815 \uac12\ub4e4\ub85c \ubd80\ud130 \uc778\uc790\ub97c \ubcc0\uacbd\ud558\ub294 \uac83\uc740 \uc77c\ubc18\uc801\uc73c\ub85c \ud544\uc694\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n \uc124\uc815\ub4e4\n \n \n Backstore\n \ubc31\uc2a4\ud1a0\uc5b4\n \n \n Confirm\n \ud655\uc778\n \n \n Advanced Settings\n \uace0\uae09\uc124\uc815\ub4e4\n \n \n Target IQN\n \ud0c0\uac9f IQN\n \n \n IQN has wrong pattern.\n IQN\uc774 \uc798\ubabb\ub41c \ud328\ud134\uc744 \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n IQN\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uc9c0\uc815\uaddc\uce59\uc774 \uc788\uc2b5\ub2c8\ub2e4.\n\'iqn.$\ub144-$\ub2ec.$\ub4a4\uc9d1\uc5b4\uc9c4\uc8fc\uc18c:$\uc815\uc758\ub41c\uc774\ub984\'\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Key\n\uc608\ub97c\ub4e4\uba74: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n \ucd94\uac00 \uc815\ubcf4\n \n \n This target has modified advanced settings.\n \uc774 \ud0c0\uac9f\uc740 \uace0\uae09\uc124\uc815\ub4e4\uc744 \uc218\uc815\ud588\uc2b5\ub2c8\ub2e4.\n \n \n Portals\n \ud3ec\ud138\n \n \n At least \n gateways are required.\n \n \uc801\uc5b4\ub3c4 \n \uac8c\uc774\ud2b8\uc6e8\uc774\ub4e4\uc744 \ud544\uc694\ub85c \ud569\ub2c8\ub2e4.\n \n \n \n Add portal\n \ud3ec\ud138 \ucd94\uac00\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n \uc774 \uc774\ubbf8\uc9c0\ub294 \uc124\uc815\ub4e4\uc744 \uc218\uc815\ud588\uc2b5\ub2c8\ub2e4. \n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n \uc774\ubbf8\uc9c0 \ucd94\uac00\n \n \n ACL authentication\n ACL \uc778\uc99d\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n \uac1c\uc2dc\uc790\ub4e4\n \n \n Initiator\n \uac1c\uc2dc\uc790\ub4e4\n \n \n Client IQN\n \ud074\ub77c\uc774\uc5b8\ud2b8 IQN\n \n \n Initiator IQN needs to be unique.\n \uac1c\uc2dc\uc790 IQN\uc740 \uc720\uc77c\ud574\uc57c \ud569\ub2c8\ub2e4.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \uc0ac\uc6a9\uc790\uc774\ub984\uc740 8~64\uc790\uae4c\uc9c0 \uae38\uc774\uc758 \ubb38\uc790\ub4e4\uc744 \uac00\uc838\uc57c \ud558\uba70 \uadf8\ub9ac\uace0, \uc624\uc9c1 , \'.\', \'@\', \'-\', \'_\', \':\' \ub4f1\uc758 \ud2b9\uc218 \ubb38\uc790\ub4e4\ub9cc \ud3ec\ud568\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n \uac1c\uc2dc\uc790\ub294 \ud558\ub098\uc758 \uadf8\ub8f9\uc5d0 \uc18d\ud574\uc57c \ud558\uace0, \uc774\ubbf8\uc9c0\ub294 \uadf8\ub8f9\uc548\uc5d0\uc11c \uc124\uc815\ud569\ub2c8\ub2e4.\n \n \n No items added.\n \ucd94\uac00\ub41c \uc544\uc774\ud15c\ub4e4\uc774 \uc5c6\uc74c\n \n \n Add initiator\n \uac8c\uc2dc\uc790 \ucd94\uac00\n \n \n Groups\n \uadf8\ub8f9\ub4e4\n \n \n Group\n \uadf8\ub8f9\n \n \n Add group\n \uadf8\ub8f9\ucd94\uac00\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n RBD \uc124\uc815\ub4e4\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n \ub85c\uceec \uad6c\uc131 \uac12\uc744 \uc81c\uac70\ud558\uc2ed\uc2dc\uc624. \uc0c1\uc704 \uad6c\uc131 \uac12\uc740 \uacc4\uc2b9\ub418\uace0 \ub300\uc2e0 \uc0ac\uc6a9\ub429\ub2c8\ub2e4.\n \n \n The mininum value is 0\n \ucd5c\uc18c\uac12\uc740 0\uc785\ub2c8\ub2e4.\n \n \n Issues\n \uc774\uc288\ub4e4\n \n \n Syncing\n \ub3d9\uae30\ud654\uc911\n \n \n Ready\n \uc900\ube44\ub428\n \n \n Edit pool mirror mode\n \ud480 \ubbf8\ub7ec\ubaa8\ub4dc\ub97c \ud3b8\uc9d1\ud558\uae30\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n \ud480\uc744 \uc704\ud55c \ubbf8\ub7ec\ubaa8\ub4dc\ub97c \ud3b8\uc9d1\ud558\uae30 \uc704\ud574\xa0\n \n \n , \uadf8 \ubaa9\ub85d\uc73c\ub85c \ubd80\ud130 \uc0c8\ub85c\uc6b4 \ubaa8\ub4dc\ub97c \uc120\ud0dd\ud558\uace0, \ud074\ub9ad\n \uac31\uc2e0\n .\n \n \n \n Mode\n \uc591\uc2dd\n \n \n Peer clusters must be removed prior to disabling mirror.\n \uc0c1\ub300\ubc29 \ud074\ub7ec\uc2a4\ud130\ub4e4\uc740 \ubbf8\ub7ec\ub97c \ub2e8\uc808\ud558\uae30 \uc804\uc5d0 \ubc18\ub4dc\uc2dc \uc81c\uac70\ub418\uc5b4\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n \n pool mirror peer\n \n \n \n \ud480 \ubbf8\ub7ec \uc0c1\ub300\ubc29\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Edit} other {Add} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n \ud480 \n \n \n \ud480\uc744 \uc704\ud558\uc5ec \uc0c1\ub300\ubc29 \uc18d\uc131 \ubbf8\ub7ec\ud558\uace0,\n \uc120\ud0dd \n \uc81c\ucd9c \n .\n \n \n \n Cluster Name\n \ud074\ub7ec\uc2a4\ud130 \uc774\ub984\n \n \n The cluster name is not valid.\n \ud074\ub7ec\uc2a4\ud130 \uc774\ub984\uc774 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n CephX ID\n CephX \uc544\uc774\ub514\n \n \n CephX ID...\n CephX \uc544\uc774\ub514...\n \n \n The CephX ID is not valid.\n CephX \uc544\uc774\ub514\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n Monitor Addresses\n \ubaa8\ub2c8\ud130 \uc8fc\uc18c\ub4e4\n \n \n Comma-delimited addresses...\n \ucf64\ub9c8\ub85c \ubd84\ub9ac\ub41c \uc8fc\uc18c\ub4e4...\n \n \n The monitory address is not valid.\n \ubaa8\ub2c8\ud130 \uc8fc\uc18c\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n CephX Key\n CephX \ud0a4\n \n \n Base64-encoded key...\n Base64\ub85c \uc778\ucf54\ub529 \ub41c \ud0a4 ...\n \n \n CephX key must be base64 encoded.\n CephX \ud0a4\ub294 \ubc18\ub4dc\uc2dc base64\ub85c \uc778\ucf54\ub4dc \ub418\uc5b4\uc57c \ud569\ub2c8\ub2e4.\n \n \n Pools List\n \ud480 \ubaa9\ub85d\ub4e4\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n \uc774\ub984\uc740 \uc601\uc22b\uc790, \ub300\uc2dc \ubc0f \ubc11\uc904\ub85c\ub9cc \uad6c\uc131 \ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n The chosen erasure code profile name is already in use.\n \uc120\ud0dd\ud55c Erasure Code \ud504\ub85c\ud30c\uc77c \uc774\ub984\uc774 \uc774\ubbf8 \uc0ac\uc6a9 \uc911\uc785\ub2c8\ub2e4.\n \n \n Plugin\n \ud50c\ub7ec\uadf8\uc778\n \n \n Data chunks (k)\n \ub370\uc774\ud130 \ub369\uc5b4\ub9ac\ub4e4 (k)\n \n \n Must be equal to or greater than 2.\n \ubc18\ub4dc\uc2dc 2\ubcf4\ub2e4 \ud06c\uac70\ub098 \uac19\uc544\uc57c\ud569\ub2c8\ub2e4.\n \n \n Coding chunks (m)\n \ucf54\ub529 \ub369\uc5b4\ub9ac\ub4e4 (m)\n \n \n Must be equal to or greater than 1.\n \ubc18\ub4dc\uc2dc 1\ubcf4\ub2e4 \ud06c\uac70\ub098 \uac19\uc544\uc57c\ud569\ub2c8\ub2e4.\n \n \n Durability estimator (c)\n \ub0b4\uad6c\uc131 \ud3c9\uac00(c)\n \n \n Locality (l)\n \uc9c0\uc5ed (l)\n \n \n Crush failure domain\n \ud06c\ub7ec\uc26c \uc2e4\ud328 \ub3c4\uba54\uc778\n \n \n Crush Locality\n \ud06c\ub7ec\uc26c \uc9c0\uc5ed\n \n \n None\n \uc5c6\uc74c\n \n \n Technique\n \uae30\uc220\n \n \n Packetsize\n \ud328\ud0b7\ud06c\uae30\n \n \n Crush root\n \ud06c\ub7ec\uc26c\ub8e8\ud2b8\n \n \n Crush device class\n \ud06c\ub7ec\uc26c \uc7a5\uce58 \ud074\ub798\uc2a4\n \n \n any\n \ubaa8\ub4e0\n \n \n Directory\n \ub514\ub809\ud1a0\ub9ac\n \n \n The chosen Ceph pool name is already in use.\n \uc120\ud0dd\ud55c Ceph \ud480\uc774\ub984\uc774 \uc774\ubbf8 \uc0ac\uc6a9\uc911\uc785\ub2c8\ub2e4.\n \n \n Pool type\n \ud480 \ud615\ud0dc\n \n \n -- Select a pool type --\n -- \ud480 \ud615\ud0dc \uc120\ud0dd --\n \n \n Placement groups\n \uac8c\uc7ac\uc704\uce58 \uadf8\ub8f9\n \n \n At least one placement group is needed!\n \uc801\uc5b4\ub3c4 \ud558\ub098\uc758 \uac8c\uc7ac\uc704\uce58 \uadf8\ub8f9\uc774 \ud544\uc694\ud568!\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n \ud074\ub7ec\uc2a4\ud130\ub294 \uc774 \ub9ce\uc740 PG\ub4e4\ub97c \ucc98\ub9ac \ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \ud544\uc694\ud55c PG \uc591\uc744 \ub2e4\uc2dc \uacc4\uc0b0\ud558\uc2ed\uc2dc\uc624.\n \n \n Calculation help\n \uacc4\uc0b0 \ub3c4\uc6c0\ub9d0\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n \ud604\uc7ac\uc758 PG\ub4e4 \uc124\uc815\ub4e4\uc774 \ub2f9\uc2e0\uc744 \uc704\ud574 \uacc4\uc0b0\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \n\ub2f9\uc2e0\uc740 \uc81c\ucd9c\ud558\uae30 \uc804\uc5d0 \ub2f9\uc2e0\uc758 \uc694\uad6c\uc5d0 \uc801\ud569\ud55c \uac12\uc778\uc9c0\ub97c \ud655\uc778\ud574\uc57c \ud569\ub2c8\ub2e4.\n \n \n Crush ruleset\n \ud06c\ub7ec\uc26c \ub8f0\uc14b\n \n \n -- Select a crush rule --\n -- \ud06c\ub7ec\uc26c \ub8f0 \uc120\ud0dd --\n \n \n Crush rule\n \ud06c\ub7ec\uc26c \ub8f0\n \n \n Crush steps\n \ud06c\ub7ec\uc26c \ub2e8\uacc4\ub4e4\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n \uc774 \ub8f0\uc5d0 \uc758\ud558\uc5ec \ucd5c\uc18c\ub85c \ud544\uc694\ub85c \ud558\ub294 OSD\ubcf4\ub2e4 \uc801\uc740 OSD\ub97c \uac00\uc9c0\uace0 \uc788\uae30\ub54c\ubb38\uc5d0 \uc774 \ub8f0\uc740 \ud604\uc7ac\uc758 \ud074\ub7ec\uc2a4\ud130\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n Replicated size\n \ubcf5\uc81c\ub418\ub294 \ud06c\uae30\n \n \n Minimum: \n \n \n \ucd5c\uc18c: \n \n \n \n \n Maximum: \n \n \n \ucd5c\ub300: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n \uc9c0\uc815\ub41c \ud06c\uae30\ub294 \ubc94\uc704\ub97c \ubc97\uc5b4\ub0ac\uc2b5\ub2c8\ub2e4.\n \uc5d0\uc11c \n \uc0ac\uc774\uc758 \uac12\uc774 \uc720\ud6a8\ud569\ub2c8\ub2e4.\n \n \n \n Erasure code profile\n Erasure Code \ud504\ub85c\ud30c\uc77c\n \n \n -- No erasure code profile available --\n -- \uc0ac\uc6a9\uac00\ub2a5\ud55c Erasure Code \ud504\ub85c\ud30c\uc77c \uc5c6\uc74c --\n \n \n -- Select an erasure code profile --\n -- \ud55c\uac1c\uc758 Erasure Code \ud504\ub85c\ud30c\uc77c \uc120\ud0dd --\n \n \n EC Overwrites\n EC \ub36e\uc5b4\uc4f0\uae30\n \n \n Applications\n \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8\ub4e4\n \n \n Compression\n \uc555\ucd95\n \n \n Algorithm\n \uc54c\uace0\ub9ac\uc998\n \n \n -- No erasure compression algorithm available --\n -- \uc774\uc6a9\uac00\ub2a5\ud55c Erasure \uc555\ucd95\uc54c\uace0\ub9ac\uc998 \uc5c6\uc74c --\n \n \n Minimum blob size\n \ucd5c\uc18c blob \ud06c\uae30\n \n \n e.g., 128KiB\n \uc608) 128KiB\n \n \n Value should be greater than 0\n \uac12\uc740 0\ubcf4\ub2e4 \ucee4\uc57c\ud569\ub2c8\ub2e4\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n \ucd5c\ub300 blob \ud06c\uae30\n \n \n e.g., 512KiB\n \uc608) 512KiB\n \n \n Value should be greater than the minimum blob size\n \uac12\uc740 \ucd5c\uc18c blob \ud06c\uae30\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4\n \n \n Ratio\n \ube44\uc728\n \n \n Compression ratio\n \uc555\ucd95\uc728\n \n \n Value should be between 0.0 and 1.0\n \uac12\uc740 0.0\uacfc 1.0 \uc0ac\uc774 \uc5ec\uc57c \ud569\ub2c8\ub2e4.\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n \uc774\ub984\uc5d0 \'/\'\uac00 \ud3ec\ud568 \ub41c RBD \ud480\uc744 \uc0dd\uc131 \ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n \uc774\ub984\uc744 \ubcc0\uacbd\ud558\uac70\ub098 \uc751\uc6a9 \ud504\ub85c\uadf8\ub7a8 \ubaa9\ub85d\uc5d0\uc11c \'rbd\'\ub97c \uc81c\uac70\ud558\uc2ed\uc2dc\uc624.\n \n \n Cache Tiers Details\n \ucf00\uc26c \uacc4\uce35\ub4e4 \uc0c1\uc138\uc124\uba85\ub4e4\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n \uc624\ube0c\uc81d\ud2b8 \uac8c\uc774\ud2b8\uc6e8\uc774 \uad00\ub9ac\uae30\ub2a5\ub4e4\uc744 \uc5b4\ub5bb\uac8c \uc124\uc815\ud558\uace0 \ucf1c\ub294\uc9c0\uc5d0 \ub300\ud574 \n\ubb38\uc11c\n \uc0c1\uc758 \n \ubd80\ubd84\uc744 \ucc38\uc870\ud558\uae30 \ubc14\ub78d\ub2c8\ub2e4.\n \n \n \n Daemons List\n \ub370\ubaac \ubaa9\ub85d\ub4e4\n \n \n Performance Counters\n \uc131\ub2a5 \uce74\uc6b4\ud130\n \n \n Loading bucket data...\n \ubc84\ud0b7\ub370\uc774\ud0c0 \uc801\uc7ac \uc911\n \n \n The bucket data could not be loaded.\n \ubc84\ud0b7 \ub370\uc774\ud0c0\ub97c \uc801\uc7ac\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n Id\n \uc544\uc774\ub514\n \n \n The value is not valid.\n \uac12\uc774 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n Owner\n \uc18c\uc720\uc790\n \n \n -- Select a user --\n -- \uc0ac\uc6a9\uc790 \uc120\ud0dd --\n \n \n ID\n \uc544\uc774\ub514\n \n \n Index type\n \uc0c9\uc778\ud615\uc2dd\n \n \n Placement rule\n \uc704\uce58\uaddc\uce59\n \n \n Marker\n \ud45c\uc2dc\n \n \n Maximum marker\n \ucd5c\ub300 \ub9c8\ucee4\n \n \n Version\n \ubc84\uc83c\n \n \n Master version\n \ub9c8\uc2a4\ud130 \ubc84\uc83c\n \n \n Modification time\n \uc218\uc815\ub41c \uc2dc\uac04\n \n \n Zonegroup\n \uc81c\ub85c\uadf8\ub8f9\n \n \n Bucket quota\n \ubc84\ud0b7 \ud560\ub2f9\ub7c9\n \n \n Enabled\n \uc774\uc6a9\uac00\ub2a5\n \n \n Maximum size\n \ucd5c\ub300 \ud06c\uae30\n \n \n Unlimited\n \ubb34\uc81c\ud55c\n \n \n Maximum objects\n \ucd5c\ub300 \uac1d\uccb4\ub4e4\n \n \n -- Select a username --\n -- \uc0ac\uc6a9\uc790\uba85 \uc120\ud0dd --\n \n \n Auto-generate key\n \uc790\ub3d9\uc0dd\uc131\ub41c \ud0a4\n \n \n Access key\n \uc811\uadfc \ud0a4\n \n \n Secret key\n \ube44\ubc00 \ud0a4\n \n \n Email address\n \uc804\uc790\uc6b0\ud3b8 \uc8fc\uc18c\n \n \n Suspended\n \uc720\uc608\ub418\ub2e4.\n \n \n System\n \uc2dc\uc2a4\ud15c\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, \uc120\ud0dd, 0 {\uc544\ub2c8\uc624} 1 {\uc608} }\n \n \n Maximum buckets\n \ucd5c\ub300 \ubc84\ud0b7\ub4e4\n \n \n Subusers\n \ubcf4\uc870\uc0ac\uc6a9\uc790\ub4e4\n \n \n Capabilities\n \ub2a5\ub825\uce58\ub4e4\n \n \n User quota\n \uc0ac\uc6a9\uc790 \ud560\ub2f9\ub7c9\n \n \n Show\n \ubcf4\uae30\n \n \n Keys\n \ud0a4\ub4e4\n \n \n -- Select a type --\n -- \ud615\ud0dc \uc120\ud0dd --\n \n \n Permission\n \uad8c\ud55c\n \n \n -- Select a permission --\n -- \uad8c\ud55c \uc120\ud0dd --\n \n \n Subuser\n \ubcf4\uc870\uc0ac\uc6a9\uc790\n \n \n The chosen subuser ID is already in use.\n \uc120\ud0dd\ud55c \ubcf4\uc870\uc0ac\uc6a9\uc790 \uc544\uc774\ub514\uac00 \uc774\ubbf8 \uc0ac\uc6a9\uc911\uc785\ub2c8\ub2e4.\n \n \n read, write\n \uc77d\uae30, \uc4f0\uae30\n \n \n full\n \uac00\ub4dd\ucc2c\n \n \n Swift key\n \uc2a4\uc704\ud504\ud2b8 \ud0a4\n \n \n Auto-generate secret\n \uc790\ub3d9\uc0dd\uc120\ub41c \ube44\ubc00\n \n \n Loading user data...\n \uc0ac\uc6a9\uc790 \ub370\uc774\ud0c0 \uc801\uc7ac \uc911...\n \n \n The user data could not be loaded.\n \uc0ac\uc6a9\uc790 \ub370\uc774\ud0c0\ub97c \uc801\uc7ac\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n The chosen user ID is already in use.\n \uc120\ud0dd\ub41c \uc0ac\uc6a9\uc790 \uc544\uc774\ub514\uac00 \uc774\ubbf8 \uc0ac\uc6a9 \uc911\uc785\ub2c8\ub2e4.\n \n \n This is not a valid email address.\n \uc774\uac83\uc740 \uc720\ud6a8\ud55c \uc804\uc790\uc6b0\ud3b8 \uc8fc\uc18c\uac00 \uc544\ub2d9\ub2c8\ub2e4.\n \n \n The chosen email address is already in use.\n \uc120\ud0dd\ud55c \uc804\uc790\uc6b0\ud3b8 \uc8fc\uc18c\uac00 \uc774\ubbf8 \uc0ac\uc6a9 \uc911\uc785\ub2c8\ub2e4.\n \n \n Max. buckets\n \ucd5c\ub300 \ubc84\ud0b7\ub4e4\n \n \n The entered value must be >= 0.\n \uc785\ub825\ub41c \uac12\uc740 \ubc18\ub4dc\uc2dc 0\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4.\n \n \n S3 key\n S3 \ud0a4\n \n \n There are no subusers.\n \ubcf4\uc870\uc0ac\uc6a9\uc790\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n \ud0a4\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n \uc2a4\uc704\ud504\ud2b8\n \n \n There are no capabilities.\n \ub2a5\ub825\uce58\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n \ubb34\uc81c\ud55c \ud06c\uae30\n \n \n Max. size\n \ucd5c\ub300 \ud06c\uae30\n \n \n Unlimited objects\n \ubb34\uc81c\ud55c \uac1d\uccb4\ub4e4\n \n \n Max. objects\n \ucd5c\ub300 \uac1d\uccb4\ub4e4\n \n \n Current\n \ud604\uc7ac\n \n \n Updated discovery authentication\n \uc5c5\ub370\uc774\ud2b8\ub41c \uac80\uc0c9 \uc778\uc99d\n \n \n There are no portals available.\n \uc0ac\uc6a9\uac00\ub2a5\ud55c \ud3ec\ud0c8\ub4e4\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n There are no images available.\n \uc0ac\uc6a9\uac00\ub2a5\ud55c \uc774\ubbf8\uc9c0\ub4e4\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n There are no images available. Please make sure you add an image to the target.\n \uc0ac\uc6a9\ud560 \uc218\uc788\ub294 \uc774\ubbf8\uc9c0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4. \ub300\uc0c1\uc5d0 \uc774\ubbf8\uc9c0\ub97c \ucd94\uac00\ud588\ub294\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n \uc0ac\uc6a9\ud560 \uc218\uc788\ub294 \uac1c\uc2dc\uc790\uac00 \uc5c6\uc2b5\ub2c8\ub2e4. \ub300\uc0c1\uc5d0 \uac1c\uc2dc\uc790\ub97c \ucd94\uac00\ud588\ub294\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624.\n \n \n target\n target\n \n \n Target\n \ud0c0\uac9f\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n \uc0c1\ud0dc\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n \uc77d\uc740 \ubc14\uc774\ud2b8\ub4e4\n \n \n Write Bytes\n \uc4f0\uae30 \ubc14\uc774\ud2b8\ub4e4\n \n \n Read Ops\n \uc77d\uae30 Ops\n \n \n Write Ops\n \uc4f0\uae30 Ops\n \n \n A/O Since\n A/O \uc774\ub798\ub85c\n \n \n Instance\n \uc778\uc2a4\ud0c4\uc2a4\n \n \n Hostname\n \ud638\uc2a4\ud2b8\uc774\ub984\n \n \n Issue\n \uc774\uc288\n \n \n Progress\n \uc9c4\ud589\uc911\n \n \n Disabled\n \uc124\uc815\ud574\uc81c\ub428\n \n \n Edit Mode\n \ud3b8\uc9d1\ubaa8\ub4dc\n \n \n Add Peer\n \uc0c1\ub300\ubc29 \ucd94\uac00\n \n \n Edit Peer\n \uc0c1\ub300\ubc29 \ud3b8\uc9d1\n \n \n Delete Peer\n \uc0c1\ub300\ubc29 \uc0ad\uc81c\n \n \n Leader\n \ub9ac\ub354\n \n \n # Local\n # \ub85c\uceec\n \n \n # Remote\n # \uc6d0\uaca9\n \n \n mirror peer\n \uc0c1\ub300\ubc29 \ubbf8\ub7ec\n \n \n Key\n \ud0a4\n \n \n RBD\n RBD\n \n \n Deep flatten\n \ub525 \ud328\ud134\n \n \n Layering\n \uacc4\uce35\ud654\n \n \n Exclusive lock\n \ubc30\ud0c0\uc801\uc778 \ub77d\n \n \n Object map (requires exclusive-lock)\n \uc624\ud504\uc81d\ud2b8-\ub9f5(\ubc30\ud0c0\uc801\uc778-\ub77d\uc744 \uc694\uad6c\ud55c\ub2e4)\n \n \n Journaling (requires exclusive-lock)\n \uc800\ub110\ub9c1(\ubc30\ud0c1\uc801\uc778-\ub77d\uc744 \uc694\uad6c\ud569\ub2c8\ub2e4.)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n RBD \uc2a4\ub0c5\uc0f7 \ub864\ubc31\n \n \n Rollback\n \ub864\ubc31\n \n \n RBD snapshot\n RBD \uc2a4\ub0c5\uc0f7\n \n \n Deleted At\n \uc0ad\uc81c\ub420 \n \n \n id\n \uc544\uc774\ub514\n \n \n type\n \ud615\ud0dc\n \n \n state\n \uc0c1\ud0dc\n \n \n version\n \ubc84\uc83c\n \n \n Host\n \ud638\uc2a4\ud2b8\n \n \n root\n \ub8e8\ud2b8\n \n \n Rank\n \uc21c\uc704\n \n \n Daemon\n \ub370\ubaac\n \n \n Activity\n \ud65c\ub3d9\n \n \n Dentries\n \ub374\ud2b8\ub9ac\ub4e4\n \n \n Inodes\n \uc544\uc774\ub178\ub4dc\ub4e4\n \n \n Usage\n \uc0ac\uc6a9\ub7c9\n \n \n Standby daemons\n \ub300\uae30 \ub370\ubaac\ub4e4\n \n \n The value can be updated at runtime.\n \uc774 \uac12\uc740 \ub7f0\ud0c0\uc784\uc5d0 \uc5c5\ub370\uc774\ud2b8 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n \ub370\ubaac\ub4e4 / \ud074\ub77c\uc774\uc5b8\ud2b8\ub4e4\uc740 \ubaa8\ub2c8\ud130 \uad6c\uc131 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c\uc774 \uac12\uc744 \uac00\uc838 \uc624\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \'ceph config set ...\'\uc744 \ud1b5\ud574\uc774 \uc635\uc158\uc744 \uc124\uc815\ud558\ub294 \uac83\uc740 \ud5c8\ub77d\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc774 \uc635\uc158\uc740 ceph.conf \ub610\ub294 \uba85\ub839 \uc904\uc744 \ud1b5\ud574 \uad6c\uc131\ud574\uc57c\ud569\ub2c8\ub2e4.\n \n \n Option takes effect only during daemon startup.\n \uc635\uc158\uc740 \ub370\ubaac \uc2dc\uc791 \uc911\uc5d0 \ub9cc \uc801\uc6a9\ub429\ub2c8\ub2e4.\n \n \n Option only affects cluster creation.\n \uc635\uc158\uc740 \ud074\ub7ec\uc2a4\ud130 \uc0dd\uc131\ud560 \ub54c \ub9cc \uc601\ud5a5\uc744 \uc90d\ub2c8\ub2e4.\n \n \n Option only affects daemon creation.\n \uc635\uc158\uc740 \ub370\ubaac \uc0dd\uc131\ud560 \ub54c\ub9cc \uc601\ud5a5\uc744\uc90d\ub2c8\ub2e4.\n \n \n Updated config option \n \n \n \uac31\uc2e0\ub41c \uc124\uc815 \uc635\uc158 \n \n \n \n \n Service\n \uc11c\ube44\uc2a4\n \n \n Current value\n \ud604\uc7ac\uac12\n \n \n Editable\n \ud3b8\uc9d1\uac00\ub2a5\n \n \n Updated options for module "\n ".\n \n \ubaa8\ub4c8\uc744 \uc704\ud574 \uac31\uc2e0\ub41c \uc635\uc158\ub4e4 &quot;\n &quot;.\n \n \n \n Enable\n \uc0ac\uc6a9\uac00\ub2a5\n \n \n Disable\n \uc0ac\uc6a9\ubd88\uac00\n \n \n Reconnecting, please wait ...\n \uc7ac-\uc811\uc18d \uc911, \uae30\ub2e4\ub824 \uc8fc\uc138\uc694...\n \n \n Public Address\n \uacf5\uac1c \uc8fc\uc18c\n \n \n Open Sessions\n \uc5f4\ub9b0 \uc138\uc158\ub4e4\n \n \n No In\n \ub4e4\uc5b4\uc62c \uc218 \uc5c6\ub294\n \n \n OSDs that were previously marked out will not be marked back in when they start\n \uc774\uc804\uc5d0 \ub9c8\ud06c \uc544\uc6c3 \ub41c OSD\ub294 \uc2dc\uc791\uc2dc \ub2e4\uc2dc \ud45c\uc2dc\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n No Out\n \ub098\uac08 \uc218 \uc5c6\ub294\n \n \n OSDs will not automatically be marked out after the configured interval\n OSD\ub4e4\uc740 \uad6c\uc131\ub41c \uac04\uaca9 \ud6c4\uc5d0\ub294 \uc790\ub3d9\uc73c\ub85c \ud45c\uc2dc\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n No Up\n \uc0b4\uc544\ub098\uc9c0 \uc54a\ub294\n \n \n OSDs are not allowed to start\n OSD\ub294 \uc2dc\uc791\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n No Down\n \uc8fd\uc77c \uc218 \uc5c6\ub294\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n \ubaa8\ub2c8\ud130\uac00 OSD\ub4e4\uc758 \ub2e4\uc6b4\uc744 \ud45c\uc2dc\ud558\uc9c0 \uc54a\ub3c4\ub85d OSD \uc7a5\uc560 \ubcf4\uace0\uc11c\uac00 \ubb34\uc2dc\ub418\uace0 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n Pause\n \uba48\ucd9c\n \n \n Pauses reads and writes\n \uc77d\uae30\uc640 \uc4f0\uae30\ub97c \uba48\ucda4\n \n \n No Scrub\n \uc2a4\ud06c\ub7ec\ube59 \uc54a\ub428\n \n \n Scrubbing is disabled\n \uc2a4\ud06c\ub7ec\ube59\uc774 \ube44\ud65c\uc131\ud654\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n \n \n No Deep Scrub\n \ub525 \uc2a4\ud06c\ub7fd \uc548\ub428\n \n \n Deep Scrubbing is disabled\n \ub525 \uc2a4\ud06c\ub7ec\ube59\uc774 \ube44\ud65c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n \n \n No Backfill\n \ubc31\ud544 \uc5c6\uc74c\n \n \n Backfilling of PGs is suspended\n PG\ub4e4\uc758 \ubc31\ud544\uc774 \uc77c\uc2dc\uc911\uc9c0 \ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n \n \n No Recover\n \ubcf5\uad6c \uc54a\ub428\n \n \n Recovery of PGs is suspended\n PG\ub4e4\uc758 \ubcf5\uad6c\uac00 \uc77c\uc2dc\uc911\uc9c0 \ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n \n \n Bitwise Sort\n \ube44\ud2b8\ub2e8\uc704 \uc815\ub82c\n \n \n Use bitwise sort\n \ube44\ud2b8\ub2e8\uc704 \uc815\ub82c\uc744 \uc0ac\uc6a9\ud558\uc138\uc694\n \n \n Purged Snapdirs\n \uc644\uc804\uc0ad\uc81c\ub41c \uc2a4\ub0c5\ub514\ub809\ud1a0\ub9ac\ub4e4\n \n \n OSDs have converted snapsets\n OSD\ub4e4\uc774 \ubcc0\ud654\ub41c \uc2a4\ub0c5\uc14b\uc744 \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n Recovery Deletes\n \uc0ad\uc81c\ub41c \ubcf5\uad6c\ub4e4\n \n \n Deletes performed during recovery instead of peering\n \ud53c\uc5b4\ub9c1 \ub300\uc2e0 \ubcf5\uad6c \uc911\uc5d0 \uc218\ud589\ub41c \uc0ad\uc81c\ubb3c\ub4e4\n \n \n PG Log Hard Limit\n PG \ub85c\uadf8 \ud558\ub4dc \ud55c\uacc4\n \n \n Puts a hard limit on pg log length\n pg \ub85c\uadf8 \uae38\uc774\uc5d0 \ud558\ub4dc \ud55c\uacc4\ub97c \ub123\uc73c\uc138\uc694\n \n \n Updated OSD Flags\n \uac31\uc2e0\ub41c OSD \ud50c\ub798\uadf8\ub4e4\n \n \n out\n \uc544\uc6c3\n \n \n in\n \uc778\n \n \n down\n \ub2e4\uc6b4\n \n \n Mark\n \ud45c\uc2dc\n \n \n OSD lost\n OSD \uc190\uc2e4\n \n \n marked lost\n \uc190\uc2e4 \ud45c\uc2dc\n \n \n Purge\n \uc644\uc804\uc81c\uac70\n \n \n OSD\n OSD\n \n \n purged\n \uc644\uc804\uc81c\uac70\ub41c\n \n \n destroy\n \ud30c\uad34\ub428\n \n \n destroyed\n \ud30c\uad34\ub41c\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n \ud30c\uad34\ub428\n \n \n Read bytes\n \uc77d\uc740 \ubc14\uc774\ud2b8\ub4e4\n \n \n Writes bytes\n \uc4f0\uae30\ub41c \ubc14\uc774\ud2b8\ub4e4\n \n \n Read ops\n \uc77d\uae30 ops\n \n \n Write ops\n \uc4f0\uae30 ops\n \n \n Mark OSD \n \n \n \ud45c\uc2dc\ub41c OSD \n \n \n \n \n Mark \n \n \n \ud45c\uc2dc\ub41c \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n \ucd5c\ub300 \ubc31\ud544\ub4e4\n \n \n Recovery Max Active\n \ucd5c\ub300 \ud65c\uc131\ud654\ub97c \ubcf5\uad6c\ud558\uae30\n \n \n Recovery Max Single Start\n \ucd5c\ub300 \ub2e8\uc77c \uc2dc\uc791\uc744 \ubcf5\uad6c\ud558\uae30\n \n \n Recovery Sleep\n \uc7a0\uc790\uae30\ub97c \ubcf5\uad6c\ud558\uae30\n \n \n Custom\n \ucee4\uc2a4\ud140\n \n \n Updated OSD recovery speed priority "\n "\n \n \uac31\uc2e0\ub41c OSD \ubcf5\uad6c \uc18d\ub3c4 \uc6b0\uc120\uc21c\uc704 &quot;\n &quot;\n \n \n \n \n was initialized in the following OSD: \n \n \n \n \uc740 \ub2e4\uc74c\uc758 OSD\ub4e4 \uc548\uc5d0 \ucd08\uae30\ud654\ub428: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n \uc77c\n \n \n Severity\n \uc2ec\uac01\ub3c4\n \n \n Started\n \uc2dc\uc791\ub41c\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n \uac31\uc2e0\ub41c\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n \uc0ac\uc6a9\ub41c\n \n \n Avail.\n \uc774\uc6a9\uac00\ub2a5:\n \n \n Clean\n \uae68\ub057\ud55c\n \n \n Working\n \uc815\uc0c1\ub3d9\uc791\uc911\n \n \n Warning\n \uacbd\uace0\n \n \n Unknown\n \uc54c\ub824\uc9c0\uc9c0 \uc54a\uc740\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n \uc815\uc0c1\n \n \n no filesystems\n \ud30c\uc77c\uc2dc\uc2a4\ud15c\ub4e4 \uc5c6\uc74c\n \n \n active\n \ud65c\uc131\ud654\ub41c\n \n \n standby\n \ub300\uae30\uc911\uc778\n \n \n n/a\n \uc774\uc6a9\ubd88\uac00\n \n \n active daemon\n \ud65c\uc131\ud654\ub41c \ub370\ubaac\ub4e4\n \n \n quorum\n \uc815\uc871\uc218\n \n \n The NFS Ganesha service is not configured.\n NFS Ganesha \uc11c\ube44\uc2a4\uac00 \uc124\uc815\ub418\uc9c0 \uc54a\uc74c\n \n \n Transport\n \uc804\uc1a1\n \n \n CephFS User\n CephFS \uc0ac\uc6a9\uc790\n \n \n CephFS Filesystem\n CephFS \ud30c\uc77c\uc2dc\uc2a4\ud15c\n \n \n (inherited from global config)\n (\uc804\uc5ed \uad6c\uc131\uc5d0\uc11c \uc0c1\uc18d)\n \n \n inherited from global config\n \uc804\uc5ed \uad6c\uc131\uc5d0\uc11c \uc0c1\uc18d\n \n \n -- Select what kind of user id squashing is performed --\n - \uc5b4\ub5a4 \uc885\ub958\uc758 \uc0ac\uc6a9\uc790 ID \uc2a4\ucffc\uc2dc\uac00 \uc218\ud589\ub418\ub294\uc9c0 \uc120\ud0dd -\n \n \n There are no daemons available.\n \uc0ac\uc6a9\uac00\ub2a5\ud55c \ub370\ubaac\uc774 \uc5c6\uc74d\ub2c8\ub2e4.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n \uce90\uc26c\ubaa8\ub4dc\n \n \n Min Evict Age\n \ucd5c\uc18c \ud1f4\uac70 \uc5f0\ub839\n \n \n Min Flush Age\n \ucd5c\uc18c \ud50c\ub7ec\uc2dc \uc5f0\ub839\n \n \n Target Max Bytes\n \ubaa9\ud45c \ucd5c\ub300 \ubc14\uc774\ud2b8\ub4e4\n \n \n Target Max Objects\n \ubaa9\ud45c \ucd5c\ub300 \uc624\ube0c\uc81d\ud2b8\ub4e4\n \n \n No applications added\n \ucd94\uac00\ub41c \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \uc5c6\uc74c\n \n \n Applications limit reached\n \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \ud55c\uacc4\uc5d0 \ub3c4\ub2ec\ud568\n \n \n A pool can only have up to four applications definitions.\n \ud558\ub098\uc758 \ud480\uc740 \uc624\uc9c1 \ub124\uac1c\uc758 \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \uc815\uc758\ub4e4\uc744 \uac00\uc9c8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n \'_a-zA-Z0-9\' \ubb38\uc790\ub4e4\ub9cc \ud5c8\ub77d\ub428\n \n \n Maximum length is 128 characters\n \ucd5c\ub300 \uae38\uc774\ub294 128\uae00\uc790\uc774\ub2e4.\n \n \n Filter or add applications\n \ud544\ud130 \ub610\ub294 \ucd94\uac00\ub41c \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8\ub4e4\n \n \n Add application\n \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \ucd94\uac00\n \n \n pool\n pool\n \n \n erasure code profile\n Erasure \ucf54\ub4dc \ud504\ub85c\ud30c\uc77c\n \n \n Replica Size\n \ubcf5\uc81c \ud06c\uae30\n \n \n Last Change\n \ub9c8\uc9c0\ub9c9 \ubcc0\uacbd\n \n \n Erasure Coded Profile\n Erasure \ucf54\ub4dc\ud654\ub41c \ud504\ub85c\ud30c\uc77c\n \n \n Crush Ruleset\n \ud06c\ub7ec\uc26c \ub8f0\uc14b\n \n \n Write bytes\n \uc4f0\uc5ec\uc9c4 \ubc14\uc774\ud2b8\ub4e4\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n \ubc84\ud0b7\n \n \n Updated Object Gateway bucket "\n "\n \n \uac31\uc2e0\ub41c \uc624\ube0c\uc81d\ud2b8 \uac8c\uc774\ud2b8\uc6e8\uc5b4 \ubc84\ud0b7 &quot;\n &quot;\n \n \n \n Created Object Gateway bucket "\n "\n \n \uc0dd\uc131\ub41c \uc624\ube0c\uc81d\ud2b8 \uac8c\uc774\ud2b8\uc6e8\uc774 \ubc84\ud0b7 &quot;\n &quot;\n \n \n \n buckets\n \ubc84\ud0b7\ub4e4\n \n \n capability\n capability\n \n \n user\n \uc0ac\uc6a9\uc790\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n \uac31\uc2e0\ub41c \uc624\ube0c\uc81d\ud2b8 \uac8c\uc774\ud2b8\uc6e8\uc774 \uc0ac\uc6a9\uc790 &quot;\n &quot;\n \n \n \n Created Object Gateway user "\n "\n \n \uc0dd\uc131\ub41c \uc624\ube0c\uc81d\ud2b8 \uac8c\uc774\ud2b8\uc6e8\uc774 \uc0ac\uc6a9\uc790 &quot;\n &quot;\n \n \n \n users\n \uc0ac\uc6a9\uc790\ub4e4\n \n \n Swift Key\n Swift Key\n \n \n Scope\n \ubc94\uc704\n \n \n Read\n \uc77d\uae30\n \n \n Create\n \ub9cc\ub4e4\uae30\n \n \n role\n role\n \n \n Created role \'\n \'\n \n \uc0dd\uc131\ub41c \ub864 \'\n \'\n \n \n \n Updated role \'\n \'\n \n \uac31\uc2e0\ub41c \ub864 \'\n \'\n \n \n \n System Role\n \uc2dc\uc2a4\ud15c \ub864\n \n \n Deleted role \'\n \'\n \n \uc0ad\uc81c\ub41c \ub864 \'\n \'\n \n \n \n Created user "\n "\n \n \uc0dd\uc131\ub41c \uc0ac\uc6a9\uc790 &quot;\n &quot;\n \n \n \n Update user\n \uac31\uc2e0\ub41c \uc0ac\uc6a9\uc790\n \n \n Continue\n \uacc4\uc18d\n \n \n You were automatically logged out because your roles have been changed.\n \ub2f9\uc2e0\uc758 \ub864\ub4e4\uc774 \ubcc0\uacbd\ub418\uc5b4 \ub2f9\uc2e0\uc740 \uc790\ub3d9\uc801\uc73c\ub85c \ub85c\uadf8\uc544\uc6c3\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n \n \n Updated user "\n "\n \n \uac31\uc2e0\ub41c \uc0ac\uc6a9\uc790 &quot;\n &quot;\n \n \n \n Deleted user "\n "\n \n \uc0ad\uc81c\ub41c \uc0ac\uc6a9\uc790 &quot;\n &quot;\n \n \n \n Failed to delete user "\n "\n \n \uc0ac\uc6a9\uc790 \uc0ad\uc81c\uac00 \uc2e4\ud3d0\ub41c &quot;\n &quot;\n \n \n \n You are currently logged in as "\n ".\n \n \ub2f9\uc2e0\uc740 \ud604\uc7ac &quot;\n &quot; \ub85c \ub85c\uadf8\uc778\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n \uac01\uac01\uc758 \uc624\ube0c\uc81d\ud2b8\ub4e4\uc740 \ub370\uc774\ud0c0-\uccad\ud06c \ubd80\ubd84\ub4e4\ub85c \ubd84\ub9ac\ub418\uc5b4, \uac01\uae30 \ub2e4\ub978 OSD\uc5d0 \ubcf4\uad00\ub429\ub2c8\ub2e4.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n \uac01 \uc624\ube0c\uc81d\ud2b8\ub4e4\uc5d0 \ub300\ud55c \ucf54\ub529 \uccad\ud06c\ub97c \uacc4\uc0b0\ud558\uace0 \uc11c\ub85c \ub2e4\ub978 OSD\uc5d0 \uc800\uc7a5\ud569\ub2c8\ub2e4. \n\ucf54\ub529\ub41c \uccad\ud06c\uc758 \uc218\ub294 \ub370\uc774\ud130 \uc190\uc2e4\uc5c6\uc774 \uc791\ub3d9\uc911\uc9c0 \ub418\uc5b4 \uc9c8 \uc218\uc788\ub294 OSD\uc758 \uc22b\uc790\uc774\uae30\ub3c4\ud569\ub2c8\ub2e4.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Jerasure \ud50c\ub7ec\uadf8\uc778\uc740 \uac00\uc7a5 \uc77c\ubc18\uc801\uc774\uace0 \uc720\uc5f0\ud55c \ud50c\ub7ec\uadf8\uc778\uc73c\ub85c,\n\ub610\ud55c Ceph erasure \ucf54\ub4dc \ud480\uc758 \uae30\ubcf8\uac12\uc774\uae30\ub3c4\ud569\ub2c8\ub2e4.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n \ubcf4\ub2e4 \uc720\uc5f0\ud55c \uae30\uc220\uc740 reed_sol_van\uc785\ub2c8\ub2e4 : k\uc640 m\uc744 \uc124\uc815\ud558\uba74 \ucda9\ubd84\ud569\ub2c8\ub2e4. \ncauchy_good \uae30\uc220\uc740 \ube60\ub97c \uc218 \uc788\uc9c0\ub9cc \ud328\ud0b7\ud06c\uae30\ub97c \uc8fc\uc758\uae4a\uac8c \uc120\ud0dd\ud574\uc57c\ud569\ub2c8\ub2e4. \nreed_sol_r6_op, liberation, blaum_roth, liber8tion\uc740 \ubaa8\ub450 m = 2\ub85c\ub9cc \uad6c\uc131 \ud560 \uc218 \uc788\ub2e4\ub294 \uc810\uc5d0\uc11c RAID-6\uc5d0 \ud574\ub2f9\ud569\ub2c8\ub2e4.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n \uc778\ucf54\ub529\uc740 \ud55c\ubc88\uc5d0 \ubc14\uc774\ud2b8\ub4e4 \ud06c\uae30\uc758 \ud328\ud0b7\uc5d0 \ub300\ud574 \uc218\ud589\ub429\ub2c8\ub2e4. \uc62c\ubc14\ub978 \ud328\ud0b7 \ud06c\uae30\ub97c \uc120\ud0dd\ud558\ub294 \uac83\uc740 \uc5b4\ub835\uc2b5\ub2c8\ub2e4. jerasure \ubb38\uc11c\uc5d0\ub294\uc774 \uc8fc\uc81c\uc5d0 \ub300\ud55c \uad11\ubc94\uc704\ud55c \uc815\ubcf4\uac00 \ub4e4\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n jerasure \ud50c\ub7ec\uadf8\uc778\uc744 \uc0ac\uc6a9\ud558\uba74 \uc0ad\uc81c \ub41c \ucf54\ub529 \ub41c \uac1d\uccb4\uac00 \uc5ec\ub7ec OSD\uc5d0 \uc800\uc7a5 \ub420 \ub54c \ud558\ub098\uc758 OSD\uac00 \uc190\uc2e4\ub418\ub294 \uac83\uc744 \ubcf5\uad6c\ud558\ub824\uba74 \ub2e4\ub978 \ubaa8\ub4e0 OSD\ub97c \uc77d\uc5b4\uc57c\ud569\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4 jerasure\uac00 k = 8 \ubc0f m = 4\ub85c \uad6c\uc131\ub418\uc5b4\uc788\ub294 \uacbd\uc6b0 \ud558\ub098\uc758 OSD\ub97c \uc783\uc5b4 \ubc84\ub9ac\uba74 11 \uba85\uc758 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc218\ub9ac\ud574\uc57c\ud569\ub2c8\ub2e4.\nlrc erasure code plugin\uc740 \uc801\uc740 \uc591\uc758 OSD\ub97c \uc0ac\uc6a9\ud558\uc5ec \ubcf5\uad6c \ud560 \uc218 \uc788\ub3c4\ub85d \ub85c\uceec \ud328\ub9ac\ud2f0 \uccad\ud06c\ub97c \ub9cc\ub4ed\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4, lrc\uac00 k = 8, m = 4 \ubc0f l = 4\ub85c \uad6c\uc131\ub41c \uacbd\uc6b0 4 \uac1c\uc758 OSD\ub9c8\ub2e4 \ucd94\uac00 \ud328\ub9ac\ud2f0 \ub369\uc5b4\ub9ac\uac00 \uc0dd\uc131\ub429\ub2c8\ub2e4. \ub2e8\uc77c OSD\uac00 \uc190\uc2e4\ub418\uba74 11 \uac1c \ub300\uc2e0 4 \uac1c\uc758 OSD\ub9cc\uc73c\ub85c \ubcf5\uad6c \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n \ucf54\ub529 \ubc0f \ub370\uc774\ud130 \uccad\ud06c\ub97c \ud06c\uae30 \uc9c0\uc5ed \uc9d1\ud569\uc73c\ub85c \uadf8\ub8f9\ud654\ud569\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4, k = 4 \ubc0f m = 2\uc5d0 \ub300\ud574, \uc9c0\uc5ed\uc131 = 3 \uc77c \ub54c \ub450 \uac1c\uc758 \uc138 \uadf8\ub8f9\uc774 \uc0dd\uc131\ub429\ub2c8\ub2e4. \uac01 \uc138\ud2b8\ub294 \ub2e4\ub978 \uc138\ud2b8\uc758 \uccad\ud06c\ub97c \uc77d\uc9c0 \uc54a\uace0\ub3c4 \ubcf5\uad6c \ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n l\ub85c \uc815\uc758 \ub41c \uac01 \uccad\ud06c \uc9d1\ud569\uc774 \uc800\uc7a5\ub418\ub294 \ud06c\ub7ec\uc2dc \ubc84\ud0b7\uc758 \uc720\ud615\uc785\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4 \ub799\uc73c\ub85c \uc124\uc815\ud558\uba74 l \uac1c\uc758 \uccad\ud06c \uadf8\ub8f9\uc774 \uac01\uac01 \ub2e4\ub978 \ub799\uc5d0 \ubc30\uce58\ub429\ub2c8\ub2e4. \n\ub799 \uc120\ud0dd \ub2e8\uacc4\uc640 \uac19\uc740 CRUSH \uaddc\uce59 \ub2e8\uacc4\ub97c \ub9cc\ub4dc\ub294 \ub370 \uc0ac\uc6a9\ub429\ub2c8\ub2e4. \uc124\uc815\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc73c\uba74, \uadf8\ub7ec\ud55c \uadf8\ub8f9\ud654\uac00 \uc218\ud589\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n isa \ud50c\ub7ec\uadf8\uc778\uc740 ISA \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \ucea1\uc290\ud654\ud569\ub2c8\ub2e4. \uc778\ud154 \ud504\ub85c\uc138\uc11c\uc5d0\uc11c\ub9cc \uc2e4\ud589\ub429\ub2c8\ub2e4.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n ISA \ud50c\ub7ec\uadf8\uc778\uc740 \ub450 \uac1c\uc758 \ub9ac\ub4dc \uc194\ub85c\ubaac \ud615\uc2dd\uc73c\ub85c \uc81c\uacf5\ub429\ub2c8\ub2e4.\nreed_sol_van\uc774 \uc124\uc815\ub418\uba74 Vandermonde, cauchy\uac00 \uc124\uc815\ub418\uba74 Cauchy\uc785\ub2c8\ub2e4.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n shec plugin\uc740 \ub2e4\uc911 SHEC \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \ucea1\uc290\ud654\ud569\ub2c8\ub2e4.\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0 ceph\uac00 \ub9ac\ub4dc \uc194\ub85c\ubaac \ucf54\ub4dc\ubcf4\ub2e4 \ub354 \ud6a8\uc728\uc801\uc73c\ub85c \ub370\uc774\ud130\ub97c \ubcf5\uad6c \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n \uac01 \ub370\uc774\ud130 \uccad\ud06c\uac00 \uacc4\uc0b0 \ubc94\uc704\uc5d0 \ud3ec\ud568\ub418\ub294 \ud328\ub9ac\ud2f0 \uccad\ud06c\uc758 \uc218\uc785\ub2c8\ub2e4. \uc774 \uc218\uce58\ub294 \ub0b4\uad6c\uc131 \uce21\uc815\uae30\ub85c \uc0ac\uc6a9\ub429\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4, c = 2 \uc778 \uacbd\uc6b0 2 \uac1c\uc758 OSD\uac00 \ub370\uc774\ud130 \uc190\uc2e4\uc5c6\uc774 \uc911\ub2e8 \ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n CRUSH \uaddc\uce59\uc758 \uccab \ubc88\uc9f8 \ub2e8\uacc4\uc5d0 \uc0ac\uc6a9 \ub41c \ud06c\ub7ec\uc2dc \ubc84\ud0b7\uc758 \uc774\ub984\uc785\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4 step\uc740 \uae30\ubcf8\uac12\uc744 \ucde8\ud569\ub2c8\ub2e4.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n \ub3d9\uc77c\ud55c \uc2e4\ud328 \ub3c4\uba54\uc778\uc744 \uac00\uc9c4 \uc591\ub3d9\uc774\uc5d0 \ub450 \uac1c\uc758 \uccad\ud06c\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud558\uc2ed\uc2dc\uc624. \uc608\ub97c \ub4e4\uc5b4 \uc2e4\ud328 \ub3c4\uba54\uc778\uc774 \ud638\uc2a4\ud2b8 \uc778 \uacbd\uc6b0 \ub450 \uac1c\uc758 \uccad\ud06c\uac00 \ub3d9\uc77c\ud55c \ud638\uc2a4\ud2b8\uc5d0 \uc800\uc7a5\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc774 \ub2e8\uacc4\ub294 \ub9ac\ud504 \ud638\uc2a4\ud2b8\ub97c \uc120\ud0dd\ud558\ub294 \ub2e8\uacc4\uc640 \uac19\uc740 CRUSH \uaddc\uce59 \ub2e8\uacc4\ub97c \ub9cc\ub4dc\ub294 \ub370 \uc0ac\uc6a9\ub429\ub2c8\ub2e4.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n CRUSH\uc9c0\ub3c4\uc5d0\uc11c \ud06c\ub798\uc2dc \uc7a5\uce58 \ud074\ub798\uc2a4 \uc774\ub984\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud2b9\uc815 \ud074\ub798\uc2a4 (\uc608 : ssd \ub610\ub294 hdd)\uc758 \uc7a5\uce58\ub85c \ubc30\uce58\ub97c \uc81c\ud55c\ud569\ub2c8\ub2e4.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n \uc0ad\uc81c \ucf54\ub4dc \ud50c\ub7ec\uadf8\uc778\uc774\ub85c\ub4dc\ub418\ub294 \ub514\ub809\ud1a0\ub9ac \uc774\ub984\uc744 \uc124\uc815\ud558\uc2ed\uc2dc\uc624.\n \n \n Allows all operations\n \ubaa8\ub4e0 \uc791\uc5c5\ub4e4 \ud5c8\uc6a9\n \n \n Allows only operations that do not modify the server\n \uc624\uc9c1 \uc11c\ubc84\ub97c \uc218\uc815\ud558\uc9c0 \uc54a\ub294 \uc791\uc5c5\ub4e4\ub9cc \uac00\ub2a5\ud569\ub2c8\ub2e4.\n \n \n Does not allow read or write operations, but allows any other operation\n \uc77d\uae30\uc640 \uc4f0\uae30 \uc791\uc5c5\uc740 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc9c0\ub9cc, \uadf8\uc678 \ubaa8\ub4e0 \uc791\uc5c5\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4.\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n \ud30c\uc77c\uc758 \uc18d\uc131\uacfc \ub514\ub809\ud1a0\ub9ac \ub0b4\uc6a9\uc744 \ubcc0\uacbd\ud558\ub294 \uc77d\uae30, \uc4f0\uae30 \ub610\ub294 \uc5b4\ub5a0\ud55c \uc791\uc5c5\uc740 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n Allows no access at all\n \uc804\ud600 \uc5b4\ub5a0\ud55c \uc811\uadfc\ub3c4 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n \n \n -- Select the priority --\n -- \uc6b0\uc120\uc21c\uc704 \uc120\ud0dd --\n \n \n Low\n \ub0ae\uc74c\n \n \n High\n \ub192\uc74c\n \n \n Last 5 minutes\n \ub9c8\uc9c0\ub9c9 5\ubd84\n \n \n Last 15 minutes\n \uc9c0\ub09c 15\ubd84\n \n \n Last 30 minutes\n \uc9c0\ub09c 30\ubd84\n \n \n Last 1 hour (Default)\n \uc9c0\ub09c 1\uc2dc\uac04(\uae30\ubcf8)\n \n \n Last 3 hours\n \uc9c0\ub09c 3\uc2dc\uac04\n \n \n Last 6 hours\n \uc9c0\ub09c 6\uc2dc\uac04\n \n \n Last 12 hours\n \uc9c0\ub09c 12\uc2dc\uac04\n \n \n Last 24 hours\n \uc9c0\ub09c 24\uc2dc\uac04\n \n \n Yesterday\n \uc5b4\uc81c\n \n \n Today\n \uc624\ub298\n \n \n Today so far\n \uc624\ub298 \uc9c0\uae08\uae4c\uc9c0\n \n \n Day before yesterday\n \uadf8\uc800\uaed8\n \n \n Last 2 days\n \uc9c0\ub09c 2\uc77c\n \n \n This day last week\n \uc774\ubc88 \uc8fc \ub9c8\uc9c0\ub9c9\ub0a0\n \n \n Previous week\n \uc804\uc8fc\n \n \n This week\n \uc774\ubc88\uc8fc\n \n \n This week so far\n \uc774\ubc88\uc8fc \uc9c0\uae08\uae4c\uc9c0\n \n \n Last 7 days\n \uc9c0\ub09c 7\uc77c\n \n \n Previous month\n \uc9c0\ub09c \ub2ec\n \n \n This month\n \uc774\ubc88 \ub2ec\n \n \n This month so far\n \uc774\ubc88 \ub2ec \uc9c0\uae08\uae4c\uc9c0\n \n \n Last 30 days\n \uc9c0\ub09c 30\uc77c\n \n \n Last 90 days\n \uc9c0\ub09c 90\uc77c\n \n \n Last 6 months\n \uc9c0\ub09c 6\uac1c\uc6d4\n \n \n Last 1 year\n \uc9c0\ub09c 1\ub144\n \n \n Previous year\n \uc804\ub144\ub3c4\n \n \n This year\n \uae08\ub144\ub3c4\n \n \n This year so far\n \uae08\ub144 \uc9c0\uae08\uae4c\uc9c0\n \n \n Last 2 years\n \uc9c0\ub09c 2\ub144\n \n \n Last 5 years\n \uc9c0\ub09c 5\ub144\n \n \n Information\n \uc815\ubcf4\n \n \n No items selected.\n \uc120\ud0dd\ub41c \uc544\uc774\ud15c \uc5c6\uc74c\n \n \n Deselect item to select again\n \ub2e4\uc2dc \uc120\ud0dd\ud558\uae30 \uc704\ud574 \uc544\uc774\ud15c \uc120\ud0dd\uc744 \ucde8\uc18c\n \n \n Selection limit reached\n \uc120\ud0dd \ud55c\uacc4\uc5d0 \ub3c4\ub2ec\ud568\n \n \n Filter tags\n \ud544\ud130 \ud14c\uadf8\ub4e4\n \n \n Add badge\n \ubca0\ucc0c \ucd94\uac00\n \n \n There are no items available.\n \uc0ac\uc6a9\uac00\ub2a5\ud55c \uc544\uc774\ud15c \uc5c6\uc74c\n \n \n Add\n \ucd94\uac00\n \n \n Remove\n Remove\n \n \n Clone\n \ubcf5\uc81c\n \n \n Copy\n \ubcf5\uc0ac\n \n \n Deep Scrub\n \ub525 \uc2a4\ud06c\ub7fd\n \n \n Destroy\n \ud30c\uad34\ub428\n \n \n Flatten\n \ub2e8\uc870\ub85c\uc6c0\n \n \n Mark Down\n \ub2e4\uc6b4 \ud45c\uc2dc\n \n \n Mark In\n \uc778 \ud45c\uc2dc\n \n \n Mark Lost\n \uc190\uc2e4 \ud45c\uc2dc\n \n \n Mark Out\n \uc544\uc6c3 \ud45c\uc2dc\n \n \n Protect\n \ubcf4\ud638\n \n \n Rename\n \uc774\ub984\ubcc0\uacbd\n \n \n Restore\n \ubcf5\uad6c\n \n \n Move to Trash\n \ud734\uc9c0\ud1b5\uc73c\ub85c \uc62e\uae30\uae30\n \n \n Unprotect\n \ubcf4\ud638\uc54a\ub428\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n \uc0ad\uc81c\ub3d4\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n \ubcf5\uc81c\ub41c\n \n \n Copied\n \ubcf5\uc0ac\ub41c\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n \uc608\n \n \n No\n \uc544\ub2c8\uc624\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n \uc11c\ube44\uc2a4 \ub7c9\n \n \n BPS Limit\n BPS \ud55c\uacc4\n \n \n The desired limit of IO bytes per second.\n \uc6d0\ud558\ub294 \ucd08\ub2f9 IO \ubc14\uc774\ud2b8 \uc218 \uc81c\ud55c\uc785\ub2c8\ub2e4.\n \n \n IOPS Limit\n IOPS \uc81c\ud55c\n \n \n The desired limit of IO operations per second.\n \uc6d0\ud558\ub294 \ucd08\ub2f9 IO \uc791\uc5c5 \uc81c\ud55c\uc785\ub2c8\ub2e4.\n \n \n Read BPS Limit\n \uc77d\uae30 BPS \uc81c\ud55c\n \n \n The desired limit of read bytes per second.\n \uc6d0\ud558\ub294 \ucd08\ub2f9 \uc77d\uae30 \ubc14\uc774\uc2a4 \uc218 \uc81c\ud55c\uc785\ub2c8\ub2e4.\n \n \n Read IOPS Limit\n \uc77d\uae30 IOPS \ud55c\ub3c4\n \n \n The desired limit of read operations per second.\n \uc6d0\ud558\ub294 \ucd08\ub2f9 \uc77d\uae30 \uc791\uc5c5 \uc81c\ud55c\uc785\ub2c8\ub2e4.\n \n \n Write BPS Limit\n \uc4f0\uae30 BPS \ud55c\ub3c4\n \n \n The desired limit of write bytes per second.\n \uc6d0\ud558\ub294 \ucd08\ub2f9 \uc4f0\uae30 \ubc14\uc774\ud2b8 \uc218 \uc81c\ud55c\uc785\ub2c8\ub2e4.\n \n \n Write IOPS Limit\n \uc4f0\uae30 IOPS \uc81c\ud55c\n \n \n The desired limit of write operations per second.\n \uc6d0\ud558\ub294 \ucd08\ub2f9 \uc4f0\uae30 \uc791\uc5c5 \uc81c\ud55c\uc785\ub2c8\ub2e4.\n \n \n BPS Burst\n BPS \ubc84\uc2a4\ud2b8\n \n \n The desired burst limit of IO bytes.\n \uc6d0\ud558\ub294 \ubc84\uc2a4\ud2b8 IO \ubc14\uc774\ud2b8 \ud55c\ub3c4 \uc785\ub2c8\ub2e4.\n \n \n IOPS Burst\n IOPS \ubc84\uc2a4\ud2b8\n \n \n The desired burst limit of IO operations.\n \uc6d0\ud558\ub294 IO \uc791\uc5c5\uc758 \ubc84\uc2a4\ud2b8 \ud55c\uacc4\uc785\ub2c8\ub2e4.\n \n \n Read BPS Burst\n \uc77d\uae30 BPS \ubc84\uc2a4\ud2b8\n \n \n The desired burst limit of read bytes.\n \uc6d0\ud558\ub294 \uc77d\uae30 \ubc84\uc2a4\ud2b8 \ud55c\uacc4\uc785\ub2c8\ub2e4.\n \n \n Read IOPS Burst\n \uc77d\uae30 IOPS \ubc84\uc2a4\ud2b8\n \n \n The desired burst limit of read operations.\n \uc6d0\ud558\ub294 \uc77d\uae30 \uc791\uc5c5\uc758 \ubc84\uc2a4\ud2b8 \ud55c\ub3c4\uc785\ub2c8\ub2e4.\n \n \n Write BPS Burst\n \uc4f0\uae30 BPS \ubc84\uc2a4\ud2b8\n \n \n The desired burst limit of write bytes.\n \uc4f0\uae30 \ubc14\uc774\ud2b8\uc758 \uc6d0\ud558\ub294 \ubc84\uc2a4\ud2b8 \ud55c\ub3c4.\n \n \n Write IOPS Burst\n \uc4f0\uae30 IOPS \ubc84\uc2a4\ud2b8\n \n \n The desired burst limit of write operations.\n \uc4f0\uae30 \ubc14\uc774\ud2b8\uc758 \uc6d0\ud558\ub294 \ubc84\uc2a4\ud2b8 \ud55c\ub3c4.\n \n \n Failed to \n \n \n \n \n \n \uc758 \uc2e4\ud3d0\n \n \n \n Executing\n \uc218\ud589\uc911\n \n \n execute\n \uc218\ud589\n \n \n Executed\n \uc218\ud589\ub41c\n \n \n unknown task\n \uc54c\ub824\uc9c0\uc9c0 \uc54a\ub294 \uc791\uc5c5\n \n \n Creating\n \uc0dd\uc131\ud558\ub294 \uc911\n \n \n create\n \uc0dd\uc131\n \n \n Updating\n \uac31\uc2e0 \uc911\n \n \n update\n \uac31\uc2e0\n \n \n Deleting\n \uc0ad\uc81c \uc911\n \n \n delete\n \uc0ad\uc81c\n \n \n RBD \'\n \'\n \n RBD \'\n \'\n \n \n \n RBD snapshot \'\n \'\n \n RBD \uc2a4\ub0c5\uc0bf \'\n \'\n \n \n \n mirror mode for pool \'\n \'\n \n \ud480 \'\n \' \uc744 \uc704\ud55c \ubbf8\ub7ec\ubaa8\ub4dc\n \n \n \n mirror peer for pool \'\n \'\n \n \ud480 \'\n \' \ubbf8\ub7ec \uc0c1\ub300\ubc29\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n \uc774\ub984\uc740 \n \uc5d0 \uc758\ud558\uc5ec \uc774\ubbf8 \uc0ac\uc6a9\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n \n \n \n Name is already used by \n .\n \n \uc774\ub984\uc740 \n \uc5d0 \uc758\ud558\uc5ec \uc774\ubbf8 \uc0ac\uc6a9\uc911\uc785\ub2c8\ub2e4.\n \n \n \n Name is already used by \n .\n \n \uc774\ub984\uc774 \n \uc5d0 \uc758\ud558\uc5ec \uc774\ubbf8 \uc0ac\uc6a9\uc911\uc785\ub2c8\ub2e4.\n \n \n \n \n contains snapshots.\n \n \n \uc774 \ud3ec\ud568\ub41c \uc2a4\ub0c5\uc0bf\ub4e4.\n \n \n \n Cloning\n \ubcf5\uc81c\uc911\n \n \n clone\n \ubcf5\uc81c\n \n \n Snapshot of \n must be protected.\n \n \ubc18\ub4dc\uc2dc\n \uc758 \uc2a4\ub0c5\uc0bf\uc740 \ubcf4\ud638\ub418\uc5b4\uc57c \ud569\ub2c8\ub2e4.\n \n \n \n Copying\n \ubcf5\uc0ac\uc911\n \n \n copy\n \ubcf5\uc0ac\n \n \n Flattening\n \ud3c9\ud3c9\ud558\uac8c \ud558\ub294 \uc911\n \n \n flatten\n \ud3c9\ud3c9\ud568\n \n \n Flattened\n \ud3c9\ud3c9\ud558\uac8c \ub428\n \n \n Name is already used by \n .\n \n \uc774\ub984\uc774 \n \uc5d0 \uc758\ud558\uc5ec \uc774\ubbf8 \uc0ac\uc6a9 \uc911.\n \n \n \n Cannot unprotect \n because it contains child images.\n \n \n \uc744 \ubcf4\ud638\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc65c\ub0d0\ud558\uba74 \uadf8\uac83\uc740 \uc790\uc2dd \uc774\ubbf8\uc9c0\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4,\n \n \n \n Cannot delete \n because it\'s protected.\n \n \n \uc744 \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc65c\ub0d0\ud558\uba74 \uadf8\uac83\uc740 \ubcf4\ud638\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.\n \n \n \n Rolling back\n \ub864\ubc31 \uc911\n \n \n rollback\n \ub864\ubc31\n \n \n Rolled back\n \ub864\ubc31\ub428\n \n \n Moving\n \uc62e\uae30\ub294 \uc911\n \n \n move\n \uc62e\uae30\uae30\n \n \n Moved\n \uc62e\uaca8\uc9d0\n \n \n image \'\n \' to trash\n \n \uc774\ubbf8\uc9c0 \'\n \' \ubc84\ub9ac\uae30\n \n \n \n Could not find image.\n \uc774\ubbf8\uc9c0\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n Restoring\n \ubcf5\uad6c\uc911\n \n \n restore\n \ubcf5\uad6c\n \n \n Restored\n \ubcf5\uad6c\ub428\n \n \n image \'\n \' into \'\n \'\n \n \uc774\ubbf8\uc9c0 \'\n \' \uc744 \'\n \' \ub85c\n \n \n \n Image name \'\n \' is already in use.\n \n \uc774\ubbf8\uc9c0 \uc774\ub984 \'\n \' \uc774 \uc774\ubbf8 \uc0ac\uc6a9\uc911\uc785\ub2c8\ub2e4.\n \n \n \n image \'\n \'\n \n \uc774\ubbf8\uc9c0 \'\n \'\n \n \n \n Purging\n \uc644\uc804\uc0ad\uc81c \uc911\n \n \n purge\n \uc644\uc804\uc0ad\uc81c\n \n \n Purged\n \uc644\uc804\uc0ad\uc81c\ub428\n \n \n all pools\n \ubaa8\ub4e0 \ud480\ub4e4\n \n \n images from \n \n \n \n \ub85c \ubd80\ud130\uc758 \uc774\ubbf8\uc9c0\ub4e4\n \n \n \n Cannot disable mirroring because it contains a peer.\n \ud53c\uc5b4\uac00 \ud3ec\ud568\ub418\uc5b4 \uc788\uae30 \ub54c\ubb38\uc5d0 \ubbf8\ub7ec\ub9c1\uc744 \ube44\ud65c\uc131\ud654 \ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \n \n pool \'\n \'\n \n \ud480 \'\n \'\n \n \n \n erasure code profile \'\n \'\n \n Erasure \ucf54\ub4dc \ud504\ub85c\ud30c\uc77c \'\n \'\n \n \n \n target \'\n \'\n \n \ud0c0\uae43 \'\n \'\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},QC43:function(t,e,n){"use strict";var a=n("CcnG"),r=n("MdoF"),i=n("lTVp");n("XFyV"),n.d(e,"a",function(){return s}),n.d(e,"b",function(){return o});var s=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"alert",[["type","info"]],null,null,null,r.c,r.b)),a["\u0275did"](1,114688,null,0,i.a,[i.b,a.ChangeDetectorRef],{type:[0,"type"]},null),(t()(),a["\u0275eld"](2,0,null,0,1,"strong",[],null,null,null,null,null)),(t()(),a["\u0275eld"](3,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-spinner fa-spin fa-fw"]],null,null,null,null,null)),a["\u0275ncd"](0,0)],function(t,e){t(e,1,0,"info")},null)}},QFaf:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("mrSG"),r=function(t){function e(e,n,a){var r=t.call(this,e,n,a)||this;return r.controls=e,r}return a.__extends(e,t),e.prototype.get=function(t){var e=this._get(t);if(!e)throw new Error("Control '"+t+"' could not be found!");return e},e.prototype._get=function(n){return t.prototype.get.call(this,n)||Object.values(this.controls).filter(function(t){return t.get}).map(function(t){return t instanceof e?t._get(n):t.get(n)}).find(function(t){return Boolean(t)})},e.prototype.getValue=function(t){return this.get(t).value},e.prototype.silentSet=function(t,e){this.get(t).setValue(e,{emitEvent:!1})},e.prototype.showError=function(t,e,n){var a=this.get(t);return(e.submitted||a.dirty)&&(n?a.hasError(n):a.invalid)},e}(n("gIcY").k)},QG5k:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.NodeMenuItemAction=function(t){return t[t.NewFolder=0]="NewFolder",t[t.NewTag=1]="NewTag",t[t.Rename=2]="Rename",t[t.Remove=3]="Remove",t[t.Custom=4]="Custom",t}(e.NodeMenuItemAction||{}),e.NodeMenuAction=function(t){return t[t.Close=0]="Close",t}(e.NodeMenuAction||{})},QGcS:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.NodeDraggableEvent=function(){return function(t,e){this.captured=t,this.target=e}}()},QHrR:function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("Y0Co")),a(n("Lwhh")),a(n("8iEZ")),a(n("L5sC"))},QTAa:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("mrSG"),r=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return a.__extends(e,t),e}(n("t/zF").a)},Qexa:function(t,e,n){"use strict";t.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},Qgas:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("dC0D"),r=n("AxiF"),i=n("HJBe"),s=n("y3By");function o(t,e){return arguments.length>=2?function(n){return Object(s.a)(Object(a.a)(t,e),Object(r.a)(1),Object(i.a)(e))(n)}:function(e){return Object(s.a)(Object(a.a)(function(e,n,a){return t(e,n,a+1)}),Object(r.a)(1))(e)}}},Qj4J:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("ar-kw",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648\u0632_\u063a\u0634\u062a_\u0634\u062a\u0646\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0646\u0628\u0631_\u062f\u062c\u0646\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062a\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062a\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:0,doy:12}})}()},"R+r5":function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("Qgas");function r(t,e,n){return 0===n?[e]:(t.push(e),t)}function i(){return Object(a.a)(r,[])}},RAwQ:function(t,e,n){!function(t){"use strict";function e(t,e,n,a){var r={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return e?r[n][0]:r[n][1]}function a(t){if(t=parseInt(t,10),isNaN(t))return!1;if(t<0)return!0;if(t<10)return 4<=t&&t<=7;if(t<100){var e=t%10;return a(0===e?t/10:e)}if(t<1e4){for(;t>=10;)t/=10;return a(t)}return a(t/=1e3)}n("wd/R").defineLocale("lb",{months:"Januar_Februar_M\xe4erz_Abr\xebll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonndeg_M\xe9indeg_D\xebnschdeg_M\xebttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._M\xe9._D\xeb._M\xeb._Do._Fr._Sa.".split("_"),weekdaysMin:"So_M\xe9_D\xeb_M\xeb_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[G\xebschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:function(t){return a(t.substr(0,t.indexOf(" ")))?"a "+t:"an "+t},past:function(t){return a(t.substr(0,t.indexOf(" ")))?"viru "+t:"virun "+t},s:"e puer Sekonnen",ss:"%d Sekonnen",m:e,mm:"%d Minutten",h:e,hh:"%d Stonnen",d:e,dd:"%d Deeg",M:e,MM:"%d M\xe9int",y:e,yy:"%d Joer"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},RCHg:function(t,e,n){"use strict";var a=n("wd/R");a="function"==typeof a?a:window.moment;var r=n("CDJp"),i=n("RDha"),s=n("cdu6"),o=n("tjFV"),u=Number.MIN_SAFE_INTEGER||-9007199254740991,c=Number.MAX_SAFE_INTEGER||9007199254740991,l={millisecond:{common:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{common:!0,size:1e3,steps:[1,2,5,10,15,30]},minute:{common:!0,size:6e4,steps:[1,2,5,10,15,30]},hour:{common:!0,size:36e5,steps:[1,2,3,6,12]},day:{common:!0,size:864e5,steps:[1,2,5]},week:{common:!1,size:6048e5,steps:[1,2,3,4]},month:{common:!0,size:2628e6,steps:[1,2,3]},quarter:{common:!1,size:7884e6,steps:[1,2,3,4]},year:{common:!0,size:3154e7}},d=Object.keys(l);function f(t,e){return t-e}function p(t){var e,n,a,r={},i=[];for(e=0,n=t.length;e=0&&s<=o;){if(i=t[a=s+o>>1],!(r=t[a-1]||null))return{lo:null,hi:i};if(i[e]n))return{lo:r,hi:i};o=a-1}}return{lo:i,hi:null}}(t,e,n),i=r.lo?r.hi?r.lo:t[t.length-2]:t[0],s=r.lo?r.hi?r.hi:t[t.length-1]:t[1],o=s[e]-i[e];return i[a]+(s[a]-i[a])*(o?(n-i[e])/o:0)}function g(t,e){var n=e.parser,r=e.parser||e.format;return"function"==typeof n?n(t):"string"==typeof t&&"string"==typeof r?a(t,r):(t instanceof a||(t=a(t)),t.isValid()?t:"function"==typeof r?r(t):t)}function b(t,e){if(i.isNullOrUndef(t))return null;var n=e.options.time,a=g(e.getRightValue(t),n);return a.isValid()?(n.round&&a.startOf(n.round),a.valueOf()):null}function m(t){for(var e=d.indexOf(t)+1,n=d.length;e=s&&n<=o&&y.push(n);return r.min=s,r.max=o,r._unit=f.unit||function(t,e,n,i){var s,o,u=a.duration(a(r.max).diff(a(n)));for(s=d.length-1;s>=d.indexOf(e);s--)if(l[o=d[s]].common&&u.as(o)>=t.length)return o;return d[e?d.indexOf(e):0]}(y,f.minUnit,r.min),r._majorUnit=m(r._unit),r._table=function(t,e,n,a){if("linear"===u.distribution||!t.length)return[{time:e,pos:0},{time:n,pos:1}];var r,i,s,o,c,l=[],d=[e];for(r=0,i=t.length;re&&o1?e[1]:a,"pos")-h(t,"time",i,"pos"))/2),r.time.max||(i=e.length>1?e[e.length-2]:n,o=(h(t,"time",e[e.length-1],"pos")-h(t,"time",i,"pos"))/2)),{left:s,right:o}}(r._table,y,s,o,u),r._labelFormat=function(t,e){var n,a,r,i=t.length;for(n=0;n=0&&t0?o:1}});o.registerScaleType("time",t,{position:"bottom",distribution:"linear",bounds:"data",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}})}},RDha:function(t,e,n){"use strict";t.exports=n("TC34"),t.exports.easing=n("u0Op"),t.exports.canvas=n("Sfow"),t.exports.options=n("As3K")},RnPR:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Keys=function(t){return t[t.up=38]="up",t[t.down=40]="down",t[t.return=13]="return",t[t.escape=27]="escape",t[t.left=37]="left",t[t.right=39]="right",t}(e.Keys||{})},RnhZ:function(t,e,n){var a={"./af":"K/tc","./af.js":"K/tc","./ar":"jnO4","./ar-dz":"o1bE","./ar-dz.js":"o1bE","./ar-kw":"Qj4J","./ar-kw.js":"Qj4J","./ar-ly":"HP3h","./ar-ly.js":"HP3h","./ar-ma":"CoRJ","./ar-ma.js":"CoRJ","./ar-sa":"gjCT","./ar-sa.js":"gjCT","./ar-tn":"bYM6","./ar-tn.js":"bYM6","./ar.js":"jnO4","./az":"SFxW","./az.js":"SFxW","./be":"H8ED","./be.js":"H8ED","./bg":"hKrs","./bg.js":"hKrs","./bm":"p/rL","./bm.js":"p/rL","./bn":"kEOa","./bn.js":"kEOa","./bo":"0mo+","./bo.js":"0mo+","./br":"aIdf","./br.js":"aIdf","./bs":"JVSJ","./bs.js":"JVSJ","./ca":"1xZ4","./ca.js":"1xZ4","./cs":"PA2r","./cs.js":"PA2r","./cv":"A+xa","./cv.js":"A+xa","./cy":"l5ep","./cy.js":"l5ep","./da":"DxQv","./da.js":"DxQv","./de":"tGlX","./de-at":"s+uk","./de-at.js":"s+uk","./de-ch":"u3GI","./de-ch.js":"u3GI","./de.js":"tGlX","./dv":"WYrj","./dv.js":"WYrj","./el":"jUeY","./el.js":"jUeY","./en-SG":"zavE","./en-SG.js":"zavE","./en-au":"Dmvi","./en-au.js":"Dmvi","./en-ca":"OIYi","./en-ca.js":"OIYi","./en-gb":"Oaa7","./en-gb.js":"Oaa7","./en-ie":"4dOw","./en-ie.js":"4dOw","./en-il":"czMo","./en-il.js":"czMo","./en-nz":"b1Dy","./en-nz.js":"b1Dy","./eo":"Zduo","./eo.js":"Zduo","./es":"iYuL","./es-do":"CjzT","./es-do.js":"CjzT","./es-us":"Vclq","./es-us.js":"Vclq","./es.js":"iYuL","./et":"7BjC","./et.js":"7BjC","./eu":"D/JM","./eu.js":"D/JM","./fa":"jfSC","./fa.js":"jfSC","./fi":"gekB","./fi.js":"gekB","./fo":"ByF4","./fo.js":"ByF4","./fr":"nyYc","./fr-ca":"2fjn","./fr-ca.js":"2fjn","./fr-ch":"Dkky","./fr-ch.js":"Dkky","./fr.js":"nyYc","./fy":"cRix","./fy.js":"cRix","./ga":"USCx","./ga.js":"USCx","./gd":"9rRi","./gd.js":"9rRi","./gl":"iEDd","./gl.js":"iEDd","./gom-latn":"DKr+","./gom-latn.js":"DKr+","./gu":"4MV3","./gu.js":"4MV3","./he":"x6pH","./he.js":"x6pH","./hi":"3E1r","./hi.js":"3E1r","./hr":"S6ln","./hr.js":"S6ln","./hu":"WxRl","./hu.js":"WxRl","./hy-am":"1rYy","./hy-am.js":"1rYy","./id":"UDhR","./id.js":"UDhR","./is":"BVg3","./is.js":"BVg3","./it":"bpih","./it-ch":"bxKX","./it-ch.js":"bxKX","./it.js":"bpih","./ja":"B55N","./ja.js":"B55N","./jv":"tUCv","./jv.js":"tUCv","./ka":"IBtZ","./ka.js":"IBtZ","./kk":"bXm7","./kk.js":"bXm7","./km":"6B0Y","./km.js":"6B0Y","./kn":"PpIw","./kn.js":"PpIw","./ko":"Ivi+","./ko.js":"Ivi+","./ku":"JCF/","./ku.js":"JCF/","./ky":"lgnt","./ky.js":"lgnt","./lb":"RAwQ","./lb.js":"RAwQ","./lo":"sp3z","./lo.js":"sp3z","./lt":"JvlW","./lt.js":"JvlW","./lv":"uXwI","./lv.js":"uXwI","./me":"KTz0","./me.js":"KTz0","./mi":"aIsn","./mi.js":"aIsn","./mk":"aQkU","./mk.js":"aQkU","./ml":"AvvY","./ml.js":"AvvY","./mn":"lYtQ","./mn.js":"lYtQ","./mr":"Ob0Z","./mr.js":"Ob0Z","./ms":"6+QB","./ms-my":"ZAMP","./ms-my.js":"ZAMP","./ms.js":"6+QB","./mt":"G0Uy","./mt.js":"G0Uy","./my":"honF","./my.js":"honF","./nb":"bOMt","./nb.js":"bOMt","./ne":"OjkT","./ne.js":"OjkT","./nl":"+s0g","./nl-be":"2ykv","./nl-be.js":"2ykv","./nl.js":"+s0g","./nn":"uEye","./nn.js":"uEye","./pa-in":"8/+R","./pa-in.js":"8/+R","./pl":"jVdC","./pl.js":"jVdC","./pt":"8mBD","./pt-br":"0tRk","./pt-br.js":"0tRk","./pt.js":"8mBD","./ro":"lyxo","./ro.js":"lyxo","./ru":"lXzo","./ru.js":"lXzo","./sd":"Z4QM","./sd.js":"Z4QM","./se":"//9w","./se.js":"//9w","./si":"7aV9","./si.js":"7aV9","./sk":"e+ae","./sk.js":"e+ae","./sl":"gVVK","./sl.js":"gVVK","./sq":"yPMs","./sq.js":"yPMs","./sr":"zx6S","./sr-cyrl":"E+lV","./sr-cyrl.js":"E+lV","./sr.js":"zx6S","./ss":"Ur1D","./ss.js":"Ur1D","./sv":"X709","./sv.js":"X709","./sw":"dNwA","./sw.js":"dNwA","./ta":"PeUW","./ta.js":"PeUW","./te":"XLvN","./te.js":"XLvN","./tet":"V2x9","./tet.js":"V2x9","./tg":"Oxv6","./tg.js":"Oxv6","./th":"EOgW","./th.js":"EOgW","./tl-ph":"Dzi0","./tl-ph.js":"Dzi0","./tlh":"z3Vd","./tlh.js":"z3Vd","./tr":"DoHr","./tr.js":"DoHr","./tzl":"z1FC","./tzl.js":"z1FC","./tzm":"wQk9","./tzm-latn":"tT3J","./tzm-latn.js":"tT3J","./tzm.js":"wQk9","./ug-cn":"YRex","./ug-cn.js":"YRex","./uk":"raLr","./uk.js":"raLr","./ur":"UpQW","./ur.js":"UpQW","./uz":"Loxo","./uz-latn":"AQ68","./uz-latn.js":"AQ68","./uz.js":"Loxo","./vi":"KSF8","./vi.js":"KSF8","./x-pseudo":"/X5v","./x-pseudo.js":"/X5v","./yo":"fzPg","./yo.js":"fzPg","./zh-cn":"XDpg","./zh-cn.js":"XDpg","./zh-hk":"SatO","./zh-hk.js":"SatO","./zh-tw":"kOpN","./zh-tw.js":"kOpN"};function r(t){var e=i(t);return n(e)}function i(t){var e=a[t];if(!(e+1)){var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}return e}r.keys=function(){return Object.keys(a)},r.resolve=i,t.exports=r,r.id="RnhZ"},S1nX:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("xlPZ"),r=n("yGWI"),i=n("K9Ia");function s(){return new i.a}function o(){return function(t){return Object(r.a)()(Object(a.a)(s)(t))}}},"S3/U":function(t,e,n){"use strict";t.exports=function(t){t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},S5bw:function(t,e,n){"use strict";n.d(e,"a",function(){return l});var a=n("mrSG"),r=n("K9Ia"),i=n("zo3G"),s=n("pugT"),o=n("mZXl"),u=n("8g8A"),c=n("uMaO"),l=function(t){function e(e,n,a){void 0===e&&(e=Number.POSITIVE_INFINITY),void 0===n&&(n=Number.POSITIVE_INFINITY);var r=t.call(this)||this;return r.scheduler=a,r._events=[],r._infiniteTimeWindow=!1,r._bufferSize=e<1?1:e,r._windowTime=n<1?1:n,n===Number.POSITIVE_INFINITY?(r._infiniteTimeWindow=!0,r.next=r.nextInfiniteTimeWindow):r.next=r.nextTimeWindow,r}return a.__extends(e,t),e.prototype.nextInfiniteTimeWindow=function(e){var n=this._events;n.push(e),n.length>this._bufferSize&&n.shift(),t.prototype.next.call(this,e)},e.prototype.nextTimeWindow=function(e){this._events.push(new d(this._getNow(),e)),this._trimBufferThenGetEvents(),t.prototype.next.call(this,e)},e.prototype._subscribe=function(t){var e,n=this._infiniteTimeWindow,a=n?this._events:this._trimBufferThenGetEvents(),r=this.scheduler,i=a.length;if(this.closed)throw new u.a;if(this.isStopped||this.hasError?e=s.a.EMPTY:(this.observers.push(t),e=new c.a(this,t)),r&&t.add(t=new o.a(t,r)),n)for(var l=0;le&&(i=Math.max(i,r-e)),i>0&&a.splice(0,i),a},e}(r.a),d=function(){return function(t,e){this.time=t,this.value=e}}()},S6ln:function(t,e,n){!function(t){"use strict";function e(t,e,n){var a=t+" ";switch(n){case"ss":return a+(1===t?"sekunda":2===t||3===t||4===t?"sekunde":"sekundi");case"m":return e?"jedna minuta":"jedne minute";case"mm":return a+(1===t?"minuta":2===t||3===t||4===t?"minute":"minuta");case"h":return e?"jedan sat":"jednog sata";case"hh":return a+(1===t?"sat":2===t||3===t||4===t?"sata":"sati");case"dd":return a+(1===t?"dan":"dana");case"MM":return a+(1===t?"mjesec":2===t||3===t||4===t?"mjeseca":"mjeseci");case"yy":return a+(1===t?"godina":2===t||3===t||4===t?"godine":"godina")}}n("wd/R").defineLocale("hr",{months:{format:"sije\u010dnja_velja\u010de_o\u017eujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"sije\u010danj_velja\u010da_o\u017eujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._o\u017eu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010der u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[pro\u0161lu] dddd [u] LT";case 6:return"[pro\u0161le] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[pro\u0161li] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:e,m:e,mm:e,h:e,hh:e,d:"dan",dd:e,M:"mjesec",MM:e,y:"godinu",yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}()},S7Ns:function(t,e,n){"use strict";t.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},S7zO:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("LvDl"),r=(n("vCyI"),n("jKX/"),function(){function t(){this.dropDownActions=[]}return t.prototype.ngOnInit=function(){this.removeActionsWithNoPermissions(),this.updateDropDownActions()},t.prototype.toClassName=function(t){return t.replace(/ /g,"-").replace(/[^a-z-]/gi,"").toLowerCase()},t.prototype.removeActionsWithNoPermissions=function(){var t=this;if(this.permission){var e=Object.keys(this.permission).filter(function(e){return t.permission[e]});this.tableActions=this.tableActions.filter(function(t){return e.includes(t.permission)})}else this.tableActions=[]},t.prototype.updateDropDownActions=function(){var t=this;this.dropDownActions=this.tableActions.filter(function(e){return e.visible?e.visible(t.selection):e})},t.prototype.getCurrentButton=function(){var t=this;if(!this.onlyDropDown){var e=this.dropDownActions.find(function(e){return t.showableAction(e)});return!e&&this.dropDownActions.length>0&&(e=this.dropDownActions[0]),e}},t.prototype.showableAction=function(t){var e=t.canBePrimary,n=this.selection.hasSingleSelection,a="create"===t.permission?!n:n;return e&&e(this.selection)||!e&&a},t.prototype.useRouterLink=function(t){if(t.routerLink&&!this.disableSelectionAction(t))return a.isString(t.routerLink)?t.routerLink:t.routerLink()},t.prototype.disableSelectionAction=function(t){var e=t.permission,n=t.disable;if(n)return Boolean(n(this.selection));var a=this.selection.hasSingleSelection&&this.selection.first();return Boolean(["update","delete"].includes(e)&&(!a||a.cdExecuting))},t.prototype.showDropDownActions=function(){return this.updateDropDownActions(),this.dropDownActions.length>1},t.prototype.useClickAction=function(t){return!this.disableSelectionAction(t)&&t.click&&t.click()},t.prototype.useDisableDesc=function(t){return t.disableDesc&&t.disableDesc()},t}())},"SB+Q":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){}return t.prototype.transform=function(t){return encodeURIComponent(t)},t}()},SFxW:function(t,e,n){!function(t){"use strict";var e={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-\xfcnc\xfc",4:"-\xfcnc\xfc",100:"-\xfcnc\xfc",6:"-nc\u0131",9:"-uncu",10:"-uncu",30:"-uncu",60:"-\u0131nc\u0131",90:"-\u0131nc\u0131"};t.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ert\u0259si_\xc7\u0259r\u015f\u0259nb\u0259 ax\u015fam\u0131_\xc7\u0259r\u015f\u0259nb\u0259_C\xfcm\u0259 ax\u015fam\u0131_C\xfcm\u0259_\u015e\u0259nb\u0259".split("_"),weekdaysShort:"Baz_BzE_\xc7Ax_\xc7\u0259r_CAx_C\xfcm_\u015e\u0259n".split("_"),weekdaysMin:"Bz_BE_\xc7A_\xc7\u0259_CA_C\xfc_\u015e\u0259".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bug\xfcn saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[g\u0259l\u0259n h\u0259ft\u0259] dddd [saat] LT",lastDay:"[d\xfcn\u0259n] LT",lastWeek:"[ke\xe7\u0259n h\u0259ft\u0259] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s \u0259vv\u0259l",s:"birne\xe7\u0259 saniy\u0259",ss:"%d saniy\u0259",m:"bir d\u0259qiq\u0259",mm:"%d d\u0259qiq\u0259",h:"bir saat",hh:"%d saat",d:"bir g\xfcn",dd:"%d g\xfcn",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gec\u0259|s\u0259h\u0259r|g\xfcnd\xfcz|ax\u015fam/,isPM:function(t){return/^(g\xfcnd\xfcz|ax\u015fam)$/.test(t)},meridiem:function(t,e,n){return t<4?"gec\u0259":t<12?"s\u0259h\u0259r":t<17?"g\xfcnd\xfcz":"ax\u015fam"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0131nc\u0131|inci|nci|\xfcnc\xfc|nc\u0131|uncu)/,ordinal:function(t){if(0===t)return t+"-\u0131nc\u0131";var n=t%10;return t+(e[n]||e[t%100-n]||e[t>=100?100:null])},week:{dow:1,doy:7}})}(n("wd/R"))},STEd:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n("FBEI");var a=n("CcnG"),r=n("xtUU"),i=n("HHO+"),s=n("Ip0R"),o=n("/TVo"),u=n("urB8"),c=n("ty8c"),l=n("FYBg"),d=n("JZ5S"),f=n("Tff5"),p=n("VUo1");e.TreeModule=function(){function t(){}return t.decorators=[{type:a.NgModule,args:[{imports:[s.CommonModule],declarations:[o.NodeDraggableDirective,r.TreeComponent,c.NodeEditableDirective,l.NodeMenuComponent,i.TreeInternalComponent,p.SafeHtmlPipe],exports:[r.TreeComponent],providers:[u.NodeDraggableService,d.NodeMenuService,f.TreeService]}]}],t}()},SZbH:function(t,e,n){"use strict";n.d(e,"a",function(){return x}),n.d(e,"b",function(){return d}),n.d(e,"c",function(){return _}),n.d(e,"d",function(){return u}),n.d(e,"e",function(){return S}),n.d(e,"f",function(){return I}),n.d(e,"g",function(){return c}),n.d(e,"h",function(){return w}),n.d(e,"i",function(){return T}),n.d(e,"j",function(){return v});var a=n("mrSG"),r=n("CcnG"),i=n("K9Ia"),s=n("ZYjt"),o=n("Ip0R"),u=function(){return function(){}}(),c=function(){function t(t,e,n,a,r,s){var o=this;this.toastId=t,this.config=e,this.message=n,this.title=a,this.toastType=r,this.toastRef=s,this._onTap=new i.a,this._onAction=new i.a,this.toastRef.afterClosed().subscribe(function(){o._onAction.complete(),o._onTap.complete()})}return t.prototype.triggerTap=function(){this._onTap.next(),this.config.tapToDismiss&&this._onTap.complete()},t.prototype.onTap=function(){return this._onTap.asObservable()},t.prototype.triggerAction=function(t){this._onAction.next(t)},t.prototype.onAction=function(){return this._onAction.asObservable()},t}(),l={maxOpened:0,autoDismiss:!1,newestOnTop:!0,preventDuplicates:!1,countDuplicates:!1,resetTimeoutOnDuplicate:!1,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},closeButton:!1,disableTimeOut:!1,timeOut:5e3,extendedTimeOut:1e3,enableHtml:!1,progressBar:!1,toastClass:"ngx-toastr",positionClass:"toast-top-right",titleClass:"toast-title",messageClass:"toast-message",easing:"ease-in",easeTime:300,tapToDismiss:!0,onActivateTick:!1,progressAnimation:"decreasing"},d=new r.InjectionToken("ToastConfig"),f=function(){function t(t,e){this.component=t,this.injector=e}return t.prototype.attach=function(t,e){return this._attachedHost=t,t.attach(this,e)},t.prototype.detach=function(){var t=this._attachedHost;if(t)return this._attachedHost=void 0,t.detach()},Object.defineProperty(t.prototype,"isAttached",{get:function(){return null!=this._attachedHost},enumerable:!0,configurable:!0}),t.prototype.setAttachedHost=function(t){this._attachedHost=t},t}(),p=function(t){function e(e,n,a){var r=t.call(this)||this;return r._hostDomElement=e,r._componentFactoryResolver=n,r._appRef=a,r}return Object(a.__extends)(e,t),e.prototype.attachComponentPortal=function(t,e){var n,a=this,r=this._componentFactoryResolver.resolveComponentFactory(t.component);return n=r.create(t.injector),this._appRef.attachView(n.hostView),this.setDisposeFn(function(){a._appRef.detachView(n.hostView),n.destroy()}),e?this._hostDomElement.insertBefore(this._getComponentRootNode(n),this._hostDomElement.firstChild):this._hostDomElement.appendChild(this._getComponentRootNode(n)),n},e.prototype._getComponentRootNode=function(t){return t.hostView.rootNodes[0]},e}(function(){function t(){}return t.prototype.attach=function(t,e){return this._attachedPortal=t,this.attachComponentPortal(t,e)},t.prototype.detach=function(){this._attachedPortal&&this._attachedPortal.setAttachedHost(),this._attachedPortal=void 0,this._disposeFn&&(this._disposeFn(),this._disposeFn=void 0)},t.prototype.setDisposeFn=function(t){this._disposeFn=t},t}()),h=function(){function t(t){this._document=t}return t.prototype.ngOnDestroy=function(){this._containerElement&&this._containerElement.parentNode&&this._containerElement.parentNode.removeChild(this._containerElement)},t.prototype.getContainerElement=function(){return this._containerElement||this._createContainer(),this._containerElement},t.prototype._createContainer=function(){var t=this._document.createElement("div");t.classList.add("overlay-container"),this._document.body.appendChild(t),this._containerElement=t},t.ngInjectableDef=Object(r.defineInjectable)({factory:function(){return new t(Object(r.inject)(o.DOCUMENT))},token:t,providedIn:"root"}),t}(),g=function(){function t(t){this._portalHost=t}return t.prototype.attach=function(t,e){return void 0===e&&(e=!0),this._portalHost.attach(t,e)},t.prototype.detach=function(){return this._portalHost.detach()},t}(),b=function(){function t(t,e,n,a){this._overlayContainer=t,this._componentFactoryResolver=e,this._appRef=n,this._document=a,this._paneElements=new Map}return t.prototype.create=function(t,e){return this._createOverlayRef(this.getPaneElement(t,e))},t.prototype.getPaneElement=function(t,e){return void 0===t&&(t=""),this._paneElements.get(e)||this._paneElements.set(e,{}),this._paneElements.get(e)[t]||(this._paneElements.get(e)[t]=this._createPaneElement(t,e)),this._paneElements.get(e)[t]},t.prototype._createPaneElement=function(t,e){var n=this._document.createElement("div");return n.id="toast-container",n.classList.add(t),n.classList.add("toast-container"),e?e.getContainerElement().appendChild(n):this._overlayContainer.getContainerElement().appendChild(n),n},t.prototype._createPortalHost=function(t){return new p(t,this._componentFactoryResolver,this._appRef)},t.prototype._createOverlayRef=function(t){return new g(this._createPortalHost(t))},t.ngInjectableDef=Object(r.defineInjectable)({factory:function(){return new t(Object(r.inject)(h),Object(r.inject)(r.ComponentFactoryResolver),Object(r.inject)(r.ApplicationRef),Object(r.inject)(o.DOCUMENT))},token:t,providedIn:"root"}),t}(),m=function(){function t(t){this._overlayRef=t,this.duplicatesCount=0,this._afterClosed=new i.a,this._activate=new i.a,this._manualClose=new i.a,this._resetTimeout=new i.a,this._countDuplicate=new i.a}return t.prototype.manualClose=function(){this._manualClose.next(),this._manualClose.complete()},t.prototype.manualClosed=function(){return this._manualClose.asObservable()},t.prototype.timeoutReset=function(){return this._resetTimeout.asObservable()},t.prototype.countDuplicate=function(){return this._countDuplicate.asObservable()},t.prototype.close=function(){this._overlayRef.detach(),this._afterClosed.next(),this._manualClose.next(),this._afterClosed.complete(),this._manualClose.complete(),this._activate.complete(),this._resetTimeout.complete(),this._countDuplicate.complete()},t.prototype.afterClosed=function(){return this._afterClosed.asObservable()},t.prototype.isInactive=function(){return this._activate.isStopped},t.prototype.activate=function(){this._activate.next(),this._activate.complete()},t.prototype.afterActivate=function(){return this._activate.asObservable()},t.prototype.onDuplicate=function(t,e){t&&this._resetTimeout.next(),e&&this._countDuplicate.next(++this.duplicatesCount)},t}(),y=function(){function t(t,e){this._toastPackage=t,this._parentInjector=e}return t.prototype.get=function(t,e,n){return t===c?this._toastPackage:this._parentInjector.get(t,e,n)},t}(),v=function(){function t(t,e,n,r,i){this.overlay=e,this._injector=n,this.sanitizer=r,this.ngZone=i,this.currentlyActive=0,this.toasts=[],this.index=0,this.toastrConfig=Object(a.__assign)({},t.default,t.config),t.config.iconClasses&&(this.toastrConfig.iconClasses=Object(a.__assign)({},t.default.iconClasses,t.config.iconClasses))}return t.prototype.show=function(t,e,n,a){return void 0===n&&(n={}),void 0===a&&(a=""),this._preBuildNotification(a,t,e,this.applyConfig(n))},t.prototype.success=function(t,e,n){return void 0===n&&(n={}),this._preBuildNotification(this.toastrConfig.iconClasses.success||"",t,e,this.applyConfig(n))},t.prototype.error=function(t,e,n){return void 0===n&&(n={}),this._preBuildNotification(this.toastrConfig.iconClasses.error||"",t,e,this.applyConfig(n))},t.prototype.info=function(t,e,n){return void 0===n&&(n={}),this._preBuildNotification(this.toastrConfig.iconClasses.info||"",t,e,this.applyConfig(n))},t.prototype.warning=function(t,e,n){return void 0===n&&(n={}),this._preBuildNotification(this.toastrConfig.iconClasses.warning||"",t,e,this.applyConfig(n))},t.prototype.clear=function(t){var e,n;try{for(var r=Object(a.__values)(this.toasts),i=r.next();!i.done;i=r.next()){var s=i.value;if(void 0!==t){if(s.toastId===t)return void s.toastRef.manualClose()}else s.toastRef.manualClose()}}catch(o){e={error:o}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(e)throw e.error}}},t.prototype.remove=function(t){var e=this._findToast(t);if(!e)return!1;if(e.activeToast.toastRef.close(),this.toasts.splice(e.index,1),this.currentlyActive=this.currentlyActive-1,!this.toastrConfig.maxOpened||!this.toasts.length)return!1;if(this.currentlyActive=this.toastrConfig.maxOpened&&(o=!0,this.toastrConfig.autoDismiss&&this.clear(this.toasts[0].toastId));var u=this.overlay.create(a.positionClass,this.overlayContainer);this.index=this.index+1;var l=e;e&&a.enableHtml&&(l=this.sanitizer.sanitize(r.SecurityContext.HTML,e));var d=new m(u),p=new c(this.index,a,l,n,t,d),h=new y(p,this._injector),g=new f(a.toastComponent,h),b=u.attach(g,this.toastrConfig.newestOnTop);d.componentInstance=b._component;var v={toastId:this.index,message:e||"",toastRef:d,onShown:d.afterActivate(),onHidden:d.afterClosed(),onTap:p.onTap(),onAction:p.onAction(),portal:b};return o||setTimeout(function(){v.toastRef.activate(),i.currentlyActive=i.currentlyActive+1}),this.toasts.push(v),v},t.ngInjectableDef=Object(r.defineInjectable)({factory:function(){return new t(Object(r.inject)(d),Object(r.inject)(b),Object(r.inject)(r.INJECTOR),Object(r.inject)(s.DomSanitizer),Object(r.inject)(r.NgZone))},token:t,providedIn:"root"}),t}(),_=function(){function t(t,e,n){var a=this;this.toastrService=t,this.toastPackage=e,this.ngZone=n,this.width=-1,this.toastClasses="",this.state={value:"inactive",params:{easeTime:this.toastPackage.config.easeTime,easing:"ease-in"}},this.message=e.message,this.title=e.title,this.options=e.config,this.originalTimeout=e.config.timeOut,this.toastClasses=e.toastType+" "+e.config.toastClass,this.sub=e.toastRef.afterActivate().subscribe(function(){a.activateToast()}),this.sub1=e.toastRef.manualClosed().subscribe(function(){a.remove()}),this.sub2=e.toastRef.timeoutReset().subscribe(function(){a.resetTimeout()}),this.sub3=e.toastRef.countDuplicate().subscribe(function(t){a.duplicatesCount=t})}return Object.defineProperty(t.prototype,"displayStyle",{get:function(){return"inactive"===this.state.value?"none":"inherit"},enumerable:!0,configurable:!0}),t.prototype.ngOnDestroy=function(){this.sub.unsubscribe(),this.sub1.unsubscribe(),this.sub2.unsubscribe(),this.sub3.unsubscribe(),clearInterval(this.intervalId),clearTimeout(this.timeout)},t.prototype.activateToast=function(){var t=this;this.state=Object(a.__assign)({},this.state,{value:"active"}),!this.options.disableTimeOut&&this.options.timeOut&&(this.outsideTimeout(function(){return t.remove()},this.options.timeOut),this.hideTime=(new Date).getTime()+this.options.timeOut,this.options.progressBar&&this.outsideInterval(function(){return t.updateProgress()},10))},t.prototype.updateProgress=function(){if(0!==this.width&&100!==this.width&&this.options.timeOut){var t=(new Date).getTime();this.width=(this.hideTime-t)/this.options.timeOut*100,"increasing"===this.options.progressAnimation&&(this.width=100-this.width),this.width<=0&&(this.width=0),this.width>=100&&(this.width=100)}},t.prototype.resetTimeout=function(){var t=this;clearTimeout(this.timeout),clearInterval(this.intervalId),this.state=Object(a.__assign)({},this.state,{value:"active"}),this.outsideTimeout(function(){return t.remove()},this.originalTimeout),this.options.timeOut=this.originalTimeout,this.hideTime=(new Date).getTime()+(this.options.timeOut||0),this.width=-1,this.options.progressBar&&this.outsideInterval(function(){return t.updateProgress()},10)},t.prototype.remove=function(){var t=this;"removed"!==this.state.value&&(clearTimeout(this.timeout),this.state=Object(a.__assign)({},this.state,{value:"removed"}),this.outsideTimeout(function(){return t.toastrService.remove(t.toastPackage.toastId)},+this.toastPackage.config.easeTime))},t.prototype.tapToast=function(){"removed"!==this.state.value&&(this.toastPackage.triggerTap(),this.options.tapToDismiss&&this.remove())},t.prototype.stickAround=function(){"removed"!==this.state.value&&(clearTimeout(this.timeout),this.options.timeOut=0,this.hideTime=0,clearInterval(this.intervalId),this.width=0)},t.prototype.delayedHideToast=function(){var t=this;this.options.disableTimeOut||0===this.options.extendedTimeOut||"removed"===this.state.value||(this.outsideTimeout(function(){return t.remove()},this.options.extendedTimeOut),this.options.timeOut=this.options.extendedTimeOut,this.hideTime=(new Date).getTime()+(this.options.timeOut||0),this.width=-1,this.options.progressBar&&this.outsideInterval(function(){return t.updateProgress()},10))},t.prototype.outsideTimeout=function(t,e){var n=this;this.ngZone?this.ngZone.runOutsideAngular(function(){return n.timeout=setTimeout(function(){return n.runInsideAngular(t)},e)}):this.timeout=setTimeout(function(){return t()},e)},t.prototype.outsideInterval=function(t,e){var n=this;this.ngZone?this.ngZone.runOutsideAngular(function(){return n.intervalId=setInterval(function(){return n.runInsideAngular(t)},e)}):this.intervalId=setInterval(function(){return t()},e)},t.prototype.runInsideAngular=function(t){this.ngZone?this.ngZone.run(function(){return t()}):t()},t}(),x=Object(a.__assign)({},l,{toastComponent:_}),T=function(){function t(){}var e;return e=t,t.forRoot=function(t){return void 0===t&&(t={}),{ngModule:e,providers:[{provide:d,useValue:{default:x,config:t}}]}},t}(),w=function(){function t(){}return t.forRoot=function(t){return void 0===t&&(t={}),{ngModule:T,providers:[{provide:d,useValue:{default:l,config:t}}]}},t}(),S=function(){function t(t,e,n){var a=this;this.toastrService=t,this.toastPackage=e,this.appRef=n,this.width=-1,this.toastClasses="",this.state="inactive",this.message=e.message,this.title=e.title,this.options=e.config,this.originalTimeout=e.config.timeOut,this.toastClasses=e.toastType+" "+e.config.toastClass,this.sub=e.toastRef.afterActivate().subscribe(function(){a.activateToast()}),this.sub1=e.toastRef.manualClosed().subscribe(function(){a.remove()}),this.sub2=e.toastRef.timeoutReset().subscribe(function(){a.resetTimeout()}),this.sub3=e.toastRef.countDuplicate().subscribe(function(t){a.duplicatesCount=t})}return Object.defineProperty(t.prototype,"displayStyle",{get:function(){return"inactive"===this.state?"none":"inherit"},enumerable:!0,configurable:!0}),t.prototype.ngOnDestroy=function(){this.sub.unsubscribe(),this.sub1.unsubscribe(),this.sub2.unsubscribe(),this.sub3.unsubscribe(),clearInterval(this.intervalId),clearTimeout(this.timeout)},t.prototype.activateToast=function(){var t=this;this.state="active",!this.options.disableTimeOut&&this.options.timeOut&&(this.timeout=setTimeout(function(){t.remove()},this.options.timeOut),this.hideTime=(new Date).getTime()+this.options.timeOut,this.options.progressBar&&(this.intervalId=setInterval(function(){return t.updateProgress()},10))),this.options.onActivateTick&&this.appRef.tick()},t.prototype.updateProgress=function(){if(0!==this.width&&100!==this.width&&this.options.timeOut){var t=(new Date).getTime();this.width=(this.hideTime-t)/this.options.timeOut*100,"increasing"===this.options.progressAnimation&&(this.width=100-this.width),this.width<=0&&(this.width=0),this.width>=100&&(this.width=100)}},t.prototype.resetTimeout=function(){var t=this;clearTimeout(this.timeout),clearInterval(this.intervalId),this.state="active",this.options.timeOut=this.originalTimeout,this.timeout=setTimeout(function(){return t.remove()},this.originalTimeout),this.hideTime=(new Date).getTime()+(this.originalTimeout||0),this.width=-1,this.options.progressBar&&(this.intervalId=setInterval(function(){return t.updateProgress()},10))},t.prototype.remove=function(){var t=this;"removed"!==this.state&&(clearTimeout(this.timeout),this.state="removed",this.timeout=setTimeout(function(){return t.toastrService.remove(t.toastPackage.toastId)}))},t.prototype.tapToast=function(){"removed"!==this.state&&(this.toastPackage.triggerTap(),this.options.tapToDismiss&&this.remove())},t.prototype.stickAround=function(){"removed"!==this.state&&(clearTimeout(this.timeout),this.options.timeOut=0,this.hideTime=0,clearInterval(this.intervalId),this.width=0)},t.prototype.delayedHideToast=function(){var t=this;this.options.disableTimeOut||0===this.options.extendedTimeOut||"removed"===this.state||(this.timeout=setTimeout(function(){return t.remove()},this.options.extendedTimeOut),this.options.timeOut=this.options.extendedTimeOut,this.hideTime=(new Date).getTime()+(this.options.timeOut||0),this.width=-1,this.options.progressBar&&(this.intervalId=setInterval(function(){return t.updateProgress()},10)))},t}(),O=Object(a.__assign)({},l,{toastComponent:S}),I=function(){function t(){}var e;return e=t,t.forRoot=function(t){return void 0===t&&(t={}),{ngModule:e,providers:[{provide:d,useValue:{default:O,config:t}}]}},t}()},SatO:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("zh-hk",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u51cc\u6668"===e||"\u65e9\u4e0a"===e||"\u4e0a\u5348"===e?t:"\u4e2d\u5348"===e?t>=11?t:t+12:"\u4e0b\u5348"===e||"\u665a\u4e0a"===e?t+12:void 0},meridiem:function(t,e,n){var a=100*t+e;return a<600?"\u51cc\u6668":a<900?"\u65e9\u4e0a":a<1130?"\u4e0a\u5348":a<1230?"\u4e2d\u5348":a<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(t,e){switch(e){case"d":case"D":case"DDD":return t+"\u65e5";case"M":return t+"\u6708";case"w":case"W":return t+"\u9031";default:return t}},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}})}()},SfHT:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG");e.ScrollerComponent=function(){function t(t,e,n){this.ngZone=t,this.renderer=n,this.scrollbarV=!1,this.scrollbarH=!1,this.scroll=new i.EventEmitter,this.scrollYPos=0,this.scrollXPos=0,this.prevScrollYPos=0,this.prevScrollXPos=0,this.element=e.nativeElement}return t.prototype.ngOnInit=function(){if(this.scrollbarV||this.scrollbarH){var t=this.renderer;this.parentElement=t.parentNode(t.parentNode(this.element)),this.parentElement.addEventListener("scroll",this.onScrolled.bind(this))}},t.prototype.ngOnDestroy=function(){(this.scrollbarV||this.scrollbarH)&&this.parentElement.removeEventListener("scroll",this.onScrolled.bind(this))},t.prototype.setOffset=function(t){this.parentElement&&(this.parentElement.scrollTop=t)},t.prototype.onScrolled=function(t){var e=this,n=t.currentTarget;requestAnimationFrame(function(){e.scrollYPos=n.scrollTop,e.scrollXPos=n.scrollLeft,e.updateOffset()})},t.prototype.updateOffset=function(){var t;this.scrollYPosthis.prevScrollYPos&&(t="up"),this.scroll.emit({direction:t,scrollYPos:this.scrollYPos,scrollXPos:this.scrollXPos}),this.prevScrollYPos=this.scrollYPos,this.prevScrollXPos=this.scrollXPos},a([i.Input(),r("design:type",Boolean)],t.prototype,"scrollbarV",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"scrollbarH",void 0),a([i.HostBinding("style.height.px"),i.Input(),r("design:type",Number)],t.prototype,"scrollHeight",void 0),a([i.HostBinding("style.width.px"),i.Input(),r("design:type",Number)],t.prototype,"scrollWidth",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"scroll",void 0),a([i.Component({selector:"datatable-scroller",template:"\n \n ",host:{class:"datatable-scroll"},changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},Sfow:function(t,e,n){"use strict";var a=n("TC34");e=t.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,a,r,i){if(i){var s=Math.min(i,r/2-1e-7,a/2-1e-7);t.moveTo(e+s,n),t.lineTo(e+a-s,n),t.arcTo(e+a,n,e+a,n+s,s),t.lineTo(e+a,n+r-s),t.arcTo(e+a,n+r,e+a-s,n+r,s),t.lineTo(e+s,n+r),t.arcTo(e,n+r,e,n+r-s,s),t.lineTo(e,n+s),t.arcTo(e,n,e+s,n,s),t.closePath(),t.moveTo(e,n)}else t.rect(e,n,a,r)},drawPoint:function(t,e,n,a,r,i){var s,o,u,c,l,d;if(i=i||0,!e||"object"!=typeof e||"[object HTMLImageElement]"!==(s=e.toString())&&"[object HTMLCanvasElement]"!==s){if(!(isNaN(n)||n<=0)){switch(t.save(),t.translate(a,r),t.rotate(i*Math.PI/180),t.beginPath(),e){default:t.arc(0,0,n,0,2*Math.PI),t.closePath();break;case"triangle":l=(o=3*n/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(-o/2,l/3),t.lineTo(o/2,l/3),t.lineTo(0,-2*l/3),t.closePath();break;case"rect":d=1/Math.SQRT2*n,t.rect(-d,-d,2*d,2*d);break;case"rectRounded":var f=n/Math.SQRT2,p=Math.SQRT2*n;this.roundedRect(t,-f,-f,p,p,.425*n);break;case"rectRot":d=1/Math.SQRT2*n,t.moveTo(-d,0),t.lineTo(0,d),t.lineTo(d,0),t.lineTo(0,-d),t.closePath();break;case"cross":t.moveTo(0,n),t.lineTo(0,-n),t.moveTo(-n,0),t.lineTo(n,0);break;case"crossRot":u=Math.cos(Math.PI/4)*n,c=Math.sin(Math.PI/4)*n,t.moveTo(-u,-c),t.lineTo(u,c),t.moveTo(-u,c),t.lineTo(u,-c);break;case"star":t.moveTo(0,n),t.lineTo(0,-n),t.moveTo(-n,0),t.lineTo(n,0),u=Math.cos(Math.PI/4)*n,c=Math.sin(Math.PI/4)*n,t.moveTo(-u,-c),t.lineTo(u,c),t.moveTo(-u,c),t.lineTo(u,-c);break;case"line":t.moveTo(-n,0),t.lineTo(n,0);break;case"dash":t.moveTo(0,0),t.lineTo(n,0)}t.fill(),t.stroke(),t.restore()}}else t.drawImage(e,a-e.width/2,r-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,n,a){if(n.steppedLine)return"after"===n.steppedLine&&!a||"after"!==n.steppedLine&&a?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y),void t.lineTo(n.x,n.y);n.tension?t.bezierCurveTo(a?e.controlPointPreviousX:e.controlPointNextX,a?e.controlPointPreviousY:e.controlPointNextY,a?n.controlPointNextX:n.controlPointPreviousX,a?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):t.lineTo(n.x,n.y)}},a.clear=e.clear,a.drawRoundedRectangle=function(t){t.beginPath(),e.roundedRect.apply(e,arguments)}},SgmB:function(t,e,n){"use strict";n.d(e,"a",function(){return u});var a=n("F/XL"),r=n("psW0"),i=n("CcnG"),s=n("t/Na"),o=n("pL04"),u=function(){function t(t){this.http=t}return t.prototype.list=function(){return this.http.get("api/role")},t.prototype.delete=function(t){return this.http.delete("api/role/"+t)},t.prototype.get=function(t){return this.http.get("api/role/"+t)},t.prototype.create=function(t){return this.http.post("api/role",t)},t.prototype.update=function(t){return this.http.put("api/role/"+t.name,t)},t.prototype.exists=function(t){return this.list().pipe(Object(r.a)(function(e){var n=e.some(function(e){return e.name===t});return Object(a.a)(n)}))},t.ngInjectableDef=i.defineInjectable({factory:function(){return new t(i.inject(s.c))},token:t,providedIn:o.a}),t}()},SjWX:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=function(){return function(t,e,n){this.name=t,this.version=e,this.os=n}}();e.BrowserInfo=a;var r=function(){return function(t){this.version=t,this.name="node",this.os=process.platform}}();e.NodeInfo=r;var i=function(){return function(){this.bot=!0,this.name="bot",this.version=null,this.os=null}}();e.BotInfo=i;var s=3,o=[["aol",/AOLShield\/([0-9\._]+)/],["edge",/Edge\/([0-9\._]+)/],["yandexbrowser",/YaBrowser\/([0-9\._]+)/],["vivaldi",/Vivaldi\/([0-9\.]+)/],["kakaotalk",/KAKAOTALK\s([0-9\.]+)/],["samsung",/SamsungBrowser\/([0-9\.]+)/],["silk",/\bSilk\/([0-9._-]+)\b/],["chrome",/(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],["phantomjs",/PhantomJS\/([0-9\.]+)(:?\s|$)/],["crios",/CriOS\/([0-9\.]+)(:?\s|$)/],["firefox",/Firefox\/([0-9\.]+)(?:\s|$)/],["fxios",/FxiOS\/([0-9\.]+)/],["opera-mini",/Opera Mini.*Version\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)(?:\s|$)/],["opera",/OPR\/([0-9\.]+)(:?\s|$)$/],["ie",/Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],["ie",/MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],["ie",/MSIE\s(7\.0)/],["bb10",/BB10;\sTouch.*Version\/([0-9\.]+)/],["android",/Android\s([0-9\.]+)/],["ios",/Version\/([0-9\._]+).*Mobile.*Safari.*/],["safari",/Version\/([0-9\._]+).*Safari/],["facebook",/FBAV\/([0-9\.]+)/],["instagram",/Instagram\s([0-9\.]+)/],["ios-webview",/AppleWebKit\/([0-9\.]+).*Mobile/],["searchbot",/alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/]],u=[["iOS",/iP(hone|od|ad)/],["Android OS",/Android/],["BlackBerry OS",/BlackBerry|BB10/],["Windows Mobile",/IEMobile/],["Amazon OS",/Kindle/],["Windows 3.11",/Win16/],["Windows 95",/(Windows 95)|(Win95)|(Windows_95)/],["Windows 98",/(Windows 98)|(Win98)/],["Windows 2000",/(Windows NT 5.0)|(Windows 2000)/],["Windows XP",/(Windows NT 5.1)|(Windows XP)/],["Windows Server 2003",/(Windows NT 5.2)/],["Windows Vista",/(Windows NT 6.0)/],["Windows 7",/(Windows NT 6.1)/],["Windows 8",/(Windows NT 6.2)/],["Windows 8.1",/(Windows NT 6.3)/],["Windows 10",/(Windows NT 10.0)/],["Windows ME",/Windows ME/],["Open BSD",/OpenBSD/],["Sun OS",/SunOS/],["Chrome OS",/CrOS/],["Linux",/(Linux)|(X11)/],["Mac OS",/(Mac_PowerPC)|(Macintosh)/],["QNX",/QNX/],["BeOS",/BeOS/],["OS/2",/OS\/2/],["Search Bot",/(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/]];function c(t){var e=""!==t&&o.reduce(function(e,n){var a=n[0];if(e)return e;var r=n[1].exec(t);return!!r&&[a,r]},!1);if(!e)return null;var n=e[0],r=e[1];if("searchbot"===n)return new i;var u=r[1]&&r[1].split(/[._]/).slice(0,3);return u?u.length=0;i--)e.call(n,t[i],i);else for(i=0;i=11?t:t+12:"sore"===e||"malam"===e?t+12:void 0},meridiem:function(t,e,n){return t<11?"pagi":t<15?"siang":t<19?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",ss:"%d detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}()},UReH:function(t,e,n){var a=n("mrSG").__decorate;Object.defineProperty(e,"__esModule",{value:!0});var r=n("CcnG");e.DatatableRowDetailTemplateDirective=function(){return a([r.Directive({selector:"[ngx-datatable-row-detail-template]"})],function(t){this.template=t})}()},USCx:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("ga",{months:["Ean\xe1ir","Feabhra","M\xe1rta","Aibre\xe1n","Bealtaine","M\xe9itheamh","I\xfail","L\xfanasa","Me\xe1n F\xf3mhair","Deaireadh F\xf3mhair","Samhain","Nollaig"],monthsShort:["Ean\xe1","Feab","M\xe1rt","Aibr","Beal","M\xe9it","I\xfail","L\xfana","Me\xe1n","Deai","Samh","Noll"],monthsParseExact:!0,weekdays:["D\xe9 Domhnaigh","D\xe9 Luain","D\xe9 M\xe1irt","D\xe9 C\xe9adaoin","D\xe9ardaoin","D\xe9 hAoine","D\xe9 Satharn"],weekdaysShort:["Dom","Lua","M\xe1i","C\xe9a","D\xe9a","hAo","Sat"],weekdaysMin:["Do","Lu","M\xe1","Ce","D\xe9","hA","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Inniu ag] LT",nextDay:"[Am\xe1rach ag] LT",nextWeek:"dddd [ag] LT",lastDay:"[Inn\xe9 aig] LT",lastWeek:"dddd [seo caite] [ag] LT",sameElse:"L"},relativeTime:{future:"i %s",past:"%s \xf3 shin",s:"c\xfapla soicind",ss:"%d soicind",m:"n\xf3im\xe9ad",mm:"%d n\xf3im\xe9ad",h:"uair an chloig",hh:"%d uair an chloig",d:"l\xe1",dd:"%d l\xe1",M:"m\xed",MM:"%d m\xed",y:"bliain",yy:"%d bliain"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(t){return t+(1===t?"d":t%10==2?"na":"mh")},week:{dow:1,doy:4}})}()},UpQW:function(t,e,n){!function(t){"use strict";var e=["\u062c\u0646\u0648\u0631\u06cc","\u0641\u0631\u0648\u0631\u06cc","\u0645\u0627\u0631\u0686","\u0627\u067e\u0631\u06cc\u0644","\u0645\u0626\u06cc","\u062c\u0648\u0646","\u062c\u0648\u0644\u0627\u0626\u06cc","\u0627\u06af\u0633\u062a","\u0633\u062a\u0645\u0628\u0631","\u0627\u06a9\u062a\u0648\u0628\u0631","\u0646\u0648\u0645\u0628\u0631","\u062f\u0633\u0645\u0628\u0631"],a=["\u0627\u062a\u0648\u0627\u0631","\u067e\u06cc\u0631","\u0645\u0646\u06af\u0644","\u0628\u062f\u06be","\u062c\u0645\u0639\u0631\u0627\u062a","\u062c\u0645\u0639\u06c1","\u06c1\u0641\u062a\u06c1"];n("wd/R").defineLocale("ur",{months:e,monthsShort:e,weekdays:a,weekdaysShort:a,weekdaysMin:a,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd\u060c D MMMM YYYY HH:mm"},meridiemParse:/\u0635\u0628\u062d|\u0634\u0627\u0645/,isPM:function(t){return"\u0634\u0627\u0645"===t},meridiem:function(t,e,n){return t<12?"\u0635\u0628\u062d":"\u0634\u0627\u0645"},calendar:{sameDay:"[\u0622\u062c \u0628\u0648\u0642\u062a] LT",nextDay:"[\u06a9\u0644 \u0628\u0648\u0642\u062a] LT",nextWeek:"dddd [\u0628\u0648\u0642\u062a] LT",lastDay:"[\u06af\u0630\u0634\u062a\u06c1 \u0631\u0648\u0632 \u0628\u0648\u0642\u062a] LT",lastWeek:"[\u06af\u0630\u0634\u062a\u06c1] dddd [\u0628\u0648\u0642\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0628\u0639\u062f",past:"%s \u0642\u0628\u0644",s:"\u0686\u0646\u062f \u0633\u06cc\u06a9\u0646\u0688",ss:"%d \u0633\u06cc\u06a9\u0646\u0688",m:"\u0627\u06cc\u06a9 \u0645\u0646\u0679",mm:"%d \u0645\u0646\u0679",h:"\u0627\u06cc\u06a9 \u06af\u06be\u0646\u0679\u06c1",hh:"%d \u06af\u06be\u0646\u0679\u06d2",d:"\u0627\u06cc\u06a9 \u062f\u0646",dd:"%d \u062f\u0646",M:"\u0627\u06cc\u06a9 \u0645\u0627\u06c1",MM:"%d \u0645\u0627\u06c1",y:"\u0627\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(t){return t.replace(/\u060c/g,",")},postformat:function(t){return t.replace(/,/g,"\u060c")},week:{dow:1,doy:4}})}()},UqmZ:function(t,e,n){"use strict";var a=n("CDJp"),r=n("K2E3"),i=n("RDha"),s=a.global;a._set("global",{elements:{line:{tension:.4,backgroundColor:s.defaultColor,borderWidth:3,borderColor:s.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),t.exports=r.extend({draw:function(){var t,e,n,a,r=this._view,o=this._chart.ctx,u=r.spanGaps,c=this._children.slice(),l=s.elements.line,d=-1;for(this._loop&&c.length&&c.push(c[0]),o.save(),o.lineCap=r.borderCapStyle||l.borderCapStyle,o.setLineDash&&o.setLineDash(r.borderDash||l.borderDash),o.lineDashOffset=r.borderDashOffset||l.borderDashOffset,o.lineJoin=r.borderJoinStyle||l.borderJoinStyle,o.lineWidth=r.borderWidth||l.borderWidth,o.strokeStyle=r.borderColor||s.defaultColor,o.beginPath(),d=-1,t=0;t=11?t:t+12:"entsambama"===e||"ebusuku"===e?0===t?0:t+12:void 0},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:"%d",week:{dow:1,doy:4}})}()},"V/fk":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},V2x9:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("tet",{months:"Janeiru_Fevereiru_Marsu_Abril_Maiu_Ju\xf1u_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu".split("_"),weekdaysShort:"Dom_Seg_Ters_Kua_Kint_Sest_Sab".split("_"),weekdaysMin:"Do_Seg_Te_Ku_Ki_Ses_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Ohin iha] LT",nextDay:"[Aban iha] LT",nextWeek:"dddd [iha] LT",lastDay:"[Horiseik iha] LT",lastWeek:"dddd [semana kotuk] [iha] LT",sameElse:"L"},relativeTime:{future:"iha %s",past:"%s liuba",s:"minutu balun",ss:"minutu %d",m:"minutu ida",mm:"minutu %d",h:"oras ida",hh:"oras %d",d:"loron ida",dd:"loron %d",M:"fulan ida",MM:"fulan %d",y:"tinan ida",yy:"tinan %d"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")},week:{dow:1,doy:4}})}()},V3my:function(t,e,n){"use strict";var a,r=n("gIcY"),i=n("LvDl"),s=(n("DSvg"),n("SgmB"),n("Mxhz"),n("OLbh")),o=n("DNAf"),u=(n("sne2"),n("mtw6")),c=n("QFaf"),l=n("1Ni5");n("aexS"),n("9nlD"),function(t){t.editing="editing"}(a||(a={}));var d=function(){return function(){}}();n.d(e,"a",function(){return f});var f=function(){function t(t,e,n,r,i,s,u,c,l,d){this.authService=t,this.authStorageService=e,this.route=n,this.router=r,this.modalService=i,this.roleService=s,this.userService=u,this.notificationService=c,this.i18n=l,this.actionLabels=d,this.userFormMode=a,this.messages=new o.a({empty:"There are no roles."},this.i18n),this.resource=this.i18n("user"),this.createForm(),this.messages=new o.a({empty:"There are no roles."},this.i18n)}return t.prototype.createForm=function(){this.userForm=new c.a({username:new r.i("",{validators:[r.A.required]}),name:new r.i(""),password:new r.i("",{validators:[]}),confirmpassword:new r.i("",{updateOn:"blur",validators:[]}),email:new r.i("",{validators:[r.A.email]}),roles:new r.i([])},{validators:[l.a.match("password","confirmpassword")]})},t.prototype.ngOnInit=function(){var t=this;this.router.url.startsWith("/user-management/users/edit")?(this.mode=this.userFormMode.editing,this.action=this.actionLabels.EDIT):this.action=this.actionLabels.CREATE,this.roleService.list().subscribe(function(e){t.allRoles=i.map(e,function(t){return t.enabled=!0,t})}),this.mode===this.userFormMode.editing&&this.initEdit()},t.prototype.initEdit=function(){var t=this;this.disableForEdit(),this.route.params.subscribe(function(e){t.userService.get(e.username).subscribe(function(e){t.response=i.cloneDeep(e),t.setResponse(e)})})},t.prototype.disableForEdit=function(){this.userForm.get("username").disable()},t.prototype.setResponse=function(t){var e=this;["username","name","email","roles"].forEach(function(n){return e.userForm.get(n).setValue(t[n])})},t.prototype.getRequest=function(){var t=this,e=new d;return["username","password","name","email","roles"].forEach(function(n){return e[n]=t.userForm.get(n).value}),e},t.prototype.createAction=function(){var t=this,e=this.getRequest();this.userService.create(e).subscribe(function(){t.notificationService.show(u.a.success,t.i18n('Created user "{{username}}"',{username:e.username})),t.router.navigate(["/user-management/users"])},function(){t.userForm.setErrors({cdSubmitButton:!0})})},t.prototype.editAction=function(){var t=this;if(this.isUserRemovingNeededRolePermissions()){var e={titleText:this.i18n("Update user"),buttonText:this.i18n("Continue"),bodyTpl:this.removeSelfUserReadUpdatePermissionTpl,onSubmit:function(){t.modalRef.hide(),t.doEditAction()},onCancel:function(){t.userForm.setErrors({cdSubmitButton:!0}),t.userForm.get("roles").reset(t.userForm.get("roles").value)}};this.modalRef=this.modalService.show(s.a,{initialState:e})}else this.doEditAction()},t.prototype.isCurrentUser=function(){return this.authStorageService.getUsername()===this.userForm.getValue("username")},t.prototype.isUserChangingRoles=function(){return this.isCurrentUser()&&this.response&&!i.isEqual(this.response.roles,this.userForm.getValue("roles"))},t.prototype.isUserRemovingNeededRolePermissions=function(){return this.isCurrentUser()&&!this.hasUserReadUpdatePermissions(this.userForm.getValue("roles"))},t.prototype.hasUserReadUpdatePermissions=function(t){void 0===t&&(t=[]);for(var e=function(e){if(-1!==t.indexOf(e.name)&&e.scopes_permissions.user){var n=e.scopes_permissions.user;return{value:["read","update"].every(function(t){return-1!==n.indexOf(t)})}}},n=0,a=this.allRoles;n0),t(e,4,0,0===n.data.length&&n.options.length>0),t(e,6,0,0===n.options.length)},null)}},WxRl:function(t,e,n){!function(t){"use strict";var e="vas\xe1rnap h\xe9tf\u0151n kedden szerd\xe1n cs\xfct\xf6rt\xf6k\xf6n p\xe9nteken szombaton".split(" ");function n(t,e,n,a){var r=t;switch(n){case"s":return a||e?"n\xe9h\xe1ny m\xe1sodperc":"n\xe9h\xe1ny m\xe1sodperce";case"ss":return r+(a||e)?" m\xe1sodperc":" m\xe1sodperce";case"m":return"egy"+(a||e?" perc":" perce");case"mm":return r+(a||e?" perc":" perce");case"h":return"egy"+(a||e?" \xf3ra":" \xf3r\xe1ja");case"hh":return r+(a||e?" \xf3ra":" \xf3r\xe1ja");case"d":return"egy"+(a||e?" nap":" napja");case"dd":return r+(a||e?" nap":" napja");case"M":return"egy"+(a||e?" h\xf3nap":" h\xf3napja");case"MM":return r+(a||e?" h\xf3nap":" h\xf3napja");case"y":return"egy"+(a||e?" \xe9v":" \xe9ve");case"yy":return r+(a||e?" \xe9v":" \xe9ve")}return""}function a(t){return(t?"":"[m\xfalt] ")+"["+e[this.day()]+"] LT[-kor]"}t.defineLocale("hu",{months:"janu\xe1r_febru\xe1r_m\xe1rcius_\xe1prilis_m\xe1jus_j\xfanius_j\xfalius_augusztus_szeptember_okt\xf3ber_november_december".split("_"),monthsShort:"jan_feb_m\xe1rc_\xe1pr_m\xe1j_j\xfan_j\xfal_aug_szept_okt_nov_dec".split("_"),weekdays:"vas\xe1rnap_h\xe9tf\u0151_kedd_szerda_cs\xfct\xf6rt\xf6k_p\xe9ntek_szombat".split("_"),weekdaysShort:"vas_h\xe9t_kedd_sze_cs\xfct_p\xe9n_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(t){return"u"===t.charAt(1).toLowerCase()},meridiem:function(t,e,n){return t<12?!0===n?"de":"DE":!0===n?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return a.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return a.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s m\xfalva",past:"%s",s:n,ss:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n("wd/R"))},WyAD:function(t,e,n){var a=n("yPMN")();a.helpers=n("RDha"),n("nDWh")(a),a.Animation=n("A5uo"),a.animationService=n("dpnK"),a.defaults=n("CDJp"),a.Element=n("K2E3"),a.elements=n("vvH+"),a.Interaction=n("mlr9"),a.layouts=n("fELs"),a.platform=n("iM7B"),a.plugins=n("VgNv"),a.Scale=n("cdu6"),a.scaleService=n("tjFV"),a.Ticks=n("g8vO"),a.Tooltip=n("x8uC"),n("6rqY")(a),n("KAQS")(a),n("paOr")(a),n("8TtQ")(a),n("YSsK")(a),n("Y4Rb")(a),n("8//i")(a),n("RCHg")(a),n("ZANz")(a),n("bidN")(a),n("XQh+")(a),n("G0Q6")(a),n("5ZZ7")(a),n("aB2c")(a),n("35yf")(a),n("ODdm")(a),n("Qexa")(a),n("S7Ns")(a),n("7O6V")(a),n("qzaf")(a),n("iYGd")(a),n("S3/U")(a);var r=n("jXIB");for(var i in r)r.hasOwnProperty(i)&&a.plugins.register(r[i]);a.platform.initialize(),t.exports=a,"undefined"!=typeof window&&(window.Chart=a),a.Legend=r.legend._element,a.Title=r.title._element,a.pluginService=a.plugins,a.PluginBase=a.Element.extend({}),a.canvasHelpers=a.helpers.canvas,a.layoutService=a.layouts},X709:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"s\xf6ndag_m\xe5ndag_tisdag_onsdag_torsdag_fredag_l\xf6rdag".split("_"),weekdaysShort:"s\xf6n_m\xe5n_tis_ons_tor_fre_l\xf6r".split("_"),weekdaysMin:"s\xf6_m\xe5_ti_on_to_fr_l\xf6".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Ig\xe5r] LT",nextWeek:"[P\xe5] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"f\xf6r %s sedan",s:"n\xe5gra sekunder",ss:"%d sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en m\xe5nad",MM:"%d m\xe5nader",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}(e|a)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"e":1===e?"a":2===e?"a":"e")},week:{dow:1,doy:4}})}()},X8CM:function(t,e,n){"use strict";var a=n("CDJp"),r=n("K2E3"),i=n("RDha");a._set("global",{elements:{arc:{backgroundColor:a.global.defaultColor,borderColor:"#fff",borderWidth:2}}}),t.exports=r.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)u;)r-=2*Math.PI;for(;r=o&&r<=u&&s>=n.innerRadius&&s<=n.outerRadius}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t=this._chart.ctx,e=this._view,n=e.startAngle,a=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,a),t.arc(e.x,e.y,e.innerRadius,a,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},XDpg:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u5468\u65e5_\u5468\u4e00_\u5468\u4e8c_\u5468\u4e09_\u5468\u56db_\u5468\u4e94_\u5468\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5Ah\u70b9mm\u5206",LLLL:"YYYY\u5e74M\u6708D\u65e5ddddAh\u70b9mm\u5206",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u51cc\u6668"===e||"\u65e9\u4e0a"===e||"\u4e0a\u5348"===e?t:"\u4e0b\u5348"===e||"\u665a\u4e0a"===e?t+12:t>=11?t:t+12},meridiem:function(t,e,n){var a=100*t+e;return a<600?"\u51cc\u6668":a<900?"\u65e9\u4e0a":a<1130?"\u4e0a\u5348":a<1230?"\u4e2d\u5348":a<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u5468)/,ordinal:function(t,e){switch(e){case"d":case"D":case"DDD":return t+"\u65e5";case"M":return t+"\u6708";case"w":case"W":return t+"\u5468";default:return t}},relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",ss:"%d \u79d2",m:"1 \u5206\u949f",mm:"%d \u5206\u949f",h:"1 \u5c0f\u65f6",hh:"%d \u5c0f\u65f6",d:"1 \u5929",dd:"%d \u5929",M:"1 \u4e2a\u6708",MM:"%d \u4e2a\u6708",y:"1 \u5e74",yy:"%d \u5e74"},week:{dow:1,doy:4}})}()},XFyV:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},XLvN:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("te",{months:"\u0c1c\u0c28\u0c35\u0c30\u0c3f_\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f_\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d_\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c41\u0c32\u0c48_\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41_\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d_\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d_\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d_\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d".split("_"),monthsShort:"\u0c1c\u0c28._\u0c2b\u0c3f\u0c2c\u0c4d\u0c30._\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f_\u0c0f\u0c2a\u0c4d\u0c30\u0c3f._\u0c2e\u0c47_\u0c1c\u0c42\u0c28\u0c4d_\u0c1c\u0c41\u0c32\u0c48_\u0c06\u0c17._\u0c38\u0c46\u0c2a\u0c4d._\u0c05\u0c15\u0c4d\u0c1f\u0c4b._\u0c28\u0c35._\u0c21\u0c3f\u0c38\u0c46.".split("_"),monthsParseExact:!0,weekdays:"\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02_\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02_\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02_\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02_\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02_\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02".split("_"),weekdaysShort:"\u0c06\u0c26\u0c3f_\u0c38\u0c4b\u0c2e_\u0c2e\u0c02\u0c17\u0c33_\u0c2c\u0c41\u0c27_\u0c17\u0c41\u0c30\u0c41_\u0c36\u0c41\u0c15\u0c4d\u0c30_\u0c36\u0c28\u0c3f".split("_"),weekdaysMin:"\u0c06_\u0c38\u0c4b_\u0c2e\u0c02_\u0c2c\u0c41_\u0c17\u0c41_\u0c36\u0c41_\u0c36".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[\u0c28\u0c47\u0c21\u0c41] LT",nextDay:"[\u0c30\u0c47\u0c2a\u0c41] LT",nextWeek:"dddd, LT",lastDay:"[\u0c28\u0c3f\u0c28\u0c4d\u0c28] LT",lastWeek:"[\u0c17\u0c24] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u0c32\u0c4b",past:"%s \u0c15\u0c4d\u0c30\u0c3f\u0c24\u0c02",s:"\u0c15\u0c4a\u0c28\u0c4d\u0c28\u0c3f \u0c15\u0c4d\u0c37\u0c23\u0c3e\u0c32\u0c41",ss:"%d \u0c38\u0c46\u0c15\u0c28\u0c4d\u0c32\u0c41",m:"\u0c12\u0c15 \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c02",mm:"%d \u0c28\u0c3f\u0c2e\u0c3f\u0c37\u0c3e\u0c32\u0c41",h:"\u0c12\u0c15 \u0c17\u0c02\u0c1f",hh:"%d \u0c17\u0c02\u0c1f\u0c32\u0c41",d:"\u0c12\u0c15 \u0c30\u0c4b\u0c1c\u0c41",dd:"%d \u0c30\u0c4b\u0c1c\u0c41\u0c32\u0c41",M:"\u0c12\u0c15 \u0c28\u0c46\u0c32",MM:"%d \u0c28\u0c46\u0c32\u0c32\u0c41",y:"\u0c12\u0c15 \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c02",yy:"%d \u0c38\u0c02\u0c35\u0c24\u0c4d\u0c38\u0c30\u0c3e\u0c32\u0c41"},dayOfMonthOrdinalParse:/\d{1,2}\u0c35/,ordinal:"%d\u0c35",meridiemParse:/\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f|\u0c09\u0c26\u0c2f\u0c02|\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02|\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"===e?t<4?t:t+12:"\u0c09\u0c26\u0c2f\u0c02"===e?t:"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02"===e?t>=10?t:t+12:"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02"===e?t+12:void 0},meridiem:function(t,e,n){return t<4?"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f":t<10?"\u0c09\u0c26\u0c2f\u0c02":t<17?"\u0c2e\u0c27\u0c4d\u0c2f\u0c3e\u0c39\u0c4d\u0c28\u0c02":t<20?"\u0c38\u0c3e\u0c2f\u0c02\u0c24\u0c4d\u0c30\u0c02":"\u0c30\u0c3e\u0c24\u0c4d\u0c30\u0c3f"},week:{dow:0,doy:6}})}()},"XQh+":function(t,e,n){"use strict";var a=n("CDJp"),r=n("vvH+"),i=n("RDha");a._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('
    ');var n=t.data,a=n.datasets,r=n.labels;if(a.length)for(var i=0;i'),r[i]&&e.push(r[i]),e.push("");return e.push("
"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,a){var r=t.getDatasetMeta(0),s=e.datasets[0],o=r.data[a],u=o&&o.custom||{},c=i.valueAtIndexOrDefault,l=t.options.elements.arc;return{text:n,fillStyle:u.backgroundColor?u.backgroundColor:c(s.backgroundColor,a,l.backgroundColor),strokeStyle:u.borderColor?u.borderColor:c(s.borderColor,a,l.borderColor),lineWidth:u.borderWidth?u.borderWidth:c(s.borderWidth,a,l.borderWidth),hidden:isNaN(s.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,a,r,i=e.index,s=this.chart;for(n=0,a=(s.data.datasets||[]).length;n=Math.PI?-1:h<-Math.PI?1:0))+p,b={x:Math.cos(h),y:Math.sin(h)},m={x:Math.cos(g),y:Math.sin(g)},y=h<=0&&g>=0||h<=2*Math.PI&&2*Math.PI<=g,v=h<=.5*Math.PI&&.5*Math.PI<=g||h<=2.5*Math.PI&&2.5*Math.PI<=g,_=h<=-Math.PI&&-Math.PI<=g||h<=Math.PI&&Math.PI<=g,x=h<=.5*-Math.PI&&.5*-Math.PI<=g||h<=1.5*Math.PI&&1.5*Math.PI<=g,T=f/100,w={x:_?-1:Math.min(b.x*(b.x<0?1:T),m.x*(m.x<0?1:T)),y:x?-1:Math.min(b.y*(b.y<0?1:T),m.y*(m.y<0?1:T))},S={x:y?1:Math.max(b.x*(b.x>0?1:T),m.x*(m.x>0?1:T)),y:v?1:Math.max(b.y*(b.y>0?1:T),m.y*(m.y>0?1:T))},O={width:.5*(S.x-w.x),height:.5*(S.y-w.y)};c=Math.min(o/O.width,u/O.height),l={x:-.5*(S.x+w.x),y:-.5*(S.y+w.y)}}n.borderWidth=e.getMaxBorderWidth(d.data),n.outerRadius=Math.max((c-n.borderWidth)/2,0),n.innerRadius=Math.max(f?n.outerRadius/100*f:0,0),n.radiusLength=(n.outerRadius-n.innerRadius)/n.getVisibleDatasetCount(),n.offsetX=l.x*n.outerRadius,n.offsetY=l.y*n.outerRadius,d.total=e.calculateTotal(),e.outerRadius=n.outerRadius-n.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-n.radiusLength,0),i.each(d.data,function(n,a){e.updateElement(n,a,t)})},updateElement:function(t,e,n){var a=this,r=a.chart,s=r.chartArea,o=r.options,u=o.animation,c=(s.left+s.right)/2,l=(s.top+s.bottom)/2,d=o.rotation,f=o.rotation,p=a.getDataset(),h=n&&u.animateRotate?0:t.hidden?0:a.calculateCircumference(p.data[e])*(o.circumference/(2*Math.PI));i.extend(t,{_datasetIndex:a.index,_index:e,_model:{x:c+r.offsetX,y:l+r.offsetY,startAngle:d,endAngle:f,circumference:h,outerRadius:n&&u.animateScale?0:a.outerRadius,innerRadius:n&&u.animateScale?0:a.innerRadius,label:(0,i.valueAtIndexOrDefault)(p.label,e,r.data.labels[e])}});var g=t._model,b=t.custom||{},m=i.valueAtIndexOrDefault,y=this.chart.options.elements.arc;g.backgroundColor=b.backgroundColor?b.backgroundColor:m(p.backgroundColor,e,y.backgroundColor),g.borderColor=b.borderColor?b.borderColor:m(p.borderColor,e,y.borderColor),g.borderWidth=b.borderWidth?b.borderWidth:m(p.borderWidth,e,y.borderWidth),n&&u.animateRotate||(g.startAngle=0===e?o.rotation:a.getMeta().data[e-1]._model.endAngle,g.endAngle=g.startAngle+g.circumference),t.pivot()},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),a=0;return i.each(n.data,function(n,r){t=e.data[r],isNaN(t)||n.hidden||(a+=Math.abs(t))}),a},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){for(var e,n,a=0,r=this.index,i=t.length,s=0;s(a=(e=t[s]._model?t[s]._model.borderWidth:0)>a?e:a)?n:a;return a}})}},Xg1U:function(t,e,n){"use strict";n.d(e,"a",function(){return u});var a=n("CcnG"),r=n("eajB"),i=(n("Ip0R"),a["\u0275crt"]({encapsulation:0,styles:[".tooltip[_nghost-%COMP%] {\n display: block;\n pointer-events: none;\n }\n .bs3.tooltip.top[_nghost-%COMP%] > .arrow[_ngcontent-%COMP%] {\n margin-left: -2px;\n }\n .bs3.tooltip.bottom[_nghost-%COMP%] {\n margin-top: 0px;\n }\n .bs3.bs-tooltip-left[_nghost-%COMP%], .bs3.bs-tooltip-right[_nghost-%COMP%]{\n margin: 0px;\n }\n .bs3.bs-tooltip-right[_nghost-%COMP%] .arrow[_ngcontent-%COMP%], .bs3.bs-tooltip-left[_nghost-%COMP%] .arrow[_ngcontent-%COMP%] {\n margin: .3rem 0;\n }"],data:{}}));function s(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,0,"div",[["class","tooltip-arrow arrow"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"div",[["class","tooltip-inner"]],null,null,null,null,null)),a["\u0275ncd"](null,0)],null,null)}function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"bs-tooltip-container",[["role","tooltip"]],[[8,"className",0],[2,"show",null],[2,"bs3",null],[1,"id",0]],null,null,s,i)),a["\u0275did"](1,4243456,null,0,r.b,[r.a],null,null)],null,function(t,e){t(e,0,0,"tooltip in tooltip-"+a["\u0275nov"](e,1).placement+" bs-tooltip-"+a["\u0275nov"](e,1).placement+" "+a["\u0275nov"](e,1).placement+" "+a["\u0275nov"](e,1).containerClass,!a["\u0275nov"](e,1).isBs3,a["\u0275nov"](e,1).isBs3,a["\u0275nov"](e,1).id)})}var u=a["\u0275ccf"]("bs-tooltip-container",r.b,o,{},{},["*"])},XlPw:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("6blF");function r(t,e){return new a.a(e?function(n){return e.schedule(i,0,{error:t,subscriber:n})}:function(e){return e.error(t)})}function i(t){t.subscriber.error(t.error)}},Y0Co:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("Lwhh"),o=n("8iEZ"),u=n("L5sC");n("BARL"),e.DataTableColumnDirective=function(){function t(t){this.columnChangesService=t,this.isFirstChange=!0}return t.prototype.ngOnChanges=function(){this.isFirstChange?this.isFirstChange=!1:this.columnChangesService.onInputChange()},a([i.Input(),r("design:type",String)],t.prototype,"name",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"prop",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"frozenLeft",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"frozenRight",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"flexGrow",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"resizeable",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"comparator",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"pipe",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"sortable",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"draggable",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"canAutoResize",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"minWidth",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"width",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"maxWidth",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"checkboxable",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"headerCheckboxable",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"headerClass",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"cellClass",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"isTreeColumn",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"treeLevelIndent",void 0),a([i.Input(),r("design:type",Function)],t.prototype,"summaryFunc",void 0),a([i.Input(),r("design:type",i.TemplateRef)],t.prototype,"summaryTemplate",void 0),a([i.Input(),i.ContentChild(o.DataTableColumnCellDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"cellTemplate",void 0),a([i.Input(),i.ContentChild(s.DataTableColumnHeaderDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"headerTemplate",void 0),a([i.Input(),i.ContentChild(u.DataTableColumnCellTreeToggle,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"treeToggleTemplate",void 0),a([i.Directive({selector:"ngx-datatable-column"})],t)}()},Y4Rb:function(t,e,n){"use strict";var a=n("RDha"),r=n("cdu6"),i=n("tjFV"),s=n("g8vO");t.exports=function(t){var e={position:"left",ticks:{callback:s.formatters.logarithmic}},n=r.extend({determineDataLimits:function(){var t=this,e=t.options,n=t.chart,r=n.data.datasets,i=t.isHorizontal();function s(e){return i?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null,t.minNotZero=null;var o=e.stacked;if(void 0===o&&a.each(r,function(t,e){if(!o){var a=n.getDatasetMeta(e);n.isDatasetVisible(e)&&s(a)&&void 0!==a.stack&&(o=!0)}}),e.stacked||o){var u={};a.each(r,function(r,i){var o=n.getDatasetMeta(i),c=[o.type,void 0===e.stacked&&void 0===o.stack?i:"",o.stack].join(".");n.isDatasetVisible(i)&&s(o)&&(void 0===u[c]&&(u[c]=[]),a.each(r.data,function(e,n){var a=u[c],r=+t.getRightValue(e);isNaN(r)||o.data[n].hidden||r<0||(a[n]=a[n]||0,a[n]+=r)}))}),a.each(u,function(e){if(e.length>0){var n=a.min(e),r=a.max(e);t.min=null===t.min?n:Math.min(t.min,n),t.max=null===t.max?r:Math.max(t.max,r)}})}else a.each(r,function(e,r){var i=n.getDatasetMeta(r);n.isDatasetVisible(r)&&s(i)&&a.each(e.data,function(e,n){var a=+t.getRightValue(e);isNaN(a)||i.data[n].hidden||a<0||(null===t.min?t.min=a:at.max&&(t.max=a),0!==a&&(null===t.minNotZero||a0?t.min:t.max<1?Math.pow(10,Math.floor(a.log10(t.max))):1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),r=t.ticks=function(t,e){var n,r,i=[],s=a.valueOrDefault,o=s(t.min,Math.pow(10,Math.floor(a.log10(e.min)))),u=Math.floor(a.log10(e.max)),c=Math.ceil(e.max/Math.pow(10,u));0===o?(n=Math.floor(a.log10(e.minNotZero)),r=Math.floor(e.minNotZero/Math.pow(10,n)),i.push(o),o=r*Math.pow(10,n)):(n=Math.floor(a.log10(o)),r=Math.floor(o/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{i.push(o),10==++r&&(r=1,l=++n>=0?1:l),o=Math.round(r*Math.pow(10,n)*l)/l}while(n=11?t:t+12},meridiem:function(t,e,n){var a=100*t+e;return a<600?"\u064a\u06d0\u0631\u0649\u0645 \u0643\u06d0\u0686\u06d5":a<900?"\u0633\u06d5\u06be\u06d5\u0631":a<1130?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0628\u06c7\u0631\u06c7\u0646":a<1230?"\u0686\u06c8\u0634":a<1800?"\u0686\u06c8\u0634\u062a\u0649\u0646 \u0643\u06d0\u064a\u0649\u0646":"\u0643\u06d5\u0686"},calendar:{sameDay:"[\u0628\u06c8\u06af\u06c8\u0646 \u0633\u0627\u0626\u06d5\u062a] LT",nextDay:"[\u0626\u06d5\u062a\u06d5 \u0633\u0627\u0626\u06d5\u062a] LT",nextWeek:"[\u0643\u06d0\u0644\u06d5\u0631\u0643\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",lastDay:"[\u062a\u06c6\u0646\u06c8\u06af\u06c8\u0646] LT",lastWeek:"[\u0626\u0627\u0644\u062f\u0649\u0646\u0642\u0649] dddd [\u0633\u0627\u0626\u06d5\u062a] LT",sameElse:"L"},relativeTime:{future:"%s \u0643\u06d0\u064a\u0649\u0646",past:"%s \u0628\u06c7\u0631\u06c7\u0646",s:"\u0646\u06d5\u0686\u0686\u06d5 \u0633\u06d0\u0643\u0648\u0646\u062a",ss:"%d \u0633\u06d0\u0643\u0648\u0646\u062a",m:"\u0628\u0649\u0631 \u0645\u0649\u0646\u06c7\u062a",mm:"%d \u0645\u0649\u0646\u06c7\u062a",h:"\u0628\u0649\u0631 \u0633\u0627\u0626\u06d5\u062a",hh:"%d \u0633\u0627\u0626\u06d5\u062a",d:"\u0628\u0649\u0631 \u0643\u06c8\u0646",dd:"%d \u0643\u06c8\u0646",M:"\u0628\u0649\u0631 \u0626\u0627\u064a",MM:"%d \u0626\u0627\u064a",y:"\u0628\u0649\u0631 \u064a\u0649\u0644",yy:"%d \u064a\u0649\u0644"},dayOfMonthOrdinalParse:/\d{1,2}(-\u0643\u06c8\u0646\u0649|-\u0626\u0627\u064a|-\u06be\u06d5\u067e\u062a\u06d5)/,ordinal:function(t,e){switch(e){case"d":case"D":case"DDD":return t+"-\u0643\u06c8\u0646\u0649";case"w":case"W":return t+"-\u06be\u06d5\u067e\u062a\u06d5";default:return t}},preparse:function(t){return t.replace(/\u060c/g,",")},postformat:function(t){return t.replace(/,/g,"\u060c")},week:{dow:1,doy:7}})}()},YSsK:function(t,e,n){"use strict";var a=n("CDJp"),r=n("RDha"),i=n("tjFV"),s=n("g8vO");t.exports=function(t){var e={position:"left",ticks:{callback:s.formatters.linear}},n=t.LinearScaleBase.extend({determineDataLimits:function(){var t=this,e=t.options,n=t.chart,a=n.data.datasets,i=t.isHorizontal();function s(e){return i?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null;var o=e.stacked;if(void 0===o&&r.each(a,function(t,e){if(!o){var a=n.getDatasetMeta(e);n.isDatasetVisible(e)&&s(a)&&void 0!==a.stack&&(o=!0)}}),e.stacked||o){var u={};r.each(a,function(a,i){var o=n.getDatasetMeta(i),c=[o.type,void 0===e.stacked&&void 0===o.stack?i:"",o.stack].join(".");void 0===u[c]&&(u[c]={positiveValues:[],negativeValues:[]});var l=u[c].positiveValues,d=u[c].negativeValues;n.isDatasetVisible(i)&&s(o)&&r.each(a.data,function(n,a){var r=+t.getRightValue(n);isNaN(r)||o.data[a].hidden||(l[a]=l[a]||0,d[a]=d[a]||0,e.relativePoints?l[a]=100:r<0?d[a]+=r:l[a]+=r)})}),r.each(u,function(e){var n=e.positiveValues.concat(e.negativeValues),a=r.min(n),i=r.max(n);t.min=null===t.min?a:Math.min(t.min,a),t.max=null===t.max?i:Math.max(t.max,i)})}else r.each(a,function(e,a){var i=n.getDatasetMeta(a);n.isDatasetVisible(a)&&s(i)&&r.each(e.data,function(e,n){var a=+t.getRightValue(e);isNaN(a)||i.data[n].hidden||(null===t.min?t.min=a:at.max&&(t.max=a))})});t.min=isFinite(t.min)&&!isNaN(t.min)?t.min:0,t.max=isFinite(t.max)&&!isNaN(t.max)?t.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this.options.ticks;if(this.isHorizontal())t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.width/50));else{var n=r.valueOrDefault(e.fontSize,a.global.defaultFontSize);t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.height/(2*n)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this,n=e.start,a=+e.getRightValue(t),r=e.end-n;return e.isHorizontal()?e.left+e.width/r*(a-n):e.bottom-e.height/r*(a-n)},getValueForPixel:function(t){var e=this,n=e.isHorizontal();return e.start+(n?t-e.left:e.bottom-t)/(n?e.width:e.height)*(e.end-e.start)},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});i.registerScaleType("linear",n,e)}},YVFZ:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("5tze"),o=n("qwkt");n("czA5"),e.DataTableBodyCellComponent=function(){function t(t,e){this.cd=e,this.activate=new i.EventEmitter,this.treeAction=new i.EventEmitter,this.isFocused=!1,this.onCheckboxChangeFn=this.onCheckboxChange.bind(this),this.activateFn=this.activate.emit.bind(this.activate),this.cellContext={onCheckboxChangeFn:this.onCheckboxChangeFn,activateFn:this.activateFn,row:this.row,group:this.group,value:this.value,column:this.column,rowHeight:this.rowHeight,isSelected:this.isSelected,rowIndex:this.rowIndex,treeStatus:this.treeStatus,onTreeAction:this.onTreeAction.bind(this)},this._element=t.nativeElement}return Object.defineProperty(t.prototype,"group",{get:function(){return this._group},set:function(t){this._group=t,this.cellContext.group=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rowHeight",{get:function(){return this._rowHeight},set:function(t){this._rowHeight=t,this.cellContext.rowHeight=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isSelected",{get:function(){return this._isSelected},set:function(t){this._isSelected=t,this.cellContext.isSelected=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"expanded",{get:function(){return this._expanded},set:function(t){this._expanded=t,this.cellContext.expanded=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rowIndex",{get:function(){return this._rowIndex},set:function(t){this._rowIndex=t,this.cellContext.rowIndex=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"column",{get:function(){return this._column},set:function(t){this._column=t,this.cellContext.column=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"row",{get:function(){return this._row},set:function(t){this._row=t,this.cellContext.row=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"sorts",{get:function(){return this._sorts},set:function(t){this._sorts=t,this.calcSortDir=this.calcSortDir(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"treeStatus",{get:function(){return this._treeStatus},set:function(t){this._treeStatus="collapsed"!==t&&"expanded"!==t&&"loading"!==t&&"disabled"!==t?"collapsed":t,this.cellContext.treeStatus=this._treeStatus,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columnCssClasses",{get:function(){var t="datatable-body-cell";if(this.column.cellClass)if("string"==typeof this.column.cellClass)t+=" "+this.column.cellClass;else if("function"==typeof this.column.cellClass){var e=this.column.cellClass({row:this.row,group:this.group,column:this.column,value:this.value,rowHeight:this.rowHeight});if("string"==typeof e)t+=e;else if("object"==typeof e)for(var n=0,a=Object.keys(e);n]+(>|$)/g,""):t},t.prototype.onTreeAction=function(){this.treeAction.emit(this.row)},t.prototype.calcLeftMargin=function(t,e){return t.isTreeColumn?e.level*(null!=t.treeLevelIndent?t.treeLevelIndent:50):0},a([i.Input(),r("design:type",Function)],t.prototype,"displayCheck",void 0),a([i.Input(),r("design:type",Object),r("design:paramtypes",[Object])],t.prototype,"group",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"rowHeight",null),a([i.Input(),r("design:type",Boolean),r("design:paramtypes",[Boolean])],t.prototype,"isSelected",null),a([i.Input(),r("design:type",Boolean),r("design:paramtypes",[Boolean])],t.prototype,"expanded",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"rowIndex",null),a([i.Input(),r("design:type",Object),r("design:paramtypes",[Object])],t.prototype,"column",null),a([i.Input(),r("design:type",Object),r("design:paramtypes",[Object])],t.prototype,"row",null),a([i.Input(),r("design:type",Array),r("design:paramtypes",[Array])],t.prototype,"sorts",null),a([i.Input(),r("design:type",String),r("design:paramtypes",[String])],t.prototype,"treeStatus",null),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"activate",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"treeAction",void 0),a([i.ViewChild("cellTemplate",{read:i.ViewContainerRef}),r("design:type",i.ViewContainerRef)],t.prototype,"cellTemplate",void 0),a([i.HostBinding("class"),r("design:type",Object),r("design:paramtypes",[])],t.prototype,"columnCssClasses",null),a([i.HostBinding("style.width.px"),r("design:type",Number),r("design:paramtypes",[])],t.prototype,"width",null),a([i.HostBinding("style.minWidth.px"),r("design:type",Number),r("design:paramtypes",[])],t.prototype,"minWidth",null),a([i.HostBinding("style.maxWidth.px"),r("design:type",Number),r("design:paramtypes",[])],t.prototype,"maxWidth",null),a([i.HostBinding("style.height"),r("design:type",Object),r("design:paramtypes",[])],t.prototype,"height",null),a([i.HostListener("focus"),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",void 0)],t.prototype,"onFocus",null),a([i.HostListener("blur"),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",void 0)],t.prototype,"onBlur",null),a([i.HostListener("click",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onClick",null),a([i.HostListener("dblclick",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onDblClick",null),a([i.HostListener("keydown",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onKeyDown",null),a([i.Component({selector:"datatable-body-cell",changeDetection:i.ChangeDetectionStrategy.OnPush,template:'\n
\n \n \n \n \n \n \n \n \n\n \n \n \n \n
\n '})],t)}()},YuTi:function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},Z21x:function(t,e,n){"use strict";n.d(e,"a",function(){return a}),n("sne2");var a=function(){return function(t,e){var n=this;this.location=t,this.actionLabels=e,this.name=this.actionLabels.CANCEL,this.back=function(){return n.location.back()}}}()},Z4QM:function(t,e,n){!function(t){"use strict";var e=["\u062c\u0646\u0648\u0631\u064a","\u0641\u064a\u0628\u0631\u0648\u0631\u064a","\u0645\u0627\u0631\u0686","\u0627\u067e\u0631\u064a\u0644","\u0645\u0626\u064a","\u062c\u0648\u0646","\u062c\u0648\u0644\u0627\u0621\u0650","\u0622\u06af\u0633\u067d","\u0633\u064a\u067e\u067d\u0645\u0628\u0631","\u0622\u06aa\u067d\u0648\u0628\u0631","\u0646\u0648\u0645\u0628\u0631","\u068a\u0633\u0645\u0628\u0631"],a=["\u0622\u0686\u0631","\u0633\u0648\u0645\u0631","\u0627\u06b1\u0627\u0631\u0648","\u0627\u0631\u0628\u0639","\u062e\u0645\u064a\u0633","\u062c\u0645\u0639","\u0687\u0646\u0687\u0631"];n("wd/R").defineLocale("sd",{months:e,monthsShort:e,weekdays:a,weekdaysShort:a,weekdaysMin:a,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd\u060c D MMMM YYYY HH:mm"},meridiemParse:/\u0635\u0628\u062d|\u0634\u0627\u0645/,isPM:function(t){return"\u0634\u0627\u0645"===t},meridiem:function(t,e,n){return t<12?"\u0635\u0628\u062d":"\u0634\u0627\u0645"},calendar:{sameDay:"[\u0627\u0684] LT",nextDay:"[\u0633\u0680\u0627\u06bb\u064a] LT",nextWeek:"dddd [\u0627\u06b3\u064a\u0646 \u0647\u0641\u062a\u064a \u062a\u064a] LT",lastDay:"[\u06aa\u0627\u0644\u0647\u0647] LT",lastWeek:"[\u06af\u0632\u0631\u064a\u0644 \u0647\u0641\u062a\u064a] dddd [\u062a\u064a] LT",sameElse:"L"},relativeTime:{future:"%s \u067e\u0648\u0621",past:"%s \u0627\u06b3",s:"\u0686\u0646\u062f \u0633\u064a\u06aa\u0646\u068a",ss:"%d \u0633\u064a\u06aa\u0646\u068a",m:"\u0647\u06aa \u0645\u0646\u067d",mm:"%d \u0645\u0646\u067d",h:"\u0647\u06aa \u06aa\u0644\u0627\u06aa",hh:"%d \u06aa\u0644\u0627\u06aa",d:"\u0647\u06aa \u068f\u064a\u0646\u0647\u0646",dd:"%d \u068f\u064a\u0646\u0647\u0646",M:"\u0647\u06aa \u0645\u0647\u064a\u0646\u0648",MM:"%d \u0645\u0647\u064a\u0646\u0627",y:"\u0647\u06aa \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(t){return t.replace(/\u060c/g,",")},postformat:function(t){return t.replace(/,/g,"\u060c")},week:{dow:1,doy:4}})}()},ZAMP:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(t,e){return 12===t&&(t=0),"pagi"===e?t:"tengahari"===e?t>=11?t:t+12:"petang"===e||"malam"===e?t+12:void 0},meridiem:function(t,e,n){return t<11?"pagi":t<15?"tengahari":t<19?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}()},ZANz:function(t,e,n){"use strict";var a=n("CDJp"),r=n("vvH+"),i=n("RDha");a._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),a._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index0?Math.min(s,a-n):s,n=a;return s}(n,c):-1,pixels:c,start:o,end:u,stackCount:a,scale:n}},calculateBarValuePixels:function(t,e){var n,a,r,i,s,o,u=this.chart,c=this.getMeta(),l=this.getValueScale(),d=u.data.datasets,f=l.getRightValue(d[t].data[e]),p=l.options.stacked,h=c.stack,g=0;if(p||void 0===p&&void 0!==h)for(n=0;n=0&&r>0)&&(g+=r));return i=l.getPixelForValue(g),{size:o=((s=l.getPixelForValue(g+f))-i)/2,base:i,head:s,center:s+o/2}},calculateBarIndexPixels:function(t,e,n){var a=n.scale.options,r="flex"===a.barThickness?function(t,e,n){var a=e.pixels,r=a[t],i=t>0?a[t-1]:null,s=tt.length)return null;if("full"===n.pathMatch&&(e.hasChildren()||a.length0?t[t.length-1]:null}function dt(t,e){for(var n in t)t.hasOwnProperty(n)&&e(t[n],n)}function ft(t){return Object(i["\u0275isObservable"])(t)?t:Object(i["\u0275isPromise"])(t)?Object(o.a)(Promise.resolve(t)):Object(s.a)(t)}function pt(t,e,n){return n?function(t,e){return ut(t,e)}(t.queryParams,e.queryParams)&&function t(e,n){if(!mt(e.segments,n.segments))return!1;if(e.numberOfChildren!==n.numberOfChildren)return!1;for(var a in n.children){if(!e.children[a])return!1;if(!t(e.children[a],n.children[a]))return!1}return!0}(t.root,e.root):function(t,e){return Object.keys(e).length<=Object.keys(t).length&&Object.keys(e).every(function(n){return e[n]===t[n]})}(t.queryParams,e.queryParams)&&function t(e,n){return function e(n,a,r){if(n.segments.length>r.length)return!!mt(s=n.segments.slice(0,r.length),r)&&!a.hasChildren();if(n.segments.length===r.length){if(!mt(n.segments,r))return!1;for(var i in a.children){if(!n.children[i])return!1;if(!t(n.children[i],a.children[i]))return!1}return!0}var s=r.slice(0,n.segments.length),o=r.slice(n.segments.length);return!!mt(n.segments,s)&&!!n.children[X]&&e(n.children[X],a,o)}(e,n,n.segments)}(t.root,e.root)}var ht=function(){function t(t,e,n){this.root=t,this.queryParams=e,this.fragment=n}return Object.defineProperty(t.prototype,"queryParamMap",{get:function(){return this._queryParamMap||(this._queryParamMap=Q(this.queryParams)),this._queryParamMap},enumerable:!0,configurable:!0}),t.prototype.toString=function(){return xt.serialize(this)},t}(),gt=function(){function t(t,e){var n=this;this.segments=t,this.children=e,this.parent=null,dt(e,function(t,e){return t.parent=n})}return t.prototype.hasChildren=function(){return this.numberOfChildren>0},Object.defineProperty(t.prototype,"numberOfChildren",{get:function(){return Object.keys(this.children).length},enumerable:!0,configurable:!0}),t.prototype.toString=function(){return Tt(this)},t}(),bt=function(){function t(t,e){this.path=t,this.parameters=e}return Object.defineProperty(t.prototype,"parameterMap",{get:function(){return this._parameterMap||(this._parameterMap=Q(this.parameters)),this._parameterMap},enumerable:!0,configurable:!0}),t.prototype.toString=function(){return kt(this)},t}();function mt(t,e){return t.length===e.length&&t.every(function(t,n){return t.path===e[n].path})}function yt(t,e){var n=[];return dt(t.children,function(t,a){a===X&&(n=n.concat(e(t,a)))}),dt(t.children,function(t,a){a!==X&&(n=n.concat(e(t,a)))}),n}var vt=function(){return function(){}}(),_t=function(){function t(){}return t.prototype.parse=function(t){var e=new Et(t);return new ht(e.parseRootSegment(),e.parseQueryParams(),e.parseFragment())},t.prototype.serialize=function(t){var e,n;return"/"+function t(e,n){if(!e.hasChildren())return Tt(e);if(n){var a=e.children[X]?t(e.children[X],!1):"",r=[];return dt(e.children,function(e,n){n!==X&&r.push(n+":"+t(e,!1))}),r.length>0?a+"("+r.join("//")+")":a}var i=yt(e,function(n,a){return a===X?[t(e.children[X],!1)]:[a+":"+t(n,!1)]});return Tt(e)+"/("+i.join("//")+")"}(t.root,!0)+(e=t.queryParams,(n=Object.keys(e).map(function(t){var n=e[t];return Array.isArray(n)?n.map(function(e){return St(t)+"="+St(e)}).join("&"):St(t)+"="+St(n)})).length?"?"+n.join("&"):"")+("string"==typeof t.fragment?"#"+encodeURI(t.fragment):"")},t}(),xt=new _t;function Tt(t){return t.segments.map(function(t){return kt(t)}).join("/")}function wt(t){return encodeURIComponent(t).replace(/%40/g,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",")}function St(t){return wt(t).replace(/%3B/gi,";")}function Ot(t){return wt(t).replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/%26/gi,"&")}function It(t){return decodeURIComponent(t)}function Ct(t){return It(t.replace(/\+/g,"%20"))}function kt(t){return""+Ot(t.path)+(e=t.parameters,Object.keys(e).map(function(t){return";"+Ot(t)+"="+Ot(e[t])}).join(""));var e}var Nt=/^[^\/()?;=#]+/;function Rt(t){var e=t.match(Nt);return e?e[0]:""}var At=/^[^=?&#]+/,Dt=/^[^?&#]+/,Et=function(){function t(t){this.url=t,this.remaining=t}return t.prototype.parseRootSegment=function(){return this.consumeOptional("/"),""===this.remaining||this.peekStartsWith("?")||this.peekStartsWith("#")?new gt([],{}):new gt([],this.parseChildren())},t.prototype.parseQueryParams=function(){var t={};if(this.consumeOptional("?"))do{this.parseQueryParam(t)}while(this.consumeOptional("&"));return t},t.prototype.parseFragment=function(){return this.consumeOptional("#")?decodeURIComponent(this.remaining):null},t.prototype.parseChildren=function(){if(""===this.remaining)return{};this.consumeOptional("/");var t=[];for(this.peekStartsWith("(")||t.push(this.parseSegment());this.peekStartsWith("/")&&!this.peekStartsWith("//")&&!this.peekStartsWith("/(");)this.capture("/"),t.push(this.parseSegment());var e={};this.peekStartsWith("/(")&&(this.capture("/"),e=this.parseParens(!0));var n={};return this.peekStartsWith("(")&&(n=this.parseParens(!1)),(t.length>0||Object.keys(e).length>0)&&(n[X]=new gt(t,e)),n},t.prototype.parseSegment=function(){var t=Rt(this.remaining);if(""===t&&this.peekStartsWith(";"))throw new Error("Empty path url segment cannot have parameters: '"+this.remaining+"'.");return this.capture(t),new bt(It(t),this.parseMatrixParams())},t.prototype.parseMatrixParams=function(){for(var t={};this.consumeOptional(";");)this.parseParam(t);return t},t.prototype.parseParam=function(t){var e=Rt(this.remaining);if(e){this.capture(e);var n="";if(this.consumeOptional("=")){var a=Rt(this.remaining);a&&this.capture(n=a)}t[It(e)]=It(n)}},t.prototype.parseQueryParam=function(t){var e,n=(e=this.remaining.match(At))?e[0]:"";if(n){this.capture(n);var a="";if(this.consumeOptional("=")){var r=function(t){var e=t.match(Dt);return e?e[0]:""}(this.remaining);r&&this.capture(a=r)}var i=Ct(n),s=Ct(a);if(t.hasOwnProperty(i)){var o=t[i];Array.isArray(o)||(t[i]=o=[o]),o.push(s)}else t[i]=s}},t.prototype.parseParens=function(t){var e={};for(this.capture("(");!this.consumeOptional(")")&&this.remaining.length>0;){var n=Rt(this.remaining),a=this.remaining[n.length];if("/"!==a&&")"!==a&&";"!==a)throw new Error("Cannot parse url '"+this.url+"'");var r=void 0;n.indexOf(":")>-1?(r=n.substr(0,n.indexOf(":")),this.capture(r),this.capture(":")):t&&(r=X);var i=this.parseChildren();e[r]=1===Object.keys(i).length?i[X]:new gt([],i),this.consumeOptional("//")}return e},t.prototype.peekStartsWith=function(t){return this.remaining.startsWith(t)},t.prototype.consumeOptional=function(t){return!!this.peekStartsWith(t)&&(this.remaining=this.remaining.substring(t.length),!0)},t.prototype.capture=function(t){if(!this.consumeOptional(t))throw new Error('Expected "'+t+'".')},t}(),Lt=function(){function t(t){this._root=t}return Object.defineProperty(t.prototype,"root",{get:function(){return this._root.value},enumerable:!0,configurable:!0}),t.prototype.parent=function(t){var e=this.pathFromRoot(t);return e.length>1?e[e.length-2]:null},t.prototype.children=function(t){var e=Pt(t,this._root);return e?e.children.map(function(t){return t.value}):[]},t.prototype.firstChild=function(t){var e=Pt(t,this._root);return e&&e.children.length>0?e.children[0].value:null},t.prototype.siblings=function(t){var e=Mt(t,this._root);return e.length<2?[]:e[e.length-2].children.map(function(t){return t.value}).filter(function(e){return e!==t})},t.prototype.pathFromRoot=function(t){return Mt(t,this._root).map(function(t){return t.value})},t}();function Pt(t,e){var n,r;if(t===e.value)return e;try{for(var i=Object(a.__values)(e.children),s=i.next();!s.done;s=i.next()){var o=Pt(t,s.value);if(o)return o}}catch(u){n={error:u}}finally{try{s&&!s.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}return null}function Mt(t,e){var n,r;if(t===e.value)return[e];try{for(var i=Object(a.__values)(e.children),s=i.next();!s.done;s=i.next()){var o=Mt(t,s.value);if(o.length)return o.unshift(e),o}}catch(u){n={error:u}}finally{try{s&&!s.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}return[]}var qt=function(){function t(t,e){this.value=t,this.children=e}return t.prototype.toString=function(){return"TreeNode("+this.value+")"},t}();function jt(t){var e={};return t&&t.children.forEach(function(t){return e[t.value.outlet]=t}),e}var Ft=function(t){function e(e,n){var a=t.call(this,e)||this;return a.snapshot=n,Bt(a,e),a}return Object(a.__extends)(e,t),e.prototype.toString=function(){return this.snapshot.toString()},e}(Lt);function zt(t,e){var n=function(t,e){var n=new Vt([],{},{},"",{},X,e,null,t.root,-1,{});return new Ht("",new qt(n,[]))}(t,e),a=new u.a([new bt("",{})]),r=new u.a({}),i=new u.a({}),s=new u.a({}),o=new u.a(""),c=new Gt(a,r,s,o,i,X,e,n.root);return c.snapshot=n.root,new Ft(new qt(c,[]),n)}var Gt=function(){function t(t,e,n,a,r,i,s,o){this.url=t,this.params=e,this.queryParams=n,this.fragment=a,this.data=r,this.outlet=i,this.component=s,this._futureSnapshot=o}return Object.defineProperty(t.prototype,"routeConfig",{get:function(){return this._futureSnapshot.routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"paramMap",{get:function(){return this._paramMap||(this._paramMap=this.params.pipe(Object(g.a)(function(t){return Q(t)}))),this._paramMap},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"queryParamMap",{get:function(){return this._queryParamMap||(this._queryParamMap=this.queryParams.pipe(Object(g.a)(function(t){return Q(t)}))),this._queryParamMap},enumerable:!0,configurable:!0}),t.prototype.toString=function(){return this.snapshot?this.snapshot.toString():"Future("+this._futureSnapshot+")"},t}();function Yt(t,e){void 0===e&&(e="emptyOnly");var n=t.pathFromRoot,r=0;if("always"!==e)for(r=n.length-1;r>=1;){var i=n[r],s=n[r-1];if(i.routeConfig&&""===i.routeConfig.path)r--;else{if(s.component)break;r--}}return function(t){return t.reduce(function(t,e){return{params:Object(a.__assign)({},t.params,e.params),data:Object(a.__assign)({},t.data,e.data),resolve:Object(a.__assign)({},t.resolve,e._resolvedData)}},{params:{},data:{},resolve:{}})}(n.slice(r))}var Vt=function(){function t(t,e,n,a,r,i,s,o,u,c,l){this.url=t,this.params=e,this.queryParams=n,this.fragment=a,this.data=r,this.outlet=i,this.component=s,this.routeConfig=o,this._urlSegment=u,this._lastPathIndex=c,this._resolve=l}return Object.defineProperty(t.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"paramMap",{get:function(){return this._paramMap||(this._paramMap=Q(this.params)),this._paramMap},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"queryParamMap",{get:function(){return this._queryParamMap||(this._queryParamMap=Q(this.queryParams)),this._queryParamMap},enumerable:!0,configurable:!0}),t.prototype.toString=function(){return"Route(url:'"+this.url.map(function(t){return t.toString()}).join("/")+"', path:'"+(this.routeConfig?this.routeConfig.path:"")+"')"},t}(),Ht=function(t){function e(e,n){var a=t.call(this,n)||this;return a.url=e,Bt(a,n),a}return Object(a.__extends)(e,t),e.prototype.toString=function(){return Ut(this._root)},e}(Lt);function Bt(t,e){e.value._routerState=t,e.children.forEach(function(e){return Bt(t,e)})}function Ut(t){var e=t.children.length>0?" { "+t.children.map(Ut).join(", ")+" } ":"";return""+t.value+e}function Wt(t){if(t.snapshot){var e=t.snapshot,n=t._futureSnapshot;t.snapshot=n,ut(e.queryParams,n.queryParams)||t.queryParams.next(n.queryParams),e.fragment!==n.fragment&&t.fragment.next(n.fragment),ut(e.params,n.params)||t.params.next(n.params),function(t,e){if(t.length!==e.length)return!1;for(var n=0;n0&&$t(n[0]))throw new Error("Root segment cannot have matrix parameters");var a=n.find(function(t){return"object"==typeof t&&null!=t&&t.outlets});if(a&&a!==lt(n))throw new Error("{outlets:{}} has to be the last command")}return t.prototype.toRoot=function(){return this.isAbsolute&&1===this.commands.length&&"/"==this.commands[0]},t}(),Jt=function(){return function(t,e,n){this.segmentGroup=t,this.processChildren=e,this.index=n}}();function Qt(t){return"object"==typeof t&&null!=t&&t.outlets?t.outlets[X]:""+t}function te(t,e,n){if(t||(t=new gt([],{})),0===t.segments.length&&t.hasChildren())return ee(t,e,n);var a=function(t,e,n){for(var a=0,r=e,i={match:!1,pathIndex:0,commandIndex:0};r=n.length)return i;var s=t.segments[r],o=Qt(n[a]),u=a0&&void 0===o)break;if(o&&u&&"object"==typeof u&&void 0===u.outlets){if(!ie(o,u,s))return i;a+=2}else{if(!ie(o,{},s))return i;a++}r++}return{match:!0,pathIndex:r,commandIndex:a}}(t,e,n),r=n.slice(a.commandIndex);if(a.match&&a.pathIndex0?new gt([],((a={})[X]=t,a)):t;return new ht(r,e,n)},t.prototype.expandSegmentGroup=function(t,e,n,a){return 0===n.segments.length&&n.hasChildren()?this.expandChildren(t,e,n).pipe(Object(g.a)(function(t){return new gt([],t)})):this.expandSegment(t,n,e,n.segments,a,!0)},t.prototype.expandChildren=function(t,e,n){var a=this;return function(n,r){if(0===Object.keys(n).length)return Object(s.a)({});var i=[],o=[],u={};return dt(n,function(n,r){var s,c,l=(s=r,c=n,a.expandSegmentGroup(t,e,c,s)).pipe(Object(g.a)(function(t){return u[r]=t}));r===X?i.push(l):o.push(l)}),s.a.apply(null,i.concat(o)).pipe(Object(b.a)(),Object(m.a)(),Object(g.a)(function(){return u}))}(n.children)},t.prototype.expandSegment=function(t,e,n,r,i,o){var u=this;return s.a.apply(void 0,Object(a.__spread)(n)).pipe(Object(g.a)(function(a){return u.expandSegmentAgainstRoute(t,e,n,a,r,i,o).pipe(Object(y.a)(function(t){if(t instanceof le)return Object(s.a)(null);throw t}))}),Object(b.a)(),Object(v.a)(function(t){return!!t}),Object(y.a)(function(t,n){if(t instanceof l.a||"EmptyError"===t.name){if(u.noLeftoversInUrl(e,r,i))return Object(s.a)(new gt([],{}));throw new le(e)}throw t}))},t.prototype.noLeftoversInUrl=function(t,e,n){return 0===e.length&&!t.children[n]},t.prototype.expandSegmentAgainstRoute=function(t,e,n,a,r,i,s){return ve(a)!==i?fe(e):void 0===a.redirectTo?this.matchSegmentAgainstRoute(t,e,a,r):s&&this.allowRedirects?this.expandSegmentAgainstRouteUsingRedirect(t,e,n,a,r,i):fe(e)},t.prototype.expandSegmentAgainstRouteUsingRedirect=function(t,e,n,a,r,i){return"**"===a.path?this.expandWildCardWithParamsAgainstRouteUsingRedirect(t,n,a,i):this.expandRegularSegmentAgainstRouteUsingRedirect(t,e,n,a,r,i)},t.prototype.expandWildCardWithParamsAgainstRouteUsingRedirect=function(t,e,n,a){var r=this,i=this.applyRedirectCommands([],n.redirectTo,{});return n.redirectTo.startsWith("/")?pe(i):this.lineralizeSegments(n,i).pipe(Object(_.a)(function(n){var i=new gt(n,{});return r.expandSegment(t,i,e,n,a,!1)}))},t.prototype.expandRegularSegmentAgainstRouteUsingRedirect=function(t,e,n,a,r,i){var s=this,o=be(e,a,r),u=o.consumedSegments,c=o.lastChild,l=o.positionalParamSegments;if(!o.matched)return fe(e);var d=this.applyRedirectCommands(u,a.redirectTo,l);return a.redirectTo.startsWith("/")?pe(d):this.lineralizeSegments(a,d).pipe(Object(_.a)(function(a){return s.expandSegment(t,e,n,a.concat(r.slice(c)),i,!1)}))},t.prototype.matchSegmentAgainstRoute=function(t,e,n,r){var i=this;if("**"===n.path)return n.loadChildren?this.configLoader.load(t.injector,n).pipe(Object(g.a)(function(t){return n._loadedConfig=t,new gt(r,{})})):Object(s.a)(new gt(r,{}));var o=be(e,n,r),u=o.consumedSegments,c=o.lastChild;if(!o.matched)return fe(e);var l=r.slice(c);return this.getChildConfig(t,n,r).pipe(Object(_.a)(function(t){var n=t.module,r=t.routes,o=function(t,e,n,r){return n.length>0&&function(t,e,n){return r.some(function(n){return ye(t,e,n)&&ve(n)!==X})}(t,n)?{segmentGroup:me(new gt(e,function(t,e){var n,r,i={};i[X]=e;try{for(var s=Object(a.__values)(t),o=s.next();!o.done;o=s.next()){var u=o.value;""===u.path&&ve(u)!==X&&(i[ve(u)]=new gt([],{}))}}catch(c){n={error:c}}finally{try{o&&!o.done&&(r=s.return)&&r.call(s)}finally{if(n)throw n.error}}return i}(r,new gt(n,t.children)))),slicedSegments:[]}:0===n.length&&function(t,e,n){return r.some(function(n){return ye(t,e,n)})}(t,n)?{segmentGroup:me(new gt(t.segments,function(t,e,n,r){var i,s,o={};try{for(var u=Object(a.__values)(n),c=u.next();!c.done;c=u.next()){var l=c.value;ye(t,e,l)&&!r[ve(l)]&&(o[ve(l)]=new gt([],{}))}}catch(d){i={error:d}}finally{try{c&&!c.done&&(s=u.return)&&s.call(u)}finally{if(i)throw i.error}}return Object(a.__assign)({},r,o)}(t,n,r,t.children))),slicedSegments:n}:{segmentGroup:t,slicedSegments:n}}(e,u,l,r),c=o.segmentGroup,d=o.slicedSegments;return 0===d.length&&c.hasChildren()?i.expandChildren(n,r,c).pipe(Object(g.a)(function(t){return new gt(u,t)})):0===r.length&&0===d.length?Object(s.a)(new gt(u,{})):i.expandSegment(n,c,r,d,X,!0).pipe(Object(g.a)(function(t){return new gt(u.concat(t.segments),t.children)}))}))},t.prototype.getChildConfig=function(t,e,n){var a=this;return e.children?Object(s.a)(new at(e.children,t)):e.loadChildren?void 0!==e._loadedConfig?Object(s.a)(e._loadedConfig):function(t,e,n){var a=e.canLoad;return a&&0!==a.length?Object(o.a)(a).pipe(Object(g.a)(function(a){var r,i=t.get(a);if(function(t){return t&&ue(t.canLoad)}(i))r=i.canLoad(e,n);else{if(!ue(i))throw new Error("Invalid CanLoad guard");r=i(e,n)}return ft(r)})).pipe(Object(b.a)(),Object(x.a)(function(t){return!0===t})):Object(s.a)(!0)}(t.injector,e,n).pipe(Object(_.a)(function(n){return n?a.configLoader.load(t.injector,e).pipe(Object(g.a)(function(t){return e._loadedConfig=t,t})):function(t){return new c.a(function(e){return e.error(et("Cannot load children because the guard of the route \"path: '"+t.path+"'\" returned false"))})}(e)})):Object(s.a)(new at([],t))},t.prototype.lineralizeSegments=function(t,e){for(var n=[],a=e.root;;){if(n=n.concat(a.segments),0===a.numberOfChildren)return Object(s.a)(n);if(a.numberOfChildren>1||!a.children[X])return he(t.redirectTo);a=a.children[X]}},t.prototype.applyRedirectCommands=function(t,e,n){return this.applyRedirectCreatreUrlTree(e,this.urlSerializer.parse(e),t,n)},t.prototype.applyRedirectCreatreUrlTree=function(t,e,n,a){var r=this.createSegmentGroup(t,e.root,n,a);return new ht(r,this.createQueryParams(e.queryParams,this.urlTree.queryParams),e.fragment)},t.prototype.createQueryParams=function(t,e){var n={};return dt(t,function(t,a){if("string"==typeof t&&t.startsWith(":")){var r=t.substring(1);n[a]=e[r]}else n[a]=t}),n},t.prototype.createSegmentGroup=function(t,e,n,a){var r=this,i=this.createSegments(t,e.segments,n,a),s={};return dt(e.children,function(e,i){s[i]=r.createSegmentGroup(t,e,n,a)}),new gt(i,s)},t.prototype.createSegments=function(t,e,n,a){var r=this;return e.map(function(e){return e.path.startsWith(":")?r.findPosParam(t,e,a):r.findOrReturn(e,n)})},t.prototype.findPosParam=function(t,e,n){var a=n[e.path.substring(1)];if(!a)throw new Error("Cannot redirect to '"+t+"'. Cannot find '"+e.path+"'.");return a},t.prototype.findOrReturn=function(t,e){var n,r,i=0;try{for(var s=Object(a.__values)(e),o=s.next();!o.done;o=s.next()){var u=o.value;if(u.path===t.path)return e.splice(i),u;i++}}catch(c){n={error:c}}finally{try{o&&!o.done&&(r=s.return)&&r.call(s)}finally{if(n)throw n.error}}return t},t}();function be(t,e,n){if(""===e.path)return"full"===e.pathMatch&&(t.hasChildren()||n.length>0)?{matched:!1,consumedSegments:[],lastChild:0,positionalParamSegments:{}}:{matched:!0,consumedSegments:[],lastChild:0,positionalParamSegments:{}};var a=(e.matcher||nt)(n,t,e);return a?{matched:!0,consumedSegments:a.consumed,lastChild:a.consumed.length,positionalParamSegments:a.posParams}:{matched:!1,consumedSegments:[],lastChild:0,positionalParamSegments:{}}}function me(t){if(1===t.numberOfChildren&&t.children[X]){var e=t.children[X];return new gt(t.segments.concat(e.segments),e.children)}return t}function ye(t,e,n){return(!(t.hasChildren()||e.length>0)||"full"!==n.pathMatch)&&""===n.path&&void 0!==n.redirectTo}function ve(t){return t.outlet||X}var _e=function(){return function(t){this.path=t,this.route=this.path[this.path.length-1]}}(),xe=function(){return function(t,e){this.component=t,this.route=e}}();function Te(t,e,n){var a=function(t){if(!t)return null;for(var e=t.parent;e;e=e.parent){var n=e.routeConfig;if(n&&n._loadedConfig)return n._loadedConfig}return null}(e);return(a?a.module.injector:n).get(t)}function we(t,e,n,a,r){void 0===r&&(r={canDeactivateChecks:[],canActivateChecks:[]});var i=jt(e);return t.children.forEach(function(t){!function(t,e,n,a,r){void 0===r&&(r={canDeactivateChecks:[],canActivateChecks:[]});var i=t.value,s=e?e.value:null,o=n?n.getContext(t.value.outlet):null;if(s&&i.routeConfig===s.routeConfig){var u=function(t,e,n){if("function"==typeof n)return n(t,e);switch(n){case"pathParamsChange":return!mt(t.url,e.url);case"pathParamsOrQueryParamsChange":return!mt(t.url,e.url)||!ut(t.queryParams,e.queryParams);case"always":return!0;case"paramsOrQueryParamsChange":return!Kt(t,e)||!ut(t.queryParams,e.queryParams);case"paramsChange":default:return!Kt(t,e)}}(s,i,i.routeConfig.runGuardsAndResolvers);u?r.canActivateChecks.push(new _e(a)):(i.data=s.data,i._resolvedData=s._resolvedData),we(t,e,i.component?o?o.children:null:n,a,r),u&&r.canDeactivateChecks.push(new xe(o&&o.outlet&&o.outlet.component||null,s))}else s&&Se(e,o,r),r.canActivateChecks.push(new _e(a)),we(t,null,i.component?o?o.children:null:n,a,r)}(t,i[t.value.outlet],n,a.concat([t.value]),r),delete i[t.value.outlet]}),dt(i,function(t,e){return Se(t,n.getContext(e),r)}),r}function Se(t,e,n){var a=jt(t),r=t.value;dt(a,function(t,a){Se(t,r.component?e?e.children.getContext(a):null:e,n)}),n.canDeactivateChecks.push(new xe(r.component&&e&&e.outlet&&e.outlet.isActivated?e.outlet.component:null,r))}var Oe=Symbol("INITIAL_VALUE");function Ie(){return Object(T.a)(function(t){return d.b.apply(void 0,Object(a.__spread)(t.map(function(t){return t.pipe(Object(w.a)(1),Object(S.a)(Oe))}))).pipe(Object(O.a)(function(t,e){var n=!1;return e.reduce(function(t,a,r){if(t!==Oe)return t;if(a===Oe&&(n=!0),!n){if(!1===a)return a;if(r===e.length-1||ce(a))return a}return t},t)},Oe),Object(I.a)(function(t){return t!==Oe}),Object(g.a)(function(t){return ce(t)?t:!0===t}),Object(w.a)(1))})}function Ce(t,e){return null!==t&&e&&e(new W(t)),Object(s.a)(!0)}function ke(t,e){return null!==t&&e&&e(new B(t)),Object(s.a)(!0)}function Ne(t,e,n){var a=e.routeConfig?e.routeConfig.canActivate:null;if(!a||0===a.length)return Object(s.a)(!0);var r=a.map(function(a){return Object(f.a)(function(){var r,i=Te(a,e,n);if(function(t){return t&&ue(t.canActivate)}(i))r=ft(i.canActivate(e,t));else{if(!ue(i))throw new Error("Invalid CanActivate guard");r=ft(i(e,t))}return r.pipe(Object(v.a)())})});return Object(s.a)(r).pipe(Ie())}function Re(t,e,n){var a=e[e.length-1],r=e.slice(0,e.length-1).reverse().map(function(t){return function(t){var e=t.routeConfig?t.routeConfig.canActivateChild:null;return e&&0!==e.length?{node:t,guards:e}:null}(t)}).filter(function(t){return null!==t}).map(function(e){return Object(f.a)(function(){var r=e.guards.map(function(r){var i,s=Te(r,e.node,n);if(function(t){return t&&ue(t.canActivateChild)}(s))i=ft(s.canActivateChild(a,t));else{if(!ue(s))throw new Error("Invalid CanActivateChild guard");i=ft(s(a,t))}return i.pipe(Object(v.a)())});return Object(s.a)(r).pipe(Ie())})});return Object(s.a)(r).pipe(Ie())}var Ae=function(){return function(){}}(),De=function(){function t(t,e,n,a,r,i){this.rootComponentType=t,this.config=e,this.urlTree=n,this.url=a,this.paramsInheritanceStrategy=r,this.relativeLinkResolution=i}return t.prototype.recognize=function(){try{var t=Pe(this.urlTree.root,[],[],this.config,this.relativeLinkResolution).segmentGroup,e=this.processSegmentGroup(this.config,t,X),n=new Vt([],Object.freeze({}),Object.freeze(Object(a.__assign)({},this.urlTree.queryParams)),this.urlTree.fragment,{},X,this.rootComponentType,null,this.urlTree.root,-1,{}),r=new qt(n,e),i=new Ht(this.url,r);return this.inheritParamsAndData(i._root),Object(s.a)(i)}catch(o){return new c.a(function(t){return t.error(o)})}},t.prototype.inheritParamsAndData=function(t){var e=this,n=t.value,a=Yt(n,this.paramsInheritanceStrategy);n.params=Object.freeze(a.params),n.data=Object.freeze(a.data),t.children.forEach(function(t){return e.inheritParamsAndData(t)})},t.prototype.processSegmentGroup=function(t,e,n){return 0===e.segments.length&&e.hasChildren()?this.processChildren(t,e):this.processSegment(t,e,e.segments,n)},t.prototype.processChildren=function(t,e){var n,a=this,r=yt(e,function(e,n){return a.processSegmentGroup(t,e,n)});return n={},r.forEach(function(t){var e=n[t.value.outlet];if(e){var a=e.url.map(function(t){return t.toString()}).join("/"),r=t.value.url.map(function(t){return t.toString()}).join("/");throw new Error("Two segments cannot have the same outlet name: '"+a+"' and '"+r+"'.")}n[t.value.outlet]=t.value}),r.sort(function(t,e){return t.value.outlet===X?-1:e.value.outlet===X?1:t.value.outlet.localeCompare(e.value.outlet)}),r},t.prototype.processSegment=function(t,e,n,r){var i,s;try{for(var o=Object(a.__values)(t),u=o.next();!u.done;u=o.next()){var c=u.value;try{return this.processSegmentAgainstRoute(c,e,n,r)}catch(l){if(!(l instanceof Ae))throw l}}}catch(d){i={error:d}}finally{try{u&&!u.done&&(s=o.return)&&s.call(o)}finally{if(i)throw i.error}}if(this.noLeftoversInUrl(e,n,r))return[];throw new Ae},t.prototype.noLeftoversInUrl=function(t,e,n){return 0===e.length&&!t.children[n]},t.prototype.processSegmentAgainstRoute=function(t,e,n,r){if(t.redirectTo)throw new Ae;if((t.outlet||X)!==r)throw new Ae;var i,s=[],o=[];if("**"===t.path){var u=n.length>0?lt(n).parameters:{};i=new Vt(n,u,Object.freeze(Object(a.__assign)({},this.urlTree.queryParams)),this.urlTree.fragment,je(t),r,t.component,t,Ee(e),Le(e)+n.length,Fe(t))}else{var c=function(t,e,n){if(""===e.path){if("full"===e.pathMatch&&(t.hasChildren()||n.length>0))throw new Ae;return{consumedSegments:[],lastChild:0,parameters:{}}}var r=(e.matcher||nt)(n,t,e);if(!r)throw new Ae;var i={};dt(r.posParams,function(t,e){i[e]=t.path});var s=r.consumed.length>0?Object(a.__assign)({},i,r.consumed[r.consumed.length-1].parameters):i;return{consumedSegments:r.consumed,lastChild:r.consumed.length,parameters:s}}(e,t,n);s=c.consumedSegments,o=n.slice(c.lastChild),i=new Vt(s,c.parameters,Object.freeze(Object(a.__assign)({},this.urlTree.queryParams)),this.urlTree.fragment,je(t),r,t.component,t,Ee(e),Le(e)+s.length,Fe(t))}var l=function(t){return t.children?t.children:t.loadChildren?t._loadedConfig.routes:[]}(t),d=Pe(e,s,o,l,this.relativeLinkResolution),f=d.segmentGroup,p=d.slicedSegments;if(0===p.length&&f.hasChildren()){var h=this.processChildren(l,f);return[new qt(i,h)]}if(0===l.length&&0===p.length)return[new qt(i,[])];var g=this.processSegment(l,f,p,X);return[new qt(i,g)]},t}();function Ee(t){for(var e=t;e._sourceSegment;)e=e._sourceSegment;return e}function Le(t){for(var e=t,n=e._segmentIndexShift?e._segmentIndexShift:0;e._sourceSegment;)n+=(e=e._sourceSegment)._segmentIndexShift?e._segmentIndexShift:0;return n-1}function Pe(t,e,n,r,i){if(n.length>0&&function(t,e,n){return r.some(function(n){return Me(t,e,n)&&qe(n)!==X})}(t,n)){var s=new gt(e,function(t,e,n,r){var i,s,o={};o[X]=r,r._sourceSegment=t,r._segmentIndexShift=e.length;try{for(var u=Object(a.__values)(n),c=u.next();!c.done;c=u.next()){var l=c.value;if(""===l.path&&qe(l)!==X){var d=new gt([],{});d._sourceSegment=t,d._segmentIndexShift=e.length,o[qe(l)]=d}}}catch(f){i={error:f}}finally{try{c&&!c.done&&(s=u.return)&&s.call(u)}finally{if(i)throw i.error}}return o}(t,e,r,new gt(n,t.children)));return s._sourceSegment=t,s._segmentIndexShift=e.length,{segmentGroup:s,slicedSegments:[]}}if(0===n.length&&function(t,e,n){return r.some(function(n){return Me(t,e,n)})}(t,n)){var o=new gt(t.segments,function(t,e,n,r,i,s){var o,u,c={};try{for(var l=Object(a.__values)(r),d=l.next();!d.done;d=l.next()){var f=d.value;if(Me(t,n,f)&&!i[qe(f)]){var p=new gt([],{});p._sourceSegment=t,p._segmentIndexShift="legacy"===s?t.segments.length:e.length,c[qe(f)]=p}}}catch(h){o={error:h}}finally{try{d&&!d.done&&(u=l.return)&&u.call(l)}finally{if(o)throw o.error}}return Object(a.__assign)({},i,c)}(t,e,n,r,t.children,i));return o._sourceSegment=t,o._segmentIndexShift=e.length,{segmentGroup:o,slicedSegments:n}}var u=new gt(t.segments,t.children);return u._sourceSegment=t,u._segmentIndexShift=e.length,{segmentGroup:u,slicedSegments:n}}function Me(t,e,n){return(!(t.hasChildren()||e.length>0)||"full"!==n.pathMatch)&&""===n.path&&void 0===n.redirectTo}function qe(t){return t.outlet||X}function je(t){return t.data||{}}function Fe(t){return t.resolve||{}}function ze(t,e,n,a){var r=Te(t,e,a);return ft(r.resolve?r.resolve(e,n):r(e,n))}function Ge(t){return function(e){return e.pipe(Object(T.a)(function(e){var n=t(e);return n?Object(o.a)(n).pipe(Object(g.a)(function(){return e})):Object(o.a)([e])}))}}var Ye=function(){return function(){}}(),Ve=function(){function t(){}return t.prototype.shouldDetach=function(t){return!1},t.prototype.store=function(t,e){},t.prototype.shouldAttach=function(t){return!1},t.prototype.retrieve=function(t){return null},t.prototype.shouldReuseRoute=function(t,e){return t.routeConfig===e.routeConfig},t}(),He=new i.InjectionToken("ROUTES"),Be=function(){function t(t,e,n,a){this.loader=t,this.compiler=e,this.onLoadStartListener=n,this.onLoadEndListener=a}return t.prototype.load=function(t,e){var n=this;return this.onLoadStartListener&&this.onLoadStartListener(e),this.loadModuleFactory(e.loadChildren).pipe(Object(g.a)(function(a){n.onLoadEndListener&&n.onLoadEndListener(e);var r=a.create(t);return new at(ct(r.injector.get(He)).map(ot),r)}))},t.prototype.loadModuleFactory=function(t){var e=this;return"string"==typeof t?Object(o.a)(this.loader.load(t)):ft(t()).pipe(Object(_.a)(function(t){return t instanceof i.NgModuleFactory?Object(s.a)(t):Object(o.a)(e.compiler.compileModuleAsync(t))}))},t}(),Ue=function(){return function(){}}(),We=function(){function t(){}return t.prototype.shouldProcessUrl=function(t){return!0},t.prototype.extract=function(t){return t},t.prototype.merge=function(t,e){return t},t}();function Ke(t){throw t}function $e(t,e,n){return e.parse("/")}function Ze(t,e){return Object(s.a)(null)}var Xe=function(){function t(t,e,n,a,r,s,o,c){var l=this;this.rootComponentType=t,this.urlSerializer=e,this.rootContexts=n,this.location=a,this.config=c,this.lastSuccessfulNavigation=null,this.currentNavigation=null,this.navigationId=0,this.isNgZoneEnabled=!1,this.events=new p.a,this.errorHandler=Ke,this.malformedUriErrorHandler=$e,this.navigated=!1,this.lastSuccessfulId=-1,this.hooks={beforePreactivation:Ze,afterPreactivation:Ze},this.urlHandlingStrategy=new We,this.routeReuseStrategy=new Ve,this.onSameUrlNavigation="ignore",this.paramsInheritanceStrategy="emptyOnly",this.urlUpdateStrategy="deferred",this.relativeLinkResolution="legacy",this.ngModule=r.get(i.NgModuleRef),this.console=r.get(i["\u0275Console"]);var d=r.get(i.NgZone);this.isNgZoneEnabled=d instanceof i.NgZone,this.resetConfig(c),this.currentUrlTree=new ht(new gt([],{}),{},null),this.rawUrlTree=this.currentUrlTree,this.browserUrlTree=this.currentUrlTree,this.configLoader=new Be(s,o,function(t){return l.triggerEvent(new V(t))},function(t){return l.triggerEvent(new H(t))}),this.routerState=zt(this.currentUrlTree,this.rootComponentType),this.transitions=new u.a({id:0,currentUrlTree:this.currentUrlTree,currentRawUrl:this.currentUrlTree,extractedUrl:this.urlHandlingStrategy.extract(this.currentUrlTree),urlAfterRedirects:this.urlHandlingStrategy.extract(this.currentUrlTree),rawUrl:this.currentUrlTree,extras:{},resolve:null,reject:null,promise:Promise.resolve(!0),source:"imperative",restoredState:null,currentSnapshot:this.routerState.snapshot,targetSnapshot:null,currentRouterState:this.routerState,targetRouterState:null,guards:{canActivateChecks:[],canDeactivateChecks:[]},guardsResult:null}),this.navigations=this.setupNavigations(this.transitions),this.processNavigations()}return t.prototype.setupNavigations=function(t){var e=this,n=this.events;return t.pipe(Object(I.a)(function(t){return 0!==t.id}),Object(g.a)(function(t){return Object(a.__assign)({},t,{extractedUrl:e.urlHandlingStrategy.extract(t.rawUrl)})}),Object(N.a)(function(t){e.currentNavigation={id:t.id,initialUrl:t.currentRawUrl,extractedUrl:t.extractedUrl,trigger:t.source,extras:t.extras,previousNavigation:e.lastSuccessfulNavigation?Object(a.__assign)({},e.lastSuccessfulNavigation,{previousNavigation:null}):null}}),Object(T.a)(function(t){var r,i,c,l=!1,d=!1;return Object(s.a)(t).pipe(Object(T.a)(function(t){var r,i,o,u,c=!e.navigated||t.extractedUrl.toString()!==e.browserUrlTree.toString();if(("reload"===e.onSameUrlNavigation||c)&&e.urlHandlingStrategy.shouldProcessUrl(t.rawUrl))return Object(s.a)(t).pipe(Object(T.a)(function(t){var a=e.transitions.getValue();return n.next(new L(t.id,e.serializeUrl(t.extractedUrl),t.source,t.restoredState)),a!==e.transitions.getValue()?h.a:[t]}),Object(T.a)(function(t){return Promise.resolve(t)}),(r=e.ngModule.injector,i=e.configLoader,o=e.urlSerializer,u=e.config,function(t){return t.pipe(Object(T.a)(function(t){return function(e,n,a,r,i){return new ge(e,n,a,t.extractedUrl,i).apply()}(r,i,o,0,u).pipe(Object(g.a)(function(e){return Object(a.__assign)({},t,{urlAfterRedirects:e})}))}))}),Object(N.a)(function(t){e.currentNavigation=Object(a.__assign)({},e.currentNavigation,{finalUrl:t.urlAfterRedirects})}),function(t,n,r,i,s){return function(r){return r.pipe(Object(_.a)(function(r){return function(t,e,n,a,r,i){return void 0===r&&(r="emptyOnly"),void 0===i&&(i="legacy"),new De(t,e,n,a,r,i).recognize()}(t,n,r.urlAfterRedirects,(o=r.urlAfterRedirects,e.serializeUrl(o)),i,s).pipe(Object(g.a)(function(t){return Object(a.__assign)({},r,{targetSnapshot:t})}));var o}))}}(e.rootComponentType,e.config,0,e.paramsInheritanceStrategy,e.relativeLinkResolution),Object(N.a)(function(t){"eager"===e.urlUpdateStrategy&&(t.extras.skipLocationChange||e.setBrowserUrl(t.urlAfterRedirects,!!t.extras.replaceUrl,t.id),e.browserUrlTree=t.urlAfterRedirects)}),Object(N.a)(function(t){var a=new j(t.id,e.serializeUrl(t.extractedUrl),e.serializeUrl(t.urlAfterRedirects),t.targetSnapshot);n.next(a)}));if(c&&e.rawUrlTree&&e.urlHandlingStrategy.shouldProcessUrl(e.rawUrlTree)){var l=t.extractedUrl,d=t.source,f=t.restoredState,p=t.extras,b=new L(t.id,e.serializeUrl(l),d,f);n.next(b);var m=zt(l,e.rootComponentType).snapshot;return Object(s.a)(Object(a.__assign)({},t,{targetSnapshot:m,urlAfterRedirects:l,extras:Object(a.__assign)({},p,{skipLocationChange:!1,replaceUrl:!1})}))}return e.rawUrlTree=t.rawUrl,t.resolve(null),h.a}),Ge(function(t){var n=t.extras;return e.hooks.beforePreactivation(t.targetSnapshot,{navigationId:t.id,appliedUrlTree:t.extractedUrl,rawUrlTree:t.rawUrl,skipLocationChange:!!n.skipLocationChange,replaceUrl:!!n.replaceUrl})}),Object(N.a)(function(t){var n=new F(t.id,e.serializeUrl(t.extractedUrl),e.serializeUrl(t.urlAfterRedirects),t.targetSnapshot);e.triggerEvent(n)}),Object(g.a)(function(t){return Object(a.__assign)({},t,{guards:(n=t.targetSnapshot,r=t.currentSnapshot,i=e.rootContexts,s=n._root,we(s,r?r._root:null,i,[s.value]))});var n,r,i,s}),function(t,e){return function(n){return n.pipe(Object(_.a)(function(n){var r=n.targetSnapshot,i=n.currentSnapshot,u=n.guards,c=u.canActivateChecks,l=u.canDeactivateChecks;return 0===l.length&&0===c.length?Object(s.a)(Object(a.__assign)({},n,{guardsResult:!0})):function(t,e,n,a){return Object(o.a)(t).pipe(Object(_.a)(function(t){return function(t,e,n,a,r){var i=e&&e.routeConfig?e.routeConfig.canDeactivate:null;if(!i||0===i.length)return Object(s.a)(!0);var o=i.map(function(i){var s,o=Te(i,e,r);if(function(t){return t&&ue(t.canDeactivate)}(o))s=ft(o.canDeactivate(t,e,n,a));else{if(!ue(o))throw new Error("Invalid CanDeactivate guard");s=ft(o(t,e,n,a))}return s.pipe(Object(v.a)())});return Object(s.a)(o).pipe(Ie())}(t.component,t.route,n,e,a)}),Object(v.a)(function(t){return!0!==t},!0))}(l,r,i,t).pipe(Object(_.a)(function(n){return n&&"boolean"==typeof n?function(t,e,n,a){return Object(o.a)(e).pipe(Object(C.a)(function(e){return Object(o.a)([ke(e.route.parent,a),Ce(e.route,a),Re(t,e.path,n),Ne(t,e.route,n)]).pipe(Object(b.a)(),Object(v.a)(function(t){return!0!==t},!0))}),Object(v.a)(function(t){return!0!==t},!0))}(r,c,t,e):Object(s.a)(n)}),Object(g.a)(function(t){return Object(a.__assign)({},n,{guardsResult:t})}))}))}}(e.ngModule.injector,function(t){return e.triggerEvent(t)}),Object(N.a)(function(t){if(ce(t.guardsResult)){var n=et('Redirecting to "'+e.serializeUrl(t.guardsResult)+'"');throw n.url=t.guardsResult,n}}),Object(N.a)(function(t){var n=new z(t.id,e.serializeUrl(t.extractedUrl),e.serializeUrl(t.urlAfterRedirects),t.targetSnapshot,!!t.guardsResult);e.triggerEvent(n)}),Object(I.a)(function(t){if(!t.guardsResult){e.resetUrlToCurrentUrlTree();var a=new M(t.id,e.serializeUrl(t.extractedUrl),"");return n.next(a),t.resolve(!1),!1}return!0}),Ge(function(t){if(t.guards.canActivateChecks.length)return Object(s.a)(t).pipe(Object(N.a)(function(t){var n=new G(t.id,e.serializeUrl(t.extractedUrl),e.serializeUrl(t.urlAfterRedirects),t.targetSnapshot);e.triggerEvent(n)}),(n=e.paramsInheritanceStrategy,r=e.ngModule.injector,function(t){return t.pipe(Object(_.a)(function(t){var e=t.targetSnapshot,i=t.guards.canActivateChecks;return i.length?Object(o.a)(i).pipe(Object(C.a)(function(t){return function(t,n,r,i){return function(t,e,n,a){var r=Object.keys(t);if(0===r.length)return Object(s.a)({});if(1===r.length){var i=r[0];return ze(t[i],e,n,a).pipe(Object(g.a)(function(t){var e;return(e={})[i]=t,e}))}var u={};return Object(o.a)(r).pipe(Object(_.a)(function(r){return ze(t[r],e,n,a).pipe(Object(g.a)(function(t){return u[r]=t,t}))})).pipe(Object(m.a)(),Object(g.a)(function(){return u}))}(t._resolve,t,e,i).pipe(Object(g.a)(function(e){return t._resolvedData=e,t.data=Object(a.__assign)({},t.data,Yt(t,r).resolve),null}))}(t.route,0,n,r)}),Object(k.a)(function(t,e){return t}),Object(g.a)(function(e){return t})):Object(s.a)(t)}))}),Object(N.a)(function(t){var n=new Y(t.id,e.serializeUrl(t.extractedUrl),e.serializeUrl(t.urlAfterRedirects),t.targetSnapshot);e.triggerEvent(n)}));var n,r}),Ge(function(t){var n=t.extras;return e.hooks.afterPreactivation(t.targetSnapshot,{navigationId:t.id,appliedUrlTree:t.extractedUrl,rawUrlTree:t.rawUrl,skipLocationChange:!!n.skipLocationChange,replaceUrl:!!n.replaceUrl})}),Object(g.a)(function(t){var n,r,i,s=(i=function t(e,n,r){if(r&&e.shouldReuseRoute(n.value,r.value.snapshot)){(l=r.value)._futureSnapshot=n.value;var i=function(e,n,r){return n.children.map(function(n){var i,s;try{for(var o=Object(a.__values)(r.children),u=o.next();!u.done;u=o.next()){var c=u.value;if(e.shouldReuseRoute(c.value.snapshot,n.value))return t(e,n,c)}}catch(l){i={error:l}}finally{try{u&&!u.done&&(s=o.return)&&s.call(o)}finally{if(i)throw i.error}}return t(e,n)})}(e,n,r);return new qt(l,i)}var s=e.retrieve(n.value);if(s){var o=s.route;return function t(e,n){if(e.value.routeConfig!==n.value.routeConfig)throw new Error("Cannot reattach ActivatedRouteSnapshot created from a different route");if(e.children.length!==n.children.length)throw new Error("Cannot reattach ActivatedRouteSnapshot with a different number of children");n.value._futureSnapshot=e.value;for(var a=0;ao;){if(u-=o,!(s=s.parent))throw new Error("Invalid number of '../'");o=s.segments.length}return new Jt(s,!1,o-u)}()}(s,0,t),u=o.processChildren?ee(o.segmentGroup,o.index,s.commands):te(o.segmentGroup,o.index,s.commands);return Zt(o.segmentGroup,u,e,r,i)}(l,this.currentUrlTree,t,f,d)},t.prototype.navigateByUrl=function(t,e){void 0===e&&(e={skipLocationChange:!1}),Object(i.isDevMode)()&&this.isNgZoneEnabled&&!i.NgZone.isInAngularZone()&&this.console.warn("Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?");var n=ce(t)?t:this.parseUrl(t),a=this.urlHandlingStrategy.merge(n,this.rawUrlTree);return this.scheduleNavigation(a,"imperative",null,e)},t.prototype.navigate=function(t,e){return void 0===e&&(e={skipLocationChange:!1}),function(t){for(var e=0;e0},e.prototype.tagName=function(t){return t.tagName},e.prototype.attributeMap=function(t){for(var e=new Map,n=t.attributes,a=0;a0;o||(o=t[s]=[]);var c=at(e)?Zone.root:Zone.current;if(0===o.length)o.push({zone:c,handler:r});else{for(var l=!1,d=0;d-1},e}(L),dt=["alt","control","meta","shift"],ft={alt:function(t){return t.altKey},control:function(t){return t.ctrlKey},meta:function(t){return t.metaKey},shift:function(t){return t.shiftKey}},pt=function(t){function e(e){return t.call(this,e)||this}var n;return Object(a.__extends)(e,t),n=e,e.prototype.supports=function(t){return null!=n.parseEventName(t)},e.prototype.addEventListener=function(t,e,a){var r=n.parseEventName(e),i=n.eventCallback(r.fullKey,a,this.manager.getZone());return this.manager.getZone().runOutsideAngular(function(){return o().onAndCancel(t,r.domEventName,i)})},e.parseEventName=function(t){var e=t.toLowerCase().split("."),a=e.shift();if(0===e.length||"keydown"!==a&&"keyup"!==a)return null;var r=n._normalizeKey(e.pop()),i="";if(dt.forEach(function(t){var n=e.indexOf(t);n>-1&&(e.splice(n,1),i+=t+".")}),i+=r,0!=e.length||0===r.length)return null;var s={};return s.domEventName=a,s.fullKey=i,s},e.getEventFullKey=function(t){var e="",n=o().getEventKey(t);return" "===(n=n.toLowerCase())?n="space":"."===n&&(n="dot"),dt.forEach(function(a){a!=n&&(0,ft[a])(t)&&(e+=a+".")}),e+=n},e.eventCallback=function(t,e,a){return function(r){n.getEventFullKey(r)===t&&a.runGuarded(function(){return e(r)})}},e._normalizeKey=function(t){switch(t){case"esc":return"escape";default:return t}},e}(L),ht=function(){return function(){}}(),gt=function(t){function e(e){var n=t.call(this)||this;return n._doc=e,n}return Object(a.__extends)(e,t),e.prototype.sanitize=function(t,e){if(null==e)return null;switch(t){case i.SecurityContext.NONE:return e;case i.SecurityContext.HTML:return e instanceof mt?e.changingThisBreaksApplicationSecurity:(this.checkNotSafeValue(e,"HTML"),Object(i["\u0275_sanitizeHtml"])(this._doc,String(e)));case i.SecurityContext.STYLE:return e instanceof yt?e.changingThisBreaksApplicationSecurity:(this.checkNotSafeValue(e,"Style"),Object(i["\u0275_sanitizeStyle"])(e));case i.SecurityContext.SCRIPT:if(e instanceof vt)return e.changingThisBreaksApplicationSecurity;throw this.checkNotSafeValue(e,"Script"),new Error("unsafe value used in a script context");case i.SecurityContext.URL:return e instanceof xt||e instanceof _t?e.changingThisBreaksApplicationSecurity:(this.checkNotSafeValue(e,"URL"),Object(i["\u0275_sanitizeUrl"])(String(e)));case i.SecurityContext.RESOURCE_URL:if(e instanceof xt)return e.changingThisBreaksApplicationSecurity;throw this.checkNotSafeValue(e,"ResourceURL"),new Error("unsafe value used in a resource URL context (see http://g.co/ng/security#xss)");default:throw new Error("Unexpected SecurityContext "+t+" (see http://g.co/ng/security#xss)")}},e.prototype.checkNotSafeValue=function(t,e){if(t instanceof bt)throw new Error("Required a safe "+e+", got a "+t.getTypeName()+" (see http://g.co/ng/security#xss)")},e.prototype.bypassSecurityTrustHtml=function(t){return new mt(t)},e.prototype.bypassSecurityTrustStyle=function(t){return new yt(t)},e.prototype.bypassSecurityTrustScript=function(t){return new vt(t)},e.prototype.bypassSecurityTrustUrl=function(t){return new _t(t)},e.prototype.bypassSecurityTrustResourceUrl=function(t){return new xt(t)},e}(ht),bt=function(){function t(t){this.changingThisBreaksApplicationSecurity=t}return t.prototype.toString=function(){return"SafeValue must use [property]=binding: "+this.changingThisBreaksApplicationSecurity+" (see http://g.co/ng/security#xss)"},t}(),mt=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.getTypeName=function(){return"HTML"},e}(bt),yt=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.getTypeName=function(){return"Style"},e}(bt),vt=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.getTypeName=function(){return"Script"},e}(bt),_t=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.getTypeName=function(){return"URL"},e}(bt),xt=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.getTypeName=function(){return"ResourceURL"},e}(bt),Tt=[{provide:i.PLATFORM_ID,useValue:r["\u0275PLATFORM_BROWSER_ID"]},{provide:i.PLATFORM_INITIALIZER,useValue:Ot,multi:!0},{provide:r.PlatformLocation,useClass:_,deps:[y]},{provide:y,useFactory:Ct,deps:[]}],wt=[{provide:i.Sanitizer,useExisting:ht},{provide:ht,useClass:gt,deps:[y]}],St=Object(i.createPlatformFactory)(i.platformCore,"browser",Tt);function Ot(){b.makeCurrent(),S.init()}function It(){return new i.ErrorHandler}function Ct(){return document}var kt=[wt,{provide:i["\u0275APP_ROOT"],useValue:!0},{provide:i.ErrorHandler,useFactory:It,deps:[]},{provide:D,useClass:it,multi:!0,deps:[y,i.NgZone,i.PLATFORM_ID]},{provide:D,useClass:pt,multi:!0,deps:[y]},{provide:D,useClass:lt,multi:!0,deps:[y,ot,i["\u0275Console"],[new i.Optional,ut]]},{provide:ot,useClass:ct,deps:[]},{provide:B,useClass:B,deps:[E,M]},{provide:i.RendererFactory2,useExisting:B},{provide:P,useExisting:M},{provide:M,useClass:M,deps:[y]},{provide:i.Testability,useClass:i.Testability,deps:[i.NgZone]},{provide:E,useClass:E,deps:[D,i.NgZone]},A],Nt=function(){function t(t){if(t)throw new Error("BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.")}var e;return e=t,t.withServerTransition=function(t){return{ngModule:e,providers:[{provide:i.APP_ID,useValue:t.appId},{provide:x,useExisting:i.APP_ID},w]}},t}();function Rt(){return new At(Object(i.inject)(y))}var At=function(){function t(t){this._doc=t,this._dom=o()}return t.prototype.addTag=function(t,e){return void 0===e&&(e=!1),t?this._getOrCreateElement(t,e):null},t.prototype.addTags=function(t,e){var n=this;return void 0===e&&(e=!1),t?t.reduce(function(t,a){return a&&t.push(n._getOrCreateElement(a,e)),t},[]):[]},t.prototype.getTag=function(t){return t&&this._dom.querySelector(this._doc,"meta["+t+"]")||null},t.prototype.getTags=function(t){if(!t)return[];var e=this._dom.querySelectorAll(this._doc,"meta["+t+"]");return e?[].slice.call(e):[]},t.prototype.updateTag=function(t,e){if(!t)return null;e=e||this._parseSelector(t);var n=this.getTag(e);return n?this._setMetaElementAttributes(t,n):this._getOrCreateElement(t,!0)},t.prototype.removeTag=function(t){this.removeTagElement(this.getTag(t))},t.prototype.removeTagElement=function(t){t&&this._dom.remove(t)},t.prototype._getOrCreateElement=function(t,e){if(void 0===e&&(e=!1),!e){var n=this._parseSelector(t),a=this.getTag(n);if(a&&this._containsAttributes(t,a))return a}var r=this._dom.createElement("meta");this._setMetaElementAttributes(t,r);var i=this._dom.getElementsByTagName(this._doc,"head")[0];return this._dom.appendChild(i,r),r},t.prototype._setMetaElementAttributes=function(t,e){var n=this;return Object.keys(t).forEach(function(a){return n._dom.setAttribute(e,a,t[a])}),e},t.prototype._parseSelector=function(t){var e=t.name?"name":"property";return e+'="'+t[e]+'"'},t.prototype._containsAttributes=function(t,e){var n=this;return Object.keys(t).every(function(a){return n._dom.getAttribute(e,a)===t[a]})},t.ngInjectableDef=Object(i.defineInjectable)({factory:Rt,token:t,providedIn:"root"}),t}();function Dt(){return new Et(Object(i.inject)(y))}var Et=function(){function t(t){this._doc=t}return t.prototype.getTitle=function(){return o().getTitle(this._doc)},t.prototype.setTitle=function(t){o().setTitle(this._doc,t)},t.ngInjectableDef=Object(i.defineInjectable)({factory:Dt,token:t,providedIn:"root"}),t}(),Lt="undefined"!=typeof window&&window||{},Pt=function(){return function(t,e){this.msPerTick=t,this.numTicks=e}}(),Mt=function(){function t(t){this.appRef=t.injector.get(i.ApplicationRef)}return t.prototype.timeChangeDetection=function(t){var e=t&&t.record,n=null!=Lt.console.profile;e&&n&&Lt.console.profile("Change Detection");for(var a=o().performanceNow(),r=0;r<5||o().performanceNow()-a<500;)this.appRef.tick(),r++;var i=o().performanceNow();e&&n&&Lt.console.profileEnd("Change Detection");var s=(i-a)/r;return Lt.console.log("ran "+r+" change detection cycles"),Lt.console.log(s.toFixed(2)+" ms per check"),new Pt(s,r)},t}(),qt="profiler";function jt(t){return O(qt,new Mt(t)),t}function Ft(){O(qt,null)}function zt(t){var e={"&":"&a;",'"':"&q;","'":"&s;","<":"&l;",">":"&g;"};return t.replace(/[&"'<>]/g,function(t){return e[t]})}function Gt(t){return t}var Yt=function(){function t(){this.store={},this.onSerializeCallbacks={}}var e;return e=t,t.init=function(t){var n=new e;return n.store=t,n},t.prototype.get=function(t,e){return void 0!==this.store[t]?this.store[t]:e},t.prototype.set=function(t,e){this.store[t]=e},t.prototype.remove=function(t){delete this.store[t]},t.prototype.hasKey=function(t){return this.store.hasOwnProperty(t)},t.prototype.onSerialize=function(t,e){this.onSerializeCallbacks[t]=e},t.prototype.toJson=function(){for(var t in this.onSerializeCallbacks)if(this.onSerializeCallbacks.hasOwnProperty(t))try{this.store[t]=this.onSerializeCallbacks[t]()}catch(e){console.warn("Exception in onSerialize callback: ",e)}return JSON.stringify(this.store)},t}();function Vt(t,e){var n,a=t.getElementById(e+"-state"),r={};if(a&&a.textContent)try{r=JSON.parse((n={"&a;":"&","&q;":'"',"&s;":"'","&l;":"<","&g;":">"},a.textContent.replace(/&[^;]+;/g,function(t){return n[t]})))}catch(i){console.warn("Exception while restoring TransferState for app "+e,i)}return Yt.init(r)}var Ht=function(){return function(){}}(),Bt=function(){function t(){}return t.all=function(){return function(t){return!0}},t.css=function(t){return function(e){return null!=e.nativeElement&&o().elementMatches(e.nativeElement,t)}},t.directive=function(t){return function(e){return-1!==e.providerTokens.indexOf(t)}},t}(),Ut=new i.Version("7.2.6")},Zduo:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_a\u016dgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_a\u016dg_sep_okt_nov_dec".split("_"),weekdays:"diman\u0109o_lundo_mardo_merkredo_\u0135a\u016ddo_vendredo_sabato".split("_"),weekdaysShort:"dim_lun_mard_merk_\u0135a\u016d_ven_sab".split("_"),weekdaysMin:"di_lu_ma_me_\u0135a_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D[-a de] MMMM, YYYY",LLL:"D[-a de] MMMM, YYYY HH:mm",LLLL:"dddd, [la] D[-a de] MMMM, YYYY HH:mm"},meridiemParse:/[ap]\.t\.m/i,isPM:function(t){return"p"===t.charAt(0).toLowerCase()},meridiem:function(t,e,n){return t>11?n?"p.t.m.":"P.T.M.":n?"a.t.m.":"A.T.M."},calendar:{sameDay:"[Hodia\u016d je] LT",nextDay:"[Morga\u016d je] LT",nextWeek:"dddd [je] LT",lastDay:"[Hiera\u016d je] LT",lastWeek:"[pasinta] dddd [je] LT",sameElse:"L"},relativeTime:{future:"post %s",past:"anta\u016d %s",s:"sekundoj",ss:"%d sekundoj",m:"minuto",mm:"%d minutoj",h:"horo",hh:"%d horoj",d:"tago",dd:"%d tagoj",M:"monato",MM:"%d monatoj",y:"jaro",yy:"%d jaroj"},dayOfMonthOrdinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}})}()},Zn8D:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("psW0"),r=n("mChF");function i(t){return void 0===t&&(t=Number.POSITIVE_INFINITY),Object(a.a)(r.a,t)}},a0VL:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(t){this.datePipe=t}return t.prototype.transform=function(t){return null===t||""===t?"":this.datePipe.transform(t,"shortDate")+" "+this.datePipe.transform(t,"mediumTime")},t}()},a278:function(t,e,n){"use strict";var a=n("CcnG"),r=n("QC43"),i=n("XFyV"),s=n("TZo1"),o=n("9Kw/"),u=n("Jm/i"),c=n("gIcY"),l=n("ANnk"),d=n("f/UV"),f=n("aexS"),p=n("Ip0R");n("insk"),n("mSOc"),n("ZYjt"),n("20UP"),n("+0ag"),n.d(e,"a",function(){return h}),n.d(e,"b",function(){return _});var h=a["\u0275crt"]({encapsulation:0,styles:[[".grafana[_ngcontent-%COMP%]{width:100%;height:600px;z-index:0}.grafana_one[_ngcontent-%COMP%]{height:400px}.grafana_two[_ngcontent-%COMP%]{height:750px}.grafana_three[_ngcontent-%COMP%]{height:900px}.timepicker[_ngcontent-%COMP%] select[_ngcontent-%COMP%]{display:inline-block}.timepicker[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{font-size:1.05em;padding:5px!important}button[_ngcontent-%COMP%]{margin-bottom:10px;margin-left:10px;float:right}button[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{font-size:14px;padding:2px}.dropdown-menu[_ngcontent-%COMP%]{top:20px;right:20px;left:auto}"]],data:{}});function g(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"cd-loading-panel",[],null,null,null,r.b,r.a)),a["\u0275did"](1,49152,null,0,i.a,[],null,null),(t()(),a["\u0275ted"](-1,0,["Loading panel data..."]))],null,null)}function b(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,5,"cd-info-panel",[],null,null,null,s.b,s.a)),a["\u0275did"](1,49152,null,0,o.a,[u.a],null,null),(t()(),a["\u0275ted"](-1,0,["Please consult the "])),(t()(),a["\u0275eld"](3,0,null,0,1,"a",[["target","_blank"]],[[8,"href",4]],null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["documentation"])),(t()(),a["\u0275ted"](-1,0,[" on how to configure and enable the monitoring functionality."]))],null,function(t,e){t(e,3,0,a["\u0275inlineInterpolate"](1,"",e.component.docsUrl,""))})}function m(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,5,"cd-info-panel",[],null,null,null,s.b,s.a)),a["\u0275did"](1,49152,null,0,o.a,[u.a],null,null),(t()(),a["\u0275ted"](-1,0,["Grafana Dashboard doesn't exist. Please refer to "])),(t()(),a["\u0275eld"](3,0,null,0,1,"a",[["target","_blank"]],[[8,"href",4]],null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["documentation"])),(t()(),a["\u0275ted"](-1,0,[" on how to add dashboards to Grafana."]))],null,function(t,e){t(e,3,0,a["\u0275inlineInterpolate"](1,"",e.component.docsUrl,""))})}function y(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),a["\u0275did"](1,147456,null,0,c.v,[a.ElementRef,a.Renderer2,[2,c.z]],{ngValue:[0,"ngValue"]},null),a["\u0275did"](2,147456,null,0,c.G,[a.ElementRef,a.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(t()(),a["\u0275ted"](3,null,[""," "]))],function(t,e){t(e,1,0,e.context.$implicit.value),t(e,2,0,e.context.$implicit.value)},function(t,e){t(e,3,0,e.context.$implicit.name)})}function v(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,21,"div",[["class","row"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,16,"div",[["class","col-md-12 timepicker"]],null,null,null,null,null)),(t()(),a["\u0275eld"](2,0,null,null,2,"label",[["class","control-label col-sm-1"],["for","timepicker-control"]],null,null,null,null,null)),(t()(),a["\u0275eld"](3,0,null,null,1,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Grafana Time Picker"])),(t()(),a["\u0275eld"](5,0,null,null,9,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),a["\u0275eld"](6,0,null,null,8,"select",[["class","form-control "],["id","timepicker"],["name","timepicker-control"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"blur"]],function(t,e,n){var r=!0,i=t.component;return"change"===e&&(r=!1!==a["\u0275nov"](t,7).onChange(n.target.value)&&r),"blur"===e&&(r=!1!==a["\u0275nov"](t,7).onTouched()&&r),"ngModelChange"===e&&(r=!1!==(i.time=n)&&r),"ngModelChange"===e&&(r=!1!==i.onTimepickerChange(n)&&r),r},null,null)),a["\u0275did"](7,16384,null,0,c.z,[a.Renderer2,a.ElementRef],null,null),a["\u0275prd"](1024,null,c.p,function(t){return[t]},[c.z]),a["\u0275did"](9,671744,null,0,c.u,[[8,null],[8,null],[8,null],[6,c.p]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),a["\u0275prd"](2048,null,c.q,null,[c.u]),a["\u0275did"](11,16384,null,0,c.r,[[4,c.q]],null,null),a["\u0275did"](12,4210688,null,0,l.a,[[2,d.a],f.a,a.ElementRef],null,null),(t()(),a["\u0275and"](16777216,null,null,1,null,y)),a["\u0275did"](14,278528,null,0,p.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),a["\u0275eld"](15,0,null,null,1,"button",[["class","btn btn-sm"],["title","Reset Settings"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.reset()&&a),a},null,null)),(t()(),a["\u0275eld"](16,0,null,null,0,"i",[["class","fa fa-undo"]],null,null,null,null,null)),(t()(),a["\u0275eld"](17,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),a["\u0275eld"](18,0,null,null,3,"div",[["class","col-md-12"]],null,null,null,null,null)),(t()(),a["\u0275eld"](19,0,null,null,2,"div",[["class","grafana-container"]],null,null,null,null,null)),(t()(),a["\u0275eld"](20,0,[["iframe",1]],null,1,"iframe",[["class","grafana"],["frameborder","0"],["id","iframe"],["scrolling","no"]],[[8,"src",5]],null,null,null,null)),a["\u0275did"](21,278528,null,0,p.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null)],function(t,e){var n=e.component;t(e,9,0,"timepicker-control",n.time),t(e,14,0,n.grafanaTimes),t(e,21,0,"grafana",n.panelStyle)},function(t,e){var n=e.component;t(e,6,0,a["\u0275nov"](e,11).ngClassUntouched,a["\u0275nov"](e,11).ngClassTouched,a["\u0275nov"](e,11).ngClassPristine,a["\u0275nov"](e,11).ngClassDirty,a["\u0275nov"](e,11).ngClassValid,a["\u0275nov"](e,11).ngClassInvalid,a["\u0275nov"](e,11).ngClassPending),t(e,20,0,n.grafanaSrc)})}function _(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,g)),a["\u0275did"](1,16384,null,0,p.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,b)),a["\u0275did"](3,16384,null,0,p.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,m)),a["\u0275did"](5,16384,null,0,p.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,v)),a["\u0275did"](7,16384,null,0,p.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.loading&&n.grafanaExist),t(e,3,0,!n.grafanaExist),t(e,5,0,!n.dashboardExist),t(e,7,0,n.grafanaExist&&n.dashboardExist)},null)}},a40w:function(t,e,n){"use strict";var a=n("CcnG"),r=n("EEJc"),i=n("ajRT"),s=n("gIcY"),o=n("Ip0R"),u=n("gp3X"),c=n("sb0X"),l=n("KVJa"),d=n("Z21x"),f=n("sne2"),p=n("OLbh"),h=n("DQlY");n.d(e,"a",function(){return v});var g=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function b(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function m(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,19,"cd-modal",[],null,[[null,"hide"]],function(t,e,n){var a=!0;return"hide"===e&&(a=!1!==t.component.cancel()&&a),a},r.c,r.b)),a["\u0275did"](1,49152,null,0,i.a,[],null,{hide:"hide"}),(t()(),a["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(t()(),a["\u0275ted"](3,null,["",""])),(t()(),a["\u0275eld"](4,0,null,1,15,null,null,null,null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,14,"form",[["class","form-horizontal"],["name","confirmationForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var r=!0;return"submit"===e&&(r=!1!==a["\u0275nov"](t,7).onSubmit(n)&&r),"reset"===e&&(r=!1!==a["\u0275nov"](t,7).onReset()&&r),r},null,null)),a["\u0275did"](6,16384,null,0,s.D,[],null,null),a["\u0275did"](7,540672,[["formDir",4]],0,s.l,[[8,null],[8,null]],{form:[0,"form"]},null),a["\u0275prd"](2048,null,s.d,null,[s.l]),a["\u0275did"](9,16384,null,0,s.s,[[4,s.d]],null,null),(t()(),a["\u0275eld"](10,0,null,null,2,"div",[["class","modal-body"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,b)),a["\u0275did"](12,540672,null,0,o.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),(t()(),a["\u0275eld"](13,0,null,null,6,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),a["\u0275eld"](14,0,null,null,5,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),a["\u0275eld"](15,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(t,e,n){var a=!0,r=t.component;return"submitAction"===e&&(a=!1!==r.onSubmit(r.confirmationForm.value)&&a),a},u.b,u.a)),a["\u0275did"](16,114688,null,0,c.a,[a.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(t()(),a["\u0275ted"](17,0,[" "," "])),(t()(),a["\u0275eld"](18,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,l.b,l.a)),a["\u0275did"](19,49152,null,0,d.a,[o.Location,f.b],{name:[0,"name"],back:[1,"back"]},null)],function(t,e){var n=e.component;t(e,7,0,n.confirmationForm),t(e,12,0,n.bodyContext,n.bodyTpl),t(e,16,0,n.confirmationForm),t(e,19,0,"Cancel",n.boundCancel)},function(t,e){var n=e.component;t(e,3,0,n.titleText),t(e,5,0,a["\u0275nov"](e,9).ngClassUntouched,a["\u0275nov"](e,9).ngClassTouched,a["\u0275nov"](e,9).ngClassPristine,a["\u0275nov"](e,9).ngClassDirty,a["\u0275nov"](e,9).ngClassValid,a["\u0275nov"](e,9).ngClassInvalid,a["\u0275nov"](e,9).ngClassPending),t(e,17,0,n.buttonText)})}function y(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"cd-confirmation-modal",[],null,null,null,m,g)),a["\u0275did"](1,114688,null,0,p.a,[h.a],null,null)],function(t,e){t(e,1,0)},null)}var v=a["\u0275ccf"]("cd-confirmation-modal",p.a,y,{},{},[])},a96k:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(t,e,n,a){void 0===a&&(a=!0),this.selected=t,this.name=e,this.description=n,this.enabled=a}}()},aB2c:function(t,e,n){"use strict";var a=n("CDJp"),r=n("vvH+"),i=n("RDha");a._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),t.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:r.Line,dataElementType:r.Point,linkScales:i.noop,update:function(t){var e=this,n=e.getMeta(),a=n.data,r=n.dataset.custom||{},s=e.getDataset(),o=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),i.extend(n.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:r.tension?r.tension:i.valueOrDefault(s.lineTension,o.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||o.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||o.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||o.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:o.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||o.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||o.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||o.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||o.borderJoinStyle}}),n.dataset.pivot(),i.each(a,function(n,a){e.updateElement(n,a,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,n){var a=this,r=t.custom||{},s=a.getDataset(),o=a.chart.scale,u=a.chart.options.elements.point,c=o.getPointPositionForValue(e,s.data[e]);void 0!==s.radius&&void 0===s.pointRadius&&(s.pointRadius=s.radius),void 0!==s.hitRadius&&void 0===s.pointHitRadius&&(s.pointHitRadius=s.hitRadius),i.extend(t,{_datasetIndex:a.index,_index:e,_scale:o,_model:{x:n?o.xCenter:c.x,y:n?o.yCenter:c.y,tension:r.tension?r.tension:i.valueOrDefault(s.lineTension,a.chart.options.elements.line.tension),radius:r.radius?r.radius:i.valueAtIndexOrDefault(s.pointRadius,e,u.radius),backgroundColor:r.backgroundColor?r.backgroundColor:i.valueAtIndexOrDefault(s.pointBackgroundColor,e,u.backgroundColor),borderColor:r.borderColor?r.borderColor:i.valueAtIndexOrDefault(s.pointBorderColor,e,u.borderColor),borderWidth:r.borderWidth?r.borderWidth:i.valueAtIndexOrDefault(s.pointBorderWidth,e,u.borderWidth),pointStyle:r.pointStyle?r.pointStyle:i.valueAtIndexOrDefault(s.pointStyle,e,u.pointStyle),rotation:r.rotation?r.rotation:i.valueAtIndexOrDefault(s.pointRotation,e,u.rotation),hitRadius:r.hitRadius?r.hitRadius:i.valueAtIndexOrDefault(s.pointHitRadius,e,u.hitRadius)}}),t._model.skip=r.skip?r.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();i.each(e.data,function(n,a){var r=n._model,s=i.splineCurve(i.previousItem(e.data,a,!0)._model,r,i.nextItem(e.data,a,!0)._model,r.tension);r.controlPointPreviousX=Math.max(Math.min(s.previous.x,t.right),t.left),r.controlPointPreviousY=Math.max(Math.min(s.previous.y,t.bottom),t.top),r.controlPointNextX=Math.max(Math.min(s.next.x,t.right),t.left),r.controlPointNextY=Math.max(Math.min(s.next.y,t.bottom),t.top),n.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t.custom||{},a=t._index,r=t._model;t.$previousStyle={backgroundColor:r.backgroundColor,borderColor:r.borderColor,borderWidth:r.borderWidth,radius:r.radius},r.radius=n.hoverRadius?n.hoverRadius:i.valueAtIndexOrDefault(e.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),r.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:i.valueAtIndexOrDefault(e.pointHoverBackgroundColor,a,i.getHoverColor(r.backgroundColor)),r.borderColor=n.hoverBorderColor?n.hoverBorderColor:i.valueAtIndexOrDefault(e.pointHoverBorderColor,a,i.getHoverColor(r.borderColor)),r.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:i.valueAtIndexOrDefault(e.pointHoverBorderWidth,a,r.borderWidth)}})}},aGNc:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("mrSG"),r=n("FFOo");function i(t){return function(e){return e.lift(new s(t))}}var s=function(){function t(t){this.value=t}return t.prototype.call=function(t,e){return e.subscribe(new o(t,this.value))},t}(),o=function(t){function e(e,n){var a=t.call(this,e)||this;return a.value=n,a}return a.__extends(e,t),e.prototype._next=function(t){this.destination.next(this.value)},e}(r.a)},aIdf:function(t,e,n){!function(t){"use strict";function e(t,e,n){return t+" "+function(t,e){return 2===e?function(t){var e={m:"v",b:"v",d:"z"};return void 0===e[t.charAt(0)]?t:e[t.charAt(0)]+t.substring(1)}(t):t}({mm:"munutenn",MM:"miz",dd:"devezh"}[n],t)}n("wd/R").defineLocale("br",{months:"Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h[e]mm A",LTS:"h[e]mm:ss A",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY h[e]mm A",LLLL:"dddd, D [a viz] MMMM YYYY h[e]mm A"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warc'hoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Dec'h da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s 'zo",s:"un nebeud segondenno\xf9",ss:"%d eilenn",m:"ur vunutenn",mm:e,h:"un eur",hh:"%d eur",d:"un devezh",dd:e,M:"ur miz",MM:e,y:"ur bloaz",yy:function(t){switch(function t(e){return e>9?t(e%10):e}(t)){case 1:case 3:case 4:case 5:case 9:return t+" bloaz";default:return t+" vloaz"}}},dayOfMonthOrdinalParse:/\d{1,2}(a\xf1|vet)/,ordinal:function(t){return t+(1===t?"a\xf1":"vet")},week:{dow:1,doy:4}})}()},aIsn:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("mi",{months:"Kohi-t\u0101te_Hui-tanguru_Pout\u016b-te-rangi_Paenga-wh\u0101wh\u0101_Haratua_Pipiri_H\u014dngoingoi_Here-turi-k\u014dk\u0101_Mahuru_Whiringa-\u0101-nuku_Whiringa-\u0101-rangi_Hakihea".split("_"),monthsShort:"Kohi_Hui_Pou_Pae_Hara_Pipi_H\u014dngoi_Here_Mahu_Whi-nu_Whi-ra_Haki".split("_"),monthsRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,weekdays:"R\u0101tapu_Mane_T\u016brei_Wenerei_T\u0101ite_Paraire_H\u0101tarei".split("_"),weekdaysShort:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),weekdaysMin:"Ta_Ma_T\u016b_We_T\u0101i_Pa_H\u0101".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [i] HH:mm",LLLL:"dddd, D MMMM YYYY [i] HH:mm"},calendar:{sameDay:"[i teie mahana, i] LT",nextDay:"[apopo i] LT",nextWeek:"dddd [i] LT",lastDay:"[inanahi i] LT",lastWeek:"dddd [whakamutunga i] LT",sameElse:"L"},relativeTime:{future:"i roto i %s",past:"%s i mua",s:"te h\u0113kona ruarua",ss:"%d h\u0113kona",m:"he meneti",mm:"%d meneti",h:"te haora",hh:"%d haora",d:"he ra",dd:"%d ra",M:"he marama",MM:"%d marama",y:"he tau",yy:"%d tau"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}()},aQkU:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("mk",{months:"\u0458\u0430\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0458_\u0458\u0443\u043d\u0438_\u0458\u0443\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u0458\u0430\u043d_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0458_\u0458\u0443\u043d_\u0458\u0443\u043b_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u0430_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0440\u0442\u043e\u043a_\u043f\u0435\u0442\u043e\u043a_\u0441\u0430\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u0435_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u0430\u0431".split("_"),weekdaysMin:"\u043de_\u043fo_\u0432\u0442_\u0441\u0440_\u0447\u0435_\u043f\u0435_\u0441a".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u0435\u043d\u0435\u0441 \u0432\u043e] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432\u043e] LT",nextWeek:"[\u0412\u043e] dddd [\u0432\u043e] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432\u043e] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0430\u0442\u0430] dddd [\u0432\u043e] LT";case 1:case 2:case 4:case 5:return"[\u0418\u0437\u043c\u0438\u043d\u0430\u0442\u0438\u043e\u0442] dddd [\u0432\u043e] LT"}},sameElse:"L"},relativeTime:{future:"\u043f\u043e\u0441\u043b\u0435 %s",past:"\u043f\u0440\u0435\u0434 %s",s:"\u043d\u0435\u043a\u043e\u043b\u043a\u0443 \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u0435\u043d\u0430",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0438",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(t){var e=t%10,n=t%100;return 0===t?t+"-\u0435\u0432":0===n?t+"-\u0435\u043d":n>10&&n<20?t+"-\u0442\u0438":1===e?t+"-\u0432\u0438":2===e?t+"-\u0440\u0438":7===e||8===e?t+"-\u043c\u0438":t+"-\u0442\u0438"},week:{dow:1,doy:7}})}()},aTeT:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.single="single",t.multi="multi"}(e.SortType||(e.SortType={}))},aXbf:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("LvDl"),r=n("CcnG"),i=function(){function t(){}return t.prototype.format_number=function(t,e,n,r){if(void 0===r&&(r=1),a.isString(t)&&(t=Number(t)),!a.isNumber(t))return"-";var i=t<1?0:Math.floor(Math.log(t)/Math.log(e));i=i>=n.length?n.length-1:i;var s=a.round(t/Math.pow(e,i),r).toString();return""===s?"-":(""!==n[i]&&(s=s+" "+n[i]),s)},t.prototype.toBytes=function(t,e){void 0===e&&(e=null);var n=["b","k","m","g","t","p","e","z","y"],r=RegExp("^(\\d+(.\\d+)?) ?(["+n.join("")+"]?(b|ib|B/s)?)?$","i").exec(t);if(null===r)return e;var i=parseFloat(r[1]);return a.isString(r[3])&&(i*=Math.pow(1024,n.indexOf(r[3].toLowerCase()[0]))),Math.round(i)},t.prototype.toMilliseconds=function(t){var e=/^\s*(\d+)\s*(ms)?\s*$/i.exec(t);return null!==e?+e[1]:0},t.prototype.toIops=function(t){var e=/^\s*(\d+)\s*(IOPS)?\s*$/i.exec(t);return null!==e?+e[1]:0},t.ngInjectableDef=r.defineInjectable({factory:function(){return new t},token:t,providedIn:"root"}),t}()},ad02:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("mrSG"),r=n("FFOo");function i(t,e){return function(n){return n.lift(new s(t,e))}}var s=function(){function t(t,e){this.compare=t,this.keySelector=e}return t.prototype.call=function(t,e){return e.subscribe(new o(t,this.compare,this.keySelector))},t}(),o=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.keySelector=a,r.hasKey=!1,"function"==typeof n&&(r.compare=n),r}return a.__extends(e,t),e.prototype.compare=function(t,e){return t===e},e.prototype._next=function(t){var e;try{var n=this.keySelector;e=n?n(t):t}catch(r){return this.destination.error(r)}var a=!1;if(this.hasKey)try{a=(0,this.compare)(this.key,e)}catch(r){return this.destination.error(r)}else this.hasKey=!0;a||(this.key=e,this.destination.next(t))},e}(r.a)},ae7Z:function(t,e,n){"use strict";function a(t){var e={left:[],center:[],right:[]};if(t)for(var n=0,a=t;n0&&this.destination.next(e),t.prototype._complete.call(this)},e}(g.a),v=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.bufferSize=n,r.startBufferEvery=a,r.buffers=[],r.count=0,r}return a.__extends(e,t),e.prototype._next=function(t){var e=this.bufferSize,n=this.startBufferEvery,a=this.buffers,r=this.count;this.count++,r%n==0&&a.push([]);for(var i=a.length;i--;){var s=a[i];s.push(t),s.length===e&&(a.splice(i,1),this.destination.next(s))}},e.prototype._complete=function(){for(var e=this.buffers,n=this.destination;e.length>0;){var a=e.shift();a.length>0&&n.next(a)}t.prototype._complete.call(this)},e}(g.a),_=n("nkY7");function x(t){var e=arguments.length,n=c.a;Object(_.a)(arguments[arguments.length-1])&&(n=arguments[arguments.length-1],e--);var a=null;e>=2&&(a=arguments[1]);var r=Number.POSITIVE_INFINITY;return e>=3&&(r=arguments[2]),function(e){return e.lift(new T(t,a,r,n))}}var T=function(){function t(t,e,n,a){this.bufferTimeSpan=t,this.bufferCreationInterval=e,this.maxBufferSize=n,this.scheduler=a}return t.prototype.call=function(t,e){return e.subscribe(new S(t,this.bufferTimeSpan,this.bufferCreationInterval,this.maxBufferSize,this.scheduler))},t}(),w=function(){return function(){this.buffer=[]}}(),S=function(t){function e(e,n,a,r,i){var s=t.call(this,e)||this;s.bufferTimeSpan=n,s.bufferCreationInterval=a,s.maxBufferSize=r,s.scheduler=i,s.contexts=[];var o=s.openContext();if(s.timespanOnly=null==a||a<0,s.timespanOnly)s.add(o.closeAction=i.schedule(O,n,{subscriber:s,context:o,bufferTimeSpan:n}));else{var u={bufferTimeSpan:n,bufferCreationInterval:a,subscriber:s,scheduler:i};s.add(o.closeAction=i.schedule(C,n,{subscriber:s,context:o})),s.add(i.schedule(I,a,u))}return s}return a.__extends(e,t),e.prototype._next=function(t){for(var e,n=this.contexts,a=n.length,r=0;r0;){var a=e.shift();n.next(a.buffer)}t.prototype._complete.call(this)},e.prototype._unsubscribe=function(){this.contexts=null},e.prototype.onBufferFull=function(t){this.closeContext(t);var e=t.closeAction;if(e.unsubscribe(),this.remove(e),!this.closed&&this.timespanOnly){t=this.openContext();var n=this.bufferTimeSpan;this.add(t.closeAction=this.scheduler.schedule(O,n,{subscriber:this,context:t,bufferTimeSpan:n}))}},e.prototype.openContext=function(){var t=new w;return this.contexts.push(t),t},e.prototype.closeContext=function(t){this.destination.next(t.buffer);var e=this.contexts;(e?e.indexOf(t):-1)>=0&&e.splice(e.indexOf(t),1)},e}(g.a);function O(t){var e=t.subscriber,n=t.context;n&&e.closeContext(n),e.closed||(t.context=e.openContext(),t.context.closeAction=this.schedule(t,t.bufferTimeSpan))}function I(t){var e=t.bufferCreationInterval,n=t.bufferTimeSpan,a=t.subscriber,r=t.scheduler,i=a.openContext();a.closed||(a.add(i.closeAction=r.schedule(C,n,{subscriber:a,context:i})),this.schedule(t,e))}function C(t){t.subscriber.closeContext(t.context)}var k=n("pugT");function N(t,e){return function(n){return n.lift(new R(t,e))}}var R=function(){function t(t,e){this.openings=t,this.closingSelector=e}return t.prototype.call=function(t,e){return e.subscribe(new A(t,this.openings,this.closingSelector))},t}(),A=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.openings=n,r.closingSelector=a,r.contexts=[],r.add(Object(i.a)(r,n)),r}return a.__extends(e,t),e.prototype._next=function(t){for(var e=this.contexts,n=e.length,a=0;a0;){var a=n.shift();a.subscription.unsubscribe(),a.buffer=null,a.subscription=null}this.contexts=null,t.prototype._error.call(this,e)},e.prototype._complete=function(){for(var e=this.contexts;e.length>0;){var n=e.shift();this.destination.next(n.buffer),n.subscription.unsubscribe(),n.buffer=null,n.subscription=null}this.contexts=null,t.prototype._complete.call(this)},e.prototype.notifyNext=function(t,e,n,a,r){t?this.closeBuffer(t):this.openBuffer(e)},e.prototype.notifyComplete=function(t){this.closeBuffer(t.context)},e.prototype.openBuffer=function(t){try{var e=this.closingSelector.call(this,t);e&&this.trySubscribe(e)}catch(n){this._error(n)}},e.prototype.closeBuffer=function(t){var e=this.contexts;if(e&&t){var n=t.subscription;this.destination.next(t.buffer),e.splice(e.indexOf(t),1),this.remove(n),n.unsubscribe()}},e.prototype.trySubscribe=function(t){var e=this.contexts,n=new k.a,a={buffer:[],subscription:n};e.push(a);var r=Object(i.a)(this,t,a);!r||r.closed?this.closeBuffer(a):(r.context=a,this.add(r),n.add(r))},e}(r.a);function D(t){return function(e){return e.lift(new E(t))}}var E=function(){function t(t){this.closingSelector=t}return t.prototype.call=function(t,e){return e.subscribe(new L(t,this.closingSelector))},t}(),L=function(t){function e(e,n){var a=t.call(this,e)||this;return a.closingSelector=n,a.subscribing=!1,a.openBuffer(),a}return a.__extends(e,t),e.prototype._next=function(t){this.buffer.push(t)},e.prototype._complete=function(){var e=this.buffer;e&&this.destination.next(e),t.prototype._complete.call(this)},e.prototype._unsubscribe=function(){this.buffer=null,this.subscribing=!1},e.prototype.notifyNext=function(t,e,n,a,r){this.openBuffer()},e.prototype.notifyComplete=function(){this.subscribing?this.complete():this.openBuffer()},e.prototype.openBuffer=function(){var t,e=this.closingSubscription;e&&(this.remove(e),e.unsubscribe()),this.buffer&&this.destination.next(this.buffer),this.buffer=[];try{t=(0,this.closingSelector)()}catch(n){return this.error(n)}e=new k.a,this.closingSubscription=e,this.add(e),this.subscribing=!0,e.add(Object(i.a)(this,t)),this.subscribing=!1},e}(r.a),P=n("9Z1F"),M=n("dzgT");function q(t){return function(e){return e.lift(new M.a(t))}}var j=n("isby"),F=n("0/uQ");function z(){for(var t=[],e=0;e0&&n[0].time-a.now()<=0;)n.shift().notification.observe(r);if(n.length>0){var i=Math.max(0,n[0].time-a.now());this.schedule(t,i)}else this.unsubscribe(),e.active=!1},e.prototype._schedule=function(t){this.active=!0,this.destination.add(t.schedule(e.dispatch,this.delay,{source:this,destination:this.destination,scheduler:t}))},e.prototype.scheduleNotification=function(t){if(!0!==this.errored){var e=this.scheduler,n=new rt(e.now()+this.delay,t);this.queue.push(n),!1===this.active&&this._schedule(e)}},e.prototype._next=function(t){this.scheduleNotification(tt.a.createNext(t))},e.prototype._error=function(t){this.errored=!0,this.queue=[],this.destination.error(t),this.unsubscribe()},e.prototype._complete=function(){this.scheduleNotification(tt.a.createComplete()),this.unsubscribe()},e}(g.a),rt=function(){return function(t,e){this.time=t,this.notification=e}}(),it=n("6blF");function st(t,e){return e?function(n){return new ct(n,e).lift(new ot(t))}:function(e){return e.lift(new ot(t))}}var ot=function(){function t(t){this.delayDurationSelector=t}return t.prototype.call=function(t,e){return e.subscribe(new ut(t,this.delayDurationSelector))},t}(),ut=function(t){function e(e,n){var a=t.call(this,e)||this;return a.delayDurationSelector=n,a.completed=!1,a.delayNotifierSubscriptions=[],a.index=0,a}return a.__extends(e,t),e.prototype.notifyNext=function(t,e,n,a,r){this.destination.next(t),this.removeSubscription(r),this.tryComplete()},e.prototype.notifyError=function(t,e){this._error(t)},e.prototype.notifyComplete=function(t){var e=this.removeSubscription(t);e&&this.destination.next(e),this.tryComplete()},e.prototype._next=function(t){var e=this.index++;try{var n=this.delayDurationSelector(t,e);n&&this.tryDelay(n,t)}catch(a){this.destination.error(a)}},e.prototype._complete=function(){this.completed=!0,this.tryComplete(),this.unsubscribe()},e.prototype.removeSubscription=function(t){t.unsubscribe();var e=this.delayNotifierSubscriptions.indexOf(t);return-1!==e&&this.delayNotifierSubscriptions.splice(e,1),t.outerValue},e.prototype.tryDelay=function(t,e){var n=Object(i.a)(this,t,e);n&&!n.closed&&(this.destination.add(n),this.delayNotifierSubscriptions.push(n))},e.prototype.tryComplete=function(){this.completed&&0===this.delayNotifierSubscriptions.length&&this.destination.complete()},e}(r.a),ct=function(t){function e(e,n){var a=t.call(this)||this;return a.source=e,a.subscriptionDelay=n,a}return a.__extends(e,t),e.prototype._subscribe=function(t){this.subscriptionDelay.subscribe(new lt(t,this.source))},e}(it.a),lt=function(t){function e(e,n){var a=t.call(this)||this;return a.parent=e,a.source=n,a.sourceSubscribed=!1,a}return a.__extends(e,t),e.prototype._next=function(t){this.subscribeToSource()},e.prototype._error=function(t){this.unsubscribe(),this.parent.error(t)},e.prototype._complete=function(){this.unsubscribe(),this.subscribeToSource()},e.prototype.subscribeToSource=function(){this.sourceSubscribed||(this.sourceSubscribed=!0,this.unsubscribe(),this.source.subscribe(this.parent))},e}(g.a);function dt(){return function(t){return t.lift(new ft)}}var ft=function(){function t(){}return t.prototype.call=function(t,e){return e.subscribe(new pt(t))},t}(),pt=function(t){function e(e){return t.call(this,e)||this}return a.__extends(e,t),e.prototype._next=function(t){t.observe(this.destination)},e}(g.a),ht=n("ou9H"),gt=n("ad02");function bt(t,e){return Object(gt.a)(function(n,a){return e?e(n[t],a[t]):n[t]===a[t]})}var mt=n("b7mW"),yt=n("VnD/"),vt=n("tNVB"),_t=n("t9fZ");function xt(t,e){if(t<0)throw new mt.a;var n=arguments.length>=2;return function(a){return a.pipe(Object(yt.a)(function(e,n){return n===t}),Object(_t.a)(1),n?Object(J.a)(e):Object(vt.a)(function(){return new mt.a}))}}var Tt=n("dEwP"),wt=n("F/XL");function St(){for(var t=[],e=0;e0&&this._next(e.shift()),this.hasCompleted&&0===this.active&&this.destination.complete()},e}(r.a),qt=n("2WpN");function jt(t,e){if("function"!=typeof t)throw new TypeError("predicate is not a function");return function(n){return n.lift(new Ft(t,n,!1,e))}}var Ft=function(){function t(t,e,n,a){this.predicate=t,this.source=e,this.yieldIndex=n,this.thisArg=a}return t.prototype.call=function(t,e){return e.subscribe(new zt(t,this.predicate,this.source,this.yieldIndex,this.thisArg))},t}(),zt=function(t){function e(e,n,a,r,i){var s=t.call(this,e)||this;return s.predicate=n,s.source=a,s.yieldIndex=r,s.thisArg=i,s.index=0,s}return a.__extends(e,t),e.prototype.notifyComplete=function(t){var e=this.destination;e.next(t),e.complete(),this.unsubscribe()},e.prototype._next=function(t){var e=this.predicate,n=this.thisArg,a=this.index++;try{e.call(n||this,t,a,this.source)&&this.notifyComplete(this.yieldIndex?a:t)}catch(r){this.destination.error(r)}},e.prototype._complete=function(){this.notifyComplete(this.yieldIndex?-1:void 0)},e}(g.a);function Gt(t,e){return function(n){return n.lift(new Ft(t,n,!0,e))}}var Yt=n("P6uZ"),Vt=n("IxPp");function Ht(){return function(t){return t.lift(new Bt)}}var Bt=function(){function t(){}return t.prototype.call=function(t,e){return e.subscribe(new Ut(t))},t}(),Ut=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return a.__extends(e,t),e.prototype._next=function(t){},e}(g.a);function Wt(){return function(t){return t.lift(new Kt)}}var Kt=function(){function t(){}return t.prototype.call=function(t,e){return e.subscribe(new $t(t))},t}(),$t=function(t){function e(e){return t.call(this,e)||this}return a.__extends(e,t),e.prototype.notifyComplete=function(t){var e=this.destination;e.next(t),e.complete()},e.prototype._next=function(t){this.notifyComplete(!1)},e.prototype._complete=function(){this.notifyComplete(!0)},e}(g.a),Zt=n("w1EH"),Xt=n("aGNc");function Jt(){return function(t){return t.lift(new Qt)}}var Qt=function(){function t(){}return t.prototype.call=function(t,e){return e.subscribe(new te(t))},t}(),te=function(t){function e(e){return t.call(this,e)||this}return a.__extends(e,t),e.prototype._next=function(t){this.destination.next(tt.a.createNext(t))},e.prototype._error=function(t){var e=this.destination;e.next(tt.a.createError(t)),e.complete()},e.prototype._complete=function(){var t=this.destination;t.next(tt.a.createComplete()),t.complete()},e}(g.a),ee=n("Qgas");function ne(t){var e="function"==typeof t?function(e,n){return t(e,n)>0?e:n}:function(t,e){return t>e?t:e};return Object(ee.a)(e)}var ae=n("p0ib");function re(){for(var t=[],e=0;e0?this._next(e.shift()):0===this.active&&this.hasCompleted&&(!1===this.hasValue&&this.destination.next(this.acc),this.destination.complete())},e}(r.a);function de(t){var e="function"==typeof t?function(e,n){return t(e,n)<0?e:n}:function(t,e){return t-1&&(this.count=n-1),e.subscribe(this._unsubscribeAndRecycle())}},e}(g.a);function qe(t){return function(e){return e.lift(new je(t))}}var je=function(){function t(t){this.notifier=t}return t.prototype.call=function(t,e){return e.subscribe(new Fe(t,this.notifier,e))},t}(),Fe=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.notifier=n,r.source=a,r.sourceIsBeingSubscribedTo=!0,r}return a.__extends(e,t),e.prototype.notifyNext=function(t,e,n,a,r){this.sourceIsBeingSubscribedTo=!0,this.source.subscribe(this)},e.prototype.notifyComplete=function(e){if(!1===this.sourceIsBeingSubscribedTo)return t.prototype.complete.call(this)},e.prototype.complete=function(){if(this.sourceIsBeingSubscribedTo=!1,!this.isStopped){if(this.retries||this.subscribeToRetries(),!this.retriesSubscription||this.retriesSubscription.closed)return t.prototype.complete.call(this);this._unsubscribeAndRecycle(),this.notifications.next()}},e.prototype._unsubscribe=function(){var t=this.notifications,e=this.retriesSubscription;t&&(t.unsubscribe(),this.notifications=null),e&&(e.unsubscribe(),this.retriesSubscription=null),this.retries=null},e.prototype._unsubscribeAndRecycle=function(){var e=this._unsubscribe;return this._unsubscribe=null,t.prototype._unsubscribeAndRecycle.call(this),this._unsubscribe=e,this},e.prototype.subscribeToRetries=function(){var e;this.notifications=new we.a;try{e=(0,this.notifier)(this.notifications)}catch(n){return t.prototype.complete.call(this)}this.retries=e,this.retriesSubscription=Object(i.a)(this,e)},e}(r.a);function ze(t){return void 0===t&&(t=-1),function(e){return e.lift(new Ge(t,e))}}var Ge=function(){function t(t,e){this.count=t,this.source=e}return t.prototype.call=function(t,e){return e.subscribe(new Ye(t,this.count,this.source))},t}(),Ye=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.count=n,r.source=a,r}return a.__extends(e,t),e.prototype.error=function(e){if(!this.isStopped){var n=this.source,a=this.count;if(0===a)return t.prototype.error.call(this,e);a>-1&&(this.count=a-1),n.subscribe(this._unsubscribeAndRecycle())}},e}(g.a);function Ve(t){return function(e){return e.lift(new He(t,e))}}var He=function(){function t(t,e){this.notifier=t,this.source=e}return t.prototype.call=function(t,e){return e.subscribe(new Be(t,this.notifier,this.source))},t}(),Be=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.notifier=n,r.source=a,r}return a.__extends(e,t),e.prototype.error=function(e){if(!this.isStopped){var n=this.errors,a=this.retries,r=this.retriesSubscription;if(a)this.errors=null,this.retriesSubscription=null;else{n=new we.a;try{a=(0,this.notifier)(n)}catch(s){return t.prototype.error.call(this,s)}r=Object(i.a)(this,a)}this._unsubscribeAndRecycle(),this.errors=n,this.retries=a,this.retriesSubscription=r,n.next(e)}},e.prototype._unsubscribe=function(){var t=this.errors,e=this.retriesSubscription;t&&(t.unsubscribe(),this.errors=null),e&&(e.unsubscribe(),this.retriesSubscription=null),this.retries=null},e.prototype.notifyNext=function(t,e,n,a,r){var i=this._unsubscribe;this._unsubscribe=null,this._unsubscribeAndRecycle(),this._unsubscribe=i,this.source.subscribe(this)},e}(r.a),Ue=n("yGWI");function We(t){return function(e){return e.lift(new Ke(t))}}var Ke=function(){function t(t){this.notifier=t}return t.prototype.call=function(t,e){var n=new $e(t),a=e.subscribe(n);return a.add(Object(i.a)(n,this.notifier)),a},t}(),$e=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.hasValue=!1,e}return a.__extends(e,t),e.prototype._next=function(t){this.value=t,this.hasValue=!0},e.prototype.notifyNext=function(t,e,n,a,r){this.emitValue()},e.prototype.notifyComplete=function(){this.emitValue()},e.prototype.emitValue=function(){this.hasValue&&(this.hasValue=!1,this.destination.next(this.value))},e}(r.a);function Ze(t,e){return void 0===e&&(e=c.a),function(n){return n.lift(new Xe(t,e))}}var Xe=function(){function t(t,e){this.period=t,this.scheduler=e}return t.prototype.call=function(t,e){return e.subscribe(new Je(t,this.period,this.scheduler))},t}(),Je=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.period=n,r.scheduler=a,r.hasValue=!1,r.add(a.schedule(Qe,n,{subscriber:r,period:n})),r}return a.__extends(e,t),e.prototype._next=function(t){this.lastValue=t,this.hasValue=!0},e.prototype.notifyNext=function(){this.hasValue&&(this.hasValue=!1,this.destination.next(this.lastValue))},e}(g.a);function Qe(t){var e=t.period;t.subscriber.notifyNext(),this.schedule(t,e)}var tn=n("dC0D");function en(t,e){return function(n){return n.lift(new nn(t,e))}}var nn=function(){function t(t,e){this.compareTo=t,this.comparator=e}return t.prototype.call=function(t,e){return e.subscribe(new an(t,this.compareTo,this.comparator))},t}(),an=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.compareTo=n,r.comparator=a,r._a=[],r._b=[],r._oneComplete=!1,r.destination.add(n.subscribe(new rn(e,r))),r}return a.__extends(e,t),e.prototype._next=function(t){this._oneComplete&&0===this._b.length?this.emit(!1):(this._a.push(t),this.checkValues())},e.prototype._complete=function(){this._oneComplete?this.emit(0===this._a.length&&0===this._b.length):this._oneComplete=!0,this.unsubscribe()},e.prototype.checkValues=function(){for(var t=this._a,e=this._b,n=this.comparator;t.length>0&&e.length>0;){var a=t.shift(),r=e.shift(),i=!1;try{i=n?n(a,r):a===r}catch(s){this.destination.error(s)}i||this.emit(!1)}},e.prototype.emit=function(t){var e=this.destination;e.next(t),e.complete()},e.prototype.nextB=function(t){this._oneComplete&&0===this._a.length?this.emit(!1):(this._b.push(t),this.checkValues())},e.prototype.completeB=function(){this._oneComplete?this.emit(0===this._a.length&&0===this._b.length):this._oneComplete=!0},e}(g.a),rn=function(t){function e(e,n){var a=t.call(this,e)||this;return a.parent=n,a}return a.__extends(e,t),e.prototype._next=function(t){this.parent.nextB(t)},e.prototype._error=function(t){this.parent.error(t),this.unsubscribe()},e.prototype._complete=function(){this.parent.completeB(),this.unsubscribe()},e}(g.a),sn=n("S1nX"),on=n("klSw"),un=n("3fWJ");function cn(t){return function(e){return e.lift(new ln(t,e))}}var ln=function(){function t(t,e){this.predicate=t,this.source=e}return t.prototype.call=function(t,e){return e.subscribe(new dn(t,this.predicate,this.source))},t}(),dn=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.predicate=n,r.source=a,r.seenValue=!1,r.index=0,r}return a.__extends(e,t),e.prototype.applySingleValue=function(t){this.seenValue?this.destination.error("Sequence contains more than one element"):(this.seenValue=!0,this.singleValue=t)},e.prototype._next=function(t){var e=this.index++;this.predicate?this.tryNext(t,e):this.applySingleValue(t)},e.prototype.tryNext=function(t,e){try{this.predicate(t,e,this.source)&&this.applySingleValue(t)}catch(n){this.destination.error(n)}},e.prototype._complete=function(){var t=this.destination;this.index>0?(t.next(this.seenValue?this.singleValue:void 0),t.complete()):t.error(new un.a)},e}(g.a);function fn(t){return function(e){return e.lift(new pn(t))}}var pn=function(){function t(t){this.total=t}return t.prototype.call=function(t,e){return e.subscribe(new hn(t,this.total))},t}(),hn=function(t){function e(e,n){var a=t.call(this,e)||this;return a.total=n,a.count=0,a}return a.__extends(e,t),e.prototype._next=function(t){++this.count>this.total&&this.destination.next(t)},e}(g.a);function gn(t){return function(e){return e.lift(new bn(t))}}var bn=function(){function t(t){if(this._skipCount=t,this._skipCount<0)throw new mt.a}return t.prototype.call=function(t,e){return e.subscribe(0===this._skipCount?new g.a(t):new mn(t,this._skipCount))},t}(),mn=function(t){function e(e,n){var a=t.call(this,e)||this;return a._skipCount=n,a._count=0,a._ring=new Array(n),a}return a.__extends(e,t),e.prototype._next=function(t){var e=this._skipCount,n=this._count++;if(n0?this.startWindowEvery:this.windowSize,n=this.destination,a=this.windowSize,r=this.windows,i=r.length,s=0;s=0&&o%e==0&&!this.closed&&r.shift().complete(),++this.count%e==0&&!this.closed){var u=new we.a;r.push(u),n.next(u)}},e.prototype._error=function(t){var e=this.windows;if(e)for(;e.length>0&&!this.closed;)e.shift().error(t);this.destination.error(t)},e.prototype._complete=function(){var t=this.windows;if(t)for(;t.length>0&&!this.closed;)t.shift().complete();this.destination.complete()},e.prototype._unsubscribe=function(){this.count=0,this.windows=null},e}(g.a);function ha(t){var e=c.a,n=null,a=Number.POSITIVE_INFINITY;return Object(_.a)(arguments[3])&&(e=arguments[3]),Object(_.a)(arguments[2])?e=arguments[2]:Object(In.a)(arguments[2])&&(a=arguments[2]),Object(_.a)(arguments[1])?e=arguments[1]:Object(In.a)(arguments[1])&&(n=arguments[1]),function(r){return r.lift(new ga(t,n,a,e))}}var ga=function(){function t(t,e,n,a){this.windowTimeSpan=t,this.windowCreationInterval=e,this.maxWindowSize=n,this.scheduler=a}return t.prototype.call=function(t,e){return e.subscribe(new ma(t,this.windowTimeSpan,this.windowCreationInterval,this.maxWindowSize,this.scheduler))},t}(),ba=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._numberOfNextedValues=0,e}return a.__extends(e,t),e.prototype.next=function(e){this._numberOfNextedValues++,t.prototype.next.call(this,e)},Object.defineProperty(e.prototype,"numberOfNextedValues",{get:function(){return this._numberOfNextedValues},enumerable:!0,configurable:!0}),e}(we.a),ma=function(t){function e(e,n,a,r,i){var s=t.call(this,e)||this;s.destination=e,s.windowTimeSpan=n,s.windowCreationInterval=a,s.maxWindowSize=r,s.scheduler=i,s.windows=[];var o=s.openWindow();if(null!==a&&a>=0){var u={windowTimeSpan:n,windowCreationInterval:a,subscriber:s,scheduler:i};s.add(i.schedule(_a,n,{subscriber:s,window:o,context:null})),s.add(i.schedule(va,a,u))}else s.add(i.schedule(ya,n,{subscriber:s,window:o,windowTimeSpan:n}));return s}return a.__extends(e,t),e.prototype._next=function(t){for(var e=this.windows,n=e.length,a=0;a=this.maxWindowSize&&this.closeWindow(r))}},e.prototype._error=function(t){for(var e=this.windows;e.length>0;)e.shift().error(t);this.destination.error(t)},e.prototype._complete=function(){for(var t=this.windows;t.length>0;){var e=t.shift();e.closed||e.complete()}this.destination.complete()},e.prototype.openWindow=function(){var t=new ba;return this.windows.push(t),this.destination.next(t),t},e.prototype.closeWindow=function(t){t.complete();var e=this.windows;e.splice(e.indexOf(t),1)},e}(g.a);function ya(t){var e=t.subscriber,n=t.windowTimeSpan,a=t.window;a&&e.closeWindow(a),t.window=e.openWindow(),this.schedule(t,n)}function va(t){var e=t.windowTimeSpan,n=t.subscriber,a=t.scheduler,r=t.windowCreationInterval,i=n.openWindow(),s={action:this,subscription:null};s.subscription=a.schedule(_a,e,{subscriber:n,window:i,context:s}),this.add(s.subscription),this.schedule(t,r)}function _a(t){var e=t.subscriber,n=t.window,a=t.context;a&&a.action&&a.subscription&&a.action.remove(a.subscription),e.closeWindow(n)}function xa(t,e){return function(n){return n.lift(new Ta(t,e))}}var Ta=function(){function t(t,e){this.openings=t,this.closingSelector=e}return t.prototype.call=function(t,e){return e.subscribe(new wa(t,this.openings,this.closingSelector))},t}(),wa=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.openings=n,r.closingSelector=a,r.contexts=[],r.add(r.openSubscription=Object(i.a)(r,n,n)),r}return a.__extends(e,t),e.prototype._next=function(t){var e=this.contexts;if(e)for(var n=e.length,a=0;a0){var s=i.indexOf(n);-1!==s&&i.splice(s,1)}},e.prototype.notifyComplete=function(){},e.prototype._next=function(t){if(0===this.toRespond.length){var e=[t].concat(this.values);this.project?this._tryProject(e):this.destination.next(e)}},e.prototype._tryProject=function(t){var e;try{e=this.project.apply(this,t)}catch(n){return void this.destination.error(n)}this.destination.next(e)},e}(r.a),Ra=n("909l");function Aa(){for(var t=[],e=0;e animated-down",animation:[{type:6,styles:{height:0,overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:0,name:"animated-up",styles:{type:6,styles:{height:"*",overflow:"hidden"},offset:null},options:void 0},{type:1,expr:"* => animated-up",animation:[{type:6,styles:{height:"*",overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:1,expr:"* => unanimated",animation:{type:4,styles:null,timings:"0s"},options:null}],options:{}}]}});function u(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"bs-days-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onHoverWeek"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.dayHoverHandler(n)&&a),"onHoverWeek"===e&&(a=!1!==r.weekHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.daySelectHandler(n)&&a),a},dt,it)),a["\u0275did"](1,49152,null,0,r.z,[r.a],{calendar:[0,"calendar"],options:[1,"options"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover",onHoverWeek:"onHoverWeek"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef]),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,1,0,e.context.$implicit,a["\u0275unv"](e,1,1,a["\u0275nov"](e,2).transform(n.options)))},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,3).transform(r.daysCalendar)))?null:n.length)>1)})}function c(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,u)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.daysCalendar)))},null)}function l(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"bs-month-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.monthHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.monthSelectHandler(n)&&a),a},gt,ft)),a["\u0275did"](1,49152,null,0,r.A,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){t(e,1,0,e.context.$implicit)},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,2).transform(r.daysCalendar)))?null:n.length)>1)})}function d(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,l)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.monthsCalendar)))},null)}function f(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"bs-years-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.yearHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.yearSelectHandler(n)&&a),a},vt,bt)),a["\u0275did"](1,49152,null,0,r.B,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){t(e,1,0,e.context.$implicit)},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,2).transform(r.daysCalendar)))?null:n.length)>1)})}function p(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,f)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.yearsCalendar)))},null)}function h(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"div",[["class","bs-datepicker-buttons"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"button",[["class","btn btn-success"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Apply"])),(t()(),a["\u0275eld"](3,0,null,null,1,"button",[["class","btn btn-default"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Cancel"]))],null,null)}function g(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["class","bs-datepicker-custom-range"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"bs-custom-date-view",[],null,null,null,wt,_t)),a["\u0275did"](2,49152,null,0,r.C,[],{ranges:[0,"ranges"]},null)],function(t,e){t(e,2,0,e.component._customRangesFish)},null)}function b(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,15,"div",[["class","bs-datepicker"]],null,null,null,null,null)),a["\u0275did"](1,278528,null,0,i.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),a["\u0275eld"](2,0,null,null,11,"div",[["class","bs-datepicker-container"]],[[24,"@datepickerAnimation",0]],[[null,"@datepickerAnimation.done"]],function(t,e,n){var a=!0;return"@datepickerAnimation.done"===e&&(a=!1!==t.component.positionServiceEnable()&&a),a},null,null)),(t()(),a["\u0275eld"](3,0,null,null,8,"div",[["class","bs-calendar-container"],["role","application"]],null,null,null,null,null)),a["\u0275did"](4,16384,null,0,i.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef]),(t()(),a["\u0275and"](16777216,null,null,1,null,c)),a["\u0275did"](7,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,d)),a["\u0275did"](9,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,p)),a["\u0275did"](11,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,h)),a["\u0275did"](13,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,g)),a["\u0275did"](15,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"bs-datepicker",n.containerClass),t(e,4,0,a["\u0275unv"](e,4,0,a["\u0275nov"](e,5).transform(n.viewMode))),t(e,7,0,"day"),t(e,9,0,"month"),t(e,11,0,"year"),t(e,13,0,!1),t(e,15,0,!1)},function(t,e){t(e,2,0,e.component.animationState)})}function m(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,2,null,b)),a["\u0275did"](1,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,1,0,a["\u0275unv"](e,1,0,a["\u0275nov"](e,2).transform(n.viewMode)))},null)}function y(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"bs-datepicker-container",[["aria-label","calendar"],["class","bottom"],["role","dialog"],["style","position: absolute; display: block;"]],null,[[null,"click"]],function(t,e,n){var r=!0;return"click"===e&&(r=!1!==a["\u0275nov"](t,3)._stopPropagation(n)&&r),r},m,o)),a["\u0275prd"](512,null,r.r,r.r,[]),a["\u0275prd"](512,null,r.s,r.s,[r.t,r.j]),a["\u0275did"](3,245760,null,0,r.b,[r.a,r.r,a.ElementRef,r.t,r.s,s.a],null,null)],function(t,e){t(e,3,0)},null)}var v=a["\u0275ccf"]("bs-datepicker-container",r.b,y,{},{},[]),_=a["\u0275crt"]({encapsulation:2,styles:[],data:{animation:[{type:7,name:"datepickerAnimation",definitions:[{type:0,name:"animated-down",styles:{type:6,styles:{height:"*",overflow:"hidden"},offset:null},options:void 0},{type:1,expr:"* => animated-down",animation:[{type:6,styles:{height:0,overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:0,name:"animated-up",styles:{type:6,styles:{height:"*",overflow:"hidden"},offset:null},options:void 0},{type:1,expr:"* => animated-up",animation:[{type:6,styles:{height:"*",overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:1,expr:"* => unanimated",animation:{type:4,styles:null,timings:"0s"},options:null}],options:{}}]}});function x(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"bs-days-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onHoverWeek"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.dayHoverHandler(n)&&a),"onHoverWeek"===e&&(a=!1!==r.weekHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.daySelectHandler(n)&&a),a},dt,it)),a["\u0275did"](1,49152,null,0,r.z,[r.a],{calendar:[0,"calendar"],options:[1,"options"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover",onHoverWeek:"onHoverWeek"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef]),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,1,0,e.context.$implicit,a["\u0275unv"](e,1,1,a["\u0275nov"](e,2).transform(n.options)))},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,3).transform(r.daysCalendar)))?null:n.length)>1)})}function T(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,x)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.daysCalendar)))},null)}function w(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"bs-month-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.monthHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.monthSelectHandler(n)&&a),a},gt,ft)),a["\u0275did"](1,49152,null,0,r.A,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){t(e,1,0,e.context.$implicit)},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,2).transform(r.daysCalendar)))?null:n.length)>1)})}function S(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,w)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.monthsCalendar)))},null)}function O(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"bs-years-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.yearHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.yearSelectHandler(n)&&a),a},vt,bt)),a["\u0275did"](1,49152,null,0,r.B,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){t(e,1,0,e.context.$implicit)},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,2).transform(r.daysCalendar)))?null:n.length)>1)})}function I(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,O)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.yearsCalendar)))},null)}function C(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"div",[["class","bs-datepicker-buttons"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"button",[["class","btn btn-success"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Apply"])),(t()(),a["\u0275eld"](3,0,null,null,1,"button",[["class","btn btn-default"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Cancel"]))],null,null)}function k(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["class","bs-datepicker-custom-range"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"bs-custom-date-view",[],null,null,null,wt,_t)),a["\u0275did"](2,49152,null,0,r.C,[],{ranges:[0,"ranges"]},null)],function(t,e){t(e,2,0,e.component._customRangesFish)},null)}function N(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,15,"div",[["class","bs-datepicker"]],null,null,null,null,null)),a["\u0275did"](1,278528,null,0,i.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),a["\u0275eld"](2,0,null,null,11,"div",[["class","bs-datepicker-container"]],[[24,"@datepickerAnimation",0]],[[null,"@datepickerAnimation.done"]],function(t,e,n){var a=!0;return"@datepickerAnimation.done"===e&&(a=!1!==t.component.positionServiceEnable()&&a),a},null,null)),(t()(),a["\u0275eld"](3,0,null,null,8,"div",[["class","bs-calendar-container"],["role","application"]],null,null,null,null,null)),a["\u0275did"](4,16384,null,0,i.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef]),(t()(),a["\u0275and"](16777216,null,null,1,null,T)),a["\u0275did"](7,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,S)),a["\u0275did"](9,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,I)),a["\u0275did"](11,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,C)),a["\u0275did"](13,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,k)),a["\u0275did"](15,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"bs-datepicker",n.containerClass),t(e,4,0,a["\u0275unv"](e,4,0,a["\u0275nov"](e,5).transform(n.viewMode))),t(e,7,0,"day"),t(e,9,0,"month"),t(e,11,0,"year"),t(e,13,0,!1),t(e,15,0,!1)},function(t,e){t(e,2,0,e.component.animationState)})}function R(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,2,null,N)),a["\u0275did"](1,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,1,0,a["\u0275unv"](e,1,0,a["\u0275nov"](e,2).transform(n.viewMode)))},null)}function A(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"bs-datepicker-inline-container",[["style","display: inline-block;"]],null,[[null,"click"]],function(t,e,n){var r=!0;return"click"===e&&(r=!1!==a["\u0275nov"](t,3)._stopPropagation(n)&&r),r},R,_)),a["\u0275prd"](512,null,r.r,r.r,[]),a["\u0275prd"](512,null,r.s,r.s,[r.t,r.j]),a["\u0275did"](3,245760,null,0,r.e,[r.a,r.r,a.ElementRef,r.t,r.s,s.a],null,null)],function(t,e){t(e,3,0)},null)}var D=a["\u0275ccf"]("bs-datepicker-inline-container",r.e,A,{},{},[]),E=a["\u0275crt"]({encapsulation:2,styles:[],data:{animation:[{type:7,name:"datepickerAnimation",definitions:[{type:0,name:"animated-down",styles:{type:6,styles:{height:"*",overflow:"hidden"},offset:null},options:void 0},{type:1,expr:"* => animated-down",animation:[{type:6,styles:{height:0,overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:0,name:"animated-up",styles:{type:6,styles:{height:"*",overflow:"hidden"},offset:null},options:void 0},{type:1,expr:"* => animated-up",animation:[{type:6,styles:{height:"*",overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:1,expr:"* => unanimated",animation:{type:4,styles:null,timings:"0s"},options:null}],options:{}}]}});function L(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"bs-days-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onHoverWeek"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.dayHoverHandler(n)&&a),"onHoverWeek"===e&&(a=!1!==r.weekHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.daySelectHandler(n)&&a),a},dt,it)),a["\u0275did"](1,49152,null,0,r.z,[r.a],{calendar:[0,"calendar"],options:[1,"options"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover",onHoverWeek:"onHoverWeek"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef]),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,1,0,e.context.$implicit,a["\u0275unv"](e,1,1,a["\u0275nov"](e,2).transform(n.options)))},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,3).transform(r.daysCalendar)))?null:n.length)>1)})}function P(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,L)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.daysCalendar)))},null)}function M(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"bs-month-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.monthHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.monthSelectHandler(n)&&a),a},gt,ft)),a["\u0275did"](1,49152,null,0,r.A,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){t(e,1,0,e.context.$implicit)},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,2).transform(r.daysCalendar)))?null:n.length)>1)})}function q(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,M)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.monthsCalendar)))},null)}function j(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"bs-years-calendar-view",[],[[2,"bs-datepicker-multiple",null]],[[null,"onNavigate"],[null,"onViewMode"],[null,"onHover"],[null,"onSelect"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.setViewMode(n)&&a),"onHover"===e&&(a=!1!==r.yearHoverHandler(n)&&a),"onSelect"===e&&(a=!1!==r.yearSelectHandler(n)&&a),a},vt,bt)),a["\u0275did"](1,49152,null,0,r.B,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode",onSelect:"onSelect",onHover:"onHover"}),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){t(e,1,0,e.context.$implicit)},function(t,e){var n,r=e.component;t(e,0,0,(null==(n=a["\u0275unv"](e,0,0,a["\u0275nov"](e,2).transform(r.daysCalendar)))?null:n.length)>1)})}function F(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"div",[["class","bs-media-container"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,2,null,j)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,2,0,a["\u0275unv"](e,2,0,a["\u0275nov"](e,3).transform(n.yearsCalendar)))},null)}function z(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"div",[["class","bs-datepicker-buttons"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"button",[["class","btn btn-success"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Apply"])),(t()(),a["\u0275eld"](3,0,null,null,1,"button",[["class","btn btn-default"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Cancel"]))],null,null)}function G(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["class","bs-datepicker-custom-range"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"bs-custom-date-view",[],null,null,null,wt,_t)),a["\u0275did"](2,49152,null,0,r.C,[],{ranges:[0,"ranges"]},null)],function(t,e){t(e,2,0,e.component._customRangesFish)},null)}function Y(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,15,"div",[["class","bs-datepicker"]],null,null,null,null,null)),a["\u0275did"](1,278528,null,0,i.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),a["\u0275eld"](2,0,null,null,11,"div",[["class","bs-datepicker-container"]],[[24,"@datepickerAnimation",0]],[[null,"@datepickerAnimation.done"]],function(t,e,n){var a=!0;return"@datepickerAnimation.done"===e&&(a=!1!==t.component.positionServiceEnable()&&a),a},null,null)),(t()(),a["\u0275eld"](3,0,null,null,8,"div",[["class","bs-calendar-container"],["role","application"]],null,null,null,null,null)),a["\u0275did"](4,16384,null,0,i.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef]),(t()(),a["\u0275and"](16777216,null,null,1,null,P)),a["\u0275did"](7,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,q)),a["\u0275did"](9,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,F)),a["\u0275did"](11,278528,null,0,i.NgSwitchCase,[a.ViewContainerRef,a.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,z)),a["\u0275did"](13,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,G)),a["\u0275did"](15,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"bs-datepicker",n.containerClass),t(e,4,0,a["\u0275unv"](e,4,0,a["\u0275nov"](e,5).transform(n.viewMode))),t(e,7,0,"day"),t(e,9,0,"month"),t(e,11,0,"year"),t(e,13,0,!1),t(e,15,0,!1)},function(t,e){t(e,2,0,e.component.animationState)})}function V(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,2,null,Y)),a["\u0275did"](1,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),a["\u0275pid"](131072,i.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,1,0,a["\u0275unv"](e,1,0,a["\u0275nov"](e,2).transform(n.viewMode)))},null)}function H(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"bs-daterangepicker-container",[["aria-label","calendar"],["class","bottom"],["role","dialog"],["style","position: absolute; display: block;"]],null,[[null,"click"]],function(t,e,n){var r=!0;return"click"===e&&(r=!1!==a["\u0275nov"](t,3)._stopPropagation(n)&&r),r},V,E)),a["\u0275prd"](512,null,r.s,r.s,[r.t,r.j]),a["\u0275prd"](512,null,r.r,r.r,[]),a["\u0275did"](3,245760,null,0,r.i,[r.s,r.t,r.a,r.r,a.ElementRef,s.a],null,null)],function(t,e){t(e,3,0)},null)}var B=a["\u0275ccf"]("bs-daterangepicker-container",r.i,H,{},{},[]),U=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function W(t){return a["\u0275vid"](2,[(t()(),a["\u0275ted"](0,null,["",""]))],null,function(t,e){t(e,0,0,e.component.day.label)})}var K=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function $(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["class","current-timedate"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,2,0,e.component.title)})}var Z=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function X(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"button",[["class","current"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.view("month")&&a),a},null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,2,0,e.component.calendar.monthTitle)})}function J(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,2,"button",[["class","previous"]],[[8,"disabled",0],[4,"visibility",null]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.navTo(!0)&&a),a},null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["\u2039"])),(t()(),a["\u0275ted"](-1,null,[" \u200b "])),(t()(),a["\u0275and"](16777216,null,null,1,null,X)),a["\u0275did"](5,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275ted"](-1,null,[" \u200b "])),(t()(),a["\u0275eld"](7,0,null,null,2,"button",[["class","current"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.view("year")&&a),a},null,null)),(t()(),a["\u0275eld"](8,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](9,null,["",""])),(t()(),a["\u0275ted"](-1,null,[" \u200b "])),(t()(),a["\u0275eld"](11,0,null,null,2,"button",[["class","next"]],[[8,"disabled",0],[4,"visibility",null]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.navTo(!1)&&a),a},null,null)),(t()(),a["\u0275eld"](12,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["\u203a"]))],function(t,e){t(e,5,0,e.component.calendar.monthTitle)},function(t,e){var n=e.component;t(e,0,0,n.calendar.disableLeftArrow,n.calendar.hideLeftArrow?"hidden":"visible"),t(e,9,0,n.calendar.yearTitle),t(e,11,0,n.calendar.disableRightArrow,n.calendar.hideRightArrow?"hidden":"visible")})}var Q=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function tt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,15,"div",[["class","bs-timepicker-container"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,5,"div",[["class","bs-timepicker-controls"]],null,null,null,null,null)),(t()(),a["\u0275eld"](2,0,null,null,1,"button",[["class","bs-decrease"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["-"])),(t()(),a["\u0275eld"](4,0,null,null,0,"input",[["placeholder","00"],["type","text"]],[[8,"value",0]],null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,1,"button",[["class","bs-increase"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["+"])),(t()(),a["\u0275eld"](7,0,null,null,5,"div",[["class","bs-timepicker-controls"]],null,null,null,null,null)),(t()(),a["\u0275eld"](8,0,null,null,1,"button",[["class","bs-decrease"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["-"])),(t()(),a["\u0275eld"](10,0,null,null,0,"input",[["placeholder","00"],["type","text"]],[[8,"value",0]],null,null,null,null)),(t()(),a["\u0275eld"](11,0,null,null,1,"button",[["class","bs-increase"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["+"])),(t()(),a["\u0275eld"](13,0,null,null,2,"button",[["class","switch-time-format"]],null,null,null,null,null)),(t()(),a["\u0275ted"](14,null,[""," "])),(t()(),a["\u0275eld"](15,0,null,null,0,"img",[["alt",""],["src","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAABSElEQVQYV3XQPUvDUBQG4HNuagtVqc6KgouCv6GIuIntYBLB9hcIQpLStCAIV7DYmpTcRWcXqZio3Vwc/UCc/QEqfgyKGbr0I7nS1EiHeqYzPO/h5SD0jaxUZjmSLCB+OFb+UFINFwASAEAdpu9gaGXVyAHHFQBkHpKHc6a9dzECvADyY9sqlAMsK9W0jzxDXqeytr3mhQckxSji27TJJ5/rPmIpwJJq3HrtduriYOurv1a4i1p5HnhkG9OFymi0ReoO05cGwb+ayv4dysVygjeFmsP05f8wpZQ8fsdvfmuY9zjWSNqUtgYFVnOVReILYoBFzdQI5/GGFzNHhGbeZnopDGU29sZbscgldmC99w35VOATTycIMMcBXIfpSVGzZhA6C8hh00conln6VQ9TGgV32OEAKQC4DrBq7CJwd0ggR7Vq/rPrfgB+C3sGypY5DAAAAABJRU5ErkJggg=="]],null,null,null,null,null))],null,function(t,e){var n=e.component;t(e,4,0,n.hours),t(e,10,0,n.minutes),t(e,14,0,n.ampm)})}var et=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function nt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"bs-current-date",[["title","hey there"]],null,null,null,$,K)),a["\u0275did"](1,49152,null,0,r.v,[],{title:[0,"title"]},null)],function(t,e){t(e,1,0,"hey there")},null)}function at(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"bs-timepicker",[],null,null,null,tt,Q)),a["\u0275did"](1,49152,null,0,r.x,[],null,null)],null,null)}function rt(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,1,null,nt)),a["\u0275did"](1,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275eld"](2,0,null,null,1,"div",[["class","bs-datepicker-head"]],null,null,null,null,null)),a["\u0275ncd"](null,0),(t()(),a["\u0275eld"](4,0,null,null,1,"div",[["class","bs-datepicker-body"]],null,null,null,null,null)),a["\u0275ncd"](null,1),(t()(),a["\u0275and"](16777216,null,null,1,null,at)),a["\u0275did"](7,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,1,0,!1),t(e,7,0,!1)},null)}var it=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function st(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"th",[],null,null,null,null,null))],null,null)}function ot(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"th",[["aria-label","weekday"]],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,[""," "]))],null,function(t,e){t(e,1,0,e.component.calendar.weekdays[e.context.index])})}function ut(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"td",[["class","week"]],[[2,"active-week",null]],null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"span",[],null,[[null,"click"],[null,"mouseenter"],[null,"mouseleave"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.selectWeek(t.parent.context.$implicit)&&a),"mouseenter"===e&&(a=!1!==r.weekHoverHandler(t.parent.context.$implicit,!0)&&a),"mouseleave"===e&&(a=!1!==r.weekHoverHandler(t.parent.context.$implicit,!1)&&a),a},null,null)),(t()(),a["\u0275ted"](2,null,["",""]))],null,function(t,e){var n=e.component;t(e,0,0,n.isWeekHovered),t(e,2,0,n.calendar.weekNumbers[e.parent.context.index])})}function ct(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"td",[["role","gridcell"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,2,"span",[["bsDatepickerDayDecorator",""]],[[2,"disabled",null],[2,"is-highlighted",null],[2,"is-other-month",null],[2,"is-active-other-month",null],[2,"in-range",null],[2,"select-start",null],[2,"select-end",null],[2,"selected",null]],[[null,"click"],[null,"mouseenter"],[null,"mouseleave"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.selectDay(t.context.$implicit)&&a),"mouseenter"===e&&(a=!1!==r.hoverDay(t.context.$implicit,!0)&&a),"mouseleave"===e&&(a=!1!==r.hoverDay(t.context.$implicit,!1)&&a),a},W,U)),a["\u0275did"](2,114688,null,0,r.u,[r.a,a.ElementRef,a.Renderer2],{day:[0,"day"]},null),(t()(),a["\u0275ted"](3,null,["",""]))],function(t,e){t(e,2,0,e.context.$implicit)},function(t,e){t(e,1,0,a["\u0275nov"](e,2).day.isDisabled,a["\u0275nov"](e,2).day.isHovered,a["\u0275nov"](e,2).day.isOtherMonth,a["\u0275nov"](e,2).day.isOtherMonthHovered,a["\u0275nov"](e,2).day.isInRange,a["\u0275nov"](e,2).day.isSelectionStart,a["\u0275nov"](e,2).day.isSelectionEnd,a["\u0275nov"](e,2).day.isSelected),t(e,3,0,e.context.$implicit.label)})}function lt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,ut)),a["\u0275did"](2,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,ct)),a["\u0275did"](4,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.component.options.showWeekNumbers),t(e,4,0,e.context.$implicit.days)},null)}function dt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,13,"bs-calendar-layout",[],null,null,null,rt,et)),a["\u0275did"](1,49152,null,0,r.y,[],null,null),(t()(),a["\u0275eld"](2,0,null,0,1,"bs-datepicker-navigation-view",[],null,[[null,"onNavigate"],[null,"onViewMode"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.changeViewMode(n)&&a),a},J,Z)),a["\u0275did"](3,49152,null,0,r.w,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode"}),(t()(),a["\u0275eld"](4,0,null,1,9,"table",[["class","days weeks"],["role","grid"]],null,null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,5,"thead",[],null,null,null,null,null)),(t()(),a["\u0275eld"](6,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,st)),a["\u0275did"](8,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,ot)),a["\u0275did"](10,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),a["\u0275eld"](11,0,null,null,2,"tbody",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,lt)),a["\u0275did"](13,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){var n=e.component;t(e,3,0,n.calendar),t(e,8,0,n.options.showWeekNumbers),t(e,10,0,n.calendar.weekdays),t(e,13,0,n.calendar.weeks)},null)}var ft=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function pt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"td",[["role","gridcell"]],[[2,"disabled",null],[2,"is-highlighted",null]],[[null,"click"],[null,"mouseenter"],[null,"mouseleave"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.viewMonth(t.context.$implicit)&&a),"mouseenter"===e&&(a=!1!==r.hoverMonth(t.context.$implicit,!0)&&a),"mouseleave"===e&&(a=!1!==r.hoverMonth(t.context.$implicit,!1)&&a),a},null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,0,0,e.context.$implicit.isDisabled,e.context.$implicit.isHovered),t(e,2,0,e.context.$implicit.label)})}function ht(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"tr",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,pt)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.context.$implicit)},null)}function gt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,7,"bs-calendar-layout",[],null,null,null,rt,et)),a["\u0275did"](1,49152,null,0,r.y,[],null,null),(t()(),a["\u0275eld"](2,0,null,0,1,"bs-datepicker-navigation-view",[],null,[[null,"onNavigate"],[null,"onViewMode"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.changeViewMode(n)&&a),a},J,Z)),a["\u0275did"](3,49152,null,0,r.w,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode"}),(t()(),a["\u0275eld"](4,0,null,1,3,"table",[["class","months"],["role","grid"]],null,null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,2,"tbody",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,ht)),a["\u0275did"](7,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){var n=e.component;t(e,3,0,n.calendar),t(e,7,0,n.calendar.months)},null)}var bt=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function mt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"td",[["role","gridcell"]],[[2,"disabled",null],[2,"is-highlighted",null]],[[null,"click"],[null,"mouseenter"],[null,"mouseleave"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.viewYear(t.context.$implicit)&&a),"mouseenter"===e&&(a=!1!==r.hoverYear(t.context.$implicit,!0)&&a),"mouseleave"===e&&(a=!1!==r.hoverYear(t.context.$implicit,!1)&&a),a},null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,0,0,e.context.$implicit.isDisabled,e.context.$implicit.isHovered),t(e,2,0,e.context.$implicit.label)})}function yt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"tr",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,mt)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.context.$implicit)},null)}function vt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,7,"bs-calendar-layout",[],null,null,null,rt,et)),a["\u0275did"](1,49152,null,0,r.y,[],null,null),(t()(),a["\u0275eld"](2,0,null,0,1,"bs-datepicker-navigation-view",[],null,[[null,"onNavigate"],[null,"onViewMode"]],function(t,e,n){var a=!0,r=t.component;return"onNavigate"===e&&(a=!1!==r.navigateTo(n)&&a),"onViewMode"===e&&(a=!1!==r.changeViewMode(n)&&a),a},J,Z)),a["\u0275did"](3,49152,null,0,r.w,[],{calendar:[0,"calendar"]},{onNavigate:"onNavigate",onViewMode:"onViewMode"}),(t()(),a["\u0275eld"](4,0,null,1,3,"table",[["class","years"],["role","grid"]],null,null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,2,"tbody",[],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,yt)),a["\u0275did"](7,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){var n=e.component;t(e,3,0,n.calendar),t(e,7,0,n.calendar.years)},null)}var _t=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function xt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"button",[],null,null,null,null,null)),(t()(),a["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.context.$implicit.label)})}function Tt(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"button",[],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Custom Range"]))],null,null)}function wt(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,4,"div",[["class","bs-datepicker-predefined-btns"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,xt)),a["\u0275did"](2,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,Tt)),a["\u0275did"](4,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,n.ranges),t(e,4,0,n.isCustomRangeShown)},null)}},awvh:function(t,e,n){"use strict";function a(t){return Error.call(this),this.message=t?t.length+" errors occurred during unsubscription:\n"+t.map(function(t,e){return e+1+") "+t.toString()}).join("\n "):"",this.name="UnsubscriptionError",this.errors=t,this}n.d(e,"a",function(){return r}),a.prototype=Object.create(Error.prototype);var r=a},b1Dy:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")},week:{dow:1,doy:4}})}()},b5OY:function(t,e,n){"use strict";n.d(e,"a",function(){return a}),n("pxLl");var a=function(){function t(t,e){this.performanceCounterService=t,this.i18n=e,this.columns=[],this.counters=[]}return t.prototype.ngOnInit=function(){this.columns=[{name:this.i18n("Name"),prop:"name",flexGrow:1},{name:this.i18n("Description"),prop:"description",flexGrow:1},{name:this.i18n("Value"),prop:"value",cellTemplate:this.valueTpl,flexGrow:1}]},t.prototype.getCounters=function(t){var e=this;this.performanceCounterService.get(this.serviceType,this.serviceId).subscribe(function(t){e.counters=t},function(n){404===n.status?(n.preventDefault(),e.counters=null):t.error()})},t}()},b7mW:function(t,e,n){"use strict";function a(){return Error.call(this),this.message="argument out of range",this.name="ArgumentOutOfRangeError",this}n.d(e,"a",function(){return r}),a.prototype=Object.create(Error.prototype);var r=a},bOMt:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"s\xf8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\xf8rdag".split("_"),weekdaysShort:"s\xf8._ma._ti._on._to._fr._l\xf8.".split("_"),weekdaysMin:"s\xf8_ma_ti_on_to_fr_l\xf8".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i g\xe5r kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",ss:"%d sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en m\xe5ned",MM:"%d m\xe5neder",y:"ett \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},bXm7:function(t,e,n){!function(t){"use strict";var e={0:"-\u0448\u0456",1:"-\u0448\u0456",2:"-\u0448\u0456",3:"-\u0448\u0456",4:"-\u0448\u0456",5:"-\u0448\u0456",6:"-\u0448\u044b",7:"-\u0448\u0456",8:"-\u0448\u0456",9:"-\u0448\u044b",10:"-\u0448\u044b",20:"-\u0448\u044b",30:"-\u0448\u044b",40:"-\u0448\u044b",50:"-\u0448\u0456",60:"-\u0448\u044b",70:"-\u0448\u0456",80:"-\u0448\u0456",90:"-\u0448\u044b",100:"-\u0448\u0456"};t.defineLocale("kk",{months:"\u049b\u0430\u04a3\u0442\u0430\u0440_\u0430\u049b\u043f\u0430\u043d_\u043d\u0430\u0443\u0440\u044b\u0437_\u0441\u04d9\u0443\u0456\u0440_\u043c\u0430\u043c\u044b\u0440_\u043c\u0430\u0443\u0441\u044b\u043c_\u0448\u0456\u043b\u0434\u0435_\u0442\u0430\u043c\u044b\u0437_\u049b\u044b\u0440\u043a\u04af\u0439\u0435\u043a_\u049b\u0430\u0437\u0430\u043d_\u049b\u0430\u0440\u0430\u0448\u0430_\u0436\u0435\u043b\u0442\u043e\u049b\u0441\u0430\u043d".split("_"),monthsShort:"\u049b\u0430\u04a3_\u0430\u049b\u043f_\u043d\u0430\u0443_\u0441\u04d9\u0443_\u043c\u0430\u043c_\u043c\u0430\u0443_\u0448\u0456\u043b_\u0442\u0430\u043c_\u049b\u044b\u0440_\u049b\u0430\u0437_\u049b\u0430\u0440_\u0436\u0435\u043b".split("_"),weekdays:"\u0436\u0435\u043a\u0441\u0435\u043d\u0431\u0456_\u0434\u04af\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0441\u04d9\u0440\u0441\u0435\u043d\u0431\u0456_\u0431\u0435\u0439\u0441\u0435\u043d\u0431\u0456_\u0436\u04b1\u043c\u0430_\u0441\u0435\u043d\u0431\u0456".split("_"),weekdaysShort:"\u0436\u0435\u043a_\u0434\u04af\u0439_\u0441\u0435\u0439_\u0441\u04d9\u0440_\u0431\u0435\u0439_\u0436\u04b1\u043c_\u0441\u0435\u043d".split("_"),weekdaysMin:"\u0436\u043a_\u0434\u0439_\u0441\u0439_\u0441\u0440_\u0431\u0439_\u0436\u043c_\u0441\u043d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u0456\u043d \u0441\u0430\u0493\u0430\u0442] LT",nextDay:"[\u0415\u0440\u0442\u0435\u04a3 \u0441\u0430\u0493\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0493\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0448\u0435 \u0441\u0430\u0493\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u0435\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u04a3] dddd [\u0441\u0430\u0493\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0456\u0448\u0456\u043d\u0434\u0435",past:"%s \u0431\u04b1\u0440\u044b\u043d",s:"\u0431\u0456\u0440\u043d\u0435\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0456\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u0431\u0456\u0440 \u0441\u0430\u0493\u0430\u0442",hh:"%d \u0441\u0430\u0493\u0430\u0442",d:"\u0431\u0456\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0456\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0456\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0448\u0456|\u0448\u044b)/,ordinal:function(t){return t+(e[t]||e[t%10]||e[t>=100?100:null])},week:{dow:1,doy:7}})}(n("wd/R"))},bYM6:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("ar-tn",{months:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:1,doy:4}})}()},bidN:function(t,e,n){"use strict";var a=n("CDJp"),r=n("vvH+"),i=n("RDha");a._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return(e.datasets[t.datasetIndex].label||"")+": ("+t.xLabel+", "+t.yLabel+", "+e.datasets[t.datasetIndex].data[t.index].r+")"}}}}),t.exports=function(t){t.controllers.bubble=t.DatasetController.extend({dataElementType:r.Point,update:function(t){var e=this,n=e.getMeta();i.each(n.data,function(n,a){e.updateElement(n,a,t)})},updateElement:function(t,e,n){var a=this,r=a.getMeta(),i=t.custom||{},s=a.getScaleForId(r.xAxisID),o=a.getScaleForId(r.yAxisID),u=a._resolveElementOptions(t,e),c=a.getDataset().data[e],l=a.index,d=n?s.getPixelForDecimal(.5):s.getPixelForValue("object"==typeof c?c:NaN,e,l),f=n?o.getBasePixel():o.getPixelForValue(c,e,l);t._xScale=s,t._yScale=o,t._options=u,t._datasetIndex=l,t._index=e,t._model={backgroundColor:u.backgroundColor,borderColor:u.borderColor,borderWidth:u.borderWidth,hitRadius:u.hitRadius,pointStyle:u.pointStyle,rotation:u.rotation,radius:n?0:u.radius,skip:i.skip||isNaN(d)||isNaN(f),x:d,y:f},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=i.valueOrDefault(n.hoverBackgroundColor,i.getHoverColor(n.backgroundColor)),e.borderColor=i.valueOrDefault(n.hoverBorderColor,i.getHoverColor(n.borderColor)),e.borderWidth=i.valueOrDefault(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},_resolveElementOptions:function(t,e){var n,a,r,s=this.chart,o=s.data.datasets[this.index],u=t.custom||{},c=s.options.elements.point,l=i.options.resolve,d=o.data[e],f={},p={chart:s,dataIndex:e,dataset:o,datasetIndex:this.index},h=["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle","rotation"];for(n=0,a=h.length;n1?Array.prototype.slice.call(arguments):t)},a,n)})}},bpWZ:function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("FO+L")),a(n("nhM1")),a(n("BARL"))},bpih:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_luned\xec_marted\xec_mercoled\xec_gioved\xec_venerd\xec_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(t){return(/^[0-9].+$/.test(t)?"tra":"in")+" "+t},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}()},buEt:function(t,e,n){"use strict";n.r(e);var a=n("DtyJ");n.d(e,"Subject",function(){return a.Subject})},bxKX:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("it-ch",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_luned\xec_marted\xec_mercoled\xec_gioved\xec_venerd\xec_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(t){return(/^[0-9].+$/.test(t)?"tra":"in")+" "+t},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}()},cRix:function(t,e,n){!function(t){"use strict";var e="jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.".split("_"),n="jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_");t.defineLocale("fy",{months:"jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber".split("_"),monthsShort:function(t,a){return t?/-MMM-/.test(a)?n[t.month()]:e[t.month()]:e},monthsParseExact:!0,weekdays:"snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon".split("_"),weekdaysShort:"si._mo._ti._wo._to._fr._so.".split("_"),weekdaysMin:"Si_Mo_Ti_Wo_To_Fr_So".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[hjoed om] LT",nextDay:"[moarn om] LT",nextWeek:"dddd [om] LT",lastDay:"[juster om] LT",lastWeek:"[\xf4fr\xfbne] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oer %s",past:"%s lyn",s:"in pear sekonden",ss:"%d sekonden",m:"ien min\xfat",mm:"%d minuten",h:"ien oere",hh:"%d oeren",d:"ien dei",dd:"%d dagen",M:"ien moanne",MM:"%d moannen",y:"ien jier",yy:"%d jierren"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(t){return t+(1===t||8===t||t>=20?"ste":"de")},week:{dow:1,doy:4}})}(n("wd/R"))},cdu6:function(t,e,n){"use strict";var a=n("CDJp"),r=n("K2E3"),i=n("RDha"),s=n("g8vO");function o(t){var e,n,a=[];for(e=0,n=t.length;ef&&st.maxHeight){s--;break}s++,d=u*c}t.labelRotation=s},afterCalculateTickRotation:function(){i.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){i.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=o(t._ticks),a=t.options,r=a.ticks,s=a.scaleLabel,u=a.gridLines,f=a.display,p=t.isHorizontal(),h=l(r),g=a.gridLines.tickMarkLength;if(e.width=p?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:f&&u.drawTicks?g:0,e.height=p?f&&u.drawTicks?g:0:t.maxHeight,s.display&&f){var b=d(s)+i.options.toPadding(s.padding).height;p?e.height+=b:e.width+=b}if(r.display&&f){var m=i.longestText(t.ctx,h.font,n,t.longestTextCache),y=i.numberOfLabelLines(n),v=.5*h.size,_=t.options.ticks.padding;if(p){t.longestLabelWidth=m;var x=i.toRadians(t.labelRotation),T=Math.cos(x),w=Math.sin(x);e.height=Math.min(t.maxHeight,e.height+(w*m+h.size*y+v*(y-1)+v)+_),t.ctx.font=h.font;var S=c(t.ctx,n[0],h.font),O=c(t.ctx,n[n.length-1],h.font);0!==t.labelRotation?(t.paddingLeft="bottom"===a.position?T*S+3:T*v+3,t.paddingRight="bottom"===a.position?T*v+3:T*O+3):(t.paddingLeft=S/2+3,t.paddingRight=O/2+3)}else r.mirror?m=0:m+=_+v,e.width=Math.min(t.maxWidth,e.width+m),t.paddingTop=h.size/2,t.paddingBottom=h.size/2}t.handleMargins(),t.width=e.width,t.height=e.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){i.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(i.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:i.noop,getPixelForValue:i.noop,getValueForPixel:i.noop,getPixelForTick:function(t){var e=this,n=e.options.offset;if(e.isHorizontal()){var a=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(n?0:1),1),r=a*t+e.paddingLeft;return n&&(r+=a/2),e.left+Math.round(r)+(e.isFullWidth()?e.margins.left:0)}return e.top+t*((e.height-(e.paddingTop+e.paddingBottom))/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;return e.isHorizontal()?e.left+Math.round((e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft)+(e.isFullWidth()?e.margins.left:0):e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,a,r,s=this,o=s.isHorizontal(),u=s.options.ticks.minor,c=t.length,l=i.toRadians(s.labelRotation),d=Math.cos(l),f=s.longestLabelWidth*d,p=[];for(u.maxTicksLimit&&(r=u.maxTicksLimit),o&&(e=!1,(f+u.autoSkipPadding)*c>s.width-(s.paddingLeft+s.paddingRight)&&(e=1+Math.floor((f+u.autoSkipPadding)*c/(s.width-(s.paddingLeft+s.paddingRight)))),r&&c>r&&(e=Math.max(e,Math.floor(c/r)))),n=0;n1&&n%e>0||n%e==0&&n+e>=c)&&n!==c-1&&delete a.label,p.push(a);return p},draw:function(t){var e=this,n=e.options;if(n.display){var r=e.ctx,s=a.global,o=n.ticks.minor,c=n.ticks.major||o,f=n.gridLines,p=n.scaleLabel,h=0!==e.labelRotation,g=e.isHorizontal(),b=o.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),m=i.valueOrDefault(o.fontColor,s.defaultFontColor),y=l(o),v=i.valueOrDefault(c.fontColor,s.defaultFontColor),_=l(c),x=f.drawTicks?f.tickMarkLength:0,T=i.valueOrDefault(p.fontColor,s.defaultFontColor),w=l(p),S=i.options.toPadding(p.padding),O=i.toRadians(e.labelRotation),I=[],C=e.options.gridLines.lineWidth,k="right"===n.position?e.left:e.right-C-x,N="right"===n.position?e.left+x:e.right,R="bottom"===n.position?e.top+C:e.bottom-x-C,A="bottom"===n.position?e.top+C+x:e.bottom+C;if(i.each(b,function(a,r){if(!i.isNullOrUndef(a.label)){var c,l,d,p,m,y,v,_,T,w,S,D,E,L,P=a.label;r===e.zeroLineIndex&&n.offset===f.offsetGridLines?(c=f.zeroLineWidth,l=f.zeroLineColor,d=f.zeroLineBorderDash,p=f.zeroLineBorderDashOffset):(c=i.valueAtIndexOrDefault(f.lineWidth,r),l=i.valueAtIndexOrDefault(f.color,r),d=i.valueOrDefault(f.borderDash,s.borderDash),p=i.valueOrDefault(f.borderDashOffset,s.borderDashOffset));var M="middle",q="middle",j=o.padding;if(g){var F=x+j;"bottom"===n.position?(q=h?"middle":"top",M=h?"right":"center",L=e.top+F):(q=h?"middle":"bottom",M=h?"left":"center",L=e.bottom-F);var z=u(e,r,f.offsetGridLines&&b.length>1);z1);V\n \n \n \n Toggle navigation\n Alternar navegaci\xf3n\n \n \n Dashboard\n Consola\n \n \n Cluster\n Cl\xfaster\n \n \n Hosts\n Hosts\n \n \n Monitors\n Monitores\n \n \n OSDs\n OSDs\n \n \n Configuration\n Configuraci\xf3n\n \n \n CRUSH map\n Mapa de CRUSH\n \n \n Manager modules\n M\xf3dulos de gestor\n \n \n Logs\n Registros\n \n \n Alerts\n Alertas\n \n \n Silences\n Silences\n \n \n Pools\n Repositorios\n \n \n Block\n Bloque\n \n \n Images\n Im\xe1genes\n \n \n Mirroring\n Duplicaci\xf3n\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n Sistemas de archivos\n \n \n Object Gateway\n Object Gateway\n \n \n Daemons\n Daemons\n \n \n Users\n Usuarios\n \n \n Buckets\n Papeleras\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Obteniendo datos \n \npara \n \n \n . Espere.\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Mostrando datos guardados previamente en cach\xe9\n \npara \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n No se han podido cargar los datos\n para\n \n \n .\nConsulte el estado del cl\xfaster.\n \n \n \n Back\n Atr\xe1s\n \n \n Select a Language\n Seleccione un idioma\n \n \n Loading panel data...\n Cargando datos del panel...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Consulte la\n documentaci\xf3n\n sobre c\xf3mo\nconfigurar y habilitar la supervisi\xf3n.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n No existe la consola de Grafana. Consulte la\n documentaci\xf3n\n sobre c\xf3mo\n a\xf1adir consolas a Grafana.\n \n \n \n Grafana Time Picker\n Selector de hora de Grafana\n \n \n Reset Settings\n Restablecer ajustes\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n Error al cargar los datos.\n \n \n selected\n seleccionados\n X selected\n \n \n found\n encontrados\n X found\n \n \n total\n total\n X total\n \n \n Edit\n Editar\n \n \n Name\n Nombre\n \n \n Description\n Descripci\xf3n\n \n \n Long description\n Descripci\xf3n larga\n \n \n Default\n Opci\xf3n por defecto\n \n \n Daemon default\n Daemon por defecto\n \n \n Services\n Servicios\n \n \n Values\n Valores\n \n \n The entered value is too high! It must not be greater than \n .\n \n El valor introducido es demasiado alto. No debe ser mayor que \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n El valor introducido es demasiado bajo. No debe ser menor que \n .\n \n \n \n Save\n Guardar\n \n \n CRUSH map viewer\n Visor del mapa de CRUSH\n \n \n Hosts List\n Lista de hosts\n \n \n Overall Performance\n Rendimiento general\n \n \n No entries found\n No se encuentra ninguna entrada\n \n \n Cluster Logs\n Registros del cl\xfaster\n \n \n Audit Logs\n Registros de auditor\xeda\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n Cargando configuraci\xf3n...\n \n \n The configuration could not be loaded.\n No es posible cargar la configuraci\xf3n.\n \n \n Edit Manager module\n M\xf3dulo del gestor de edici\xf3n\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n El valor introducido no es un UUID v\xe1lido, por ejemplo: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n El valor introducido debe ser una direcci\xf3n IP v\xe1lida.\n \n \n This field is required.\n Este campo es obligatorio.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n El valor introducido es demasiado alto. Debe ser menor o igual que \n .\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n El valor introducido es demasiado bajo. Debe ser mayor o igual que \n .\n \n \n \n The entered value needs to be a number.\n El valor introducido debe ser un n\xfamero.\n \n \n The entered value needs to be a number or decimal.\n El valor introducido debe ser un n\xfamero o un decimal.\n \n \n Update\n Actualizar\n \n \n Status\n Estado\n \n \n Cluster ID\n ID de cl\xfaster\n \n \n monmap modified\n Mapa de supervisi\xf3n modificado\n \n \n monmap epoch\n \xc9poca de mapa de supervisi\xf3n\n \n \n quorum con\n qu\xf3rum de con\n \n \n quorum mon\n qu\xf3rum de mon\n \n \n required con\n con requerido\n \n \n required mon\n mon requerido\n \n \n In Quorum\n Con qu\xf3rum\n \n \n Not In Quorum\n Sin qu\xf3rum\n \n \n Cancel\n Cancelar\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n \xbfSeguro que quiere \n el elemento \n seleccionado?\n \n \n \n Yes, I am sure.\n S\xed, seguro.\n \n \n Cluster-wide OSD Flags\n Indicadores OSD de todo el cl\xfaster\n \n \n Submit\n Enviar\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Avanzado...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n Prioridad de recuperaci\xf3n de OSD\n \n \n Priority\n Prioridad\n \n \n Customize priority values\n Personalizar valores de prioridad\n \n \n This field is required!\n Este campo es obligatorio.\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n El valor introducido es demasiado alto. No debe ser mayor que \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n El valor introducido es demasiado bajo. No debe ser menor que \n .\n \n \n \n Reweight OSD\n Reequilibrar peso de OSD\n \n \n The value needs to be between 0 and 1.\n El valor debe estar entre 0 y 1.\n \n \n Reweight\n Reequilibrar peso\n \n \n OSDs \n Scrub\n \n \n Depuraci\xf3n de OSDs\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {Profundo} }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Se dispone a aplicar una \n depuraci\xf3n\n al OSD \n \n \n .\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {profundo} }\n \n \n OSDs List\n Lista de OSD\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n Si contin\xfaa, el \n OSD \n \n \n se marcar\xe1 \n \n \n .\n \n \n \n The OSD is not safe to destroy!\n No es seguro destruir el OSD.\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n Si contin\xfaa, el \n OSD \n \n \n se \n \n \n .\n \n \n \n Details\n Detalles\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Valor\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Cerrar\n \n \n Delete\n Suprimir\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Estado\n \n \n Statistics\n Estad\xedsticas\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Consulte la \n documentaci\xf3n\n \n sobre c\xf3mo configurar y habilitar la funci\xf3n de gesti\xf3n de NFS Ganesha.\n \n \n \n Clients\n Clientes\n \n \n Any client can access\n Cualquier cliente puede acceder\n \n \n Addresses\n Destinatarios\n \n \n Required field\n Campo requerido\n \n \n Must contain one or more comma-separated values\n Debe contener uno o varios valores separados por comas\n \n \n For example:\n Por ejemplo:\n \n \n Access Type\n Tipo de acceso\n \n \n Squash\n Reducir privilegios\n \n \n Add clients\n A\xf1adir clientes\n \n \n Loading...\n Cargando...\n \n \n -- No cluster available --\n -- No hay ning\xfan cl\xfaster disponible --\n \n \n -- Select the cluster --\n -- Seleccione el cl\xfaster --\n \n \n Add daemon\n A\xf1adir daemon\n \n \n Storage Backend\n Motor de almacenamiento\n \n \n -- No data pools available --\n -- No hay ning\xfan repositorio de datos disponible --\n \n \n -- Select the storage backend --\n -- Seleccione el motor de almacenamiento --\n \n \n Object Gateway User\n Usuario de Object Gateway\n \n \n -- No users available --\n -- No hay ning\xfan usuario disponible --\n \n \n -- Select the object gateway user --\n -- Seleccione el usuario de Object Gateway --\n \n \n CephFS User ID\n ID de usuario de CephFS\n \n \n -- No clients available --\n -- No hay ning\xfan cliente disponible --\n \n \n -- Select the cephx client --\n -- Seleccione el cliente de CephX --\n \n \n CephFS Name\n Nombre de CephFS\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n Etiqueta de seguridad\n \n \n Enable security label\n Habilitar etiqueta de seguridad\n \n \n CephFS Path\n Ruta de CephFS\n \n \n Path need to start with a \'/\' and can be followed by a word\n La ruta debe empezar por "/" y puede ir seguida de una palabra\n \n \n New directory will be created\n Se crear\xe1 un directorio nuevo\n \n \n Path\n Ruta\n \n \n Path can only be a single \'/\' or a word\n La ruta solo puede ser una "/" o una palabra\n \n \n New bucket will be created\n Se crear\xe1 una papelera nueva\n \n \n NFS Protocol\n Protocolo NFS\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n Etiqueta NFS\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Acceso alternativo para montajes \n NFS v3\n (no debe empezar con /).\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n Puede que los clientes no monten subdirectorios (es decir, si Etiqueta = foo, el cliente puede que no monte foo/baz).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n Al usar distintas opciones de Etiqueta, la misma Ruta se puede exportar varias veces.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n La posici\xf3n que ocupa esta exportaci\xf3n \n NFS v4\n \n en \n Pseudo FS\n (debe ser exclusiva).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n Al usar distintas opciones de Pseudo, la misma Ruta se puede exportar varias veces.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- No hay ning\xfan tipo de acceso disponible --\n \n \n -- Select the access type --\n -- Seleccione el tipo de acceso --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- No hay ninguna reducci\xf3n de privilegios disponible --\n \n \n --Select what kind of user id squashing is performed --\n -- Seleccione el tipo de reducci\xf3n de privilegios de ID de usuario que se va a realizar --\n \n \n Transport Protocol\n Protocolo de transporte\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n \xa1Bienvenidos a Ceph!\n The welcome message on the login page\n \n \n Username is required\n El nombre de usuario es obligatorio\n \n \n Password is required\n La contrase\xf1a es obligatoria\n \n \n Login\n Entrada\n \n \n Sorry, the user does not exist in Ceph.\n Lo sentimos. El usuario no existe en Ceph.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Vuelva a la \n P\xe1gina de entrada\n . Saldr\xe1 del proveedor de identidad cuando vuelva a intentar entrar a la sesi\xf3n.\n \n \n \n Forbidden\n Prohibido\n \n \n Sorry, you are not allowed to see what you were looking for.\n Lo sentimos. No tiene permiso para ver lo que busca.\n \n \n Sorry, we could not find what you were looking for\n Lo sentimos. No se encuentra lo que busca\n \n \n Remove all\n Eliminar todo\n \n \n Recent Notifications\n Notificaciones recientes\n \n \n There are no background tasks.\n No hay tareas en segundo plano.\n \n \n Background Tasks\n Tareas en segundo plano\n \n \n Help\n Ayuda\n \n \n Documentation\n Documentaci\xf3n\n \n \n API\n API\n \n \n About\n Acerca de\n \n \n Dashboard Settings\n Ajustes de la consola\n \n \n User management\n Gesti\xf3n del usuario\n \n \n Logged in user\n Usuario que ha entrado\n \n \n Signed in as\n \n \n \n \n Ha entrado como\n \n \n \n \n \n \n Sign out\n Salir\n \n \n Name...\n Nombre...\n \n \n The chosen name is already in use.\n El nombre que ha elegido ya est\xe1 en uso.\n \n \n Description...\n Descripci\xf3n...\n \n \n Permissions\n Permisos\n \n \n Roles\n Funciones\n \n \n Username\n Nombre de usuario\n \n \n Password\n Contrase\xf1a\n \n \n Confirm password\n Confirmar contrase\xf1a\n \n \n Password confirmation doesn\'t match the password.\n Las contrase\xf1as no coinciden.\n \n \n Full name\n Nombre completo\n \n \n Email\n Correo electr\xf3nico\n \n \n Invalid email.\n Correo electr\xf3nico no v\xe1lido.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Se dispone a eliminar los permisos "lectura/actualizaci\xf3n de usuario" de su propio usuario.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Si contin\xfaa, no podr\xe1 a\xf1adir ni eliminar funciones en ning\xfan usuario.\n \n \n Are you sure you want to continue?\n \xbfSeguro que desea continuar?\n \n \n Performance counters not available\n Los contadores de rendimiento no est\xe1n disponibles\n \n \n Attributes (OSD map)\n Atributos (mapa de OSD)\n \n \n Metadata not available\n Los metadatos no est\xe1n disponibles\n \n \n Metadata\n Metadatos\n \n \n Performance counter\n Contandor de rendimiento\n \n \n Histogram not available: \n \n \n El histograma no est\xe1 disponible: \n \n \n \n \n Writes\n Escrituras\n \n \n Reads\n Lecturas\n \n \n Histogram\n Histograma\n \n \n Performance Details\n Detalles de rendimiento\n \n \n Current values\n Valores actuales\n \n \n Type\n Tipo\n \n \n Min\n M\xedn.\n \n \n Max\n M\xe1x.\n \n \n Flags\n Indicadores\n \n \n Source\n Origen\n \n \n Level\n Nivel\n \n \n Can be updated at runtime (editable)\n Se puede actualizar en el tiempo de ejecuci\xf3n (editable)\n \n \n Tags\n Etiquetas\n \n \n Enum values\n Valores Enum\n \n \n See also\n V\xe9ase tambi\xe9n\n \n \n Cluster Status\n Estado del cl\xfaster\n \n \n Manager Daemons\n Daemons de gestor\n \n \n Object Gateways\n Instancias de Object Gateway\n \n \n Metadata Servers\n Servidores de metadatos\n \n \n iSCSI Gateways\n Puertas de enlace iSCSI\n \n \n Client IOPS\n IOPS de cliente\n \n \n Client Throughput\n Rendimiento del cliente\n \n \n Client Read/Write\n Lectura/escritura de cliente\n \n \n Recovery Throughput\n Rendimiento de recuperaci\xf3n\n \n \n Scrub\n Depuraci\xf3n\n \n \n Performance\n Rendimiento\n \n \n Raw Capacity\n Capacidad en bruto\n \n \n Objects\n Objetos\n \n \n PGs per OSD\n Grupos de colocaci\xf3n por OSD\n \n \n PG Status\n Estado del grupo de colocaci\xf3n\n \n \n Capacity\n Capacidad\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n Consulte la secci\xf3n \n Registros\n para obtener m\xe1s datos.\n \n \n \n Ranks\n Clasificaciones\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Clientes: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n Mover una imagen a la papelera\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n Para mover \n \n /\n \n a la papelera,\n haga clic en \n Mover imagen\n . Opcionalmente, puede seleccionar una fecha de caducidad.\n \n \n \n Protection expires at\n La protecci\xf3n caduca a las\n \n \n NOT PROTECTED\n SIN PROTECCI\xd3N\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Formato de fecha err\xf3neo. Use el formato "AAAA-MM-DD HH:mm:ss".\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n La protecci\xf3n ya ha caducado. Seleccione una fecha del futuro o deje el campo vac\xedo.\n \n \n Move Image\n Mover imagen\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n Resumen\n \n \n Targets\n Destinos\n \n \n Discovery Authentication\n Autenticaci\xf3n de descubrimiento\n \n \n User\n Usuario\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Los nombres de usuario deben tener entre 8 y 64 caracteres y\n solo pueden incluir letras y estos caracteres: ".", "@", "-", "_" o ":".\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n Usuario mutuo\n \n \n Mutual Password\n Contrase\xf1a mutua\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Consulte la \n documentaci\xf3n\n \n sobre c\xf3mo configurar y habilitar la funci\xf3n de gesti\xf3n de destinos iSCSI.\n \n \n \n Available information:\n Informaci\xf3n disponible:\n \n \n iSCSI Targets not available\n Destinos iSCSI no disponibles\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n Solo disponible para im\xe1genes RBD con \n fast-diff\n habilitado\n \n \n \n Pool\n Repositorio\n \n \n Data Pool\n Repositorio de datos\n \n \n Created\n Creados\n \n \n Size\n Tama\xf1o\n \n \n Object size\n Tama\xf1o del objeto\n \n \n Features\n Caracter\xedsticas\n \n \n Provisioned\n Aprovisionados\n \n \n N/A\n N/D\n \n \n Total provisioned\n Total aprovisionado\n \n \n Striping unit\n Unidad de repartici\xf3n\n \n \n Striping count\n Recuento de repartici\xf3n\n \n \n Parent\n Padre\n \n \n Block name prefix\n Prefijo de nombre de bloque\n \n \n Order\n Orden\n \n \n Snapshots\n Instant\xe1neas\n \n \n Image\n Imagen\n \n \n This setting overrides the global value\n Este ajuste sustituye al valor global\n \n \n Global\n Global\n \n \n This is the global value. No value for this option has been set for this image.\n Este es el valor global. No se ha definido ning\xfan valor para esta opci\xf3n para esta imagen.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n No se permiten los caracteres "/" ni "@".\n \n \n -- No rbd pools available --\n -- No hay ning\xfan repositorio RBD disponible --\n \n \n -- Select a pool --\n -- Seleccione un repositorio --\n \n \n Use a dedicated data pool\n Usar un repositorio dedicado para datos\n \n \n Data pool\n Repositorio de datos\n \n \n Dedicated pool that stores the object-data of the RBD.\n Repositorio dedicado para almacenar los datos de objeto de RBD.\n \n \n e.g., 10GiB\n ej.: 10 GiB\n \n \n You have to increase the size.\n Debe aumentar el tama\xf1o.\n \n \n Advanced\n Avanzado\n \n \n Striping\n Repartici\xf3n\n \n \n Stripe unit\n Unidad de repartici\xf3n\n \n \n -- Select stripe unit --\n -- Seleccione la unidad de repartici\xf3n --\n \n \n This field is required because stripe count is defined!\n Este campo es obligatorio porque se ha definido el recuento de repartici\xf3n.\n \n \n Stripe unit is greater than object size.\n La unidad de repartici\xf3n es mayor que el tama\xf1o del objeto.\n \n \n Stripe count\n Recuento de repartici\xf3n\n \n \n This field is required because stripe unit is defined!\n Este campo es obligatorio porque se ha definido la unidad de repartici\xf3n.\n \n \n Stripe count must be greater than 0.\n El recuento de repartici\xf3n debe ser mayor que 0.\n \n \n \n RBD Snapshot\n \n \n instant\xe1nea RBD\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Renombrar} other {Crear} }\n \n \n \n Snapshot\n \n \n instant\xe1nea\n \n \n \n PROTECTED\n CON PROTECCI\xd3N\n \n \n UNPROTECTED\n SIN PROTECCI\xd3N\n \n \n You are about to rollback\n Se dispone a revertir\n \n \n Purge Trash\n Vaciar papelera\n \n \n To purge, select one or All images and click\n Para limpiar, seleccione una imagen, o todas las im\xe1genes, y haga clic en\n \n \n Pool:\n Repositorio:\n \n \n Pool name...\n Nombre del repositorio...\n \n \n All\n Todas\n \n \n Restore Image\n Restaurar im\xe1genes\n \n \n To restore\n Para restaurar\n \n \n type the image\'s new name and click\n escriba el nombre nuevo de la imagen y haga clic en\n \n \n New Name\n Nombre nuevo\n \n \n Expired at\n Caduc\xf3 a las\n \n \n Protected until\n Protecci\xf3n hasta\n \n \n This image is protected until \n .\n \n Esta imagen est\xe1 protegida hasta el \n .\n \n \n \n Trash\n Papelera\n \n \n iSCSI Topology\n Topolog\xeda iSCSI\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n Normalmente no es necesario cambiar los valores por defecto de estos par\xe1metros.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Ajustes\n \n \n Backstore\n Almac\xe9n\n \n \n Confirm\n Confirmar\n \n \n Advanced Settings\n Ajustes avanzados\n \n \n Target IQN\n IQN de destino\n \n \n IQN has wrong pattern.\n El IQN tiene un patr\xf3n err\xf3neo.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n Los IQN tienen esta notaci\xf3n: iqn.$year-$month.$reversedAddress:$definedName\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Por ejemplo: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n M\xe1s informaci\xf3n\n \n \n This target has modified advanced settings.\n Este destino tiene ajustes avanzados modificados.\n \n \n Portals\n Portales\n \n \n At least \n gateways are required.\n \n Se requieren al menos \n puertas de enlace.\n \n \n \n Add portal\n A\xf1adir portal\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Esta imagen tiene ajustes modificados.\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n A\xf1adir imagen\n \n \n ACL authentication\n Autenticaci\xf3n de ACL\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Iniciadores\n \n \n Initiator\n Iniciador\n \n \n Client IQN\n IQN del cliente\n \n \n Initiator IQN needs to be unique.\n El IQN del iniciador debe ser exclusivo.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Los nombres de usuario deben tener entre 8 y 64 caracteres y\n solo pueden incluir letras y estos caracteres: ".", "@", "-", "_" o ":".\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n El iniciador pertenece a un grupo. Las im\xe1genes se configurar\xe1n en el grupo.\n \n \n No items added.\n No se ha a\xf1adido ning\xfan elemento.\n \n \n Add initiator\n A\xf1adir iniciador\n \n \n Groups\n Grupos\n \n \n Group\n Grupo\n \n \n Add group\n A\xf1adir grupo\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n Configuraci\xf3n de RBD\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Elimina el valor de configuraci\xf3n local. Se heredar\xe1 y usar\xe1 en su lugar el valor de configuraci\xf3n padre.\n \n \n The mininum value is 0\n El valor m\xednimo es 0\n \n \n Issues\n Problemas\n \n \n Syncing\n Sincronizando\n \n \n Ready\n Listo\n \n \n Edit pool mirror mode\n Editar modo de duplicaci\xf3n de repositorio\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n Para editar el modo de duplicaci\xf3n del repositorio\xa0\n \n \n , seleccione un modo nuevo en la lista y haga clic\xa0\n en \n Actualizar\n .\n \n \n \n Mode\n Modo\n \n \n Peer clusters must be removed prior to disabling mirror.\n Los cl\xfasteres de par deben eliminarse antes de inhabilitar la duplicaci\xf3n.\n \n \n \n \n pool mirror peer\n \n \n \nduplicar par de repositorio\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Editar} other {A\xf1adir} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n los atributos del par\n de duplicaci\xf3n del respositorio \n \n \n y haga clic en \n Enviar\n .\n \n \n \n Cluster Name\n Nombre del cl\xfaster\n \n \n The cluster name is not valid.\n El nombre del cl\xfaster no es v\xe1lido.\n \n \n CephX ID\n ID de CephX\n \n \n CephX ID...\n ID de CephX...\n \n \n The CephX ID is not valid.\n El ID de CephX no es v\xe1lido.\n \n \n Monitor Addresses\n Direcciones de monitores\n \n \n Comma-delimited addresses...\n Direcciones delimitadas por comas...\n \n \n The monitory address is not valid.\n La direcci\xf3n del monitor no es v\xe1lida.\n \n \n CephX Key\n Clave de CephX\n \n \n Base64-encoded key...\n Clave con cifrado base64...\n \n \n CephX key must be base64 encoded.\n La clave de CephX debe tener cifrado base64\n \n \n Pools List\n Lista de repositorios\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n El nombre solo puede tener caracteres alfanum\xe9ricos, guiones y guiones bajos.\n \n \n The chosen erasure code profile name is already in use.\n El nombre del perfil de c\xf3digo de borrado que ha elegido ya est\xe1 en uso.\n \n \n Plugin\n Complemento\n \n \n Data chunks (k)\n Porciones de datos (k)\n \n \n Must be equal to or greater than 2.\n Debe ser igual o mayor que 2.\n \n \n Coding chunks (m)\n Porciones de c\xf3digo (m)\n \n \n Must be equal to or greater than 1.\n Debe ser igual o mayor que 1.\n \n \n Durability estimator (c)\n Estimador de durabilidad (c)\n \n \n Locality (l)\n Localizaci\xf3n (l)\n \n \n Crush failure domain\n Dominio de error de CRUSH\n \n \n Crush Locality\n Localizaci\xf3n de CRUSH\n \n \n None\n Ninguna\n \n \n Technique\n T\xe9cnica\n \n \n Packetsize\n Tama\xf1o del paquete\n \n \n Crush root\n Ra\xedz de CRUSH\n \n \n Crush device class\n Clase de dispositivo de CRUSH\n \n \n any\n cualquiera\n \n \n Directory\n Directorio\n \n \n The chosen Ceph pool name is already in use.\n El nombre del repositorio de Ceph que ha elegido ya est\xe1 en uso.\n \n \n Pool type\n Tipo de repositorio\n \n \n -- Select a pool type --\n -- Seleccione un tipo de repositorio --\n \n \n Placement groups\n Grupos de colocaci\xf3n\n \n \n At least one placement group is needed!\n Se necesita al menos un grupo de colocaci\xf3n.\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n El cl\xfaster no puede gestionar tantos grupos de colocaci\xf3n. Vuelva a calcular la cantidad que necesita.\n \n \n Calculation help\n Ayuda para el c\xe1lculo\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n El n\xfamero grupos de colocaci\xf3n actual se ha calculado\n\xa0 autom\xe1ticamente. Debe asegurarse de que sirve para sus necesidades antes de enviar.\n \n \n Crush ruleset\n Conjunto de reglas de CRUSH\n \n \n -- Select a crush rule --\n -- Seleccione una regla de CRUSH --\n \n \n Crush rule\n Regla de CRUSH\n \n \n Crush steps\n Pasos de CRUSH\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n La regla no se puede usar en el cl\xfaster actual, ya que\n no tiene suficientes OSD que cumplan el m\xednimo requerido.\n \n \n Replicated size\n Tama\xf1o replicado\n \n \n Minimum: \n \n \n M\xednimo: \n \n \n \n \n Maximum: \n \n \n M\xe1ximo: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n El tama\xf1o especificado est\xe1 fuera del intervalo. Los valores v\xe1lidos\n son del \n al \n .\n \n \n \n Erasure code profile\n Perfil de c\xf3digo de borrado\n \n \n -- No erasure code profile available --\n -- No hay ning\xfan perfil de c\xf3digo de borrado disponible --\n \n \n -- Select an erasure code profile --\n -- Seleccione un perfil de c\xf3digo de borrado --\n \n \n EC Overwrites\n Sustituciones de c\xf3digos de borrado\n \n \n Applications\n Aplicaciones\n \n \n Compression\n Compresi\xf3n\n \n \n Algorithm\n Algoritmo\n \n \n -- No erasure compression algorithm available --\n -- No hay ning\xfan algoritmo de compresi\xf3n de borrado disponible --\n \n \n Minimum blob size\n Tama\xf1o de Blob m\xednimo\n \n \n e.g., 128KiB\n p. ej. 128 KiB\n \n \n Value should be greater than 0\n El valor debe ser mayor que 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Tama\xf1o de Blob m\xe1ximo\n \n \n e.g., 512KiB\n p. ej. 512 KiB\n \n \n Value should be greater than the minimum blob size\n El valor debe ser mayor que el tama\xf1o de Blob m\xednimo\n \n \n Ratio\n Relaci\xf3n\n \n \n Compression ratio\n Relaci\xf3n de compresi\xf3n\n \n \n Value should be between 0.0 and 1.0\n El valor debe estar entre 0,0 y 1,0\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n No es posible crear un repositorio RBD con el nombre "/".\n \n \n Please change the name or remove \'rbd\' from the applications list.\n Cambie el nombre o elimine "rbd" de la lista de aplicaciones.\n \n \n Cache Tiers Details\n Detalles de niveles de cach\xe9\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Consulte la \n documentaci\xf3n\n \n sobre c\xf3mo configurar y habilitar la funci\xf3n de gesti\xf3n de Object Gateway.\n \n \n \n Daemons List\n Lista de daemons\n \n \n Performance Counters\n Contadores de rendimiento\n \n \n Loading bucket data...\n Cargando datos de la papelera...\n \n \n The bucket data could not be loaded.\n No es posible cargar los datos de la papelera.\n \n \n Id\n ID\n \n \n The value is not valid.\n El valor no es v\xe1lido.\n \n \n Owner\n Propietario\n \n \n -- Select a user --\n -- Seleccione un usuario --\n \n \n ID\n ID\n \n \n Index type\n Tipo de \xedndice\n \n \n Placement rule\n Regla de colocaci\xf3n\n \n \n Marker\n Marcador\n \n \n Maximum marker\n Marcador m\xe1ximo\n \n \n Version\n Versi\xf3n\n \n \n Master version\n Versi\xf3n maestra\n \n \n Modification time\n Hora de modificaci\xf3n\n \n \n Zonegroup\n Grupo de zona\n \n \n Bucket quota\n Cuota de papelera\n \n \n Enabled\n Habilitado\n \n \n Maximum size\n Tama\xf1o m\xe1ximo\n \n \n Unlimited\n Sin l\xedmite\n \n \n Maximum objects\n N\xfamero m\xe1ximo de objetos\n \n \n -- Select a username --\n -- Seleccione un nombre de usuario --\n \n \n Auto-generate key\n Autogenerar clave\n \n \n Access key\n Clave de acceso\n \n \n Secret key\n Clave secreta\n \n \n Email address\n Direcci\xf3n de correo electr\xf3nico\n \n \n Suspended\n Suspendido\n \n \n System\n Sistema\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {No} 1 {S\xed} }\n \n \n Maximum buckets\n N\xfamero m\xe1ximo de papeleras\n \n \n Subusers\n Subusuarios\n \n \n Capabilities\n Capacidades\n \n \n User quota\n Cuota de usuario\n \n \n Show\n Mostrar\n \n \n Keys\n Claves\n \n \n -- Select a type --\n -- Seleccione un tipo --\n \n \n Permission\n Permiso\n \n \n -- Select a permission --\n -- Seleccione un permiso --\n \n \n Subuser\n Subusuario\n \n \n The chosen subuser ID is already in use.\n El ID de subusuario que ha elegido ya est\xe1 en uso.\n \n \n read, write\n lectura, escritura\n \n \n full\n todos\n \n \n Swift key\n Clave Swift\n \n \n Auto-generate secret\n Autogenerar secreto\n \n \n Loading user data...\n Cargando datos del usuario...\n \n \n The user data could not be loaded.\n No es posible cargar los datos del usuario.\n \n \n The chosen user ID is already in use.\n El ID de usuario que ha elegido ya est\xe1 en uso.\n \n \n This is not a valid email address.\n Esta direcci\xf3n no es v\xe1lida.\n \n \n The chosen email address is already in use.\n La direcci\xf3n de correo electr\xf3nico que ha elegido ya est\xe1 en uso.\n \n \n Max. buckets\n M\xe1x. papeleras\n \n \n The entered value must be >= 0.\n El valor introducido debe ser mayor o igual que 0.\n \n \n S3 key\n Clave S3\n \n \n There are no subusers.\n No hay ning\xfan subusuario.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n No hay ninguna clave.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n No hay ninguna capacidad\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Tama\xf1o ilimitado\n \n \n Max. size\n Tama\xf1o m\xe1x.\n \n \n Unlimited objects\n Objetos ilimitados\n \n \n Max. objects\n Objetos m\xe1x.\n \n \n Current\n Actual\n \n \n Updated discovery authentication\n Autenticaci\xf3n de descubrimiento actualizada\n \n \n There are no portals available.\n No hay ning\xfan portal disponible.\n \n \n There are no images available.\n No hay ninguna imagen disponible.\n \n \n There are no images available. Please make sure you add an image to the target.\n No hay ninguna imagen disponible. Aseg\xfarese de a\xf1adir una imagen al destino.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n No hay ning\xfan iniciador disponible. Aseg\xfarese de a\xf1adir un iniciador al destino.\n \n \n target\n target\n \n \n Target\n Destino\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n Estado\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Bytes de lectura\n \n \n Write Bytes\n Bytes de escritura\n \n \n Read Ops\n Operaciones de lectura\n \n \n Write Ops\n Operaciones de escritura\n \n \n A/O Since\n A/O desde\n \n \n Instance\n Instancia\n \n \n Hostname\n Nombre de host\n \n \n Issue\n Problema\n \n \n Progress\n Progreso\n \n \n Disabled\n Inhabilitado\n \n \n Edit Mode\n Editar modo\n \n \n Add Peer\n A\xf1adir par\n \n \n Edit Peer\n Editar par\n \n \n Delete Peer\n Suprimir par\n \n \n Leader\n L\xedder\n \n \n # Local\n N.\xba locales\n \n \n # Remote\n N.\xba remotos\n \n \n mirror peer\n duplicar par\n \n \n Key\n Clave\n \n \n RBD\n RBD\n \n \n Deep flatten\n Aplanamiento profundo\n \n \n Layering\n En capas\n \n \n Exclusive lock\n Bloqueo exclusivo\n \n \n Object map (requires exclusive-lock)\n Mapa de objetos (requiere bloqueo exclusivo)\n \n \n Journaling (requires exclusive-lock)\n En diario (requiere bloqueo exclusivo)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Reversi\xf3n de instant\xe1nea RBD\n \n \n Rollback\n Revertir\n \n \n RBD snapshot\n Instant\xe1nea RBD\n \n \n Deleted At\n Suprimido a las\n \n \n id\n ID\n \n \n type\n tipo\n \n \n state\n estado\n \n \n version\n versi\xf3n\n \n \n Host\n Host\n \n \n root\n ra\xedz\n \n \n Rank\n Clasificaci\xf3n\n \n \n Daemon\n Daemon\n \n \n Activity\n Actividad\n \n \n Dentries\n Dentries\n \n \n Inodes\n Inodos\n \n \n Usage\n Uso\n \n \n Standby daemons\n Daemons de reserva\n \n \n The value can be updated at runtime.\n El valor se puede actualizar en el tiempo de ejecuci\xf3n.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n Los daemons/clientes no extraen este valor de la\n base de datos de configuraci\xf3n del monitor. No se recomienda definir esta opci\xf3n con "ceph config\n set ...". Esta opci\xf3n se debe configurar mediante ceph.conf o a trav\xe9s\n de la l\xednea de comandos.\n \n \n Option takes effect only during daemon startup.\n La opci\xf3n solo surte efecto durante el inicio del daemon.\n \n \n Option only affects cluster creation.\n La opci\xf3n solo afecta a la creaci\xf3n del cl\xfaster.\n \n \n Option only affects daemon creation.\n La opci\xf3n solo afecta a la creaci\xf3n del daemon.\n \n \n Updated config option \n \n \n Opci\xf3n de configuraci\xf3n actualizada \n \n \n \n \n Service\n Servicio\n \n \n Current value\n Valor actual\n \n \n Editable\n Editable\n \n \n Updated options for module "\n ".\n \n Opciones actualizadas para el m\xf3dulo \n .\n \n \n \n Enable\n Habilitar\n \n \n Disable\n Inhabilitar\n \n \n Reconnecting, please wait ...\n Conectando de nuevo. Espere...\n \n \n Public Address\n Direcci\xf3n p\xfablica\n \n \n Open Sessions\n Sesiones abiertas\n \n \n No In\n No incluir\n \n \n OSDs that were previously marked out will not be marked back in when they start\n Los OSD que se excluyeron anteriormente no se volver\xe1n a incluir cuando se inicien\n \n \n No Out\n No excluir\n \n \n OSDs will not automatically be marked out after the configured interval\n Los OSD no se excluir\xe1n autom\xe1ticamente despu\xe9s del intervalo configurado\n \n \n No Up\n No activar\n \n \n OSDs are not allowed to start\n No se permite que los OSD se inicien\n \n \n No Down\n No desactivar\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n Se ignoran los informes de error de OSD, de forma que los monitores no desactivar\xe1n los OSD\n \n \n Pause\n Pausa\n \n \n Pauses reads and writes\n Pone en pausa las lecturas y escrituras\n \n \n No Scrub\n No depurar\n \n \n Scrubbing is disabled\n La depuraci\xf3n est\xe1 inhabilitada\n \n \n No Deep Scrub\n No depuraci\xf3n profunda\n \n \n Deep Scrubbing is disabled\n La depuraci\xf3n profunda est\xe1 inhabilitada\n \n \n No Backfill\n No reponer\n \n \n Backfilling of PGs is suspended\n La reposici\xf3n de grupos de colocaci\xf3n se suspende\n \n \n No Recover\n No recuperar\n \n \n Recovery of PGs is suspended\n La recuperaci\xf3n de los grupos de colocaci\xf3n se suspende\n \n \n Bitwise Sort\n Orden bit a bit\n \n \n Use bitwise sort\n Usar orden bit a bit\n \n \n Purged Snapdirs\n Snapdir limpiados\n \n \n OSDs have converted snapsets\n Los OSD tienen snapset convertidos\n \n \n Recovery Deletes\n Supresiones de recuperaci\xf3n\n \n \n Deletes performed during recovery instead of peering\n Supresiones realizadas durante la recuperaci\xf3n, en lugar de emparejamientos\n \n \n PG Log Hard Limit\n L\xedmite estricto de registro del grupo de colocaci\xf3n\n \n \n Puts a hard limit on pg log length\n Establece un l\xedmite estricto para la longitud del registro del grupo de colocaci\xf3n\n \n \n Updated OSD Flags\n Indicadores de OSD actualizados\n \n \n out\n excluir\n \n \n in\n Incluir\n \n \n down\n desactivar\n \n \n Mark\n Marcar\n \n \n OSD lost\n OSD perdido\n \n \n marked lost\n marcado como perdido\n \n \n Purge\n Limpiar\n \n \n OSD\n OSD\n \n \n purged\n limpiado\n \n \n destroy\n destruir\n \n \n destroyed\n destruido\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n Grupos de colocaci\xf3n\n \n \n Read bytes\n Bytes de lectura\n \n \n Writes bytes\n Bytes de escritura\n \n \n Read ops\n Operaciones de lectura\n \n \n Write ops\n Operaciones de escritura\n \n \n Mark OSD \n \n \n Marcar OSD \n \n \n \n \n Mark \n \n \n Marcar \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n N\xfamero m\xe1ximo de reposiciones\n \n \n Recovery Max Active\n M\xe1ximo de recuperaciones activas\n \n \n Recovery Max Single Start\n M\xe1ximo de recuperaciones de inicio \xfanico\n \n \n Recovery Sleep\n Reposo de recuperaci\xf3n\n \n \n Custom\n Personalizar\n \n \n Updated OSD recovery speed priority "\n "\n \n Prioridad de velocidad de recuperaci\xf3n de OSD actualizada \n \n \n \n \n \n was initialized in the following OSD: \n \n \n \n se ha inicializado en el siguiente OSD: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n Trabajo\n \n \n Severity\n Gravedad\n \n \n Started\n Iniciado\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Actualizado\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n Usado\n \n \n Avail.\n Dispon.\n \n \n Clean\n Limpio\n \n \n Working\n En curso\n \n \n Warning\n Advertencia\n \n \n Unknown\n Desconocido\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n activo\n \n \n no filesystems\n sin sistemas de archivos\n \n \n active\n activo\n \n \n standby\n reserva\n \n \n n/a\n n/d\n \n \n active daemon\n daemon activo\n \n \n quorum\n qu\xf3rum\n \n \n The NFS Ganesha service is not configured.\n El servicio NFS Ganesha no est\xe1 configurado.\n \n \n Transport\n Transportar\n \n \n CephFS User\n Usuario de CephFS\n \n \n CephFS Filesystem\n Sistemas de archivos CephFS\n \n \n (inherited from global config)\n (se hereda de la configuraci\xf3n global)\n \n \n inherited from global config\n se hereda de la configuraci\xf3n global\n \n \n -- Select what kind of user id squashing is performed --\n -- Seleccione el tipo de reducci\xf3n de privilegios de ID de usuario que se va a realizar --\n \n \n There are no daemons available.\n No hay ning\xfan daemon disponible.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Modo de cach\xe9\n \n \n Min Evict Age\n Antig\xfcedad m\xednima de expulsi\xf3n\n \n \n Min Flush Age\n Antig\xfcedad m\xednima de vaciado\n \n \n Target Max Bytes\n N\xfamero m\xe1ximo de bytes de destino\n \n \n Target Max Objects\n N\xfamero m\xe1ximo de objetos de destino\n \n \n No applications added\n No se ha a\xf1adido ninguna aplicaci\xf3n\n \n \n Applications limit reached\n Se ha alcanzado el l\xedmite de aplicaciones\n \n \n A pool can only have up to four applications definitions.\n Un repositorio solo puede tener hasta cuatro definiciones de aplicaciones.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n Caracteres permitidos: _, a-z, A-Z y 0-9\n \n \n Maximum length is 128 characters\n La longitud m\xe1xima es 128 caracteres\n \n \n Filter or add applications\n Filtrar o a\xf1adir aplicaciones\n \n \n Add application\n A\xf1adir aplicaci\xf3n\n \n \n pool\n pool\n \n \n erasure code profile\n perfil de c\xf3digo de borrado\n \n \n Replica Size\n Tama\xf1o de r\xe9plica\n \n \n Last Change\n \xdaltimo cambio\n \n \n Erasure Coded Profile\n Perfil de c\xf3digo de borrado\n \n \n Crush Ruleset\n Conjunto de reglas de CRUSH\n \n \n Write bytes\n Bytes de escritura\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n papelera\n \n \n Updated Object Gateway bucket "\n "\n \n Papelera de Object Gateway actualizada "\n "\n \n \n \n Created Object Gateway bucket "\n "\n \n Papelera de Object Gateway creada "\n "\n \n \n \n buckets\n papeleras\n \n \n capability\n capability\n \n \n user\n usuario\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Usuario de Object Gateway actualizado "\n "\n \n \n \n Created Object Gateway user "\n "\n \n Usuario de Object Gateway creado "\n "\n \n \n \n users\n usuarios\n \n \n Swift Key\n Swift Key\n \n \n Scope\n \xc1mbito\n \n \n Read\n Lectura\n \n \n Create\n Crear\n \n \n role\n role\n \n \n Created role \'\n \'\n \n Se ha creado la funci\xf3n \n \n \n \n \n Updated role \'\n \'\n \n Se ha actualizado la funci\xf3n \n \n \n \n \n System Role\n Funci\xf3n del sistema\n \n \n Deleted role \'\n \'\n \n Se ha suprimido la funci\xf3n \n \n \n \n \n Created user "\n "\n \n Se ha creado el usuario \n \n \n \n \n Update user\n Actualizar usuario\n \n \n Continue\n Continuar\n \n \n You were automatically logged out because your roles have been changed.\n La sesi\xf3n se ha cerrado autom\xe1ticamente porque sus funciones han cambiado.\n \n \n Updated user "\n "\n \n Se ha actualizado el usuario \n \n \n \n \n Deleted user "\n "\n \n Se ha suprimido el usuario \n \n \n \n \n Failed to delete user "\n "\n \n Error al suprimir el usuario \n \n \n \n \n You are currently logged in as "\n ".\n \n Ha entrado a la sesi\xf3n como \n \n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Cada objeto se divide en porciones de datos, cada una almacenada en un OSD distinto.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Calcula las porciones de c\xf3digo para cada objeto y las almacena en distintos OSD.\n El n\xfamero de porciones de c\xf3digo es tambi\xe9n el n\xfamero de OSD que pueden estar inactivos sin que se pierdan datos.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n El complemento jerasure es el m\xe1s gen\xe9rico y flexible,\n y tambi\xe9n el complemento por defecto para los repositorios de c\xf3digo de borrado de Ceph.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n La t\xe9cnica m\xe1s flexible es reed_sol_van: basta con definir k y m.\n La t\xe9cnica cauchy_good puede ser m\xe1s r\xe1pida, pero hay que elegir con cuidado el tama\xf1o\n del paquete. reed_sol_r6_op, liberation, blaum_roth y liber8tion son todas equivalentes a RAID6\n en el sentido de que solo se pueden configurar con m=2.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n La codificaci\xf3n se realizar\xe1 seg\xfan el tama\xf1o de los paquetes de bytes de uno en uno.\n Elegir el tama\xf1o correcto es dif\xedcil.\n La documentaci\xf3n de jerasure incluye informaci\xf3n completa sobre el tema.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n Con el complemento jerasure, cuando un objeto de c\xf3digo de borrado se almacena\n en varios OSD, para recuperarse de la p\xe9rdida de un OSD es necesario leer de todos los dem\xe1s.\n Por ejemplo, si jerasure est\xe1 configurado con k=8 y m=4, cuando se pierde un OSD es necesario leer\n de los otros once para repararlo.\n\n El complemento de c\xf3digo de borrado lrc crea porciones de paridad local para poder realizar la recuperaci\xf3n con\n menos OSDs. Por ejemplo, is lrc est\xe1 configurado con k=8, m=4 y l=4, crear\xe1\n una porci\xf3n de paridad adicional para cada cuatro OSDs. Si se pierde un solo OSD, se puede recuperar\n solo con cuatro OSD, en lugar de con once.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Agrupa las porciones de c\xf3digo y de datos en localizaciones de conjuntos de tama\xf1o. Por ejemplo,\n para k=4 y m=2, si locality=3, se crean dos grupos de tres. Cada conjunto\n se puede recuperar sin leer porciones de otro conjunto.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n El tipo de papelera de CRUSH en el que se almacenar\xe1 cada\n conjunto de porciones definido por l. Por ejemplo, si se define como bastidor, cada grupo de l porciones\n se colocar\xe1 en un bastidor distinto. Se usa para crear un paso de regla de CRUSH, por ejemplo, "step choose\n rack". Si no se define, no se realiza este tipo de agrupamiento.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n El complemento isa encapsula la biblioteca ISA. Solo funciona en procesadores Intel.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n El complemento ISA viene en dos formatos de Reed Solomon.\n Si se define reed_sol_van, se trata de Vandermonde; si se define cauchy, se trata de Cauchy.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n El complemento shec encapsula las distintas bibliotecas SHEC.\n Permite a Ceph recuperar datos de forma m\xe1s eficiente que los c\xf3digos de Reed Solomon.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n El n\xfamero de porciones de paridad. Cada uno de ellas incluye cada porci\xf3n de datos\n en su intervalo de c\xe1lculo. El n\xfamero se usa como estimador de durabilidad. Por ejemplo, si c=2,\n 2 OSD pueden estar inactivos sin que se pierdan datos.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n El nombre de la papelera de CRUSH usado para el primer paso de la regla de CRUSH.\n Por ejemplo, "step take default".\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n Aseg\xfarese de que no hay dos porciones en una papelera con el mismo\n dominio de error. Por ejemplo, si el dominio de error es host, no debe haber dos porciones almacenadas en el mismo\n host. Se usa para crear un paso de regla de CRUSH, por ejemplo, "step chooseleaf host".\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Restringe la colocaci\xf3n a dispositivos de una clase concreta\n (p.ej., ssd o hdd) usando los nombre de clase de dispositivo CRUSH en el mapa de CRUSH.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n Define el nombre de directorio del que se cargar\xe1 el complemento de c\xf3digo de borrado.\n \n \n Allows all operations\n Permite todas las operaciones\n \n \n Allows only operations that do not modify the server\n Permite solo las operaciones que no modifican el servidor\n \n \n Does not allow read or write operations, but allows any other operation\n No permite operaciones de lectura o escritura, pero s\xed cualquier otra\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n No permite operaciones de lectura o escritura, ni ninguna otra que modifique los atributos del archivo o el contenido del directorio\n \n \n Allows no access at all\n No permite ning\xfan tipo de acceso\n \n \n -- Select the priority --\n -- Seleccione la prioridad --\n \n \n Low\n Baja\n \n \n High\n Alta\n \n \n Last 5 minutes\n \xdaltimos 5 minutos\n \n \n Last 15 minutes\n \xdaltimos 15 minutos\n \n \n Last 30 minutes\n \xdaltimos 30 minutos\n \n \n Last 1 hour (Default)\n \xdaltima hora (opci\xf3n por defecto)\n \n \n Last 3 hours\n \xdaltimas 3 horas\n \n \n Last 6 hours\n \xdaltimas 6 horas\n \n \n Last 12 hours\n \xdaltimas 12 horas\n \n \n Last 24 hours\n \xdaltimas 24 horas\n \n \n Yesterday\n Ayer\n \n \n Today\n Hoy\n \n \n Today so far\n Hoy hasta ahora\n \n \n Day before yesterday\n Anteayer\n \n \n Last 2 days\n Los \xfaltimos 2 d\xedas\n \n \n This day last week\n Este d\xeda la semana pasada\n \n \n Previous week\n La semana pasada\n \n \n This week\n Esta semana\n \n \n This week so far\n Esta semana hasta ahora\n \n \n Last 7 days\n Los \xfaltimos 7 d\xedas\n \n \n Previous month\n El mes pasado\n \n \n This month\n Este mes\n \n \n This month so far\n Este mes hasta ahora\n \n \n Last 30 days\n Los \xfaltimos 30 d\xedas\n \n \n Last 90 days\n Los \xfaltimos 90 d\xedas\n \n \n Last 6 months\n Los \xfaltimos 6 meses\n \n \n Last 1 year\n El \xfaltimo a\xf1o\n \n \n Previous year\n El a\xf1o pasado\n \n \n This year\n Este a\xf1o\n \n \n This year so far\n Este a\xf1o hasta ahora\n \n \n Last 2 years\n Los \xfaltimos 2 a\xf1os\n \n \n Last 5 years\n Los \xfaltimos 5 a\xf1os\n \n \n Information\n Informaci\xf3n\n \n \n No items selected.\n No se ha seleccionado ning\xfan elemento.\n \n \n Deselect item to select again\n Deseleccione el elemento para volver a seleccionarlo\n \n \n Selection limit reached\n Se ha alcanzado el l\xedmite de selecci\xf3n\n \n \n Filter tags\n Filtrar etiquetas\n \n \n Add badge\n A\xf1adir insignia\n \n \n There are no items available.\n No hay ning\xfan elemento disponible.\n \n \n Add\n A\xf1adir\n \n \n Remove\n Remove\n \n \n Clone\n Clonar\n \n \n Copy\n Copiar\n \n \n Deep Scrub\n Depuraci\xf3n profunda\n \n \n Destroy\n Destruir\n \n \n Flatten\n Aplanar\n \n \n Mark Down\n Marcar para desactivar\n \n \n Mark In\n Marcar para incluir\n \n \n Mark Lost\n Marcar como perdido\n \n \n Mark Out\n Marcar para excluir\n \n \n Protect\n Proteger\n \n \n Rename\n Renombrar\n \n \n Restore\n Restaurar\n \n \n Move to Trash\n Mover a la papelera\n \n \n Unprotect\n Desproteger\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Suprimido\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Clonado\n \n \n Copied\n Copiado\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n S\xed\n \n \n No\n No\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Calidad del servicio\n \n \n BPS Limit\n L\xedmite de BPS\n \n \n The desired limit of IO bytes per second.\n El l\xedmite deseado de bytes de E/S por segundo.\n \n \n IOPS Limit\n L\xedmite de IOPS\n \n \n The desired limit of IO operations per second.\n El l\xedmite deseado de operaciones de E/S por segundo.\n \n \n Read BPS Limit\n L\xedmite de BPS de lectura\n \n \n The desired limit of read bytes per second.\n El l\xedmite deseado de bytes de lectura por segundo.\n \n \n Read IOPS Limit\n L\xedmite de IOPS de lectura\n \n \n The desired limit of read operations per second.\n El l\xedmite deseado de operaciones de lectura por segundo.\n \n \n Write BPS Limit\n L\xedmite de BPS de escritura\n \n \n The desired limit of write bytes per second.\n El l\xedmite deseado de bytes de escritura por segundo.\n \n \n Write IOPS Limit\n L\xedmite de IOPS de escritura\n \n \n The desired limit of write operations per second.\n El l\xedmite deseado de operaciones de escritura por segundo.\n \n \n BPS Burst\n R\xe1faga de BPS\n \n \n The desired burst limit of IO bytes.\n El l\xedmite deseado de r\xe1faga de bytes de E/S.\n \n \n IOPS Burst\n R\xe1faga de IOPS\n \n \n The desired burst limit of IO operations.\n El l\xedmite deseado de r\xe1faga de operaciones de E/S.\n \n \n Read BPS Burst\n R\xe1faga de BPS de lectura\n \n \n The desired burst limit of read bytes.\n El l\xedmite deseado de r\xe1faga de bytes de lectura.\n \n \n Read IOPS Burst\n R\xe1faga de IOPS de lectura\n \n \n The desired burst limit of read operations.\n El l\xedmite deseado de r\xe1faga de operaciones de lectura.\n \n \n Write BPS Burst\n R\xe1faga de BPS de escritura\n \n \n The desired burst limit of write bytes.\n El l\xedmite deseado de r\xe1faga de bytes de escritura.\n \n \n Write IOPS Burst\n R\xe1faga de IOPS de escritura\n \n \n The desired burst limit of write operations.\n El l\xedmite deseado de r\xe1faga de operaciones de escritura.\n \n \n Failed to \n \n \n \n Error al \n \n \n \n \n \n Executing\n Ejecutando\n \n \n execute\n ejecutar\n \n \n Executed\n Ejecutado\n \n \n unknown task\n tarea desconocida\n \n \n Creating\n Creando\n \n \n create\n crear\n \n \n Updating\n Actualizando\n \n \n update\n actualizar\n \n \n Deleting\n Suprimiendo\n \n \n delete\n suprimir\n \n \n RBD \'\n \'\n \n RBD \n \n \n \n \n RBD snapshot \'\n \'\n \n Instant\xe1nea RBD \n \n \n \n \n mirror mode for pool \'\n \'\n \n modo de duplicaci\xf3n para repositorio \n \n \n \n \n mirror peer for pool \'\n \'\n \n par de duplicaci\xf3n para repositorio \n \n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n \n ya est\xe1 usando el nombre.\n \n \n \n Name is already used by \n .\n \n \n ya est\xe1 usando el nombre.\n \n \n \n Name is already used by \n .\n \n \n ya est\xe1 usando el nombre.\n \n \n \n \n contains snapshots.\n \n \n contiene instant\xe1neas.\n \n \n \n Cloning\n Clonando\n \n \n clone\n clonar\n \n \n Snapshot of \n must be protected.\n \n La instant\xe1nea de \n debe estar protegida.\n \n \n \n Copying\n Copiando\n \n \n copy\n copiar\n \n \n Flattening\n Aplanando\n \n \n flatten\n aplanar\n \n \n Flattened\n Aplanado\n \n \n Name is already used by \n .\n \n \n ya est\xe1 usando el nombre.\n \n \n \n Cannot unprotect \n because it contains child images.\n \n No es posible desproteger \n porque contiene im\xe1genes hijas.\n \n \n \n Cannot delete \n because it\'s protected.\n \n No es posible suprimir \n porque est\xe1 protegido.\n \n \n \n Rolling back\n Revirtiendo\n \n \n rollback\n revertir\n \n \n Rolled back\n Revertido\n \n \n Moving\n Moviendo\n \n \n move\n mover\n \n \n Moved\n Movido\n \n \n image \'\n \' to trash\n \n la imagen \n a la papelera\n \n \n \n Could not find image.\n No se encuentra la imagen.\n \n \n Restoring\n Restaurando\n \n \n restore\n restaurar\n \n \n Restored\n Restaurado\n \n \n image \'\n \' into \'\n \'\n \n la imagen \n en \n \n \n \n \n Image name \'\n \' is already in use.\n \n El nombre de imagen \n ya est\xe1 en uso.\n \n \n \n image \'\n \'\n \n la imagen \n \n \n \n \n Purging\n Limpiando\n \n \n purge\n limpiar\n \n \n Purged\n Limpiado\n \n \n all pools\n todos los repositorios\n \n \n images from \n \n \n im\xe1genes de \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n No es posible inhabilitar la duplicaci\xf3n porque contiene un par\n \n \n pool \'\n \'\n \n repositorio \n \n \n \n \n erasure code profile \'\n \'\n \n perfil de c\xf3digo de borrado \n \n \n \n \n target \'\n \'\n \n destino \n \n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},czA5:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.MouseEvent=("undefined"!=typeof window&&window||global).MouseEvent,e.KeyboardEvent=("undefined"!=typeof window&&window||global).KeyboardEvent,e.Event=("undefined"!=typeof window&&window||global).Event},czMo:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("en-il",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}})}()},"d+Og":function(t,e,n){"use strict";var a=n("LvDl"),r=function(){function t(t){if(this.type=t,!this.isValidType())throw new Error("Wrong placement group category type");this.setTypeStates()}return t.prototype.isValidType=function(){return t.VALID_CATEGORIES.includes(this.type)},t.prototype.setTypeStates=function(){switch(this.type){case t.CATEGORY_CLEAN:this.states=["active","clean"];break;case t.CATEGORY_WORKING:this.states=["activating","backfill_wait","backfilling","creating","deep","degraded","forced_backfill","forced_recovery","peering","peered","recovering","recovery_wait","repair","scrubbing","snaptrim","snaptrim_wait"];break;case t.CATEGORY_WARNING:this.states=["backfill_toofull","backfill_unfound","down","incomplete","inconsistent","recovery_toofull","recovery_unfound","remapped","snaptrim_error","stale","undersized"];break;default:this.states=[]}},t.VALID_CATEGORIES=[t.CATEGORY_CLEAN="clean",t.CATEGORY_WORKING="working",t.CATEGORY_WARNING="warning",t.CATEGORY_UNKNOWN="unknown"],t}(),i=n("CcnG"),s=n("kJI8");n.d(e,"a",function(){return o});var o=function(){function t(){this.categories=this.createCategories()}return t.prototype.getAllTypes=function(){return r.VALID_CATEGORIES},t.prototype.getTypeByStates=function(t){var e=this,n=this.getPgStatesFromText(t);if(0===n.length)return r.CATEGORY_UNKNOWN;var i=a.zipObject(r.VALID_CATEGORIES,r.VALID_CATEGORIES.map(function(t){return a.intersection(e.categories[t].states,n).length}));if(i[r.CATEGORY_WARNING]>0)return r.CATEGORY_WARNING;var s=i[r.CATEGORY_WORKING];return n.length>i[r.CATEGORY_CLEAN]+s?r.CATEGORY_UNKNOWN:s?r.CATEGORY_WORKING:r.CATEGORY_CLEAN},t.prototype.createCategories=function(){return a.zipObject(r.VALID_CATEGORIES,r.VALID_CATEGORIES.map(function(t){return new r(t)}))},t.prototype.getPgStatesFromText=function(t){var e=t.replace(/[^a-z]+/g," ").trim().split(" ");return a.uniq(e)},t.ngInjectableDef=i.defineInjectable({factory:function(){return new t},token:t,providedIn:s.a}),t}()},dC0D:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("mrSG"),r=n("FFOo");function i(t,e){var n=!1;return arguments.length>=2&&(n=!0),function(a){return a.lift(new s(t,e,n))}}var s=function(){function t(t,e,n){void 0===n&&(n=!1),this.accumulator=t,this.seed=e,this.hasSeed=n}return t.prototype.call=function(t,e){return e.subscribe(new o(t,this.accumulator,this.seed,this.hasSeed))},t}(),o=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.accumulator=n,i._seed=a,i.hasSeed=r,i.index=0,i}return a.__extends(e,t),Object.defineProperty(e.prototype,"seed",{get:function(){return this._seed},set:function(t){this.hasSeed=!0,this._seed=t},enumerable:!0,configurable:!0}),e.prototype._next=function(t){if(this.hasSeed)return this._tryNext(t);this.seed=t,this.destination.next(t)},e.prototype._tryNext=function(t){var e,n=this.index++;try{e=this.accumulator(this.seed,t,n)}catch(a){this.destination.error(a)}this.seed=e,this.destination.next(e)},e}(r.a)},dEH0:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){}return t.prototype.transform=function(t){return t+" ms"},t}()},dEwP:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("F/XL"),r=n("Txjg");function i(){for(var t=[],e=0;e1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+n);var a=Date.now();t.dropFrames+=(a-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,n,a=this.animations,i=0;i=e.numSteps?(r.callback(e.onAnimationComplete,[e],n),n.animating=!1,a.splice(i,1)):++i}}},dzgT:function(t,e,n){"use strict";n.d(e,"b",function(){return l}),n.d(e,"a",function(){return d});var a=n("mrSG"),r=n("nkY7"),i=n("isby"),s=n("MGBS"),o=n("zotm"),u=n("IUTb"),c={};function l(){for(var t=[],e=0;e1&&t<5}function r(t,e,n,r){var i=t+" ";switch(n){case"s":return e||r?"p\xe1r sek\xfand":"p\xe1r sekundami";case"ss":return e||r?i+(a(t)?"sekundy":"sek\xfand"):i+"sekundami";case"m":return e?"min\xfata":r?"min\xfatu":"min\xfatou";case"mm":return e||r?i+(a(t)?"min\xfaty":"min\xfat"):i+"min\xfatami";case"h":return e?"hodina":r?"hodinu":"hodinou";case"hh":return e||r?i+(a(t)?"hodiny":"hod\xedn"):i+"hodinami";case"d":return e||r?"de\u0148":"d\u0148om";case"dd":return e||r?i+(a(t)?"dni":"dn\xed"):i+"d\u0148ami";case"M":return e||r?"mesiac":"mesiacom";case"MM":return e||r?i+(a(t)?"mesiace":"mesiacov"):i+"mesiacmi";case"y":return e||r?"rok":"rokom";case"yy":return e||r?i+(a(t)?"roky":"rokov"):i+"rokmi"}}t.defineLocale("sk",{months:e,monthsShort:n,weekdays:"nede\u013ea_pondelok_utorok_streda_\u0161tvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_\u0161t_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_\u0161t_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nede\u013eu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo \u0161tvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[v\u010dera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minul\xfa nede\u013eu o] LT";case 1:case 2:return"[minul\xfd] dddd [o] LT";case 3:return"[minul\xfa stredu o] LT";case 4:case 5:return"[minul\xfd] dddd [o] LT";case 6:return"[minul\xfa sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:r,ss:r,m:r,mm:r,h:r,hh:r,d:r,dd:r,M:r,MM:r,y:r,yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n("wd/R"))},eTJe:function(t,e,n){"use strict";var a,r=n("gIcY"),i=n("LvDl"),s=n("VNr4"),o=(n("SgmB"),n("ZDA6"),n("sne2"),n("mtw6")),u=n("QFaf"),c=n("1Ni5");n("9nlD"),function(t){t.editing="editing"}(a||(a={}));var l=function(){return function(){}}();n.d(e,"a",function(){return d});var d=function(){function t(t,e,n,r,i,s,o){this.route=t,this.router=e,this.roleService=n,this.scopeService=r,this.notificationService=i,this.i18n=s,this.actionLabels=o,this.scopes=[],this.scopes_permissions=[],this.roleFormMode=a,this.resource=this.i18n("role"),this.createForm(),this.listenToChanges()}return t.prototype.createForm=function(){this.roleForm=new u.a({name:new r.i("",{validators:[r.A.required],asyncValidators:[c.a.unique(this.roleService.exists,this.roleService)]}),description:new r.i(""),scopes_permissions:new r.i({})})},t.prototype.ngOnInit=function(){this.columns=[{prop:"scope",name:this.i18n("All"),flexGrow:2,cellTemplate:this.cellScopeCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"read",name:this.i18n("Read"),flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"create",name:this.i18n("Create"),flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"update",name:this.i18n("Update"),flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl},{prop:"delete",name:this.i18n("Delete"),flexGrow:1,cellClass:"text-center",cellTemplate:this.cellPermissionCheckboxTpl,headerTemplate:this.headerPermissionCheckboxTpl}],this.router.url.startsWith("/user-management/roles/edit")?(this.mode=this.roleFormMode.editing,this.action=this.actionLabels.EDIT):this.action=this.actionLabels.CREATE,this.mode===this.roleFormMode.editing?this.initEdit():this.initCreate()},t.prototype.initCreate=function(){var t=this;this.scopeService.list().subscribe(function(e){t.scopes=e,t.roleForm.get("scopes_permissions").setValue({})})},t.prototype.initEdit=function(){var t=this;this.roleForm.get("name").disable(),this.route.params.subscribe(function(e){var n=[];n.push(t.scopeService.list()),n.push(t.roleService.get(e.name)),Object(s.a)(n).subscribe(function(e){t.scopes=e[0],["name","description","scopes_permissions"].forEach(function(n){return t.roleForm.get(n).setValue(e[1][n])})})})},t.prototype.listenToChanges=function(){var t=this;this.roleForm.get("scopes_permissions").valueChanges.subscribe(function(e){var n=[];i.each(t.scopes,function(t){var a={read:!1,create:!1,update:!1,delete:!1};a.scope=t,t in e&&i.each(e[t],function(t){a[t]=!0}),n.push(a)}),t.scopes_permissions=n})},t.prototype.isRowChecked=function(t){var e=i.find(this.scopes_permissions,function(e){return e.scope===t});return!i.isUndefined(e)&&e.read&&e.create&&e.update&&e.delete},t.prototype.isHeaderChecked=function(t){var e=this,n=[t];return"scope"===t&&(n=["read","create","update","delete"]),n.every(function(t){return e.scopes_permissions.every(function(e){return e[t]})})},t.prototype.onClickCellCheckbox=function(t,e,n){void 0===n&&(n=null);var a=i.cloneDeep(this.roleForm.getValue("scopes_permissions")),r=[e];"scope"===e&&(r=["read","create","update","delete"]),t in a||(a[t]=[]),n&&n.target.checked||!i.isEqual(r.sort(),i.intersection(a[t],r).sort())?a[t]=i.union(a[t],r):(a[t]=i.difference(a[t],r),i.isEmpty(a[t])&&i.unset(a,t)),this.roleForm.get("scopes_permissions").setValue(a)},t.prototype.onClickHeaderCheckbox=function(t,e){var n=this,a=i.cloneDeep(this.roleForm.getValue("scopes_permissions")),r=[t];"scope"===t&&(r=["read","create","update","delete"]),i.each(r,function(t){i.each(n.scopes,function(n){e.target.checked?a[n]=i.union(a[n],[t]):(a[n]=i.difference(a[n],[t]),i.isEmpty(a[n])&&i.unset(a,n))})}),this.roleForm.get("scopes_permissions").setValue(a)},t.prototype.getRequest=function(){var t=this,e=new l;return["name","description","scopes_permissions"].forEach(function(n){return e[n]=t.roleForm.get(n).value}),e},t.prototype.createAction=function(){var t=this,e=this.getRequest();this.roleService.create(e).subscribe(function(){t.notificationService.show(o.a.success,t.i18n("Created role '{{role_name}}'",{role_name:e.name})),t.router.navigate(["/user-management/roles"])},function(){t.roleForm.setErrors({cdSubmitButton:!0})})},t.prototype.editAction=function(){var t=this,e=this.getRequest();this.roleService.update(e).subscribe(function(){t.notificationService.show(o.a.success,t.i18n("Updated role '{{role_name}}'",{role_name:e.name})),t.router.navigate(["/user-management/roles"])},function(){t.roleForm.setErrors({cdSubmitButton:!0})})},t.prototype.submit=function(){this.mode===this.roleFormMode.editing?this.editAction():this.createAction()},t}()},eajB:function(t,e,n){"use strict";n.d(e,"a",function(){return c}),n.d(e,"b",function(){return l}),n.d(e,"c",function(){return f}),n.d(e,"d",function(){return p});var a=n("CcnG"),r=n("rpEJ"),i=n("mrSG"),s=n("lqqz"),o=n("NJnL"),u=n("gI3B"),c=function(){return function(){this.adaptivePosition=!0,this.placement="top",this.triggers="hover focus",this.delay=0}}(),l=function(){function t(t){Object.assign(this,t)}return Object.defineProperty(t.prototype,"isBs3",{get:function(){return Object(r.d)()},enumerable:!0,configurable:!0}),t.prototype.ngAfterViewInit=function(){this.classMap={in:!1,fade:!1},this.classMap[this.placement]=!0,this.classMap["tooltip-"+this.placement]=!0,this.classMap.in=!0,this.animation&&(this.classMap.fade=!0),this.containerClass&&(this.classMap[this.containerClass]=!0)},t}(),d=0,f=function(){function t(t,e,n,r,i,s){this._elementRef=r,this._renderer=i,this._positionService=s,this.tooltipId=d++,this.tooltipChange=new a.EventEmitter,this.containerClass="",this.tooltipAnimation=!0,this.tooltipFadeDuration=150,this.ariaDescribedby="tooltip-"+this.tooltipId,this.tooltipStateChanged=new a.EventEmitter,this._tooltip=e.createLoader(this._elementRef,t,this._renderer).provide({provide:c,useValue:n}),Object.assign(this,n),this.onShown=this._tooltip.onShown,this.onHidden=this._tooltip.onHidden}return Object.defineProperty(t.prototype,"isOpen",{get:function(){return this._tooltip.isShown},set:function(t){t?this.show():this.hide()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"htmlContent",{set:function(t){Object(r.i)("tooltipHtml was deprecated, please use `tooltip` instead"),this.tooltip=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_placement",{set:function(t){Object(r.i)("tooltipPlacement was deprecated, please use `placement` instead"),this.placement=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_isOpen",{get:function(){return Object(r.i)("tooltipIsOpen was deprecated, please use `isOpen` instead"),this.isOpen},set:function(t){Object(r.i)("tooltipIsOpen was deprecated, please use `isOpen` instead"),this.isOpen=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_enable",{get:function(){return Object(r.i)("tooltipEnable was deprecated, please use `isDisabled` instead"),this.isDisabled},set:function(t){Object(r.i)("tooltipEnable was deprecated, please use `isDisabled` instead"),this.isDisabled=!t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_appendToBody",{get:function(){return Object(r.i)('tooltipAppendToBody was deprecated, please use `container="body"` instead'),"body"===this.container},set:function(t){Object(r.i)('tooltipAppendToBody was deprecated, please use `container="body"` instead'),this.container=t?"body":this.container},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_popupClass",{set:function(t){Object(r.i)("tooltipClass deprecated")},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_tooltipContext",{set:function(t){Object(r.i)("tooltipContext deprecated")},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_tooltipPopupDelay",{set:function(t){Object(r.i)("tooltipPopupDelay is deprecated, use `delay` instead"),this.delay=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_tooltipTrigger",{get:function(){return Object(r.i)("tooltipTrigger was deprecated, please use `triggers` instead"),this.triggers},set:function(t){Object(r.i)("tooltipTrigger was deprecated, please use `triggers` instead"),this.triggers=(t||"").toString()},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){var t=this;this._tooltip.listen({triggers:this.triggers,show:function(){return t.show()}}),this.tooltipChange.subscribe(function(e){e||t._tooltip.hide()})},t.prototype.toggle=function(){if(this.isOpen)return this.hide();this.show()},t.prototype.show=function(){var t=this;if(this._positionService.setOptions({modifiers:{flip:{enabled:this.adaptivePosition},preventOverflow:{enabled:this.adaptivePosition}}}),!(this.isOpen||this.isDisabled||this._delayTimeoutId)&&this.tooltip){var e=function(){t._delayTimeoutId&&(t._delayTimeoutId=void 0),t._tooltip.attach(l).to(t.container).position({attachment:t.placement}).show({content:t.tooltip,placement:t.placement,containerClass:t.containerClass,id:t.ariaDescribedby})},n=function(){t._tooltipCancelShowFn&&t._tooltipCancelShowFn()};if(this.delay){var a=Object(u.a)(this.delay).subscribe(function(){e(),n()});if(this.triggers){var i=Object(r.f)(this.triggers);this._tooltipCancelShowFn=this._renderer.listen(this._elementRef.nativeElement,i[0].close,function(){a.unsubscribe(),n()})}}else e()}},t.prototype.hide=function(){var t=this;this._delayTimeoutId&&(clearTimeout(this._delayTimeoutId),this._delayTimeoutId=void 0),this._tooltip.isShown&&(this._tooltip.instance.classMap.in=!1,setTimeout(function(){t._tooltip.hide()},this.tooltipFadeDuration))},t.prototype.ngOnDestroy=function(){this._tooltip.dispose()},Object(i.__decorate)([Object(r.a)(),Object(i.__metadata)("design:type",Object)],t.prototype,"tooltip",void 0),t}(),p=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[c,s.a,o.a]}},t}()},"ej+x":function(t,e,n){"use strict";n.d(e,"a",function(){return u});var a=n("gI3B"),r=n("psW0"),i=n("klSw"),s=n("CcnG"),o=n("t/Na"),u=function(){function t(t){var e=this;this.http=t,this.API_URL="api/feature_toggles",this.REFRESH_INTERVAL=2e4,this.featureToggleMap$=Object(a.a)(0,this.REFRESH_INTERVAL).pipe(Object(r.a)(function(){return e.http.get(e.API_URL)}),Object(i.a)(1))}return t.prototype.get=function(){return this.featureToggleMap$},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(o.c))},token:t,providedIn:"root"}),t}()},ejVf:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.standard="standard",t.flex="flex",t.force="force"}(e.ColumnMode||(e.ColumnMode={}))},"f/UV":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},fB8H:function(t,e){t.exports='\n \n \n \n Toggle navigation\n \u5207\u6362\u5bfc\u822a\n \n \n Dashboard\n \u4eea\u8868\u76d8\n \n \n Cluster\n \u96c6\u7fa4\n \n \n Hosts\n \u4e3b\u673a\n \n \n Monitors\n Monitor\n \n \n OSDs\n OSD\n \n \n Configuration\n \u914d\u7f6e\u9879\n \n \n CRUSH map\n CRUSH \u7d22\u5f15\n \n \n Manager modules\n Manager \u6269\u5c55\u6a21\u5757\n \n \n Logs\n \u65e5\u5fd7\n \n \n Alerts\n \u8b66\u544a\n \n \n Silences\n Silences\n \n \n Pools\n \u5b58\u50a8\u6c60\n \n \n Block\n \u5757\u8bbe\u5907\n \n \n Images\n \u6620\u50cf\n \n \n Mirroring\n \u955c\u50cf\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n \u6587\u4ef6\u7cfb\u7edf\n \n \n Object Gateway\n \u5bf9\u8c61\u7f51\u5173\n \n \n Daemons\n \u5b88\u62a4\u8fdb\u7a0b\n \n \n Users\n \u7528\u6237\n \n \n Buckets\n \u5b58\u50a8\u6876\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n \u5173\u4e8e\n \u7684\u6570\u636e\uff0c\u6b63\u4e3a\n \n \n \u83b7\u53d6\u4e2d\uff0c\u8bf7\u7a0d\u5019...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n \u5173\u4e8e\u4e4b\u524d\u7f13\u5b58\u7684\u6570\u636e\n \uff0c\u6b63\u4e3a\n \n \n \u663e\u793a\u3002\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n \u5173\u4e8e\u6570\u636e\n \uff0c\u65e0\u6cd5\u4e3a\n \n \n \u52a0\u8f7d\u3002\n \u8bf7\u68c0\u67e5\u96c6\u7fa4\u7684\u5065\u5eb7\u72b6\u51b5\u3002\n \n \n \n Back\n \u8fd4\u56de\n \n \n Select a Language\n \u8bf7\u9009\u62e9\u8bed\u8a00\n \n \n Loading panel data...\n \u6b63\u5728\u52a0\u8f7d\u9762\u677f\u7684\u76f8\u5173\u6570\u636e\u2026\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n \u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u4ee5\u53ca\u6253\u5f00\u76d1\u63a7\u529f\u80fd\uff0c\n\u8bf7\u53c2\u9605\n \u6587\u6863\n \u3002\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n \u65e0 Grafana \u4eea\u8868\u76d8\u3002\u5173\u4e8e\u5982\u4f55\u4e3a Grafana \u6dfb\u52a0\n\u4eea\u8868\u76d8\uff0c\u8bf7\u53c2\u8003\n \u6587\u6863\n \u3002\n \n \n \n Grafana Time Picker\n Grafana \u65f6\u95f4\u9009\u62e9\u5de5\u5177\n \n \n Reset Settings\n \u91cd\u65b0\u8bbe\u7f6e\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n \u65e0\u6cd5\u52a0\u8f7d\u6570\u636e\u3002\n \n \n selected\n \u9009\u4e2d\u4e2a\u6570\n X selected\n \n \n found\n \u547d\u4e2d\u4e2a\u6570\n X found\n \n \n total\n \u603b\u6570\n X total\n \n \n Edit\n \u7f16\u8f91\n \n \n Name\n \u540d\u79f0\n \n \n Description\n \u89e3\u91ca\n \n \n Long description\n \u66f4\u8be6\u5c3d\u7684\u89e3\u91ca\n \n \n Default\n \u7f3a\u7701\u503c\n \n \n Daemon default\n \u5b88\u62a4\u8fdb\u7a0b\u7684\u7f3a\u7701\u503c\n \n \n Services\n \u5bf9\u5e94\u7684\u670d\u52a1\n \n \n Values\n \u53ef\u9009\u503c\n \n \n The entered value is too high! It must not be greater than \n .\n \n \u8bbe\u7f6e\u7684\u503c\u592a\u5927\u4e86\uff01\u5e94\u4f4e\u4e8e \n \u3002\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \u8bbe\u7f6e\u7684\u503c\u592a\u5c0f\u4e86\uff01\u4e0d\u80fd\u4f4e\u4e8e \n \u3002\n \n \n \n Save\n \u4fdd\u5b58\n \n \n CRUSH map viewer\n \u68c0\u67e5 CRUSH \u7d22\u5f15\u56fe\n \n \n Hosts List\n \u4e3b\u673a\u5217\u8868\n \n \n Overall Performance\n \u603b\u4f53\u6027\u80fd\n \n \n No entries found\n \u65e0\u6cd5\u627e\u5230\u76f8\u5173\u6761\u76ee\n \n \n Cluster Logs\n \u96c6\u7fa4\u65e5\u5fd7\n \n \n Audit Logs\n \u5ba1\u8ba1\u65e5\u5fd7\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n \u6b63\u5728\u52a0\u8f7d\u76f8\u5173\u914d\u7f6e\u4fe1\u606f...\n \n \n The configuration could not be loaded.\n \u914d\u7f6e\u4fe1\u606f\u65e0\u6cd5\u52a0\u8f7d\u3002\n \n \n Edit Manager module\n \u7f16\u8f91 Manager \u6269\u5c55\u6a21\u5757\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \u8f93\u5165\u503c\u4e0d\u662f\u6709\u6548\u7684 UUID\uff0c\u5982\uff1a67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n \u8f93\u5165\u7684\u5e94\u8be5\u662f\u4e2a\u6709\u6548\u7684 IP \u5730\u5740\u3002\n \n \n This field is required.\n \u8bf7\u586b\u5199\u6b64\u680f\u76ee\uff01\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n \u8f93\u5165\u503c\u8fc7\u5927\uff01\u5fc5\u987b\u5c0f\u4e8e\u6216\u7b49\u4e8e \n \u3002\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n \u8f93\u5165\u503c\u8fc7\u5c0f\uff01\u5fc5\u987b\u5927\u4e8e\u6216\u7b49\u4e8e \n \u3002\n \n \n \n The entered value needs to be a number.\n \u8f93\u5165\u987b\u4e3a\u6570\u5b57\u3002\n \n \n The entered value needs to be a number or decimal.\n \u8f93\u5165\u7684\u5e94\u8be5\u662f\u4e00\u4e2a\u6d6e\u70b9\u6570\u6216\u8005\u5341\u8fdb\u5236\u6574\u6570\u3002\n \n \n Update\n \u66f4\u65b0\n \n \n Status\n \u72b6\u6001\n \n \n Cluster ID\n \u96c6\u7fa4 ID\n \n \n monmap modified\n monmap \u4fee\u6539\u65f6\u95f4\n \n \n monmap epoch\n monmap epoch\n \n \n quorum con\n quorum con \n \n \n quorum mon\n quorum mon\n \n \n required con\n required con\n \n \n required mon\n required mon\n \n \n In Quorum\n \u4ef2\u88c1\u6210\u5458\n \n \n Not In Quorum\n \u975e\u4ef2\u88c1\u6210\u5458\n \n \n Cancel\n \u53d6\u6d88\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n \u60a8\u786e\u5b9a\u8981\n \u9009\u4e2d\u7684\n \u5417\uff1f\n \n \n \n Yes, I am sure.\n \u662f\u7684\uff0c\u6211\u786e\u5b9a\u3002\n \n \n Cluster-wide OSD Flags\n \u96c6\u7fa4\u8303\u56f4\u7684 OSD \u6807\u5fd7\n \n \n Submit\n \u63d0\u4ea4\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n \u9ad8\u7ea7\u8bbe\u7f6e\u2026\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n OSD \u6062\u590d\u4f18\u5148\u7ea7\n \n \n Priority\n \u4f18\u5148\u7ea7\n \n \n Customize priority values\n \u81ea\u5b9a\u4e49\u4f18\u5148\u7ea7\n \n \n This field is required!\n \u8fd9\u4e2a\u5b57\u6bb5\u662f\u5fc5\u586b\u7684\uff01\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n \u8f93\u5165\u503c\u8fc7\u5927\uff01\u4e0d\u80fd\u5927\u4e8e \n \u3002\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \u8f93\u5165\u503c\u8fc7\u5c0f\uff01\u4e0d\u80fd\u5c0f\u4e8e \n \u3002\n \n \n \n Reweight OSD\n \u91cd\u65b0\u8bbe\u7f6e OSD \u7684\u6743\u91cd\n \n \n The value needs to be between 0 and 1.\n \u6743\u91cd\u503c\u5fc5\u987b\u5728 0 \u548c 1 \u4e4b\u95f4\n \n \n Reweight\n \u91cd\u8bbe\u6743\u91cd\n \n \n OSDs \n Scrub\n \n OSD \n \u6d17\u5237\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {\u6df1\u5ea6}}\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n \u5373\u5c06\u5bf9 OSD\n \n \n \u6267\u884c\n \u6d17\u5237\u3002\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {\u6df1\u5ea6} }\n \n \n OSDs List\n OSD \u5217\u8868\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \u5982\u679c\u7ee7\u7eed\uff0c\n OSD\n \n \n\u5c06\u88ab\u6807\u8bb0\u4e3a\n \n \n \u3002\n \n \n \n The OSD is not safe to destroy!\n OSD \u4e0d\u5b89\u5168\uff0c\u65e0\u6cd5\u9500\u6bc1\uff01\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \u5982\u679c\u7ee7\u7eed\uff0c\n OSD\n \n \n\u5c06\u88ab\n \n \n \u3002\n \n \n \n Details\n \u8be6\u60c5\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n \u503c\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n \u5173\u95ed\n \n \n Delete\n \u5220\u9664\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n \u5065\u5eb7\u72b6\u51b5\n \n \n Statistics\n \u7edf\u8ba1\u6570\u636e\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n \u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u548c\u542f\u7528 NFS Ganesha \u7ba1\u7406\u529f\u80fd\uff0c\n\u8bf7\u53c2\u8003\n \u6587\u6863\n \u3002\n \n \n \n Clients\n \u5ba2\u6237\u7aef\n \n \n Any client can access\n \u4efb\u4f55\u5ba2\u6237\u7aef\u5747\u53ef\u8bbf\u95ee\n \n \n Addresses\n \u5730\u5740\n \n \n Required field\n \u5fc5\u586b\u9879\n \n \n Must contain one or more comma-separated values\n \u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u6216\u591a\u4e2a\u9017\u53f7\u5206\u9694\u503c\n \n \n For example:\n \u4f8b\u5982\uff1a\n \n \n Access Type\n \u8bbf\u95ee\u7c7b\u578b\n \n \n Squash\n Squash\n \n \n Add clients\n \u6dfb\u52a0\u5ba2\u6237\u7aef\n \n \n Loading...\n \u6b63\u5728\u52a0\u8f7d\u2026\n \n \n -- No cluster available --\n -- \u65e0\u53ef\u7528\u96c6\u7fa4 --\n \n \n -- Select the cluster --\n -- \u8bf7\u9009\u62e9\u4e00\u4e2a\u96c6\u7fa4 --\n \n \n Add daemon\n \u6dfb\u52a0\u5b88\u62a4\u8fdb\u7a0b\n \n \n Storage Backend\n \u5b58\u50a8\u540e\u7aef\n \n \n -- No data pools available --\n -- \u6ca1\u6709\u53ef\u7528\u7684\u6570\u636e\u5b58\u50a8\u6c60 --\n \n \n -- Select the storage backend --\n -- \u8bf7\u9009\u62e9\u5b58\u50a8\u540e\u7aef --\n \n \n Object Gateway User\n \u5bf9\u8c61\u7f51\u5173\u7528\u6237\n \n \n -- No users available --\n -- \u65e0\u53ef\u9009\u7528\u6237 --\n \n \n -- Select the object gateway user --\n -- \u8bf7\u9009\u62e9\u5bf9\u8c61\u7f51\u5173\u7528\u6237 --\n \n \n CephFS User ID\n CephFS \u7528\u6237 ID\n \n \n -- No clients available --\n -- \u65e0\u53ef\u7528\u5ba2\u6237\u7aef --\n \n \n -- Select the cephx client --\n -- \u8bf7\u9009\u62e9 cephx \u5ba2\u6237\u7aef --\n \n \n CephFS Name\n CephFS \u540d\u79f0\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n \u5b89\u5168\u6807\u7b7e\n \n \n Enable security label\n \u542f\u7528\u5b89\u5168\u6807\u7b7e\n \n \n CephFS Path\n CephFS \u8def\u5f84\n \n \n Path need to start with a \'/\' and can be followed by a word\n \u8def\u5f84\u9700\u4ee5\u201c/\u201d\u5f00\u5934\uff0c\u540e\u9762\u53ef\u8ddf\u5355\u8bcd\n \n \n New directory will be created\n \u5c06\u521b\u5efa\u65b0\u6587\u4ef6\u5939\n \n \n Path\n \u8def\u5f84\n \n \n Path can only be a single \'/\' or a word\n \u8def\u5f84\u53ea\u80fd\u662f\u5355\u4e2a\u201c/\u201d\u6216\u5355\u8bcd\n \n \n New bucket will be created\n \u5c06\u521b\u5efa\u65b0\u7684\u6876\n \n \n NFS Protocol\n NFS \u534f\u8bae\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n NFS \u6807\u7b7e\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n \n NFS v3\n \u88c5\u5165\u7684\u5907\u7528\u8bbf\u95ee\uff08\u4e0d\u5f97\u5305\u542b\u524d\u7f6e /\uff09\u3002\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n \u5ba2\u6237\u7aef\u4e0d\u80fd\u88c5\u5165\u5b50\u76ee\u5f55\uff08\u5373\u5982\u679c\u6807\u8bb0\u4e3a foo\uff0c\u5219\u5ba2\u6237\u7aef\u65e0\u6cd5\u88c5\u5165 foo/baz\uff09\u3002\n \n \n By using different Tag options, the same Path may be exported multiple times.\n \u901a\u8fc7\u4f7f\u7528\u4e0d\u540c\u6807\u8bb0\u9009\u9879\uff0c\u53ef\u5c06\u540c\u4e00\u8def\u5f84\u5bfc\u51fa\u591a\u6b21\u3002\n \n \n Pseudo\n \u4f2a\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n \u6b64 \n NFS v4\n \u5bfc\u51fa\u5728\n \u4f2a\u6587\u4ef6\u7cfb\u7edf\n \u4e2d\n \u6240\u5360\u7528\u7684\u4f4d\u7f6e\uff08\u5fc5\u987b\u552f\u4e00\uff09\u3002\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n \u901a\u8fc7\u4f7f\u7528\u4e0d\u540c\u4f2a\u9009\u9879\uff0c\u53ef\u5c06\u540c\u4e00\u8def\u5f84\u5bfc\u51fa\u591a\u6b21\u3002\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- \u6ca1\u6709\u53ef\u7528\u7684\u8bbf\u95ee\u7c7b\u578b --\n \n \n -- Select the access type --\n -- \u9009\u62e9\u8bbf\u95ee\u7c7b\u578b --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- \u6ca1\u6709\u53ef\u7528\u7684 squash --\n \n \n --Select what kind of user id squashing is performed --\n -- \u9009\u62e9\u6267\u884c\u54ea\u79cd\u7c7b\u578b\u7684\u7528\u6237 ID \u533f\u540d\u8bbf\u95ee --\n \n \n Transport Protocol\n \u4f20\u8f93\u534f\u8bae\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n \u6b22\u8fce\u4f7f\u7528 Ceph\uff01\n The welcome message on the login page\n \n \n Username is required\n \u8bf7\u8f93\u5165\u7528\u6237\u540d\n \n \n Password is required\n \u8bf7\u8f93\u5165\u5bc6\u7801\n \n \n Login\n \u767b\u5f55\n \n \n Sorry, the user does not exist in Ceph.\n \u62b1\u6b49\uff0c\u6b64\u7528\u6237\u4e0d\u5b58\u5728\u3002\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n \u8fd4\u56de\n \u767b\u5f55\u9875\n \u3002\u60a8\u5c06\u5728\u91cd\u65b0\u767b\u5f55\u65f6\u4ece\u8eab\u4efd\u63d0\u4f9b\u7a0b\u5e8f\u6ce8\u9500\u3002\n \n \n \n Forbidden\n \u7981\u6b62\u8bbf\u95ee\n \n \n Sorry, you are not allowed to see what you were looking for.\n \u62b1\u6b49\uff0c\u60a8\u65e0\u6743\u8bbf\u95ee\u8fd9\u4e2a\u9875\u9762\u3002\n \n \n Sorry, we could not find what you were looking for\n \u62b1\u6b49\uff0c\u6211\u4eec\u627e\u4e0d\u5230\u60a8\u8981\u770b\u7684\u4e1c\u897f\u3002\n \n \n Remove all\n \u5168\u90e8\u5df2\u8bfb\n \n \n Recent Notifications\n \u6700\u65b0\u7684\u901a\u77e5\n \n \n There are no background tasks.\n \u6ca1\u6709\u540e\u53f0\u4efb\u52a1\u6b63\u5728\u6267\u884c\u3002\n \n \n Background Tasks\n \u540e\u53f0\u4efb\u52a1\n \n \n Help\n \u5e2e\u52a9\n \n \n Documentation\n \u6587\u6863\n \n \n API\n API\n \n \n About\n \u5173\u4e8e\n \n \n Dashboard Settings\n \u4eea\u8868\u76d8\u8bbe\u7f6e\n \n \n User management\n \u7528\u6237\u7ba1\u7406\n \n \n Logged in user\n \u767b\u5f55\u7684\u7528\u6237\n \n \n Signed in as\n \n \n \n \n \u4ee5\u7528\u6237\u540d \n \n \n \n\u8fdb\u884c\u767b\u5f55\n \n \n \n Sign out\n \u767b\u51fa\n \n \n Name...\n \u540d\u79f0\u2026\n \n \n The chosen name is already in use.\n \u6240\u9009\u540d\u79f0\u5df2\u7ecf\u88ab\u4f7f\u7528\u3002\n \n \n Description...\n \u63cf\u8ff0\u2026\n \n \n Permissions\n \u6743\u9650\n \n \n Roles\n \u89d2\u8272\n \n \n Username\n \u7528\u6237\u540d\n \n \n Password\n \u5bc6\u7801\n \n \n Confirm password\n \u786e\u8ba4\u5bc6\u7801\n \n \n Password confirmation doesn\'t match the password.\n \u5bc6\u7801\u548c\u4e4b\u524d\u7684\u8f93\u5165\u4e0d\u5339\u914d\u3002\n \n \n Full name\n \u5168\u540d\n \n \n Email\n \u90ae\u7bb1\n \n \n Invalid email.\n \u90ae\u7bb1\u5730\u5740\u65e0\u6548\u3002\n \n \n You are about to remove "user read / update" permissions from your own user.\n \u60a8\u5373\u5c06\u53d6\u6d88\u60a8\u81ea\u5df1\u7528\u6237\u7684 "user read / update" \u6743\u9650\u3002\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n \u5982\u679c\u60a8\u7ee7\u7eed\u7684\u8bdd\uff0c\u60a8\u4ee5\u540e\u5c31\u6ca1\u529e\u6cd5\u4e3a\u5176\u4ed6\u7528\u6237\u6dfb\u52a0\u6216\u8005\u5220\u9664\u89d2\u8272\u4e86\u3002\n \n \n Are you sure you want to continue?\n \u60a8\u786e\u5b9e\u8981\u7ee7\u7eed\u5417\uff1f\n \n \n Performance counters not available\n \u65e0\u6cd5\u8bfb\u53d6\u6027\u80fd\u8ba1\u6570\u5668\n \n \n Attributes (OSD map)\n OSD map\n \n \n Metadata not available\n \u5143\u6570\u636e\u4e0d\u53ef\u7528\n \n \n Metadata\n \u76f8\u5173\u5143\u6570\u636e\n \n \n Performance counter\n \u6027\u80fd\u8ba1\u6570\u5668\n \n \n Histogram not available: \n \n \n \u76f4\u65b9\u56fe\u4e0d\u53ef\u7528\uff1a\n \n \n \n \n Writes\n \u5199\u5165\u8bf7\u6c42\n \n \n Reads\n \u8bfb\u53d6\u8bf7\u6c42\n \n \n Histogram\n \u76f4\u65b9\u56fe\n \n \n Performance Details\n \u6027\u80fd\u8be6\u60c5\n \n \n Current values\n \u5f53\u524d\u503c\n \n \n Type\n \u7c7b\u578b\n \n \n Min\n \u4e0b\u9650\n \n \n Max\n \u4e0a\u9650\n \n \n Flags\n \u6807\u5fd7\n \n \n Source\n \u6765\u6e90\n \n \n Level\n \u7ea7\u522b\n \n \n Can be updated at runtime (editable)\n \u53ef\u5728\u8fd0\u884c\u65f6\u66f4\u65b0\uff08\u53ef\u7f16\u8f91\uff09\n \n \n Tags\n \u6807\u8bb0\n \n \n Enum values\n \u53ef\u9009\u9879\n \n \n See also\n \u53c2\u89c1\n \n \n Cluster Status\n \u96c6\u7fa4\u72b6\u6001\n \n \n Manager Daemons\n manager \u5b88\u62a4\u8fdb\u7a0b\n \n \n Object Gateways\n \u5bf9\u8c61\u7f51\u5173\n \n \n Metadata Servers\n metadata \u670d\u52a1\u5668\n \n \n iSCSI Gateways\n iSCSI \u7f51\u5173\n \n \n Client IOPS\n \u5ba2\u6237\u7aef IOPS\n \n \n Client Throughput\n \u5ba2\u6237\u7aef\u541e\u5410\u91cf\n \n \n Client Read/Write\n \u5ba2\u6237\u7aef\u8bfb/\u5199\n \n \n Recovery Throughput\n \u6062\u590d\u541e\u5410\u91cf\n \n \n Scrub\n \u6d17\u5237\n \n \n Performance\n \u6027\u80fd\n \n \n Raw Capacity\n \u57fa\u672c\u5bb9\u91cf\n \n \n Objects\n \u5bf9\u8c61\u6570\n \n \n PGs per OSD\n \u6bcf\u4e2a OSD \u7684 PG \u6570\n \n \n PG Status\n PG \u72b6\u6001\n \n \n Capacity\n \u5bb9\u91cf\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n \u67e5\u770b\n \u65e5\u5fd7\n \u4ee5\u83b7\u5f97\u66f4\u591a\u7ec6\u8282\u3002\n \n \n \n Ranks\n \u6392\u4f4d\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n \u5ba2\u6237\u7aef\uff1a\n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n \u5c06\u6620\u50cf\u79fb\u81f3\u56de\u6536\u7ad9\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n \u8981\u5c06 \n \n /\n \n \u79fb\u81f3\u56de\u6536\u7ad9\uff0c\n \u8bf7\u70b9\u51fb \n \u79fb\u52a8\u6620\u50cf\n \u3002\u6b64\u5916\uff0c\u53ef\u9009\u62e9\u8bbe\u7f6e\u4e00\u4e2a\u8fc7\u671f\u65f6\u95f4\u3002\n \n \n \n Protection expires at\n \u4fdd\u62a4\u671f\u4e00\u76f4\u5230\n \n \n NOT PROTECTED\n \u65e0\u4fdd\u62a4\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n \u65e5\u671f\u683c\u5f0f\u6709\u95ee\u9898\u3002\u8bf7\u4f7f\u7528\u201cYYYY-MM-DD HH:mm:ss\u201d\u3002\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n \u4fdd\u62a4\u671f\u9650\u5df2\u7ecf\u8fc7\u4e86\u3002\u8bf7\u8bbe\u7f6e\u4e00\u4e2a\u5c06\u6765\u7684\u65e5\u671f\uff0c\u6216\u8005\u6e05\u7a7a\u4e0d\u586b\u3002\n \n \n Move Image\n \u79fb\u52a8\u6620\u50cf\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n \u6982\u89c8\n \n \n Targets\n \u76ee\u6807\n \n \n Discovery Authentication\n \u53d1\u73b0\u8eab\u4efd\u9a8c\u8bc1\n \n \n User\n \u7528\u6237\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \u7528\u6237\u540d\u957f\u5ea6\u5fc5\u987b\u5728 8 \u5230 64 \u4e2a\u5b57\u7b26\u4e4b\u95f4\uff0c\u4e14\u53ea\u80fd\u5305\u542b\n\u4ee5\u4e0b\u5b57\u7b26\uff1a\u82f1\u6587\u5b57\u6bcd\u3001\u201c.\u201d\u3001\u201c@\u201d\u3001\u201c-\u201d\u3001\u201c_\u201d\u6216\u201c:\u201d\u3002\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n \u4e92\u8ba4\u8bc1\u7528\u6237\n \n \n Mutual Password\n \u4e92\u8ba4\u8bc1\u5bc6\u7801\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n \u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u548c\u542f\u7528 iSCSI \u76ee\u6807\u7ba1\u7406\u529f\u80fd\uff0c\n\u8bf7\u53c2\u8003\n \u6587\u6863\n \u3002\n \n \n \n Available information:\n \u53ef\u7528\u4fe1\u606f\uff1a\n \n \n iSCSI Targets not available\n \u65e0\u53ef\u7528 iSCSI \u76ee\u6807\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n \u53ea\u5bf9\u542f\u52a8\u4e86 \n fast-diff\n \u529f\u80fd\u7684 RBD \u6620\u50cf\u53ef\u7528\n \n \n \n Pool\n \u5b58\u50a8\u6c60\n \n \n Data Pool\n \u6570\u636e\u5b58\u50a8\u6c60\n \n \n Created\n \u521b\u5efa\n \n \n Size\n \u5bb9\u91cf\n \n \n Object size\n \u5bf9\u8c61\u5927\u5c0f\n \n \n Features\n \u7279\u6027\n \n \n Provisioned\n \u4f9b\u7ed9\u5bb9\u91cf\n \n \n N/A\n N/A\n \n \n Total provisioned\n \u603b\u4f9b\u7ed9\u5bb9\u91cf\n \n \n Striping unit\n \u6761\u5e26\u5355\u5143\n \n \n Striping count\n \u6761\u5e26\u4e2a\u6570\n \n \n Parent\n \u7236\u8282\u70b9\n \n \n Block name prefix\n \u5757\u5b58\u50a8\u540d\u5b57\u524d\u7f00\n \n \n Order\n order\n \n \n Snapshots\n \u5feb\u7167\n \n \n Image\n \u6620\u50cf\n \n \n This setting overrides the global value\n \u6b64\u8bbe\u7f6e\u4f1a\u8986\u76d6\u5168\u5c40\u503c\n \n \n Global\n \u5168\u5c40\n \n \n This is the global value. No value for this option has been set for this image.\n \u8be5\u503c\u4e3a\u5168\u5c40\u503c\u3002\u6ca1\u6709\u4e3a\u6b64\u6620\u50cf\u8bbe\u7f6e\u6b64\u9009\u9879\u7684\u503c\u3002\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \u4e0d\u5141\u8bb8\u4f7f\u7528\u201c/\u201d\u548c\u201c@\u201d\u3002\n \n \n -- No rbd pools available --\n -- \u6ca1\u6709\u53ef\u7528\u7684 RBD \u5b58\u50a8\u6c60 --\n \n \n -- Select a pool --\n -- \u8bf7\u9009\u62e9\u5b58\u50a8\u6c60 --\n \n \n Use a dedicated data pool\n \u4f7f\u7528\u4e00\u4e2a\u4e13\u7528\u7684\u6570\u636e\u6c60\n \n \n Data pool\n \u6570\u636e\u6c60\n \n \n Dedicated pool that stores the object-data of the RBD.\n \u4e3a\u4fdd\u5b58 RBD \u7684\u5bf9\u8c61\u6570\u636e\u5355\u72ec\u5206\u914d\u7684\u5b58\u50a8\u6c60\u3002\n \n \n e.g., 10GiB\n \u5982 10 GiB\n \n \n You have to increase the size.\n \u60a8\u9700\u8981\u8bbe\u7f6e\u5927\u4e00\u4e9b\u7684\u5bb9\u91cf\u3002\n \n \n Advanced\n \u9ad8\u7ea7\u8bbe\u7f6e\n \n \n Striping\n \u6761\u5e26\n \n \n Stripe unit\n \u6761\u5e26\u5355\u5143\u5927\u5c0f\n \n \n -- Select stripe unit --\n -- \u9009\u62e9\u6761\u5e26\u5355\u5143\u5927\u5c0f --\n \n \n This field is required because stripe count is defined!\n \u56e0\u4e3a\u8bbe\u7f6e\u4e86\u6761\u5e26\u4e2a\u6570\uff0c\u6240\u4ee5\u8fd9\u4e2a\u5b57\u6bb5\u662f\u5fc5\u9009\u7684\uff01\n \n \n Stripe unit is greater than object size.\n \u6761\u5e26\u5355\u5143\u5927\u5c0f\u8d85\u8fc7\u4e86\u5bf9\u8c61\u5927\u5c0f\u3002\n \n \n Stripe count\n \u6761\u5e26\u4e2a\u6570\n \n \n This field is required because stripe unit is defined!\n \u56e0\u4e3a\u8bbe\u7f6e\u4e86\u6761\u5e26\u5355\u5143\u5927\u5c0f\uff0c\u6240\u4ee5\u8fd9\u4e2a\u5b57\u6bb5\u662f\u5fc5\u9009\u7684\uff01\n \n \n Stripe count must be greater than 0.\n \u6761\u5e26\u7684\u4e2a\u6570\u5fc5\u987b\u5927\u4e8e 0\u3002\n \n \n \n RBD Snapshot\n \n \n RBD \u5feb\u7167\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {\u6539\u540d} other {\u521b\u5efa} }\n \n \n \n Snapshot\n \n \n \u5feb\u7167\n \n \n \n PROTECTED\n \u53d7\u4fdd\u62a4\u7684\n \n \n UNPROTECTED\n \u65e0\u4fdd\u62a4\u7684\n \n \n You are about to rollback\n \u60a8\u5373\u5c06\u8fdb\u884c\u56de\u6eda\u64cd\u4f5c\n \n \n Purge Trash\n \u6e05\u7a7a\u56de\u6536\u7ad9\n \n \n To purge, select one or All images and click\n \u8981\u5f7b\u5e95\u6e05\u7a7a\u7684\u8bdd\uff0c\u8bf7\u9009\u62e9\u5355\u4e2a\u6216\u6240\u6709\u7684\u6620\u50cf\uff0c\u7136\u540e\u70b9\u51fb\n \n \n Pool:\n \u5b58\u50a8\u6c60\uff1a\n \n \n Pool name...\n \u5b58\u50a8\u6c60\u540d\u79f0\u2026\n \n \n All\n \u5168\u9009\n \n \n Restore Image\n \u6062\u590d\u6620\u50cf\n \n \n To restore\n \u8981\u6062\u590d\n \n \n type the image\'s new name and click\n \u8f93\u5165\u6620\u50cf\u7684\u65b0\u540d\u79f0\uff0c\u5e76\u70b9\u51fb\n \n \n New Name\n \u65b0\u540d\u79f0\n \n \n Expired at\n \u8fc7\u671f\u65f6\u95f4\n \n \n Protected until\n \u4fdd\u62a4\u671f\u9650\n \n \n This image is protected until \n .\n \n \u4e00\u76f4\u5230\n \uff0c\u8be5\u6620\u50cf\u90fd\u4f1a\u53d7\u4fdd\u62a4\u3002\n \n \n \n Trash\n \u56de\u6536\u7ad9\n \n \n iSCSI Topology\n iSCSI \u7ed3\u6784\u56fe\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n \u901a\u5e38\u65e0\u987b\u6539\u53d8\u8fd9\u4e9b\u9ed8\u8ba4\u53c2\u6570\u503c\u3002\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n \u8bbe\u7f6e\n \n \n Backstore\n \u540e\u5907\u5b58\u50a8\n \n \n Confirm\n \u786e\u8ba4\n \n \n Advanced Settings\n \u9ad8\u7ea7\u8bbe\u7f6e\n \n \n Target IQN\n \u76ee\u6807\u9650\u5b9a\u540d\n \n \n IQN has wrong pattern.\n IQN \u683c\u5f0f\u9519\u8bef\u3002\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n IQN \u5e94\u7531\u4ee5\u4e0b\u683c\u5f0f\u6784\u6210\uff1a\u201ciqn.$year-$month.$reversedAddress:$definedName\u201d\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \u4f8b\u5982\uff1aiqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n \u66f4\u591a\u4fe1\u606f\n \n \n This target has modified advanced settings.\n \u6b64\u76ee\u6807\u7684\u9ad8\u7ea7\u8bbe\u7f6e\u9879\u5b58\u5728\u4fee\u6539\u3002\n \n \n Portals\n \u7aef\u53e3\n \n \n At least \n gateways are required.\n \n \u81f3\u5c11\u9700\u8981 \n \u4e2a\u7f51\u5173\u3002\n \n \n \n Add portal\n \u6dfb\u52a0\u7aef\u53e3\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n \u6b64\u6620\u50cf\u7684\u8bbe\u7f6e\u9879\u5b58\u5728\u4fee\u6539\u3002\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n \u6dfb\u52a0\u6620\u50cf\n \n \n ACL authentication\n ACL \u8eab\u4efd\u9a8c\u8bc1\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n \u6388\u6743\u4eba\n \n \n Initiator\n \u6388\u6743\u4eba\n \n \n Client IQN\n \u5ba2\u6237\u7aef IQN\n \n \n Initiator IQN needs to be unique.\n \u6388\u6743\u4eba IQN \u5fc5\u987b\u552f\u4e00\u3002\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \u7528\u6237\u540d\u957f\u5ea6\u5fc5\u987b\u5728 8 \u5230 64 \u4e2a\u5b57\u7b26\u4e4b\u95f4\uff0c\u4e14\u53ea\u80fd\u5305\u542b\n\u4ee5\u4e0b\u5b57\u7b26\uff1a\u82f1\u6587\u5b57\u6bcd\u3001\u201c.\u201d\u3001\u201c@\u201d\u3001\u201c-\u201d\u3001\u201c_\u201d\u6216\u201c:\u201d\u3002\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n \u6388\u6743\u4eba\u5c5e\u4e8e\u7fa4\u7ec4\u3002\u6620\u50cf\u987b\u5728\u7fa4\u7ec4\u4e2d\u8fdb\u884c\u8bbe\u7f6e\u3002\n \n \n No items added.\n \u65e0\u9879\u76ee\u6dfb\u52a0\u3002\n \n \n Add initiator\n \u6dfb\u52a0\u6388\u6743\u4eba\n \n \n Groups\n \u7fa4\u7ec4\n \n \n Group\n \u7fa4\u7ec4\n \n \n Add group\n \u6dfb\u52a0\u7fa4\u7ec4\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n RBD \u914d\u7f6e\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n \u5220\u9664\u672c\u5730\u7684\u914d\u7f6e\u9879\uff0c\u6539\u7528\u66f4\u9ad8\u4f5c\u7528\u57df\u7684\u914d\u7f6e\u503c\u3002\n \n \n The mininum value is 0\n \u6700\u5c0f\u503c\u4e3a 0\n \n \n Issues\n \u95ee\u9898\n \n \n Syncing\n \u6b63\u5728\u540c\u6b65\n \n \n Ready\n \u5df2\u5c31\u7eea\n \n \n Edit pool mirror mode\n \u7f16\u8f91\u5b58\u50a8\u6c60\u955c\u50cf\u6a21\u5f0f\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n \u8981\u7f16\u8f91\u5b58\u50a8\u6c60\n \n \n \xa0\n \u7684\u955c\u50cf\u6a21\u5f0f\uff0c\u8bf7\u4ece\u5217\u8868\u4e2d\u9009\u62e9\u4e00\u9879\uff0c\u5e76\u70b9\u51fb\xa0\n \u66f4\u65b0\n \u3002\n \n \n \n Mode\n \u6a21\u5f0f\n \n \n Peer clusters must be removed prior to disabling mirror.\n \u5728\u7981\u7528\u955c\u50cf\u529f\u80fd\u524d\u5fc5\u987b\u5148\u79fb\u9664\u540c\u4f34\u96c6\u7fa4\u3002\n \n \n \n \n pool mirror peer\n \n \n \n\u5b58\u50a8\u6c60\u955c\u50cf\u540c\u4f34\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {\u7f16\u8f91} other {\u6dfb\u52a0} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n \u5b58\u50a8\u6c60\n \n \n \n \u7684\u5b58\u50a8\u6c60\u955c\u50cf\u540c\u4f34\u5c5e\u6027\uff0c\u5e76\u70b9\u51fb\n \u63d0\u4ea4\n \u3002\n \n \n \n Cluster Name\n \u96c6\u7fa4\u540d\u79f0\n \n \n The cluster name is not valid.\n \u96c6\u7fa4\u540d\u79f0\u65e0\u6548\u3002\n \n \n CephX ID\n CephX ID\n \n \n CephX ID...\n CephX ID...\n \n \n The CephX ID is not valid.\n CephX ID \u65e0\u6548\u3002\n \n \n Monitor Addresses\n Monitor \u5730\u5740\n \n \n Comma-delimited addresses...\n \u9017\u53f7\u5206\u5272\u7684\u5730\u5740...\n \n \n The monitory address is not valid.\n Monitor \u5730\u5740\u65e0\u6548\u3002\n \n \n CephX Key\n CephX \u5bc6\u94a5\n \n \n Base64-encoded key...\n Base64 \u7f16\u7801\u7684\u5bc6\u94a5...\n \n \n CephX key must be base64 encoded.\n CephX \u5bc6\u94a5\u5fc5\u987b\u662f base64 \u7f16\u7801\u7684\u3002\n \n \n Pools List\n \u5b58\u50a8\u6c60\u5217\u8868\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n \u540d\u79f0\u53ea\u80fd\u7531\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u77ed\u5212\u7ebf\u548c\u4e0b\u5212\u7ebf\u7ec4\u6210\u3002\n \n \n The chosen erasure code profile name is already in use.\n \u6b64\u7ea0\u5220\u7801\u914d\u7f6e\u540d\u79f0\u5df2\u88ab\u4f7f\u7528\u3002\n \n \n Plugin\n \u7ea0\u5220\u7801\u7b97\u6cd5\n \n \n Data chunks (k)\n \u6570\u636e\u5757 (k)\n \n \n Must be equal to or greater than 2.\n \u5fc5\u987b\u5927\u4e8e\u7b49\u4e8e 2\n \n \n Coding chunks (m)\n \u6821\u9a8c\u5757 (m)\n \n \n Must be equal to or greater than 1.\n \u5fc5\u987b\u5927\u4e8e\u7b49\u4e8e 1\n \n \n Durability estimator (c)\n \u6301\u4e45\u56e0\u5b50 (c)\n \n \n Locality (l)\n \u5c40\u90e8\u6027\u56e0\u5b50 (l)\n \n \n Crush failure domain\n CRUSH \u6545\u969c\u57df\n \n \n Crush Locality\n CRUSH \u5c40\u90e8\u6027\n \n \n None\n \u65e0\n \n \n Technique\n \u7b97\u6cd5\n \n \n Packetsize\n packetsize\n \n \n Crush root\n CRUSH \u6839\n \n \n Crush device class\n CRUSH \u8bbe\u5907\u7c7b\u578b\n \n \n any\n \u4efb\u610f\n \n \n Directory\n \u76ee\u5f55\n \n \n The chosen Ceph pool name is already in use.\n \u6b64 Ceph \u5b58\u50a8\u6c60\u540d\u79f0\u5df2\u88ab\u4f7f\u7528\u3002\n \n \n Pool type\n \u5b58\u50a8\u6c60\u7c7b\u578b\n \n \n -- Select a pool type --\n -- \u8bf7\u9009\u62e9\u5b58\u50a8\u6c60\u7684\u7c7b\u578b --\n \n \n Placement groups\n \u5f52\u7f6e\u7ec4 (PG)\n \n \n At least one placement group is needed!\n \u81f3\u5c11\u9700\u8981\u4e00\u4e2a\u5f52\u7f6e\u7ec4\uff01\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n \u60a8\u7684\u96c6\u7fa4\u6ca1\u6cd5\u652f\u6301\u8fd9\u4e48\u591a\u7684 PG\u3002\u8bf7\u91cd\u65b0\u8ba1\u7b97\u9700\u8981\u7684 PG \u4e2a\u6570\u3002\n \n \n Calculation help\n \u5728\u7ebf PG \u8ba1\u7b97\u5668\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n \u5df2\u6839\u636e\u5f53\u524d\u60c5\u51b5\u4e3a\u60a8\u63a8\u7b97\u51fa\u4e86 PG \u7684\u8bbe\u7f6e\uff0c\u60a8\n\u6700\u597d\u5728\u63d0\u4ea4\u4e4b\u524d\u786e\u8ba4\u8fd9\u4e9b\u8bbe\u7f6e\u662f\u5408\u9002\u7684\u3002\n \n \n Crush ruleset\n CRUSH \u7b97\u6cd5\u89c4\u5219\u7ec4\n \n \n -- Select a crush rule --\n -- \u9009\u62e9 CRUSH \u89c4\u5219 --\n \n \n Crush rule\n CRUSH \u89c4\u5219\n \n \n Crush steps\n CRUSH \u6b65\u9aa4\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n \u5f53\u524d\u7684\u96c6\u7fa4\u65e0\u6cd5\u4f7f\u7528\u8be5\u89c4\u5219\uff0c\u56e0\u4e3a\u96c6\u7fa4\u7684 OSD \u4e2a\u6570\u8fc7\u5c11\uff0c\n \u65e0\u6cd5\u6ee1\u8db3\u89c4\u5219\u6240\u9700\u7684\u6700\u4f4e OSD \u6570\u91cf\u3002\n \n \n Replicated size\n \u526f\u672c\u4e2a\u6570\n \n \n Minimum: \n \n \n \u6700\u4f4e\uff1a\n \n \n \n \n Maximum: \n \n \n \u6700\u9ad8\uff1a\n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n \u8bbe\u7f6e\u7684\u8d85\u8fc7\u4e86\u9650\u5236\u3002\u8bbe\u7f6e\u503c\u5e94\u8be5\u5728\n \u548c \n \u4e2d\u95f4\u4e3a\u5b9c.\n \n \n \n Erasure code profile\n \u7ea0\u5220\u7801\u914d\u7f6e\n \n \n -- No erasure code profile available --\n -- \u65e0\u7ea0\u5220\u7801\u914d\u7f6e\u53ef\u9009 --\n \n \n -- Select an erasure code profile --\n -- \u8bf7\u9009\u62e9\u4e00\u4e2a\u7ea0\u5220\u7801\u914d\u7f6e --\n \n \n EC Overwrites\n EC \u91cd\u5199 (overwrite)\n \n \n Applications\n \u5e94\u7528\u7c7b\u578b\n \n \n Compression\n \u538b\u7f29\n \n \n Algorithm\n \u7b97\u6cd5\n \n \n -- No erasure compression algorithm available --\n -- \u65e0\u53ef\u7528\u7684\u7ea0\u5220\u7801\u538b\u7f29\u7b97\u6cd5 --\n \n \n Minimum blob size\n blob \u5927\u5c0f\u4e0b\u9650\n \n \n e.g., 128KiB\n \u6bd4\u5982 128 KiB\n \n \n Value should be greater than 0\n \u53d6\u503c\u5fc5\u987b\u5927\u4e8e 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n blob \u5927\u5c0f\u4e0a\u9650\n \n \n e.g., 512KiB\n \u5982 512KiB\n \n \n Value should be greater than the minimum blob size\n \u53d6\u503c\u5fc5\u987b\u5927\u4e8e blob \u5927\u5c0f\u4e0b\u9650\n \n \n Ratio\n \u6bd4\u4f8b\n \n \n Compression ratio\n \u538b\u7f29\u7387\n \n \n Value should be between 0.0 and 1.0\n \u53d6\u503c\u5fc5\u987b\u5728 0.0 \u548c 1.0 \u4e4b\u95f4\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n \u65e0\u6cd5\u65b0\u5efa\u540d\u5b57\u4e2d\u6709\u201c/\u201d\u7684 RBD \u5b58\u50a8\u6c60\u3002\n \n \n Please change the name or remove \'rbd\' from the applications list.\n \u8bf7\u91cd\u65b0\u547d\u540d\uff0c\u6216\u8005\u628a\u5b58\u50a8\u6c60\u7684\u201crbd\u201d\u5e94\u7528\u6807\u8bb0\u53bb\u6389\u3002\n \n \n Cache Tiers Details\n \u7f13\u5b58\u5c42\u8be6\u7ec6\u4fe1\u606f\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n \u5173\u4e8e\u5982\u4f55\u914d\u7f6e\u548c\u542f\u7528\u5bf9\u8c61\u7f51\u5173\u7684\u529f\u80fd\uff0c\n \u8bf7\u53c2\u8003\n \u6587\u6863\n \u3002\n \n \n \n Daemons List\n \u5b88\u62a4\u8fdb\u7a0b\u5217\u8868\n \n \n Performance Counters\n \u6027\u80fd\u8ba1\u6570\u5668\n \n \n Loading bucket data...\n \u6b63\u5728\u52a0\u8f7d\u5b58\u50a8\u6876\u6570\u636e\u2026\n \n \n The bucket data could not be loaded.\n \u5b58\u50a8\u6876\u6570\u636e\u65e0\u6cd5\u52a0\u8f7d\u3002\n \n \n Id\n ID\n \n \n The value is not valid.\n \u8f93\u5165\u503c\u65e0\u6548\u3002\n \n \n Owner\n \u6240\u6709\u8005\n \n \n -- Select a user --\n -- \u8bf7\u9009\u62e9\u4e00\u4e2a\u7528\u6237 --\n \n \n ID\n ID\n \n \n Index type\n \u7d22\u5f15\u7c7b\u578b\n \n \n Placement rule\n \u5f52\u7f6e\u89c4\u5219\n \n \n Marker\n \u6807\u8bc6\n \n \n Maximum marker\n max marker\n \n \n Version\n \u7248\u672c\n \n \n Master version\n \u4e3b\u7248\u672c\n \n \n Modification time\n \u4fee\u6539\u65f6\u95f4\n \n \n Zonegroup\n zonegroup\n \n \n Bucket quota\n \u5b58\u50a8\u6876\u914d\u989d\n \n \n Enabled\n \u5f00\u542f\n \n \n Maximum size\n \u6700\u5927\u6570\u76ee\n \n \n Unlimited\n \u65e0\u9650\u5236\n \n \n Maximum objects\n \u6700\u5927\u5bf9\u8c61\u6570\u76ee\n \n \n -- Select a username --\n -- \u8bf7\u9009\u62e9\u7528\u6237\u540d --\n \n \n Auto-generate key\n \u81ea\u52a8\u751f\u6210\u5bc6\u94a5\n \n \n Access key\n \u8bbf\u95ee\u5bc6\u94a5\n \n \n Secret key\n \u79d8\u5bc6\u5bc6\u94a5\n \n \n Email address\n \u90ae\u7bb1\n \n \n Suspended\n \u51bb\u7ed3\n \n \n System\n \u7cfb\u7edf\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {\u5426} 1 {\u662f} }\n \n \n Maximum buckets\n \u6700\u5927\u5b58\u50a8\u6876\u6570\u76ee\n \n \n Subusers\n \u5b50\u7528\u6237\n \n \n Capabilities\n \u7528\u6237\u6743\u9650\n \n \n User quota\n \u7528\u6237\u914d\u989d\n \n \n Show\n \u663e\u793a\n \n \n Keys\n \u5bc6\u94a5\n \n \n -- Select a type --\n -- \u8bf7\u9009\u62e9\u4e00\u4e2a\u7c7b\u578b --\n \n \n Permission\n \u6743\u9650\n \n \n -- Select a permission --\n -- \u8bf7\u9009\u62e9\u6743\u9650\u7c7b\u578b --\n \n \n Subuser\n \u5b50\u7528\u6237\n \n \n The chosen subuser ID is already in use.\n \u6240\u9009\u7684\u5b50\u7528\u6237 ID \u5df2\u88ab\u4f7f\u7528\u3002\n \n \n read, write\n \u8bfb\u3001\u5199\n \n \n full\n \u5168\u90e8\n \n \n Swift key\n Swift \u5bc6\u94a5\n \n \n Auto-generate secret\n \u81ea\u52a8\u751f\u6210\u5bc6\u94a5\n \n \n Loading user data...\n \u6b63\u5728\u52a0\u8f7d\u7528\u6237\u6570\u636e\u2026\n \n \n The user data could not be loaded.\n \u7528\u6237\u6570\u636e\u65e0\u6cd5\u52a0\u8f7d\u3002 \n \n \n The chosen user ID is already in use.\n \u6240\u9009\u7684\u7528\u6237 ID \u5df2\u88ab\u4f7f\u7528\u3002\n \n \n This is not a valid email address.\n \u65e0\u6548\u7684\u90ae\u7bb1\u5730\u5740\u3002\n \n \n The chosen email address is already in use.\n \u6b64\u90ae\u7bb1\u5730\u5740\u5df2\u88ab\u4f7f\u7528\u3002\n \n \n Max. buckets\n \u5b58\u50a8\u6876\u4e2a\u6570\u7684\u4e0a\u9650\n \n \n The entered value must be >= 0.\n \u8bbe\u7f6e\u7684\u503c\u5fc5\u987b >= 0\u3002\n \n \n S3 key\n S3 \u5bc6\u94a5\n \n \n There are no subusers.\n \u6ca1\u6709\u5b50\u7528\u6237\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n \u6ca1\u6709\u4efb\u4f55\u5bc6\u94a5\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n \u6743\u9650\u4e3a\u7a7a\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n \u7a7a\u95f4\u65e0\u9650\u5236\n \n \n Max. size\n \u7a7a\u95f4\u4e0a\u9650\n \n \n Unlimited objects\n \u5bf9\u8c61\u4e2a\u6570\u65e0\u9650\u5236\n \n \n Max. objects\n \u5bf9\u8c61\u4e2a\u6570\u4e0a\u9650\n \n \n Current\n \u5f53\u524d\n \n \n Updated discovery authentication\n \u5df2\u66f4\u65b0\u53d1\u73b0\u8eab\u4efd\u9a8c\u8bc1\n \n \n There are no portals available.\n \u65e0\u53ef\u7528\u7aef\u53e3\u3002\n \n \n There are no images available.\n \u65e0\u53ef\u7528\u6620\u50cf\u3002\n \n \n There are no images available. Please make sure you add an image to the target.\n \u65e0\u53ef\u7528\u6620\u50cf\u3002\u8bf7\u786e\u4fdd\u4e3a\u76ee\u6807\u6dfb\u52a0\u4e00\u4e2a\u6620\u50cf\u3002\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n \u65e0\u53ef\u7528\u6388\u6743\u4eba\u3002\u8bf7\u786e\u4fdd\u4e3a\u76ee\u6807\u6dfb\u52a0\u4e00\u4e2a\u6388\u6743\u4eba\u3002\n \n \n target\n target\n \n \n Target\n \u76ee\u6807\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n \u72b6\u6001\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n \u8bfb\u5b57\u8282\u6570\n \n \n Write Bytes\n \u5199\u5b57\u8282\u6570\n \n \n Read Ops\n \u8bfb\u8bf7\u6c42\u6570\n \n \n Write Ops\n \u5199\u8bf7\u6c42\u6570\n \n \n A/O Since\n \u6d3b\u52a8/\u4f18\u5316\u81ea\n \n \n Instance\n \u5b9e\u4f8b\n \n \n Hostname\n \u4e3b\u673a\u540d\n \n \n Issue\n \u95ee\u9898\n \n \n Progress\n \u8fdb\u5ea6\n \n \n Disabled\n \u7981\u7528\n \n \n Edit Mode\n \u7f16\u8f91\u6a21\u5f0f\n \n \n Add Peer\n \u6dfb\u52a0 peer\n \n \n Edit Peer\n \u7f16\u8f91 peer\n \n \n Delete Peer\n \u5220\u9664 peer\n \n \n Leader\n Leader\n \n \n # Local\n # \u672c\u5730\n \n \n # Remote\n # \u8fdc\u7a0b\n \n \n mirror peer\n \u955c\u50cf peer\n \n \n Key\n \u5bc6\u94a5\n \n \n RBD\n RBD\n \n \n Deep flatten\n \u5b8c\u5168\u5c55\u5f00\n \n \n Layering\n \u5206\u5c42\n \n \n Exclusive lock\n \u4e92\u65a5\u9501\n \n \n Object map (requires exclusive-lock)\n object map\uff08\u8981\u6c42\u4e92\u65a5\u9501\u652f\u6301\uff09\n \n \n Journaling (requires exclusive-lock)\n \u65e5\u5fd7\uff08\u8981\u6c42\u4e92\u65a5\u9501\u652f\u6301\uff09\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n RBD \u5feb\u7167\u56de\u6eda\n \n \n Rollback\n \u56de\u6eda\n \n \n RBD snapshot\n RBD \u5feb\u7167\n \n \n Deleted At\n \u5b9a\u70b9\u5220\u9664\n \n \n id\n ID\n \n \n type\n \u7c7b\u578b\n \n \n state\n \u72b6\u6001\n \n \n version\n \u7248\u672c\n \n \n Host\n \u4e3b\u673a\n \n \n root\n \u6839\n \n \n Rank\n \u6392\u4f4d\n \n \n Daemon\n \u5b88\u62a4\u8fdb\u7a0b\n \n \n Activity\n \u6d3b\u8dc3\u5ea6\n \n \n Dentries\n dentries\n \n \n Inodes\n inodes\n \n \n Usage\n \u4f7f\u7528\u7387\n \n \n Standby daemons\n \u5907\u7528\u670d\u52a1\n \n \n The value can be updated at runtime.\n \u8be5\u503c\u53ef\u5728\u8fd0\u884c\u65f6\u66f4\u65b0\u3002\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n \u670d\u52a1\u5668\u6216\u5ba2\u6237\u7aef\u4e0d\u4f1a\u4e3b\u52a8\u4ece monitor \u7684\u914d\u7f6e\u6570\u636e\u5e93\u8bfb\u53d6\u8fd9\u4e2a\u914d\u7f6e\u3002\n \u6240\u4ee5\u4e0d\u80fd\u7528\u201cceph config set ...\u201d\u8bbe\u7f6e\u5b83\u3002\u4f46\u662f\u53ef\u4ee5\u901a\u8fc7\n ceph.conf \u6216\u8005\u7528\u547d\u4ee4\u884c\u8fdb\u884c\u914d\u7f6e\u3002\n \n \n Option takes effect only during daemon startup.\n \u8be5\u914d\u7f6e\u53ea\u6709\u5728\u670d\u52a1\u542f\u52a8\u7684\u65f6\u5019\u624d\u4f1a\u751f\u6548\u3002\n \n \n Option only affects cluster creation.\n \u8be5\u914d\u7f6e\u53ea\u5728\u521b\u5efa\u96c6\u7fa4\u7684\u65f6\u5019\u624d\u4f1a\u751f\u6548\u3002\n \n \n Option only affects daemon creation.\n \u8be5\u914d\u7f6e\u53ea\u5728\u670d\u52a1\u521b\u5efa\u7684\u65f6\u5019\u624d\u4f1a\u751f\u6548\u3002\n \n \n Updated config option \n \n \n \u5df2\u66f4\u65b0\u914d\u7f6e\u9009\u9879\n \n \n \n \n Service\n \u670d\u52a1\n \n \n Current value\n \u5f53\u524d\u503c\n \n \n Editable\n \u53ef\u7f16\u8f91\n \n \n Updated options for module "\n ".\n \n \u5df2\u66f4\u65b0\u6269\u5c55\u6a21\u5757\u201c\n \u201d\u7684\u9009\u9879\u3002\n \n \n \n Enable\n \u542f\u7528\n \n \n Disable\n \u7981\u7528\n \n \n Reconnecting, please wait ...\n \u6b63\u5728\u91cd\u65b0\u8fde\u63a5\uff0c\u8bf7\u7a0d\u5019\u2026\n \n \n Public Address\n \u5916\u90e8\u5730\u5740\n \n \n Open Sessions\n \u6d3b\u52a8\u4f1a\u8bdd\n \n \n No In\n \u7981\u6b62\u52a0\u5165\n \n \n OSDs that were previously marked out will not be marked back in when they start\n \u4e4b\u524d\u88ab\u9664\u540d\u7684 OSD \u5728\u542f\u52a8\u4e4b\u540e\uff0c\u4e0d\u4f1a\u88ab\u52a0\u5165\u96c6\u7fa4\n \n \n No Out\n \u7981\u6b62\u9664\u540d\n \n \n OSDs will not automatically be marked out after the configured interval\n \u5728\u53d1\u73b0 OSD \u6ca1\u6709\u54cd\u5e94\u4e4b\u540e\u4e00\u6bb5\u65f6\u95f4\uff0c\u8be5 OSD \u4f1a\u88ab\u8e22\u51fa\u96c6\u7fa4\u3002\u8be5\u6807\u5fd7\u4f1a\u7981\u6b62\u8fd9\u4e2a\u529f\u80fd\u3002\n \n \n No Up\n \u7981\u6b62\u542f\u7528\n \n \n OSDs are not allowed to start\n \u4e0d\u5141\u8bb8 OSD \u542f\u52a8\n \n \n No Down\n \u7981\u6b62\u505c\u7528\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n \u5f53\u524d\u4e0d\u53d7\u7406\u5bf9 OSD \u7684\u5931\u6548\u62a5\u544a\uff0c\u56e0\u800c monitor \u4e0d\u4f1a\u505c\u7528 OSD\n \n \n Pause\n \u6682\u505c\n \n \n Pauses reads and writes\n \u6682\u505c\u8bfb\u5199\n \n \n No Scrub\n \u7981\u6b62\u6d17\u5237\n \n \n Scrubbing is disabled\n \u6d17\u5237\u5df2\u7981\u6b62\n \n \n No Deep Scrub\n \u7981\u6b62\u6df1\u5c42\u6d17\u5237\n \n \n Deep Scrubbing is disabled\n \u6df1\u5c42\u6d17\u5237\u5df2\u7981\u6b62\n \n \n No Backfill\n \u7981\u6b62\u56de\u586b\n \n \n Backfilling of PGs is suspended\n PG \u56de\u586b\u5df2\u63a8\u8fdf\n \n \n No Recover\n \u7981\u6b62\u6062\u590d\n \n \n Recovery of PGs is suspended\n PG \u6062\u590d\u5df2\u63a8\u8fdf\n \n \n Bitwise Sort\n \u9010\u4f4d\u6392\u5e8f\n \n \n Use bitwise sort\n \u4f7f\u7528\u9010\u4f4d\u6392\u5e8f\n \n \n Purged Snapdirs\n \u8001\u7248\u672c\u7684\u5feb\u7167\u5df2\u5168\u90e8\u5347\u7ea7\n \n \n OSDs have converted snapsets\n OSD \u4e0a\u7684\u5feb\u7167\u5df2\u5168\u90e8\u8f6c\u6362\u5b8c\u6bd5\n \n \n Recovery Deletes\n \u5728\u6062\u590d\u65f6\u8fdb\u884c\u5220\u9664\u64cd\u4f5c\n \n \n Deletes performed during recovery instead of peering\n \u5728\u6062\u590d\u65f6\uff0c\u800c\u975e\u5bf9\u9f50\u9636\u6bb5\u8fdb\u884c\u5220\u9664\n \n \n PG Log Hard Limit\n PG \u65e5\u5fd7\u786c\u9650\u5236\n \n \n Puts a hard limit on pg log length\n \u4e3a pg \u65e5\u5fd7\u957f\u5ea6\u6dfb\u52a0\u786c\u9650\u5236\n \n \n Updated OSD Flags\n \u5df2\u66f4\u65b0 OSD \u6807\u5fd7\n \n \n out\n \u9664\u540d\n \n \n in\n \u52a0\u5165\n \n \n down\n \u505c\u7528\n \n \n Mark\n \u6807\u8bb0\n \n \n OSD lost\n OSD \u4e22\u5931\n \n \n marked lost\n \u5df2\u6807\u8bb0\u4e22\u5931\n \n \n Purge\n \u6e05\u9664\n \n \n OSD\n OSD\n \n \n purged\n \u5df2\u6e05\u9664\n \n \n destroy\n \u9500\u6bc1\n \n \n destroyed\n \u5df2\u9500\u6bc1\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n PG\n \n \n Read bytes\n \u8bfb\u5b57\u8282\u6570\n \n \n Writes bytes\n \u5199\u5b57\u8282\u6570\n \n \n Read ops\n \u8bfb\u8bf7\u6c42\u6570\n \n \n Write ops\n \u5199\u8bf7\u6c42\u6570\n \n \n Mark OSD \n \n \n \u6807\u8bb0 OSD \u4e3a\n \n \n \n \n Mark \n \n \n \u6807\u8bb0\u4e3a\n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n \u6700\u5927\u56de\u586b\u91cf\n \n \n Recovery Max Active\n \u6700\u5927\u6d3b\u8dc3\u6062\u590d\u8bf7\u6c42\u6570\n \n \n Recovery Max Single Start\n \u6700\u5927\u5355\u6b21\u6062\u590d\u64cd\u4f5c\u6570\n \n \n Recovery Sleep\n \u6062\u590d/\u56de\u586b\u64cd\u4f5c\u95f4\u9694\u7761\u7720\u65f6\u95f4\n \n \n Custom\n \u81ea\u5b9a\u4e49\n \n \n Updated OSD recovery speed priority "\n "\n \n \u5df2\u66f4\u65b0 OSD \u6062\u590d\u901f\u5ea6\u4f18\u5148\u7ea7\u201c\n \u201d\n \n \n \n \n was initialized in the following OSD: \n \n \n \u5982\u4e0b OSD \u5df2\u7ecf\u542f\u52a8\u4e86\n \u64cd\u4f5c\uff1a\n \n \n \n \n Create silence\n Create silence\n \n \n Job\n \u4efb\u52a1\n \n \n Severity\n \u4e25\u91cd\u7a0b\u5ea6\n \n \n Started\n \u5df2\u542f\u52a8\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n \u66f4\u65b0\u5b8c\u6210\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n \u5df2\u4f7f\u7528\n \n \n Avail.\n \u7a7a\u95f2\n \n \n Clean\n \u6b63\u5e38\n \n \n Working\n \u8fd0\u884c\u4e2d\n \n \n Warning\n \u8b66\u62a5\n \n \n Unknown\n \u672a\u77e5\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n \u542f\u7528\u4e2d\n \n \n no filesystems\n \u65e0\u6587\u4ef6\u7cfb\u7edf\n \n \n active\n \u5de5\u4f5c\n \n \n standby\n \u5f85\u673a\n \n \n n/a\n n/a\n \n \n active daemon\n \u5de5\u4f5c\u7684\u5b88\u62a4\u8fdb\u7a0b\n \n \n quorum\n quorum\n \n \n The NFS Ganesha service is not configured.\n NFS Ganesha \u670d\u52a1\u7684\u914d\u7f6e\u8fd8\u6ca1\u6709\u5b8c\u6210\u3002\n \n \n Transport\n \u4f20\u8f93\n \n \n CephFS User\n CephFS \u7528\u6237\n \n \n CephFS Filesystem\n CephFS \u6587\u4ef6\u7cfb\u7edf\n \n \n (inherited from global config)\n \uff08\u7ee7\u627f\u81ea\u5168\u5c40\u914d\u7f6e\uff09\n \n \n inherited from global config\n \u7ee7\u627f\u81ea\u5168\u5c40\u914d\u7f6e\n \n \n -- Select what kind of user id squashing is performed --\n -- \u9009\u62e9\u6267\u884c\u54ea\u79cd\u7c7b\u578b\u7684\u7528\u6237 ID \u533f\u540d\u8bbf\u95ee --\n \n \n There are no daemons available.\n \u6ca1\u6709\u53ef\u7528\u7684\u5b88\u62a4\u8fdb\u7a0b\u3002\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n \u7f13\u5b58\u6a21\u5f0f\n \n \n Min Evict Age\n \u6700\u5c11\u5ef6\u8fdf\u8d76\u51fa\u65f6\u95f4\n \n \n Min Flush Age\n \u6700\u5c11\u5ef6\u8fdf\u5237\u56de\u65f6\u95f4\n \n \n Target Max Bytes\n \u76ee\u6807\u5668\u6700\u5927\u5b57\u8282\u6570\n \n \n Target Max Objects\n \u76ee\u6807\u5668\u6700\u5927\u5bf9\u8c61\u6570\n \n \n No applications added\n \u8fd8\u6ca1\u6709\u4efb\u4f55\u5e94\u7528\u6807\u8bb0\n \n \n Applications limit reached\n \u5e94\u7528\u6807\u8bb0\u5230\u4e86\u4e0a\u9650\n \n \n A pool can only have up to four applications definitions.\n \u4e00\u4e2a\u5b58\u50a8\u6c60\u6700\u591a\u80fd\u6709\u56db\u4e2a\u5e94\u7528\u6807\u8bb0\u3002\n \n \n Allowed characters \'_a-zA-Z0-9\'\n \u53ef\u7528\u7684\u5b57\u7b26\u4e3a\u201c_a-zA-Z0-9\u201d\n \n \n Maximum length is 128 characters\n \u957f\u5ea6\u9650\u5236\u4e3a 128 \u4e2a\u5b57\u7b26\n \n \n Filter or add applications\n \u6dfb\u52a0\u5e94\u7528\u6807\u8bb0\u6216\u6839\u636e\u5176\u8fdb\u884c\u7b5b\u9009\n \n \n Add application\n \u6dfb\u52a0\u5e94\u7528\u6807\u8bb0\n \n \n pool\n pool\n \n \n erasure code profile\n \u7ea0\u5220\u7801\u914d\u7f6e\n \n \n Replica Size\n \u526f\u672c\u4e2a\u6570\n \n \n Last Change\n \u6700\u540e\u4fee\u6539\u65f6\u95f4\n \n \n Erasure Coded Profile\n \u7ea0\u5220\u7801\u914d\u7f6e\n \n \n Crush Ruleset\n CRUSH \u89c4\u5219\u96c6\n \n \n Write bytes\n \u5199\u5b57\u8282\u6570\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n \u5b58\u50a8\u6876\n \n \n Updated Object Gateway bucket "\n "\n \n \u5df2\u66f4\u65b0\u5bf9\u8c61\u7f51\u5173\u5b58\u50a8\u6876\u201c\n \u201d\n \n \n \n Created Object Gateway bucket "\n "\n \n \u5df2\u521b\u5efa\u5bf9\u8c61\u7f51\u5173\u5b58\u50a8\u6876\u201c\n \u201d\n \n \n \n buckets\n \u5b58\u50a8\u6876\n \n \n capability\n capability\n \n \n user\n \u7528\u6237\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n \u5df2\u66f4\u65b0\u5bf9\u8c61\u7f51\u5173\u7528\u6237\u201c\n \u201d\n \n \n \n Created Object Gateway user "\n "\n \n \u5df2\u521b\u5efa\u5bf9\u8c61\u7f51\u5173\u7528\u6237\u201c\n \u201d\n \n \n \n users\n \u7528\u6237\n \n \n Swift Key\n Swift Key\n \n \n Scope\n \u4f5c\u7528\u8303\u56f4\n \n \n Read\n \u8bfb\u6743\u9650\n \n \n Create\n \u65b0\u5efa\n \n \n role\n role\n \n \n Created role \'\n \'\n \n \u65b0\u5efa\u89d2\u8272\u201c\n \u201d\n \n \n \n Updated role \'\n \'\n \n \u66f4\u65b0\u89d2\u8272\u201c\n \u201d\n \n \n \n System Role\n \u7cfb\u7edf\u89d2\u8272\n \n \n Deleted role \'\n \'\n \n \u5df2\u5220\u9664\u89d2\u8272\u201c\n \u201d\n \n \n \n Created user "\n "\n \n \u5df2\u65b0\u5efa\u7528\u6237\u201c\n \u201d\n \n \n \n Update user\n \u66f4\u65b0\u7528\u6237\n \n \n Continue\n \u7ee7\u7eed\n \n \n You were automatically logged out because your roles have been changed.\n \u60a8\u88ab\u81ea\u52a8\u767b\u51fa\uff0c\u56e0\u4e3a\u60a8\u7684\u89d2\u8272\u6709\u4e86\u53d8\u52a8\u3002\n \n \n Updated user "\n "\n \n \u5df2\u66f4\u65b0\u7528\u6237\u201c\n \u201d\n \n \n \n Deleted user "\n "\n \n \u5df2\u5220\u9664\u7528\u6237\u201c\n \u201d\n \n \n \n Failed to delete user "\n "\n \n \u5220\u9664\u7528\u6237\u201c\n \u201d\u5931\u8d25\n \n \n \n You are currently logged in as "\n ".\n \n \u60a8\u5f53\u524d\u5728\u7528\u201c\n \u201d\u7684\u8eab\u4efd\u767b\u5f55\u3002\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n \u5404\u5bf9\u8c61\u90fd\u88ab\u5206\u5272\u4e3a\u6570\u636e\u5757\uff0c\u5206\u522b\u5b58\u50a8\u4e8e\u4e0d\u540c OSD \u3002\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n \u8ba1\u7b97\u5404\u5bf9\u8c61\u7684\u7f16\u7801\u5757\u3001\u5e76\u5b58\u50a8\u4e8e\u4e0d\u540c OSD \u3002\n\u7f16\u7801\u5757\u7684\u6570\u91cf\u7b49\u540c\u4e8e\u5728\u4e0d\u4e22\u6570\u636e\u7684\u524d\u63d0\u4e0b\u5141\u8bb8\u540c\u65f6\u5931\u6548\u7684 OSD \u6570\u91cf\u3002\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n jerasure \u63d2\u4ef6\u662f\u6700\u901a\u7528\u3001\u6700\u7075\u6d3b\u7684\u63d2\u4ef6\uff0c\n\u4e5f\u662f Ceph \u7ea0\u5220\u7801\u5b58\u50a8\u6c60\u7684\u9ed8\u8ba4\u63d2\u4ef6\u3002\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n reed_sol_van \u6280\u672f\u66f4\u7075\u6d3b\uff1a\u5b83\u8db3\u4ee5\u8bbe\u7f6e k \u548c m \u503c\u3002 \ncauchy_good \u6280\u672f\u66f4\u5feb\uff0c\u4f46\u4f60\u5f97\u8c28\u614e\u5730\u9009\u62e9 packetsize \u503c\u3002\nreed_sol_r6_op \u3001 liberation \u3001 blaum_roth \u3001 liber8tion \u90fd\u662f\u4e0e RAID6 \u7b49\u4ef7\u7684\u6280\u672f\uff0c\n\u5b83\u4eec\u53ea\u80fd\u914d\u7f6e\u4e3a m=2 \u3002\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n \u4ee5 bytes \u5927\u5c0f\u7684\u5305\u4e3a\u5355\u4f4d\u8fdb\u884c\u7f16\u7801\u3002\n\u786e\u5b9a\u5408\u9002\u7684\u5305\u5c3a\u5bf8\u5f88\u96be\uff0c \njerasure \u6587\u6863\u5bf9\u6b64\u6709\u5f88\u8be6\u7ec6\u7684\u63cf\u8ff0\u3002\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n \u7528 jerasure \u63d2\u4ef6\u65f6\uff0c\u7ea0\u5220\u7801\u7f16\u7801\u7684\u5bf9\u8c61\u5b58\u50a8\u5728\u591a\u4e2a OSD \u4e0a\uff0c\n\u4e22\u5931\u4e00\u4e2a OSD \u7684\u6062\u590d\u8fc7\u7a0b\u9700\u8bfb\u53d6\u6240\u6709\u5176\u4ed6\u7684 OSD \u3002\n\u6bd4\u5982 jerasure \u7684\u914d\u7f6e\u4e3a k=8 \u4e14 m=4 \uff0c\u4e22\u5931\u4e00\u4e2a OSD \u540e\u9700\u8bfb\u53d6\u5176\u4ed6 11 \u4e2a OSD \u624d\u80fd\u6062\u590d\u3002\n\nlrc \u7ea0\u5220\u7801\u63d2\u4ef6\u521b\u5efa\u7684\u662f\u5c40\u90e8\u6821\u9a8c\u5757\uff0c\u8fd9\u6837\u53ea\u9700\u8f83\u5c11\u7684 OSD \u5373\u53ef\u6062\u590d\u3002\n\u6bd4\u5982 lrc \u7684\u914d\u7f6e\u4e3a k=8 \u3001 m=4 \u4e14 l=4 \uff0c\u5b83\u5c06\u4e3a\u6bcf\u56db\u4e2a OSD \u521b\u5efa\u989d\u5916\u7684\u6821\u9a8c\u5757\uff0c\n\u5f53\u4e00\u4e2a OSD \u4e22\u5931\u65f6\uff0c\u5b83\u53ea\u9700\u56db\u4e2a OSD \u5373\u53ef\u6062\u590d\uff0c\u800c\u4e0d\u9700\u8981\u5341\u4e00\u4e2a\u3002\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n \u628a\u7f16\u7801\u5757\u548c\u6570\u636e\u5757\u5206\u7ec4\u4e3a\u5927\u5c0f\u4e3a locality \u7684\u96c6\u5408\u3002\n\u6bd4\u5982\uff0c k=4 \u4e14 m=2 \u65f6\uff0c\u82e5\u8bbe\u7f6e locality=3 \uff0c\u5c06\u4f1a\u5206\u7ec4\u4e3a\u5927\u5c0f\u4e3a\u4e09\u7684\u4e24\u7ec4\uff0c\n\u8fd9\u6837\u5404\u7ec4\u90fd\u80fd\u81ea\u884c\u6062\u590d\uff0c\u65e0\u9700\u4ece\u53e6\u4e00\u7ec4\u8bfb\u6570\u636e\u5757\u3002\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n \u7531 l \u5b9a\u4e49\u7684\u5757\u96c6\u5408\u5c06\u6309\u54ea\u79cd crush \u6876\u7c7b\u578b\u5b58\u50a8\u3002\n\u6bd4\u5982\uff0c\u82e5\u8bbe\u7f6e\u4e3a rack \uff0c\u5927\u5c0f\u4e3a l \u5757\u7684\u5404\u7ec4\u5c06\u88ab\u5b58\u5165\u4e0d\u540c\u7684\u673a\u67b6\uff0c\n\u6b64\u503c\u4f1a\u88ab\u7528\u4e8e\u521b\u5efa\u7c7b\u4f3c step choose rack \u7684\u89c4\u5219\u96c6\u3002\n\u5982\u679c\u6ca1\u8bbe\u7f6e\uff0c\u5c31\u4e0d\u4f1a\u8fd9\u6837\u5206\u7ec4\u3002\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n isa \u63d2\u4ef6\u5c01\u88c5\u4e86 ISA \u5e93\u3002\u5b83\u53ea\u80fd\u8fd0\u884c\u5728 Intel \u5904\u7406\u5668\u4e0a\u3002\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n ISA \u63d2\u4ef6\u5305\u542b\u4e24\u79cd Reed Solomon \u7f16\u7801\u5f62\u5f0f\u3002\n\u8bbe\u7f6e\u4e3a reed_sol_van \u8868\u793a\u7528 Vandermonde \u7b97\u6cd5\uff0c\u8bbe\u7f6e\u4e3a cauchy \u8868\u793a\u7528 Cauchy \u7b97\u6cd5\u3002\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n shec \u63d2\u4ef6\u5c01\u88c5\u4e86 multiple SHEC \u5e93\u3002\n\u4e0e Reed Solomon \u7f16\u7801\u76f8\u6bd4\uff0c\u5b83\u80fd\u4f7f Ceph \u66f4\u9ad8\u6548\u5730\u6062\u590d\u6570\u636e\u3002\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n \u5947\u5076\u6821\u9a8c\u5757\u6570\u91cf\uff0c\u5b83\u4eec\u5728\u5404\u81ea\u7684\u8ba1\u7b97\u8303\u56f4\u5185\u5305\u542b\u4e86\u5404\u6570\u636e\u5757\u3002\n\u6b64\u6570\u503c\u88ab\u7528\u4f5c\u6301\u4e45\u6027\u4f30\u503c\u3002\n\u4f8b\u5982\uff0c\u5047\u8bbe c=2 \uff0c\u5c31\u662f\u8bf4\u4e0d\u4e1f\u6570\u636e\u7684\u60c5\u51b5\u4e0b\u53ef\u635f\u5931 2 \u4e2a OSD \u3002\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n \u89c4\u5219\u96c6\u7b2c\u4e00\u6b65\u6240\u6307\u5411\u7684 CRUSH \u6876\u4e4b\u540d\uff0c\n\u5982 step take default \u3002\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n \u786e\u4fdd\u4e24\u4e2a\u7f16\u7801\u5757\u4e0d\u4f1a\u5b58\u5728\u4e8e\u540c\u4e00\u6545\u969c\u57df\u7684\u6876\u91cc\u9762\u3002\n\u6bd4\u5982\uff0c\u5047\u8bbe\u6545\u969c\u57df\u662f host \uff0c\u5c31\u4e0d\u4f1a\u6709\u4e24\u4e2a\u7f16\u7801\u5757\u5b58\u50a8\u5230\u540c\u4e00\u4e3b\u673a\uff1b\n\u6b64\u503c\u7528\u4e8e\u5728\u89c4\u5219\u96c6\u4e2d\u521b\u5efa\u7c7b\u4f3c step chooseleaf host \u7684\u6b65\u9aa4\u3002\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n \u4f7f\u7528 CRUSH \u7d22\u5f15\u4e2d\u7684 crush \u8bbe\u5907\u7c7b\u540d\uff0c\n\u5c06\u5f52\u7f6e\u9650\u5236\u4e8e\u7279\u5b9a\u7c7b\u7684\u8bbe\u5907\uff08\u4f8b\u5982\uff0cssd \u6216 hdd\uff09\u3002\n \n \n Set the directory name from which the erasure code plugin is loaded.\n \u8bbe\u7f6e\u7ea0\u5220\u7801\u63d2\u4ef6\u6240\u5728\u76ee\u5f55\u3002\n \n \n Allows all operations\n \u5141\u8bb8\u6240\u6709\u64cd\u4f5c\n \n \n Allows only operations that do not modify the server\n \u53ea\u5141\u8bb8\u4e0d\u4fee\u6539\u670d\u52a1\u5668\u7aef\u6570\u636e\u7684\u64cd\u4f5c\n \n \n Does not allow read or write operations, but allows any other operation\n \u7981\u6b62\u8bfb\u5199\uff0c\u4f46\u662f\u5141\u8bb8\u5176\u4ed6\u7684\u64cd\u4f5c\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n \u7981\u6b62\u8bfb\u3001\u5199\u4ee5\u53ca\u4efb\u4f55\u53ef\u80fd\u4fee\u6539\u6587\u4ef6\u5185\u5bb9\u7684\u64cd\u4f5c\n \n \n Allows no access at all\n \u5b8c\u5168\u7981\u6b62\u8bbf\u95ee\n \n \n -- Select the priority --\n -- \u9009\u62e9\u4f18\u5148\u7ea7 --\n \n \n Low\n \u4f4e\n \n \n High\n \u9ad8\n \n \n Last 5 minutes\n \u8fc7\u53bb 5 \u5206\u949f\n \n \n Last 15 minutes\n \u8fc7\u53bb 15 \u5206\u949f\n \n \n Last 30 minutes\n \u8fc7\u53bb 30 \u5206\u949f\n \n \n Last 1 hour (Default)\n \u8fc7\u53bb 1 \u5c0f\u65f6\uff08\u9ed8\u8ba4\uff09\n \n \n Last 3 hours\n \u8fc7\u53bb 3 \u5c0f\u65f6\n \n \n Last 6 hours\n \u8fc7\u53bb 6 \u5c0f\u65f6\n \n \n Last 12 hours\n \u8fc7\u53bb 12 \u5c0f\u65f6\n \n \n Last 24 hours\n \u8fc7\u53bb 24 \u5c0f\u65f6\n \n \n Yesterday\n \u6628\u5929\n \n \n Today\n \u4eca\u5929\n \n \n Today so far\n \u4eca\u5929\u5230\u73b0\u5728\u4e3a\u6b62\n \n \n Day before yesterday\n \u524d\u5929\n \n \n Last 2 days\n \u8fc7\u53bb 2 \u5929\n \n \n This day last week\n \u4e0a\u5468\u7684\u4eca\u5929\n \n \n Previous week\n \u4e0a\u4e2a\u661f\u671f\n \n \n This week\n \u672c\u5468\n \n \n This week so far\n \u672c\u5468\u4ee5\u6765\n \n \n Last 7 days\n \u8fc7\u53bb 7 \u5929\n \n \n Previous month\n \u4e0a\u4e2a\u6708\n \n \n This month\n \u5f53\u6708\n \n \n This month so far\n \u672c\u6708\u4ee5\u6765\n \n \n Last 30 days\n \u8fc7\u53bb 30 \u5929\n \n \n Last 90 days\n \u8fc7\u53bb 90 \u5929\n \n \n Last 6 months\n \u8fc7\u53bb 6 \u4e2a\u6708\n \n \n Last 1 year\n \u8fc7\u53bb 1 \u5e74\n \n \n Previous year\n \u53bb\u5e74\n \n \n This year\n \u4eca\u5e74\n \n \n This year so far\n \u4eca\u5e74\u4ee5\u6765\n \n \n Last 2 years\n \u8fc7\u53bb 2 \u5e74\n \n \n Last 5 years\n \u8fc7\u53bb 5 \u5e74\n \n \n Information\n \u4fe1\u606f\n \n \n No items selected.\n \u65e0\u9009\u4e2d\u9879\u76ee\u3002\n \n \n Deselect item to select again\n \u53d6\u6d88\u9009\u62e9\n \n \n Selection limit reached\n \u8fbe\u5230\u9009\u62e9\u9879\u6570\u4e0a\u9650\u3002\n \n \n Filter tags\n \u8fc7\u6ee4\u6807\u7b7e\n \n \n Add badge\n \u6dfb\u52a0 badge\n \n \n There are no items available.\n \u65e0\u53ef\u9009\u9879\u76ee\u3002\n \n \n Add\n \u6dfb\u52a0\n \n \n Remove\n Remove\n \n \n Clone\n \u514b\u9686\n \n \n Copy\n \u590d\u5236\n \n \n Deep Scrub\n \u6df1\u5c42\u6d17\u5237\n \n \n Destroy\n \u9500\u6bc1\n \n \n Flatten\n \u5c55\u5f00\n \n \n Mark Down\n \u6807\u8bb0\u4e3a\u505c\u7528\n \n \n Mark In\n \u6807\u8bb0\u4e3a\u52a0\u5165\n \n \n Mark Lost\n \u6807\u8bb0\u4e3a\u4e22\u5931\n \n \n Mark Out\n \u6807\u8bb0\u4e3a\u5df2\u9664\u540d\n \n \n Protect\n \u4fdd\u62a4\n \n \n Rename\n \u91cd\u547d\u540d\n \n \n Restore\n \u6062\u590d\n \n \n Move to Trash\n \u79fb\u81f3\u56de\u6536\u7ad9\n \n \n Unprotect\n \u89e3\u9664\u4fdd\u62a4\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n \u5220\u9664\u5b8c\u6210\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n \u514b\u9686\u5b8c\u6210\n \n \n Copied\n \u590d\u5236\u5b8c\u6210\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n \u662f\n \n \n No\n \u5426\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n \u670d\u52a1\u8d28\u91cf (QoS)\n \n \n BPS Limit\n BPS \u4e0a\u9650\n \n \n The desired limit of IO bytes per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2 IO \u5b57\u8282\u6570\u4e0a\u9650\u3002\n \n \n IOPS Limit\n IOPS \u4e0a\u9650\n \n \n The desired limit of IO operations per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2 IO \u64cd\u4f5c\u6b21\u6570\u4e0a\u9650\u3002\n \n \n Read BPS Limit\n \u8bfb BPS \u4e0a\u9650\n \n \n The desired limit of read bytes per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u5185\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u4e0a\u9650\u3002\n \n \n Read IOPS Limit\n \u8bfb IOPS \u4e0a\u9650\n \n \n The desired limit of read operations per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u8bfb\u64cd\u4f5c\u6b21\u6570\u4e0a\u9650\u3002\n \n \n Write BPS Limit\n \u5199 BPS \u4e0a\u9650\n \n \n The desired limit of write bytes per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u5185\u5199\u5165\u7684\u5b57\u8282\u6570\u4e0a\u9650\u3002\n \n \n Write IOPS Limit\n \u5199 IOPS \u4e0a\u9650\n \n \n The desired limit of write operations per second.\n \u6307\u5b9a\u7684\u6bcf\u79d2\u5199\u64cd\u4f5c\u6b21\u6570\u4e0a\u9650\u3002\n \n \n BPS Burst\n BPS \u7a81\u53d1\n \n \n The desired burst limit of IO bytes.\n \u6307\u5b9a\u7684 IO \u5b57\u8282\u6570\u7a81\u53d1\u4e0a\u9650\u3002\n \n \n IOPS Burst\n IOPS \u7a81\u53d1\n \n \n The desired burst limit of IO operations.\n \u6307\u5b9a\u7684 IO \u64cd\u4f5c\u6b21\u6570\u7a81\u53d1\u4e0a\u9650\u3002\n \n \n Read BPS Burst\n \u8bfb BPS \u7a81\u53d1\n \n \n The desired burst limit of read bytes.\n \u6307\u5b9a\u7684\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u7a81\u53d1\u4e0a\u9650\u3002\n \n \n Read IOPS Burst\n \u8bfb IOPS \u7a81\u53d1\n \n \n The desired burst limit of read operations.\n \u6307\u5b9a\u7684\u8bfb\u64cd\u4f5c\u6b21\u6570\u7a81\u53d1\u4e0a\u9650\u3002\n \n \n Write BPS Burst\n \u5199 BPS \u7a81\u53d1\n \n \n The desired burst limit of write bytes.\n \u6307\u5b9a\u7684\u5199\u5165\u7684\u5b57\u8282\u6570\u7a81\u53d1\u4e0a\u9650\u3002\n \n \n Write IOPS Burst\n \u5199 IOPS \u7a81\u53d1\n \n \n The desired burst limit of write operations.\n \u6307\u5b9a\u7684\u5199\u64cd\u4f5c\u6b21\u6570\u7a81\u53d1\u4e0a\u9650\u3002\n \n \n Failed to \n \n \n \n \n \n \u5931\u8d25\n \n \n \n Executing\n \u6b63\u5728\u6267\u884c\n \n \n execute\n \u6267\u884c\n \n \n Executed\n \u6267\u884c\u5b8c\u6bd5\n \n \n unknown task\n \u672a\u77e5\u4efb\u52a1\n \n \n Creating\n \u6b63\u5728\u521b\u5efa\n \n \n create\n \u521b\u5efa\n \n \n Updating\n \u6b63\u5728\u66f4\u65b0\n \n \n update\n \u66f4\u65b0\n \n \n Deleting\n \u6b63\u5728\u5220\u9664\n \n \n delete\n \u5220\u9664\n \n \n RBD \'\n \'\n \n RBD\u201c\n \u201d\n \n \n \n RBD snapshot \'\n \'\n \n RBD \u5feb\u7167\u201c\n \u201d\n \n \n \n mirror mode for pool \'\n \'\n \n \u5b58\u50a8\u6c60\u201c\n \u201d\u7684\u955c\u50cf\u6a21\u5f0f\n \n \n \n mirror peer for pool \'\n \'\n \n \u5b58\u50a8\u6c60\u201c\n \u201d\u7684\u955c\u50cf\u540c\u4f34\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n \u8be5\u540d\u79f0\u5df2\u88ab\n \u4f7f\u7528\u3002\n \n \n \n Name is already used by \n .\n \n \u8be5\u540d\u79f0\u5df2\u88ab\n \u4f7f\u7528\u3002\n \n \n \n Name is already used by \n .\n \n \u8be5\u540d\u79f0\u5df2\u88ab\n \u4f7f\u7528\u3002\n \n \n \n \n contains snapshots.\n \n \n \u5305\u542b\u6709\u5feb\u7167\u3002\n \n \n \n Cloning\n \u6b63\u5728\u514b\u9686\n \n \n clone\n \u514b\u9686\n \n \n Snapshot of \n must be protected.\n \n \n \u7684\u5feb\u7167\u5fc5\u987b\u5904\u4e8e\u53d7\u4fdd\u62a4\u72b6\u6001\u3002\n \n \n \n Copying\n \u6b63\u5728\u590d\u5236\n \n \n copy\n \u590d\u5236\n \n \n Flattening\n \u6b63\u5728\u5c55\u5f00\n \n \n flatten\n \u5c55\u5f00\n \n \n Flattened\n \u5c55\u5f00\u5b8c\u6210\n \n \n Name is already used by \n .\n \n \u8be5\u540d\u79f0\u5df2\u88ab\n \u4f7f\u7528\u3002\n \n \n \n Cannot unprotect \n because it contains child images.\n \n \u65e0\u6cd5\u53bb\u6389\n \u7684\u4fdd\u62a4\u72b6\u6001\uff0c\u56e0\u4e3a\u5b83\u6709\u5b50\u6620\u50cf\u3002\n \n \n \n Cannot delete \n because it\'s protected.\n \n \u65e0\u6cd5\u5220\u9664\n \uff0c\u56e0\u4e3a\u5b83\u5904\u4e8e\u53d7\u4fdd\u62a4\u72b6\u6001\u3002\n \n \n \n Rolling back\n \u6b63\u5728\u56de\u6eda\n \n \n rollback\n \u56de\u6eda\n \n \n Rolled back\n \u56de\u6eda\u5b8c\u6210\n \n \n Moving\n \u6b63\u5728\u628a\n \n \n move\n \u628a\n \n \n Moved\n \u5df2\u7ecf\u628a\n \n \n image \'\n \' to trash\n \n \u6620\u50cf\u201c\n \u201d\u79fb\u81f3\u56de\u6536\u7ad9\n \n \n \n Could not find image.\n \u65e0\u6cd5\u627e\u5230\u6620\u50cf\u3002\n \n \n Restoring\n \u6b63\u5728\u628a\n \n \n restore\n \u628a\n \n \n Restored\n \u5df2\u7ecf\u628a\n \n \n image \'\n \' into \'\n \'\n \n \u6620\u50cf\u4ece\u201c\n \u201d\u6062\u590d\u5230\u201c\n \u201d\n \n \n \n Image name \'\n \' is already in use.\n \n \u6620\u50cf\u540d\u79f0\u201c\n \u201d\u5df2\u88ab\u4f7f\u7528\u3002\n \n \n \n image \'\n \'\n \n \u6620\u50cf\u201c\n \u201d\n \n \n \n Purging\n \u6b63\u5728\u6e05\u9664\n \n \n purge\n \u6e05\u9664\n \n \n Purged\n \u5df2\u6e05\u9664\n \n \n all pools\n \u6240\u6709\u5b58\u50a8\u6c60\n \n \n images from \n \n \n \n \u91cc\u7684\u6620\u50cf\n \n \n \n Cannot disable mirroring because it contains a peer.\n \u56e0\u4e3a\u5305\u542b\u540c\u4f34\u96c6\u7fa4\uff0c\u65e0\u6cd5\u7981\u7528\u955c\u50cf\u529f\u80fd\n \n \n pool \'\n \'\n \n \u5b58\u50a8\u6c60\u201c\n \u201d\n \n \n \n erasure code profile \'\n \'\n \n \u7ea0\u5220\u7801\u914d\u7f6e\u201c\n \u201d\n \n \n \n target \'\n \'\n \n \u76ee\u6807\u5668\u201c\n \u201d\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},fELs:function(t,e,n){"use strict";var a=n("RDha");function r(t,e){return a.where(t,function(t){return t.position===e})}function i(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,n){var a=e?n:t,r=e?t:n;return a.weight===r.weight?a._tmpIndex_-r._tmpIndex_:a.weight-r.weight}),t.forEach(function(t){delete t._tmpIndex_})}t.exports={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;-1!==n&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var a,r=["fullWidth","position","weight"],i=r.length,s=0;s1},t.prototype.canNext=function(){return this.page0&&t<=this.totalPages&&t!==this.page&&(this.page=t,this.change.emit({page:t}))},t.prototype.calcPages=function(t){var e=[],n=1,a=this.totalPages;t=t||this.page,5this.totalPages&&(n=Math.max(this.totalPages-5+1,1),a=this.totalPages));for(var r=n;r<=a;r++)e.push({number:r,text:r});return e},a([i.Input(),r("design:type",String)],t.prototype,"pagerLeftArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerRightArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerPreviousIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerNextIcon",void 0),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"size",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"count",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"page",null),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"change",void 0),a([i.Component({selector:"datatable-pager",template:'\n
    \n
  • \n \n \n \n
  • \n
  • \n \n \n \n
  • \n \n \n {{pg.text}}\n \n \n
  • \n \n \n \n
  • \n
  • \n \n \n \n
  • \n
\n ',host:{class:"datatable-pager"},changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},fktO:function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("Ahxa")),a(n("fhFe")),a(n("lUjN")),a(n("vxfy"))},fzPg:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("yo",{months:"S\u1eb9\u0301r\u1eb9\u0301_E\u0300re\u0300le\u0300_\u1eb8r\u1eb9\u0300na\u0300_I\u0300gbe\u0301_E\u0300bibi_O\u0300ku\u0300du_Ag\u1eb9mo_O\u0300gu\u0301n_Owewe_\u1ecc\u0300wa\u0300ra\u0300_Be\u0301lu\u0301_\u1ecc\u0300p\u1eb9\u0300\u0300".split("_"),monthsShort:"S\u1eb9\u0301r_E\u0300rl_\u1eb8rn_I\u0300gb_E\u0300bi_O\u0300ku\u0300_Ag\u1eb9_O\u0300gu\u0301_Owe_\u1ecc\u0300wa\u0300_Be\u0301l_\u1ecc\u0300p\u1eb9\u0300\u0300".split("_"),weekdays:"A\u0300i\u0300ku\u0301_Aje\u0301_I\u0300s\u1eb9\u0301gun_\u1eccj\u1ecd\u0301ru\u0301_\u1eccj\u1ecd\u0301b\u1ecd_\u1eb8ti\u0300_A\u0300ba\u0301m\u1eb9\u0301ta".split("_"),weekdaysShort:"A\u0300i\u0300k_Aje\u0301_I\u0300s\u1eb9\u0301_\u1eccjr_\u1eccjb_\u1eb8ti\u0300_A\u0300ba\u0301".split("_"),weekdaysMin:"A\u0300i\u0300_Aj_I\u0300s_\u1eccr_\u1eccb_\u1eb8t_A\u0300b".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[O\u0300ni\u0300 ni] LT",nextDay:"[\u1ecc\u0300la ni] LT",nextWeek:"dddd [\u1eccs\u1eb9\u0300 to\u0301n'b\u1ecd] [ni] LT",lastDay:"[A\u0300na ni] LT",lastWeek:"dddd [\u1eccs\u1eb9\u0300 to\u0301l\u1ecd\u0301] [ni] LT",sameElse:"L"},relativeTime:{future:"ni\u0301 %s",past:"%s k\u1ecdja\u0301",s:"i\u0300s\u1eb9ju\u0301 aaya\u0301 die",ss:"aaya\u0301 %d",m:"i\u0300s\u1eb9ju\u0301 kan",mm:"i\u0300s\u1eb9ju\u0301 %d",h:"wa\u0301kati kan",hh:"wa\u0301kati %d",d:"\u1ecdj\u1ecd\u0301 kan",dd:"\u1ecdj\u1ecd\u0301 %d",M:"osu\u0300 kan",MM:"osu\u0300 %d",y:"\u1ecddu\u0301n kan",yy:"\u1ecddu\u0301n %d"},dayOfMonthOrdinalParse:/\u1ecdj\u1ecd\u0301\s\d{1,2}/,ordinal:"\u1ecdj\u1ecd\u0301 %d",week:{dow:1,doy:4}})}()},g8vO:function(t,e,n){"use strict";var a=n("RDha");t.exports={formatters:{values:function(t){return a.isArray(t)?t:""+t},linear:function(t,e,n){var r=n.length>3?n[2]-n[1]:n[1]-n[0];Math.abs(r)>1&&t!==Math.floor(t)&&(r=t-Math.floor(t));var i=a.log10(Math.abs(r)),s="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=a.log10(Math.abs(t));s=t.toExponential(Math.floor(o)-Math.floor(i))}else{var u=-1*Math.floor(i);u=Math.max(Math.min(u,20),0),s=t.toFixed(u)}else s="0";return s},logarithmic:function(t,e,n){var r=t/Math.pow(10,Math.floor(a.log10(t)));return 0===t?"0":1===r||2===r||5===r||0===e||e===n.length-1?t.toExponential():""}}}},gI3B:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("6blF"),r=n("T1DM"),i=n("/21U"),s=n("nkY7");function o(t,e,n){void 0===t&&(t=0);var o=-1;return Object(i.a)(e)?o=Number(e)<1?1:Number(e):Object(s.a)(e)&&(n=e),Object(s.a)(n)||(n=r.a),new a.a(function(e){var a=Object(i.a)(t)?t:+t-n.now();return n.schedule(u,a,{index:0,period:o,subscriber:e})})}function u(t){var e=t.index,n=t.period,a=t.subscriber;if(a.next(e),!a.closed){if(-1===n)return a.complete();t.index=e+1,this.schedule(t,n)}}},gIcY:function(t,e,n){"use strict";n.d(e,"B",function(){return It}),n.d(e,"D",function(){return Ot}),n.d(e,"C",function(){return S}),n.d(e,"E",function(){return C}),n.d(e,"F",function(){return mt}),n.d(e,"G",function(){return F}),n.d(e,"c",function(){return v}),n.d(e,"d",function(){return l}),n.d(e,"p",function(){return y}),n.d(e,"b",function(){return _}),n.d(e,"e",function(){return x}),n.d(e,"q",function(){return I}),n.d(e,"r",function(){return et}),n.d(e,"s",function(){return nt}),n.d(e,"t",function(){return dt}),n.d(e,"u",function(){return bt}),n.d(e,"w",function(){return k}),n.d(e,"j",function(){return Tt}),n.d(e,"l",function(){return yt}),n.d(e,"g",function(){return _t}),n.d(e,"m",function(){return vt}),n.d(e,"v",function(){return M}),n.d(e,"z",function(){return P}),n.d(e,"y",function(){return wt}),n.d(e,"h",function(){return St}),n.d(e,"a",function(){return st}),n.d(e,"f",function(){return ct}),n.d(e,"i",function(){return ot}),n.d(e,"k",function(){return ut}),n.d(e,"o",function(){return f}),n.d(e,"A",function(){return h}),n.d(e,"n",function(){return Ct}),n.d(e,"x",function(){return kt});var a=n("mrSG"),r=n("CcnG"),i=n("VNr4"),s=n("0/uQ"),o=n("67Y/"),u=n("ZYjt"),c=function(){function t(){}return Object.defineProperty(t.prototype,"value",{get:function(){return this.control?this.control.value:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"valid",{get:function(){return this.control?this.control.valid:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"invalid",{get:function(){return this.control?this.control.invalid:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pending",{get:function(){return this.control?this.control.pending:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"disabled",{get:function(){return this.control?this.control.disabled:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"enabled",{get:function(){return this.control?this.control.enabled:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"errors",{get:function(){return this.control?this.control.errors:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pristine",{get:function(){return this.control?this.control.pristine:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"dirty",{get:function(){return this.control?this.control.dirty:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"touched",{get:function(){return this.control?this.control.touched:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"status",{get:function(){return this.control?this.control.status:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"untouched",{get:function(){return this.control?this.control.untouched:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"statusChanges",{get:function(){return this.control?this.control.statusChanges:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"valueChanges",{get:function(){return this.control?this.control.valueChanges:null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"path",{get:function(){return null},enumerable:!0,configurable:!0}),t.prototype.reset=function(t){void 0===t&&(t=void 0),this.control&&this.control.reset(t)},t.prototype.hasError=function(t,e){return!!this.control&&this.control.hasError(t,e)},t.prototype.getError=function(t,e){return this.control?this.control.getError(t,e):null},t}(),l=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),Object.defineProperty(e.prototype,"formDirective",{get:function(){return null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return null},enumerable:!0,configurable:!0}),e}(c);function d(t){return null==t||0===t.length}var f=new r.InjectionToken("NgValidators"),p=/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/,h=function(){function t(){}return t.min=function(t){return function(e){if(d(e.value)||d(t))return null;var n=parseFloat(e.value);return!isNaN(n)&&nt?{max:{max:t,actual:e.value}}:null}},t.required=function(t){return d(t.value)?{required:!0}:null},t.requiredTrue=function(t){return!0===t.value?null:{required:!0}},t.email=function(t){return d(t.value)?null:p.test(t.value)?null:{email:!0}},t.minLength=function(t){return function(e){if(d(e.value))return null;var n=e.value?e.value.length:0;return nt?{maxlength:{requiredLength:t,actualLength:n}}:null}},t.pattern=function(e){return e?("string"==typeof e?(a="","^"!==e.charAt(0)&&(a+="^"),a+=e,"$"!==e.charAt(e.length-1)&&(a+="$"),n=new RegExp(a)):(a=e.toString(),n=e),function(t){if(d(t.value))return null;var e=t.value;return n.test(e)?null:{pattern:{requiredPattern:a,actualValue:e}}}):t.nullValidator;var n,a},t.nullValidator=function(t){return null},t.compose=function(t){if(!t)return null;var e=t.filter(g);return 0==e.length?null:function(t){return m(function(t,n){return e.map(function(e){return e(t)})}(t))}},t.composeAsync=function(t){if(!t)return null;var e=t.filter(g);return 0==e.length?null:function(t){var n=function(t,n){return e.map(function(e){return e(t)})}(t).map(b);return Object(i.a)(n).pipe(Object(o.a)(m))}},t}();function g(t){return null!=t}function b(t){var e=Object(r["\u0275isPromise"])(t)?Object(s.a)(t):t;if(!Object(r["\u0275isObservable"])(e))throw new Error("Expected validator to return Promise or Observable.");return e}function m(t){var e=t.reduce(function(t,e){return null!=e?Object(a.__assign)({},t,e):t},{});return 0===Object.keys(e).length?null:e}var y=new r.InjectionToken("NgValueAccessor"),v=function(){function t(t,e){this._renderer=t,this._elementRef=e,this.onChange=function(t){},this.onTouched=function(){}}return t.prototype.writeValue=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"checked",t)},t.prototype.registerOnChange=function(t){this.onChange=t},t.prototype.registerOnTouched=function(t){this.onTouched=t},t.prototype.setDisabledState=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",t)},t}(),_=new r.InjectionToken("CompositionEventMode"),x=function(){function t(t,e,n){var a;this._renderer=t,this._elementRef=e,this._compositionMode=n,this.onChange=function(t){},this.onTouched=function(){},this._composing=!1,null==this._compositionMode&&(this._compositionMode=(a=Object(u["\u0275getDOM"])()?Object(u["\u0275getDOM"])().getUserAgent():"",!/android (\d+)/.test(a.toLowerCase())))}return t.prototype.writeValue=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"value",null==t?"":t)},t.prototype.registerOnChange=function(t){this.onChange=t},t.prototype.registerOnTouched=function(t){this.onTouched=t},t.prototype.setDisabledState=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",t)},t.prototype._handleInput=function(t){(!this._compositionMode||this._compositionMode&&!this._composing)&&this.onChange(t)},t.prototype._compositionStart=function(){this._composing=!0},t.prototype._compositionEnd=function(t){this._composing=!1,this._compositionMode&&this.onChange(t)},t}();function T(t){return t.validate?function(e){return t.validate(e)}:t}function w(t){return t.validate?function(e){return t.validate(e)}:t}var S=function(){function t(t,e){this._renderer=t,this._elementRef=e,this.onChange=function(t){},this.onTouched=function(){}}return t.prototype.writeValue=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"value",null==t?"":t)},t.prototype.registerOnChange=function(t){this.onChange=function(e){t(""==e?null:parseFloat(e))}},t.prototype.registerOnTouched=function(t){this.onTouched=t},t.prototype.setDisabledState=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",t)},t}();function O(){throw new Error("unimplemented")}var I=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._parent=null,e.name=null,e.valueAccessor=null,e._rawValidators=[],e._rawAsyncValidators=[],e}return Object(a.__extends)(e,t),Object.defineProperty(e.prototype,"validator",{get:function(){return O()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return O()},enumerable:!0,configurable:!0}),e}(c),C=function(){function t(){this._accessors=[]}return t.prototype.add=function(t,e){this._accessors.push([t,e])},t.prototype.remove=function(t){for(var e=this._accessors.length-1;e>=0;--e)if(this._accessors[e][1]===t)return void this._accessors.splice(e,1)},t.prototype.select=function(t){var e=this;this._accessors.forEach(function(n){e._isSameGroup(n,t)&&n[1]!==t&&n[1].fireUncheck(t.value)})},t.prototype._isSameGroup=function(t,e){return!!t[0].control&&t[0]._parent===e._control._parent&&t[1].name===e.name},t}(),k=function(){function t(t,e,n,a){this._renderer=t,this._elementRef=e,this._registry=n,this._injector=a,this.onChange=function(){},this.onTouched=function(){}}return t.prototype.ngOnInit=function(){this._control=this._injector.get(I),this._checkName(),this._registry.add(this._control,this)},t.prototype.ngOnDestroy=function(){this._registry.remove(this)},t.prototype.writeValue=function(t){this._state=t===this.value,this._renderer.setProperty(this._elementRef.nativeElement,"checked",this._state)},t.prototype.registerOnChange=function(t){var e=this;this._fn=t,this.onChange=function(){t(e.value),e._registry.select(e)}},t.prototype.fireUncheck=function(t){this.writeValue(t)},t.prototype.registerOnTouched=function(t){this.onTouched=t},t.prototype.setDisabledState=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",t)},t.prototype._checkName=function(){this.name&&this.formControlName&&this.name!==this.formControlName&&this._throwNameError(),!this.name&&this.formControlName&&(this.name=this.formControlName)},t.prototype._throwNameError=function(){throw new Error('\n If you define both a name and a formControlName attribute on your radio button, their values\n must match. Ex: \n ')},t}(),N=function(){function t(t,e){this._renderer=t,this._elementRef=e,this.onChange=function(t){},this.onTouched=function(){}}return t.prototype.writeValue=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"value",parseFloat(t))},t.prototype.registerOnChange=function(t){this.onChange=function(e){t(""==e?null:parseFloat(e))}},t.prototype.registerOnTouched=function(t){this.onTouched=t},t.prototype.setDisabledState=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",t)},t}(),R='\n
\n \n
\n\n In your class:\n\n this.myGroup = new FormGroup({\n firstName: new FormControl()\n });',A='\n
\n
\n \n
\n
\n\n In your class:\n\n this.myGroup = new FormGroup({\n person: new FormGroup({ firstName: new FormControl() })\n });',D='\n
\n
\n \n
\n
',E=function(){function t(){}return t.controlParentException=function(){throw new Error("formControlName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n "+R)},t.ngModelGroupException=function(){throw new Error('formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents\n that also have a "form" prefix: formGroupName, formArrayName, or formGroup.\n\n Option 1: Update the parent to be formGroupName (reactive form strategy)\n\n '+A+"\n\n Option 2: Use ngModel instead of formControlName (template-driven strategy)\n\n "+D)},t.missingFormException=function(){throw new Error("formGroup expects a FormGroup instance. Please pass one in.\n\n Example:\n\n "+R)},t.groupParentException=function(){throw new Error("formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n "+A)},t.arrayParentException=function(){throw new Error('formArrayName must be used with a parent formGroup directive. You\'ll want to add a formGroup\n directive and pass it an existing FormGroup instance (you can create one in your class).\n\n Example:\n\n \n
\n
\n
\n \n
\n
\n
\n\n In your class:\n\n this.cityArray = new FormArray([new FormControl(\'SF\')]);\n this.myGroup = new FormGroup({\n cities: this.cityArray\n });')},t.disabledAttrWarning=function(){console.warn("\n It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true\n when you set up this control in your component class, the disabled attribute will actually be set in the DOM for\n you. We recommend using this approach to avoid 'changed after checked' errors.\n \n Example: \n form = new FormGroup({\n first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),\n last: new FormControl('Drew', Validators.required)\n });\n ")},t.ngModelWarning=function(t){console.warn("\n It looks like you're using ngModel on the same form field as "+t+". \n Support for using the ngModel input property and ngModelChange event with \n reactive form directives has been deprecated in Angular v6 and will be removed \n in Angular v7.\n \n For more information on this, see our API docs here:\n https://angular.io/api/forms/"+("formControl"===t?"FormControlDirective":"FormControlName")+"#use-with-ngmodel\n ")},t}();function L(t,e){return null==t?""+e:(e&&"object"==typeof e&&(e="Object"),(t+": "+e).slice(0,50))}var P=function(){function t(t,e){this._renderer=t,this._elementRef=e,this._optionMap=new Map,this._idCounter=0,this.onChange=function(t){},this.onTouched=function(){},this._compareWith=r["\u0275looseIdentical"]}return Object.defineProperty(t.prototype,"compareWith",{set:function(t){if("function"!=typeof t)throw new Error("compareWith must be a function, but received "+JSON.stringify(t));this._compareWith=t},enumerable:!0,configurable:!0}),t.prototype.writeValue=function(t){this.value=t;var e=this._getOptionId(t);null==e&&this._renderer.setProperty(this._elementRef.nativeElement,"selectedIndex",-1);var n=L(e,t);this._renderer.setProperty(this._elementRef.nativeElement,"value",n)},t.prototype.registerOnChange=function(t){var e=this;this.onChange=function(n){e.value=e._getOptionValue(n),t(e.value)}},t.prototype.registerOnTouched=function(t){this.onTouched=t},t.prototype.setDisabledState=function(t){this._renderer.setProperty(this._elementRef.nativeElement,"disabled",t)},t.prototype._registerOption=function(){return(this._idCounter++).toString()},t.prototype._getOptionId=function(t){var e,n;try{for(var r=Object(a.__values)(Array.from(this._optionMap.keys())),i=r.next();!i.done;i=r.next()){var s=i.value;if(this._compareWith(this._optionMap.get(s),t))return s}}catch(o){e={error:o}}finally{try{i&&!i.done&&(n=r.return)&&n.call(r)}finally{if(e)throw e.error}}return null},t.prototype._getOptionValue=function(t){var e=function(t){return t.split(":")[0]}(t);return this._optionMap.has(e)?this._optionMap.get(e):t},t}(),M=function(){function t(t,e,n){this._element=t,this._renderer=e,this._select=n,this._select&&(this.id=this._select._registerOption())}return Object.defineProperty(t.prototype,"ngValue",{set:function(t){null!=this._select&&(this._select._optionMap.set(this.id,t),this._setElementValue(L(this.id,t)),this._select.writeValue(this._select.value))},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"value",{set:function(t){this._setElementValue(t),this._select&&this._select.writeValue(this._select.value)},enumerable:!0,configurable:!0}),t.prototype._setElementValue=function(t){this._renderer.setProperty(this._element.nativeElement,"value",t)},t.prototype.ngOnDestroy=function(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))},t}();function q(t,e){return null==t?""+e:("string"==typeof e&&(e="'"+e+"'"),e&&"object"==typeof e&&(e="Object"),(t+": "+e).slice(0,50))}var j=function(){function t(t,e){this._renderer=t,this._elementRef=e,this._optionMap=new Map,this._idCounter=0,this.onChange=function(t){},this.onTouched=function(){},this._compareWith=r["\u0275looseIdentical"]}return Object.defineProperty(t.prototype,"compareWith",{set:function(t){if("function"!=typeof t)throw new Error("compareWith must be a function, but received "+JSON.stringify(t));this._compareWith=t},enumerable:!0,configurable:!0}),t.prototype.writeValue=function(t){var e,n=this;if(this.value=t,Array.isArray(t)){var a=t.map(function(t){return n._getOptionId(t)});e=function(t,e){t._setSelected(a.indexOf(e.toString())>-1)}}else e=function(t,e){t._setSelected(!1)};this._optionMap.forEach(e)},t.prototype.registerOnChange=function(t){var e=this;this.onChange=function(n){var a=[];if(n.hasOwnProperty("selectedOptions"))for(var r=n.selectedOptions,i=0;i1?"path: '"+t.path.join(" -> ")+"'":t.path[0]?"name: '"+t.path+"'":"unspecified name attribute",new Error(e+" "+n)}function U(t){return null!=t?h.compose(t.map(T)):null}function W(t){return null!=t?h.composeAsync(t.map(w)):null}function K(t,e){if(!t.hasOwnProperty("model"))return!1;var n=t.model;return!!n.isFirstChange()||!Object(r["\u0275looseIdentical"])(e,n.currentValue)}var $=[v,N,S,P,j,k];function Z(t,e){t._syncPendingControls(),e.forEach(function(t){var e=t.control;"submit"===e.updateOn&&e._pendingChange&&(t.viewToModelUpdate(e._pendingValue),e._pendingChange=!1)})}function X(t,e){if(!e)return null;Array.isArray(e)||B(t,"Value accessor was not provided as an array for form control with");var n=void 0,a=void 0,r=void 0;return e.forEach(function(e){var i;e.constructor===x?n=e:(i=e,$.some(function(t){return i.constructor===t})?(a&&B(t,"More than one built-in value accessor matches form control with"),a=e):(r&&B(t,"More than one custom value accessor matches form control with"),r=e))}),r||a||n||(B(t,"No valid value accessor for form control with"),null)}function J(t,e){var n=t.indexOf(e);n>-1&&t.splice(n,1)}var Q=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(a.__extends)(e,t),e.prototype.ngOnInit=function(){this._checkParentType(),this.formDirective.addFormGroup(this)},e.prototype.ngOnDestroy=function(){this.formDirective&&this.formDirective.removeFormGroup(this)},Object.defineProperty(e.prototype,"control",{get:function(){return this.formDirective.getFormGroup(this)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return z(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"formDirective",{get:function(){return this._parent?this._parent.formDirective:null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return U(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return W(this._asyncValidators)},enumerable:!0,configurable:!0}),e.prototype._checkParentType=function(){},e}(l),tt=function(){function t(t){this._cd=t}return Object.defineProperty(t.prototype,"ngClassUntouched",{get:function(){return!!this._cd.control&&this._cd.control.untouched},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassTouched",{get:function(){return!!this._cd.control&&this._cd.control.touched},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassPristine",{get:function(){return!!this._cd.control&&this._cd.control.pristine},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassDirty",{get:function(){return!!this._cd.control&&this._cd.control.dirty},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassValid",{get:function(){return!!this._cd.control&&this._cd.control.valid},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassInvalid",{get:function(){return!!this._cd.control&&this._cd.control.invalid},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"ngClassPending",{get:function(){return!!this._cd.control&&this._cd.control.pending},enumerable:!0,configurable:!0}),t}(),et=function(t){function e(e){return t.call(this,e)||this}return Object(a.__extends)(e,t),e}(tt),nt=function(t){function e(e){return t.call(this,e)||this}return Object(a.__extends)(e,t),e}(tt);function at(t){var e=it(t)?t.validators:t;return Array.isArray(e)?U(e):e||null}function rt(t,e){var n=it(e)?e.asyncValidators:t;return Array.isArray(n)?W(n):n||null}function it(t){return null!=t&&!Array.isArray(t)&&"object"==typeof t}var st=function(){function t(t,e){this.validator=t,this.asyncValidator=e,this._onCollectionChange=function(){},this.pristine=!0,this.touched=!1,this._onDisabledChange=[]}return Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"valid",{get:function(){return"VALID"===this.status},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"invalid",{get:function(){return"INVALID"===this.status},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"pending",{get:function(){return"PENDING"==this.status},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"disabled",{get:function(){return"DISABLED"===this.status},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"enabled",{get:function(){return"DISABLED"!==this.status},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"dirty",{get:function(){return!this.pristine},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"untouched",{get:function(){return!this.touched},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"updateOn",{get:function(){return this._updateOn?this._updateOn:this.parent?this.parent.updateOn:"change"},enumerable:!0,configurable:!0}),t.prototype.setValidators=function(t){this.validator=at(t)},t.prototype.setAsyncValidators=function(t){this.asyncValidator=rt(t)},t.prototype.clearValidators=function(){this.validator=null},t.prototype.clearAsyncValidators=function(){this.asyncValidator=null},t.prototype.markAsTouched=function(t){void 0===t&&(t={}),this.touched=!0,this._parent&&!t.onlySelf&&this._parent.markAsTouched(t)},t.prototype.markAsUntouched=function(t){void 0===t&&(t={}),this.touched=!1,this._pendingTouched=!1,this._forEachChild(function(t){t.markAsUntouched({onlySelf:!0})}),this._parent&&!t.onlySelf&&this._parent._updateTouched(t)},t.prototype.markAsDirty=function(t){void 0===t&&(t={}),this.pristine=!1,this._parent&&!t.onlySelf&&this._parent.markAsDirty(t)},t.prototype.markAsPristine=function(t){void 0===t&&(t={}),this.pristine=!0,this._pendingDirty=!1,this._forEachChild(function(t){t.markAsPristine({onlySelf:!0})}),this._parent&&!t.onlySelf&&this._parent._updatePristine(t)},t.prototype.markAsPending=function(t){void 0===t&&(t={}),this.status="PENDING",!1!==t.emitEvent&&this.statusChanges.emit(this.status),this._parent&&!t.onlySelf&&this._parent.markAsPending(t)},t.prototype.disable=function(t){void 0===t&&(t={}),this.status="DISABLED",this.errors=null,this._forEachChild(function(e){e.disable(Object(a.__assign)({},t,{onlySelf:!0}))}),this._updateValue(),!1!==t.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._updateAncestors(t),this._onDisabledChange.forEach(function(t){return t(!0)})},t.prototype.enable=function(t){void 0===t&&(t={}),this.status="VALID",this._forEachChild(function(e){e.enable(Object(a.__assign)({},t,{onlySelf:!0}))}),this.updateValueAndValidity({onlySelf:!0,emitEvent:t.emitEvent}),this._updateAncestors(t),this._onDisabledChange.forEach(function(t){return t(!1)})},t.prototype._updateAncestors=function(t){this._parent&&!t.onlySelf&&(this._parent.updateValueAndValidity(t),this._parent._updatePristine(),this._parent._updateTouched())},t.prototype.setParent=function(t){this._parent=t},t.prototype.updateValueAndValidity=function(t){void 0===t&&(t={}),this._setInitialStatus(),this._updateValue(),this.enabled&&(this._cancelExistingSubscription(),this.errors=this._runValidator(),this.status=this._calculateStatus(),"VALID"!==this.status&&"PENDING"!==this.status||this._runAsyncValidator(t.emitEvent)),!1!==t.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._parent&&!t.onlySelf&&this._parent.updateValueAndValidity(t)},t.prototype._updateTreeValidity=function(t){void 0===t&&(t={emitEvent:!0}),this._forEachChild(function(e){return e._updateTreeValidity(t)}),this.updateValueAndValidity({onlySelf:!0,emitEvent:t.emitEvent})},t.prototype._setInitialStatus=function(){this.status=this._allControlsDisabled()?"DISABLED":"VALID"},t.prototype._runValidator=function(){return this.validator?this.validator(this):null},t.prototype._runAsyncValidator=function(t){var e=this;if(this.asyncValidator){this.status="PENDING";var n=b(this.asyncValidator(this));this._asyncValidationSubscription=n.subscribe(function(n){return e.setErrors(n,{emitEvent:t})})}},t.prototype._cancelExistingSubscription=function(){this._asyncValidationSubscription&&this._asyncValidationSubscription.unsubscribe()},t.prototype.setErrors=function(t,e){void 0===e&&(e={}),this.errors=t,this._updateControlsErrors(!1!==e.emitEvent)},t.prototype.get=function(t){return function(t,e,n){return null==e?null:(e instanceof Array||(e=e.split(".")),e instanceof Array&&0===e.length?null:e.reduce(function(t,e){return t instanceof ut?t.controls.hasOwnProperty(e)?t.controls[e]:null:t instanceof ct&&t.at(e)||null},t))}(this,t)},t.prototype.getError=function(t,e){var n=e?this.get(e):this;return n&&n.errors?n.errors[t]:null},t.prototype.hasError=function(t,e){return!!this.getError(t,e)},Object.defineProperty(t.prototype,"root",{get:function(){for(var t=this;t._parent;)t=t._parent;return t},enumerable:!0,configurable:!0}),t.prototype._updateControlsErrors=function(t){this.status=this._calculateStatus(),t&&this.statusChanges.emit(this.status),this._parent&&this._parent._updateControlsErrors(t)},t.prototype._initObservables=function(){this.valueChanges=new r.EventEmitter,this.statusChanges=new r.EventEmitter},t.prototype._calculateStatus=function(){return this._allControlsDisabled()?"DISABLED":this.errors?"INVALID":this._anyControlsHaveStatus("PENDING")?"PENDING":this._anyControlsHaveStatus("INVALID")?"INVALID":"VALID"},t.prototype._anyControlsHaveStatus=function(t){return this._anyControls(function(e){return e.status===t})},t.prototype._anyControlsDirty=function(){return this._anyControls(function(t){return t.dirty})},t.prototype._anyControlsTouched=function(){return this._anyControls(function(t){return t.touched})},t.prototype._updatePristine=function(t){void 0===t&&(t={}),this.pristine=!this._anyControlsDirty(),this._parent&&!t.onlySelf&&this._parent._updatePristine(t)},t.prototype._updateTouched=function(t){void 0===t&&(t={}),this.touched=this._anyControlsTouched(),this._parent&&!t.onlySelf&&this._parent._updateTouched(t)},t.prototype._isBoxedValue=function(t){return"object"==typeof t&&null!==t&&2===Object.keys(t).length&&"value"in t&&"disabled"in t},t.prototype._registerOnCollectionChange=function(t){this._onCollectionChange=t},t.prototype._setUpdateStrategy=function(t){it(t)&&null!=t.updateOn&&(this._updateOn=t.updateOn)},t}(),ot=function(t){function e(e,n,a){void 0===e&&(e=null);var r=t.call(this,at(n),rt(a,n))||this;return r._onChange=[],r._applyFormState(e),r._setUpdateStrategy(n),r.updateValueAndValidity({onlySelf:!0,emitEvent:!1}),r._initObservables(),r}return Object(a.__extends)(e,t),e.prototype.setValue=function(t,e){var n=this;void 0===e&&(e={}),this.value=this._pendingValue=t,this._onChange.length&&!1!==e.emitModelToViewChange&&this._onChange.forEach(function(t){return t(n.value,!1!==e.emitViewToModelChange)}),this.updateValueAndValidity(e)},e.prototype.patchValue=function(t,e){void 0===e&&(e={}),this.setValue(t,e)},e.prototype.reset=function(t,e){void 0===t&&(t=null),void 0===e&&(e={}),this._applyFormState(t),this.markAsPristine(e),this.markAsUntouched(e),this.setValue(this.value,e),this._pendingChange=!1},e.prototype._updateValue=function(){},e.prototype._anyControls=function(t){return!1},e.prototype._allControlsDisabled=function(){return this.disabled},e.prototype.registerOnChange=function(t){this._onChange.push(t)},e.prototype._clearChangeFns=function(){this._onChange=[],this._onDisabledChange=[],this._onCollectionChange=function(){}},e.prototype.registerOnDisabledChange=function(t){this._onDisabledChange.push(t)},e.prototype._forEachChild=function(t){},e.prototype._syncPendingControls=function(){return!("submit"!==this.updateOn||(this._pendingDirty&&this.markAsDirty(),this._pendingTouched&&this.markAsTouched(),!this._pendingChange)||(this.setValue(this._pendingValue,{onlySelf:!0,emitModelToViewChange:!1}),0))},e.prototype._applyFormState=function(t){this._isBoxedValue(t)?(this.value=this._pendingValue=t.value,t.disabled?this.disable({onlySelf:!0,emitEvent:!1}):this.enable({onlySelf:!0,emitEvent:!1})):this.value=this._pendingValue=t},e}(st),ut=function(t){function e(e,n,a){var r=t.call(this,at(n),rt(a,n))||this;return r.controls=e,r._initObservables(),r._setUpdateStrategy(n),r._setUpControls(),r.updateValueAndValidity({onlySelf:!0,emitEvent:!1}),r}return Object(a.__extends)(e,t),e.prototype.registerControl=function(t,e){return this.controls[t]?this.controls[t]:(this.controls[t]=e,e.setParent(this),e._registerOnCollectionChange(this._onCollectionChange),e)},e.prototype.addControl=function(t,e){this.registerControl(t,e),this.updateValueAndValidity(),this._onCollectionChange()},e.prototype.removeControl=function(t){this.controls[t]&&this.controls[t]._registerOnCollectionChange(function(){}),delete this.controls[t],this.updateValueAndValidity(),this._onCollectionChange()},e.prototype.setControl=function(t,e){this.controls[t]&&this.controls[t]._registerOnCollectionChange(function(){}),delete this.controls[t],e&&this.registerControl(t,e),this.updateValueAndValidity(),this._onCollectionChange()},e.prototype.contains=function(t){return this.controls.hasOwnProperty(t)&&this.controls[t].enabled},e.prototype.setValue=function(t,e){var n=this;void 0===e&&(e={}),this._checkAllValuesPresent(t),Object.keys(t).forEach(function(a){n._throwIfControlMissing(a),n.controls[a].setValue(t[a],{onlySelf:!0,emitEvent:e.emitEvent})}),this.updateValueAndValidity(e)},e.prototype.patchValue=function(t,e){var n=this;void 0===e&&(e={}),Object.keys(t).forEach(function(a){n.controls[a]&&n.controls[a].patchValue(t[a],{onlySelf:!0,emitEvent:e.emitEvent})}),this.updateValueAndValidity(e)},e.prototype.reset=function(t,e){void 0===t&&(t={}),void 0===e&&(e={}),this._forEachChild(function(n,a){n.reset(t[a],{onlySelf:!0,emitEvent:e.emitEvent})}),this.updateValueAndValidity(e),this._updatePristine(e),this._updateTouched(e)},e.prototype.getRawValue=function(){return this._reduceChildren({},function(t,e,n){return t[n]=e instanceof ot?e.value:e.getRawValue(),t})},e.prototype._syncPendingControls=function(){var t=this._reduceChildren(!1,function(t,e){return!!e._syncPendingControls()||t});return t&&this.updateValueAndValidity({onlySelf:!0}),t},e.prototype._throwIfControlMissing=function(t){if(!Object.keys(this.controls).length)throw new Error("\n There are no form controls registered with this group yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");if(!this.controls[t])throw new Error("Cannot find form control with name: "+t+".")},e.prototype._forEachChild=function(t){var e=this;Object.keys(this.controls).forEach(function(n){return t(e.controls[n],n)})},e.prototype._setUpControls=function(){var t=this;this._forEachChild(function(e){e.setParent(t),e._registerOnCollectionChange(t._onCollectionChange)})},e.prototype._updateValue=function(){this.value=this._reduceValue()},e.prototype._anyControls=function(t){var e=this,n=!1;return this._forEachChild(function(a,r){n=n||e.contains(r)&&t(a)}),n},e.prototype._reduceValue=function(){var t=this;return this._reduceChildren({},function(e,n,a){return(n.enabled||t.disabled)&&(e[a]=n.value),e})},e.prototype._reduceChildren=function(t,e){var n=t;return this._forEachChild(function(t,a){n=e(n,t,a)}),n},e.prototype._allControlsDisabled=function(){var t,e;try{for(var n=Object(a.__values)(Object.keys(this.controls)),r=n.next();!r.done;r=n.next())if(this.controls[r.value].enabled)return!1}catch(i){t={error:i}}finally{try{r&&!r.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}return Object.keys(this.controls).length>0||this.disabled},e.prototype._checkAllValuesPresent=function(t){this._forEachChild(function(e,n){if(void 0===t[n])throw new Error("Must supply a value for form control with name: '"+n+"'.")})},e}(st),ct=function(t){function e(e,n,a){var r=t.call(this,at(n),rt(a,n))||this;return r.controls=e,r._initObservables(),r._setUpdateStrategy(n),r._setUpControls(),r.updateValueAndValidity({onlySelf:!0,emitEvent:!1}),r}return Object(a.__extends)(e,t),e.prototype.at=function(t){return this.controls[t]},e.prototype.push=function(t){this.controls.push(t),this._registerControl(t),this.updateValueAndValidity(),this._onCollectionChange()},e.prototype.insert=function(t,e){this.controls.splice(t,0,e),this._registerControl(e),this.updateValueAndValidity()},e.prototype.removeAt=function(t){this.controls[t]&&this.controls[t]._registerOnCollectionChange(function(){}),this.controls.splice(t,1),this.updateValueAndValidity()},e.prototype.setControl=function(t,e){this.controls[t]&&this.controls[t]._registerOnCollectionChange(function(){}),this.controls.splice(t,1),e&&(this.controls.splice(t,0,e),this._registerControl(e)),this.updateValueAndValidity(),this._onCollectionChange()},Object.defineProperty(e.prototype,"length",{get:function(){return this.controls.length},enumerable:!0,configurable:!0}),e.prototype.setValue=function(t,e){var n=this;void 0===e&&(e={}),this._checkAllValuesPresent(t),t.forEach(function(t,a){n._throwIfControlMissing(a),n.at(a).setValue(t,{onlySelf:!0,emitEvent:e.emitEvent})}),this.updateValueAndValidity(e)},e.prototype.patchValue=function(t,e){var n=this;void 0===e&&(e={}),t.forEach(function(t,a){n.at(a)&&n.at(a).patchValue(t,{onlySelf:!0,emitEvent:e.emitEvent})}),this.updateValueAndValidity(e)},e.prototype.reset=function(t,e){void 0===t&&(t=[]),void 0===e&&(e={}),this._forEachChild(function(n,a){n.reset(t[a],{onlySelf:!0,emitEvent:e.emitEvent})}),this.updateValueAndValidity(e),this._updatePristine(e),this._updateTouched(e)},e.prototype.getRawValue=function(){return this.controls.map(function(t){return t instanceof ot?t.value:t.getRawValue()})},e.prototype._syncPendingControls=function(){var t=this.controls.reduce(function(t,e){return!!e._syncPendingControls()||t},!1);return t&&this.updateValueAndValidity({onlySelf:!0}),t},e.prototype._throwIfControlMissing=function(t){if(!this.controls.length)throw new Error("\n There are no form controls registered with this array yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n ");if(!this.at(t))throw new Error("Cannot find form control at index "+t)},e.prototype._forEachChild=function(t){this.controls.forEach(function(e,n){t(e,n)})},e.prototype._updateValue=function(){var t=this;this.value=this.controls.filter(function(e){return e.enabled||t.disabled}).map(function(t){return t.value})},e.prototype._anyControls=function(t){return this.controls.some(function(e){return e.enabled&&t(e)})},e.prototype._setUpControls=function(){var t=this;this._forEachChild(function(e){return t._registerControl(e)})},e.prototype._checkAllValuesPresent=function(t){this._forEachChild(function(e,n){if(void 0===t[n])throw new Error("Must supply a value for form control at index: "+n+".")})},e.prototype._allControlsDisabled=function(){var t,e;try{for(var n=Object(a.__values)(this.controls),r=n.next();!r.done;r=n.next())if(r.value.enabled)return!1}catch(i){t={error:i}}finally{try{r&&!r.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}return this.controls.length>0||this.disabled},e.prototype._registerControl=function(t){t.setParent(this),t._registerOnCollectionChange(this._onCollectionChange)},e}(st),lt=Promise.resolve(null),dt=function(t){function e(e,n){var a=t.call(this)||this;return a.submitted=!1,a._directives=[],a.ngSubmit=new r.EventEmitter,a.form=new ut({},U(e),W(n)),a}return Object(a.__extends)(e,t),e.prototype.ngAfterViewInit=function(){this._setUpdateStrategy()},Object.defineProperty(e.prototype,"formDirective",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"control",{get:function(){return this.form},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"controls",{get:function(){return this.form.controls},enumerable:!0,configurable:!0}),e.prototype.addControl=function(t){var e=this;lt.then(function(){var n=e._findContainer(t.path);t.control=n.registerControl(t.name,t.control),G(t.control,t),t.control.updateValueAndValidity({emitEvent:!1}),e._directives.push(t)})},e.prototype.getControl=function(t){return this.form.get(t.path)},e.prototype.removeControl=function(t){var e=this;lt.then(function(){var n=e._findContainer(t.path);n&&n.removeControl(t.name),J(e._directives,t)})},e.prototype.addFormGroup=function(t){var e=this;lt.then(function(){var n=e._findContainer(t.path),a=new ut({});V(a,t),n.registerControl(t.name,a),a.updateValueAndValidity({emitEvent:!1})})},e.prototype.removeFormGroup=function(t){var e=this;lt.then(function(){var n=e._findContainer(t.path);n&&n.removeControl(t.name)})},e.prototype.getFormGroup=function(t){return this.form.get(t.path)},e.prototype.updateModel=function(t,e){var n=this;lt.then(function(){n.form.get(t.path).setValue(e)})},e.prototype.setValue=function(t){this.control.setValue(t)},e.prototype.onSubmit=function(t){return this.submitted=!0,Z(this.form,this._directives),this.ngSubmit.emit(t),!1},e.prototype.onReset=function(){this.resetForm()},e.prototype.resetForm=function(t){void 0===t&&(t=void 0),this.form.reset(t),this.submitted=!1},e.prototype._setUpdateStrategy=function(){this.options&&null!=this.options.updateOn&&(this.form._updateOn=this.options.updateOn)},e.prototype._findContainer=function(t){return t.pop(),t.length?this.form.get(t):this.form},e}(l),ft=function(){function t(){}return t.modelParentException=function(){throw new Error('\n ngModel cannot be used to register form controls with a parent formGroup directive. Try using\n formGroup\'s partner directive "formControlName" instead. Example:\n\n '+R+'\n\n Or, if you\'d like to avoid registering this form control, indicate that it\'s standalone in ngModelOptions:\n\n Example:\n\n \n
\n \n \n
\n ')},t.formGroupNameException=function(){throw new Error("\n ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.\n\n Option 1: Use formControlName instead of ngModel (reactive strategy):\n\n "+A+"\n\n Option 2: Update ngModel's parent be ngModelGroup (template-driven strategy):\n\n "+D)},t.missingNameException=function(){throw new Error('If ngModel is used within a form tag, either the name attribute must be set or the form\n control must be defined as \'standalone\' in ngModelOptions.\n\n Example 1: \n Example 2: ')},t.modelGroupParentException=function(){throw new Error("\n ngModelGroup cannot be used with a parent formGroup directive.\n\n Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):\n\n "+A+"\n\n Option 2: Use a regular form tag instead of the formGroup directive (template-driven strategy):\n\n "+D)},t.ngFormWarning=function(){console.warn("\n It looks like you're using 'ngForm'.\n\n Support for using the 'ngForm' element selector has been deprecated in Angular v6 and will be removed\n in Angular v9.\n\n Use 'ng-form' instead.\n\n Before:\n \n\n After:\n \n ")},t}(),pt=new r.InjectionToken("NgFormSelectorWarning"),ht=function(t){function e(e,n,a){var r=t.call(this)||this;return r._parent=e,r._validators=n,r._asyncValidators=a,r}var n;return Object(a.__extends)(e,t),n=e,e.prototype._checkParentType=function(){this._parent instanceof n||this._parent instanceof dt||ft.modelGroupParentException()},e}(Q),gt=Promise.resolve(null),bt=function(t){function e(e,n,a,i){var s=t.call(this)||this;return s.control=new ot,s._registered=!1,s.update=new r.EventEmitter,s._parent=e,s._rawValidators=n||[],s._rawAsyncValidators=a||[],s.valueAccessor=X(s,i),s}return Object(a.__extends)(e,t),e.prototype.ngOnChanges=function(t){this._checkForErrors(),this._registered||this._setUpControl(),"isDisabled"in t&&this._updateDisabled(t),K(t,this.viewModel)&&(this._updateValue(this.model),this.viewModel=this.model)},e.prototype.ngOnDestroy=function(){this.formDirective&&this.formDirective.removeControl(this)},Object.defineProperty(e.prototype,"path",{get:function(){return this._parent?z(this.name,this._parent):[this.name]},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"formDirective",{get:function(){return this._parent?this._parent.formDirective:null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return U(this._rawValidators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return W(this._rawAsyncValidators)},enumerable:!0,configurable:!0}),e.prototype.viewToModelUpdate=function(t){this.viewModel=t,this.update.emit(t)},e.prototype._setUpControl=function(){this._setUpdateStrategy(),this._isStandalone()?this._setUpStandalone():this.formDirective.addControl(this),this._registered=!0},e.prototype._setUpdateStrategy=function(){this.options&&null!=this.options.updateOn&&(this.control._updateOn=this.options.updateOn)},e.prototype._isStandalone=function(){return!this._parent||!(!this.options||!this.options.standalone)},e.prototype._setUpStandalone=function(){G(this.control,this),this.control.updateValueAndValidity({emitEvent:!1})},e.prototype._checkForErrors=function(){this._isStandalone()||this._checkParentType(),this._checkName()},e.prototype._checkParentType=function(){!(this._parent instanceof ht)&&this._parent instanceof Q?ft.formGroupNameException():this._parent instanceof ht||this._parent instanceof dt||ft.modelParentException()},e.prototype._checkName=function(){this.options&&this.options.name&&(this.name=this.options.name),this._isStandalone()||this.name||ft.missingNameException()},e.prototype._updateValue=function(t){var e=this;gt.then(function(){e.control.setValue(t,{emitViewToModelChange:!1})})},e.prototype._updateDisabled=function(t){var e=this,n=t.isDisabled.currentValue,a=""===n||n&&"false"!==n;gt.then(function(){a&&!e.control.disabled?e.control.disable():!a&&e.control.disabled&&e.control.enable()})},e}(I),mt=new r.InjectionToken("NgModelWithFormControlWarning"),yt=function(t){function e(e,n){var a=t.call(this)||this;return a._validators=e,a._asyncValidators=n,a.submitted=!1,a.directives=[],a.form=null,a.ngSubmit=new r.EventEmitter,a}return Object(a.__extends)(e,t),e.prototype.ngOnChanges=function(t){this._checkFormPresent(),t.hasOwnProperty("form")&&(this._updateValidators(),this._updateDomValue(),this._updateRegistrations())},Object.defineProperty(e.prototype,"formDirective",{get:function(){return this},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"control",{get:function(){return this.form},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return[]},enumerable:!0,configurable:!0}),e.prototype.addControl=function(t){var e=this.form.get(t.path);return G(e,t),e.updateValueAndValidity({emitEvent:!1}),this.directives.push(t),e},e.prototype.getControl=function(t){return this.form.get(t.path)},e.prototype.removeControl=function(t){J(this.directives,t)},e.prototype.addFormGroup=function(t){var e=this.form.get(t.path);V(e,t),e.updateValueAndValidity({emitEvent:!1})},e.prototype.removeFormGroup=function(t){},e.prototype.getFormGroup=function(t){return this.form.get(t.path)},e.prototype.addFormArray=function(t){var e=this.form.get(t.path);V(e,t),e.updateValueAndValidity({emitEvent:!1})},e.prototype.removeFormArray=function(t){},e.prototype.getFormArray=function(t){return this.form.get(t.path)},e.prototype.updateModel=function(t,e){this.form.get(t.path).setValue(e)},e.prototype.onSubmit=function(t){return this.submitted=!0,Z(this.form,this.directives),this.ngSubmit.emit(t),!1},e.prototype.onReset=function(){this.resetForm()},e.prototype.resetForm=function(t){void 0===t&&(t=void 0),this.form.reset(t),this.submitted=!1},e.prototype._updateDomValue=function(){var t=this;this.directives.forEach(function(e){var n=t.form.get(e.path);e.control!==n&&(function(t,e){e.valueAccessor.registerOnChange(function(){return H(e)}),e.valueAccessor.registerOnTouched(function(){return H(e)}),e._rawValidators.forEach(function(t){t.registerOnValidatorChange&&t.registerOnValidatorChange(null)}),e._rawAsyncValidators.forEach(function(t){t.registerOnValidatorChange&&t.registerOnValidatorChange(null)}),t&&t._clearChangeFns()}(e.control,e),n&&G(n,e),e.control=n)}),this.form._updateTreeValidity({emitEvent:!1})},e.prototype._updateRegistrations=function(){var t=this;this.form._registerOnCollectionChange(function(){return t._updateDomValue()}),this._oldForm&&this._oldForm._registerOnCollectionChange(function(){}),this._oldForm=this.form},e.prototype._updateValidators=function(){var t=U(this._validators);this.form.validator=h.compose([this.form.validator,t]);var e=W(this._asyncValidators);this.form.asyncValidator=h.composeAsync([this.form.asyncValidator,e])},e.prototype._checkFormPresent=function(){this.form||E.missingFormException()},e}(l),vt=function(t){function e(e,n,a){var r=t.call(this)||this;return r._parent=e,r._validators=n,r._asyncValidators=a,r}return Object(a.__extends)(e,t),e.prototype._checkParentType=function(){xt(this._parent)&&E.groupParentException()},e}(Q),_t=function(t){function e(e,n,a){var r=t.call(this)||this;return r._parent=e,r._validators=n,r._asyncValidators=a,r}return Object(a.__extends)(e,t),e.prototype.ngOnInit=function(){this._checkParentType(),this.formDirective.addFormArray(this)},e.prototype.ngOnDestroy=function(){this.formDirective&&this.formDirective.removeFormArray(this)},Object.defineProperty(e.prototype,"control",{get:function(){return this.formDirective.getFormArray(this)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"formDirective",{get:function(){return this._parent?this._parent.formDirective:null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"path",{get:function(){return z(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return U(this._validators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return W(this._asyncValidators)},enumerable:!0,configurable:!0}),e.prototype._checkParentType=function(){xt(this._parent)&&E.arrayParentException()},e}(l);function xt(t){return!(t instanceof vt||t instanceof yt||t instanceof _t)}var Tt=function(t){function e(e,n,a,i,s){var o=t.call(this)||this;return o._ngModelWarningConfig=s,o._added=!1,o.update=new r.EventEmitter,o._ngModelWarningSent=!1,o._parent=e,o._rawValidators=n||[],o._rawAsyncValidators=a||[],o.valueAccessor=X(o,i),o}var n;return Object(a.__extends)(e,t),n=e,Object.defineProperty(e.prototype,"isDisabled",{set:function(t){E.disabledAttrWarning()},enumerable:!0,configurable:!0}),e.prototype.ngOnChanges=function(t){var e,a;this._added||this._setUpControl(),K(t,this.viewModel)&&("formControlName",e=n,this,a=this._ngModelWarningConfig,Object(r.isDevMode)()&&"never"!==a&&((null!==a&&"once"!==a||e._ngModelWarningSentOnce)&&("always"!==a||this._ngModelWarningSent)||(E.ngModelWarning("formControlName"),e._ngModelWarningSentOnce=!0,this._ngModelWarningSent=!0)),this.viewModel=this.model,this.formDirective.updateModel(this,this.model))},e.prototype.ngOnDestroy=function(){this.formDirective&&this.formDirective.removeControl(this)},e.prototype.viewToModelUpdate=function(t){this.viewModel=t,this.update.emit(t)},Object.defineProperty(e.prototype,"path",{get:function(){return z(this.name,this._parent)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"formDirective",{get:function(){return this._parent?this._parent.formDirective:null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"validator",{get:function(){return U(this._rawValidators)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asyncValidator",{get:function(){return W(this._rawAsyncValidators)},enumerable:!0,configurable:!0}),e.prototype._checkParentType=function(){!(this._parent instanceof vt)&&this._parent instanceof Q?E.ngModelGroupException():this._parent instanceof vt||this._parent instanceof yt||this._parent instanceof _t||E.controlParentException()},e.prototype._setUpControl=function(){this._checkParentType(),this.control=this.formDirective.addControl(this),this.control.disabled&&this.valueAccessor.setDisabledState&&this.valueAccessor.setDisabledState(!0),this._added=!0},e._ngModelWarningSentOnce=!1,e}(I),wt=function(){function t(){}return Object.defineProperty(t.prototype,"required",{get:function(){return this._required},set:function(t){this._required=null!=t&&!1!==t&&""+t!="false",this._onChange&&this._onChange()},enumerable:!0,configurable:!0}),t.prototype.validate=function(t){return this.required?h.required(t):null},t.prototype.registerOnValidatorChange=function(t){this._onChange=t},t}(),St=function(){function t(){}return t.prototype.group=function(t,e){void 0===e&&(e=null);var n=this._reduceControls(t),a=null,r=null,i=void 0;return null!=e&&(function(t){return void 0!==t.asyncValidators||void 0!==t.validators||void 0!==t.updateOn}(e)?(a=null!=e.validators?e.validators:null,r=null!=e.asyncValidators?e.asyncValidators:null,i=null!=e.updateOn?e.updateOn:void 0):(a=null!=e.validator?e.validator:null,r=null!=e.asyncValidator?e.asyncValidator:null)),new ut(n,{asyncValidators:r,updateOn:i,validators:a})},t.prototype.control=function(t,e,n){return new ot(t,e,n)},t.prototype.array=function(t,e,n){var a=this,r=t.map(function(t){return a._createControl(t)});return new ct(r,e,n)},t.prototype._reduceControls=function(t){var e=this,n={};return Object.keys(t).forEach(function(a){n[a]=e._createControl(t[a])}),n},t.prototype._createControl=function(t){return t instanceof ot||t instanceof ut||t instanceof ct?t:Array.isArray(t)?this.control(t[0],t.length>1?t[1]:null,t.length>2?t[2]:null):this.control(t)},t}(),Ot=function(){return function(){}}(),It=function(){return function(){}}(),Ct=function(){function t(){}var e;return e=t,t.withConfig=function(t){return{ngModule:e,providers:[{provide:pt,useValue:t.warnOnDeprecatedNgFormSelector}]}},t}(),kt=function(){function t(){}var e;return e=t,t.withConfig=function(t){return{ngModule:e,providers:[{provide:mt,useValue:t.warnOnNgModelWithFormControl}]}},t}()},gVVK:function(t,e,n){!function(t){"use strict";function e(t,e,n,a){var r=t+" ";switch(n){case"s":return e||a?"nekaj sekund":"nekaj sekundami";case"ss":return r+(1===t?e?"sekundo":"sekundi":2===t?e||a?"sekundi":"sekundah":t<5?e||a?"sekunde":"sekundah":"sekund");case"m":return e?"ena minuta":"eno minuto";case"mm":return r+(1===t?e?"minuta":"minuto":2===t?e||a?"minuti":"minutama":t<5?e||a?"minute":"minutami":e||a?"minut":"minutami");case"h":return e?"ena ura":"eno uro";case"hh":return r+(1===t?e?"ura":"uro":2===t?e||a?"uri":"urama":t<5?e||a?"ure":"urami":e||a?"ur":"urami");case"d":return e||a?"en dan":"enim dnem";case"dd":return r+(1===t?e||a?"dan":"dnem":2===t?e||a?"dni":"dnevoma":e||a?"dni":"dnevi");case"M":return e||a?"en mesec":"enim mesecem";case"MM":return r+(1===t?e||a?"mesec":"mesecem":2===t?e||a?"meseca":"mesecema":t<5?e||a?"mesece":"meseci":e||a?"mesecev":"meseci");case"y":return e||a?"eno leto":"enim letom";case"yy":return r+(1===t?e||a?"leto":"letom":2===t?e||a?"leti":"letoma":t<5?e||a?"leta":"leti":e||a?"let":"leti")}}n("wd/R").defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_\u010detrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._\u010det._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_\u010de_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[v\u010deraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prej\u0161njo] [nedeljo] [ob] LT";case 3:return"[prej\u0161njo] [sredo] [ob] LT";case 6:return"[prej\u0161njo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prej\u0161nji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"\u010dez %s",past:"pred %s",s:e,ss:e,m:e,mm:e,h:e,hh:e,d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}()},gekB:function(t,e,n){!function(t){"use strict";var e="nolla yksi kaksi kolme nelj\xe4 viisi kuusi seitsem\xe4n kahdeksan yhdeks\xe4n".split(" "),n=["nolla","yhden","kahden","kolmen","nelj\xe4n","viiden","kuuden",e[7],e[8],e[9]];function a(t,a,r,i){var s="";switch(r){case"s":return i?"muutaman sekunnin":"muutama sekunti";case"ss":return i?"sekunnin":"sekuntia";case"m":return i?"minuutin":"minuutti";case"mm":s=i?"minuutin":"minuuttia";break;case"h":return i?"tunnin":"tunti";case"hh":s=i?"tunnin":"tuntia";break;case"d":return i?"p\xe4iv\xe4n":"p\xe4iv\xe4";case"dd":s=i?"p\xe4iv\xe4n":"p\xe4iv\xe4\xe4";break;case"M":return i?"kuukauden":"kuukausi";case"MM":s=i?"kuukauden":"kuukautta";break;case"y":return i?"vuoden":"vuosi";case"yy":s=i?"vuoden":"vuotta"}return function(t,a){return t<10?a?n[t]:e[t]:t}(t,i)+" "+s}t.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kes\xe4kuu_hein\xe4kuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kes\xe4_hein\xe4_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[t\xe4n\xe4\xe4n] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s p\xe4\xe4st\xe4",past:"%s sitten",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n("wd/R"))},gjCT:function(t,e,n){!function(t){"use strict";var e={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},n={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"};t.defineLocale("ar-sa",{months:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u064a\u0646\u0627\u064a\u0631_\u0641\u0628\u0631\u0627\u064a\u0631_\u0645\u0627\u0631\u0633_\u0623\u0628\u0631\u064a\u0644_\u0645\u0627\u064a\u0648_\u064a\u0648\u0646\u064a\u0648_\u064a\u0648\u0644\u064a\u0648_\u0623\u063a\u0633\u0637\u0633_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(t){return"\u0645"===t},meridiem:function(t,e,n){return t<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},preparse:function(t){return t.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(t){return n[t]}).replace(/\u060c/g,",")},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]}).replace(/,/g,"\u060c")},week:{dow:0,doy:6}})}(n("wd/R"))},gp3X:function(t,e,n){"use strict";var a=n("CcnG"),r=n("Ip0R");n("sb0X"),n.d(e,"a",function(){return i}),n.d(e,"b",function(){return o});var i=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function s(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,0,"i",[["class","fa fa-spinner fa-spin fa-fw"]],null,null,null,null,null))],null,null)}function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"button",[["class","btn btn-sm btn-primary tc_submitButton"]],[[8,"type",0],[8,"disabled",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.submit(n)&&a),a},null,null)),a["\u0275ncd"](null,0),(t()(),a["\u0275and"](16777216,null,null,1,null,s)),a["\u0275did"](3,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,3,0,e.component.loading)},function(t,e){var n=e.component;t(e,0,0,n.type,n.loading||n.disabled)})}},"h+PQ":function(t,e,n){"use strict";function a(){return""}function r(t,e){if(null==t)return"";if(!t||null==e)return t;var n=t[e];return null==n?"":n}function i(t,e){if(null==t)return"";if(!t||!e)return t;var n=t[e];return null==n?"":n}function s(t,e){if(null==t)return"";if(!t||!e)return t;var n=t[e];if(void 0!==n)return n;n=t;var a=e.split(".");if(a.length)for(var r=0;re)return 1}else if(isNaN(parseFloat(t))||!isFinite(t)||isNaN(parseFloat(e))||!isFinite(e)){if(t=String(t),e=String(e),t.toLowerCase()e.toLowerCase())return 1}else{if(parseFloat(t)parseFloat(e))return 1}return 0}e.nextSortDir=function(t,e){return t===a.SortType.single?e===a.SortDirection.asc?a.SortDirection.desc:a.SortDirection.asc:e?e===a.SortDirection.asc?a.SortDirection.desc:void 0:a.SortDirection.asc},e.orderByComparator=i,e.sortRows=function(t,e,n){if(!t)return[];if(!n||!n.length||!e)return t.slice();var s=new Map;t.forEach(function(t,e){return s.set(t,e)});var o=t.slice(),u=e.reduce(function(t,e){return e.comparator&&"function"==typeof e.comparator&&(t[e.prop]=e.comparator),t},{}),c=n.map(function(t){var e=t.prop;return{prop:e,dir:t.dir,valueGetter:r.getterForProp(e),compareFn:u[e]||i}});return o.sort(function(t,e){for(var n=0,r=c;n\n \n \n \n Toggle navigation\n Attiva/Disattiva barra di navigazione\n \n \n Dashboard\n Dashboard\n \n \n Cluster\n Cluster\n \n \n Hosts\n Host\n \n \n Monitors\n Monitor\n \n \n OSDs\n OSD\n \n \n Configuration\n Configurazione\n \n \n CRUSH map\n Mappa CRUSH\n \n \n Manager modules\n Moduli Manager\n \n \n Logs\n Log\n \n \n Alerts\n Avvisi\n \n \n Silences\n Silences\n \n \n Pools\n Pool\n \n \n Block\n Blocco\n \n \n Images\n Immagini\n \n \n Mirroring\n Esecuzione della copia speculare\n \n \n iSCSI\n iSCSI \n \n \n NFS\n NFS\n \n \n Filesystems\n File system\n \n \n Object Gateway\n Object Gateway\n \n \n Daemons\n Daemon\n \n \n Users\n Utenti\n \n \n Buckets\n Compartimenti\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Recupero dati\n per\n \n \n . Attendere...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Visualizzazione dei dati memorizzati in precedenza nella cache\n \n per \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Impossibile caricare i dati\n per\n \n \n .\n Verificare lo stato del cluster.\n \n \n \n Back\n Indietro\n \n \n Select a Language\n Selezionare una lingua\n \n \n Loading panel data...\n Caricamento pannello dati in corso...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Consultare la\n documentazione\n su come\n configurare e abilitare la funzionalit\xe0 di monitoraggio.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Il dashboard di Grafana non esiste. Consultare la\n documentazione\n su come\n aggiungere dashboard a Grafana.\n \n \n \n Grafana Time Picker\n Selezione ora di Grafana\n \n \n Reset Settings\n Impostazioni di ripristino\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n Non \xe8 stato possibile caricare i dati.\n \n \n selected\n selezionato\n X selected\n \n \n found\n trovato\n X found\n \n \n total\n totale\n X total\n \n \n Edit\n Modifica\n \n \n Name\n Nome\n \n \n Description\n Descrizione\n \n \n Long description\n Descrizione lunga\n \n \n Default\n Default\n \n \n Daemon default\n Default del daemon\n \n \n Services\n Servizi\n \n \n Values\n Valori\n \n \n The entered value is too high! It must not be greater than \n .\n \n Il valore immesso \xe8 troppo alto. Non deve essere maggiore di \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Il valore immesso \xe8 troppo basso. Non deve essere minore di \n .\n \n \n \n Save\n Salva\n \n \n CRUSH map viewer\n Visualizzatore mappa CRUSH\n \n \n Hosts List\n Elenco degli host\n \n \n Overall Performance\n Prestazioni complessive\n \n \n No entries found\n Nessuna voce trovata\n \n \n Cluster Logs\n Log dei cluster\n \n \n Audit Logs\n Log delle revisioni\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n Caricamento della configurazione in corso...\n \n \n The configuration could not be loaded.\n Impossibile caricare la configurazione.\n \n \n Edit Manager module\n Modifica modulo Manager\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n Il valore immesso non \xe8 un UUID valido, ad es.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n Il valore immesso deve essere un indirizzo IP valido.\n \n \n This field is required.\n Questo campo \xe8 obbligatorio.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n Il valore immesso \xe8 troppo alto. Deve essere minore o uguale a \n .\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n Il valore immesso \xe8 troppo basso. Deve essere maggiore o uguale a \n .\n \n \n \n The entered value needs to be a number.\n Il valore immesso deve essere un numero.\n \n \n The entered value needs to be a number or decimal.\n Il valore immesso deve essere un numero o un decimale.\n \n \n Update\n Aggiorna\n \n \n Status\n Stato\n \n \n Cluster ID\n ID cluster\n \n \n monmap modified\n mappa mon modificata\n \n \n monmap epoch\n epoca mappa mon\n \n \n quorum con\n quorum con\n \n \n quorum mon\n quorum mon\n \n \n required con\n con richiesta\n \n \n required mon\n mon richiesto\n \n \n In Quorum\n Nel quorum\n \n \n Not In Quorum\n Non nel quorum\n \n \n Cancel\n Annulla\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n Si \xe8 sicuri di voler \n l\'elemento \n selezionato?\n \n \n \n Yes, I am sure.\n S\xec.\n \n \n Cluster-wide OSD Flags\n Flag OSD in tutto il cluster\n \n \n Submit\n Invia\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Avanzate...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n Priorit\xe0 di recupero OSD\n \n \n Priority\n Priorit\xe0\n \n \n Customize priority values\n Personalizza valori di priorit\xe0\n \n \n This field is required!\n Questo campo \xe8 obbligatorio.\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n Il valore immesso \xe8 troppo alto. Non deve essere maggiore di \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Il valore immesso \xe8 troppo basso. Non deve essere minore di \n .\n \n \n \n Reweight OSD\n Ripesa OSD\n \n \n The value needs to be between 0 and 1.\n Il valore deve essere compreso tra 0 e 1.\n \n \n Reweight\n Ripesa\n \n \n OSDs \n Scrub\n \n Pulitura degli \n OSD\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {Deep } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Si sta per eseguire una \n pulitura\n dell\'OSD \n \n \n .\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {deep } }\n \n \n OSDs List\n Elenco degli OSD\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \n L\'OSD \n \n viene contrassegnato\n \n \n se si procede.\n \n \n \n The OSD is not safe to destroy!\n Non \xe8 sicuro eliminare definitivamente l\'OSD.\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \n L\'OSD \n \n viene\n \n \n se si procede.\n \n \n \n Details\n Dettagli\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Valore\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Chiudi\n \n \n Delete\n Elimina\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Stato\n \n \n Statistics\n Statistiche\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Consultare la \n documentazione\n \n su come configurare e abilitare la funzionalit\xe0 di gestione di NFS Ganesha.\n \n \n \n Clients\n Client\n \n \n Any client can access\n Pu\xf2 accedere qualsiasi client\n \n \n Addresses\n Indirizzi\n \n \n Required field\n Campo obbligatorio\n \n \n Must contain one or more comma-separated values\n Deve contenere uno o pi\xf9 valori delimitati da virgole\n \n \n For example:\n Ad esempio:\n \n \n Access Type\n Tipo di accesso\n \n \n Squash\n Esegui squash\n \n \n Add clients\n Aggiungi client\n \n \n Loading...\n Caricamento in corso...\n \n \n -- No cluster available --\n -- Nessun cluster disponibile --\n \n \n -- Select the cluster --\n -- Selezionare il cluster --\n \n \n Add daemon\n Aggiungi daemon\n \n \n Storage Backend\n Backend di storage\n \n \n -- No data pools available --\n -- Nessun pool di dati disponibile --\n \n \n -- Select the storage backend --\n -- Selezionare il backend di storage --\n \n \n Object Gateway User\n Utente Object Gateway\n \n \n -- No users available --\n -- Nessun utente disponibile --\n \n \n -- Select the object gateway user --\n -- Selezionare l\'utente Object Gateway --\n \n \n CephFS User ID\n ID utente CephFS\n \n \n -- No clients available --\n -- Nessun client disponibile --\n \n \n -- Select the cephx client --\n -- Selezionare il client Cephx --\n \n \n CephFS Name\n Nome CephFS\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n Etichetta di sicurezza\n \n \n Enable security label\n Abilita etichetta di sicurezza\n \n \n CephFS Path\n Percorso CephFS\n \n \n Path need to start with a \'/\' and can be followed by a word\n Il percorso deve iniziare con una barra \'/\' e pu\xf2 essere seguito da una parola\n \n \n New directory will be created\n Viene creata la nuova directory\n \n \n Path\n Percorso\n \n \n Path can only be a single \'/\' or a word\n Il percorso pu\xf2 essere solo una singola barra \'/\' o parola\n \n \n New bucket will be created\n Viene creato il nuovo compartimento\n \n \n NFS Protocol\n Protocollo NFS\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n Tag NFS\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Accesso alternativo per montaggi \n NFS v3\n (non deve contenere una / iniziale).\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n I client non possono montare le sottodirectory (ad es. se Tag = foo, il client non pu\xf2 montare foo/baz).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n Utilizzando diverse opzioni Tag, \xe8 possibile esportare pi\xf9 volte lo stesso percorso.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n La posizione che occupa l\'esportazione \n NFS v4\n \n nello \n Pseudo FS\n (deve essere univoca).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n Utilizzando diverse opzioni Pseudo, \xe8 possibile esportare pi\xf9 volte lo stesso percorso.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- Nessun tipo di accesso disponibile --\n \n \n -- Select the access type --\n -- Selezionare il tipo di accesso --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- Nessuno squash disponibile --\n \n \n --Select what kind of user id squashing is performed --\n --Selezionare il tipo di squash dell\'ID utente da eseguire --\n \n \n Transport Protocol\n Protocollo di trasporto\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Benvenuto in Ceph.\n The welcome message on the login page\n \n \n Username is required\n Nome utente necessario\n \n \n Password is required\n Password richiesta\n \n \n Login\n Login\n \n \n Sorry, the user does not exist in Ceph.\n Spiacenti, l\'utente non esiste in Ceph.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Tornale alla \n Pagina di login\n . Si viene disconnessi dal Provider di identit\xe0\n quando si riprova a eseguire il login.\n \n \n \n Forbidden\n Non consentito\n \n \n Sorry, you are not allowed to see what you were looking for.\n Spiacenti, non \xe8 consentito visualizzare ci\xf2 che si stava cercando.\n \n \n Sorry, we could not find what you were looking for\n Spiacenti, impossibile trovare ci\xf2 che si stava cercando\n \n \n Remove all\n Rimuovi tutto\n \n \n Recent Notifications\n Notifiche recenti\n \n \n There are no background tasks.\n Non esistono task in background.\n \n \n Background Tasks\n Task in background\n \n \n Help\n Guida\n \n \n Documentation\n Documentazione\n \n \n API\n API\n \n \n About\n Informazioni su\n \n \n Dashboard Settings\n Impostazioni del dashboard\n \n \n User management\n Gestione utenti\n \n \n Logged in user\n Utente connesso\n \n \n Signed in as\n \n \n \n \n Connesso come\n \n \n \n \n \n \n Sign out\n Disconnetti\n \n \n Name...\n Nome...\n \n \n The chosen name is already in use.\n Il nome scelto \xe8 gi\xe0 in uso.\n \n \n Description...\n Descrizione...\n \n \n Permissions\n Autorizzazioni\n \n \n Roles\n Ruoli\n \n \n Username\n Nome utente\n \n \n Password\n Password\n \n \n Confirm password\n Conferma password\n \n \n Password confirmation doesn\'t match the password.\n La password di conferma non corrisponde alla password.\n \n \n Full name\n Nome completo\n \n \n Email\n E-mail\n \n \n Invalid email.\n E-mail non valida.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Si stanno per rimuovere le autorizzazioni di "lettura/aggiornamento utente" dal proprio utente.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Se si continua, non \xe8 pi\xf9 possibile aggiungere o rimuovere ruoli da qualsiasi utente.\n \n \n Are you sure you want to continue?\n Continuare?\n \n \n Performance counters not available\n Contatori delle prestazioni non disponibili\n \n \n Attributes (OSD map)\n Attributi (mappa OSD)\n \n \n Metadata not available\n Metadati non disponibili\n \n \n Metadata\n Metadati\n \n \n Performance counter\n Contatore delle prestazioni\n \n \n Histogram not available: \n \n \n Istogramma non disponibile: \n \n \n \n \n Writes\n Scritture\n \n \n Reads\n Letture\n \n \n Histogram\n Istogramma\n \n \n Performance Details\n Dettagli sulle prestazioni\n \n \n Current values\n Valori attuali\n \n \n Type\n Tipo\n \n \n Min\n Min\n \n \n Max\n Max\n \n \n Flags\n Flag\n \n \n Source\n Origine\n \n \n Level\n Livello\n \n \n Can be updated at runtime (editable)\n Pu\xf2 essere aggiornato al runtime (modificabile)\n \n \n Tags\n Tag\n \n \n Enum values\n Valori di enumerazione\n \n \n See also\n Vedere anche\n \n \n Cluster Status\n Stato del cluster\n \n \n Manager Daemons\n Manager Daemon\n \n \n Object Gateways\n Object Gateway\n \n \n Metadata Servers\n Server di metadati\n \n \n iSCSI Gateways\n iSCSI Gateway\n \n \n Client IOPS\n IOPS client\n \n \n Client Throughput\n Velocit\xe0 effettiva client\n \n \n Client Read/Write\n Lettura/scrittura client\n \n \n Recovery Throughput\n Velocit\xe0 effettiva di recupero\n \n \n Scrub\n Pulitura\n \n \n Performance\n Prestazioni\n \n \n Raw Capacity\n Capacit\xe0 di base\n \n \n Objects\n Oggetti\n \n \n PGs per OSD\n Gruppi di posizionamento per OSD\n \n \n PG Status\n Stato gruppo di posizionamento\n \n \n Capacity\n Capacit\xe0\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n Vedere \n Log\n per ulteriori informazioni.\n \n \n \n Ranks\n Classificazioni\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Client: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n Sposta un\'immagine nel cestino\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n Per spostare \n \n /\n \n nel cestino,\n fare clic su \n Sposta immagine\n . Facoltativamente, \xe8 possibile selezionare una data di scadenza.\n \n \n \n Protection expires at\n La protezione scade alle\n \n \n NOT PROTECTED\n NON PROTETTO\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Formato data errato. Utilizzare "AAAA-MM-GG HH:mm:ss".\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n La protezione \xe8 gi\xe0 scaduta. Selezionare una data futura o lasciarla vuota.\n \n \n Move Image\n Sposta immagine\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n Panoramica\n \n \n Targets\n Destinazioni\n \n \n Discovery Authentication\n Autenticazione rilevazione\n \n \n User\n Utente\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n I nomi utente devono avere una lunghezza compresa tra 8 e 64 caratteri e\n possono contenere solo lettere, \'.\', \'@\', \'-\', \'_\' o \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n Utente reciproco\n \n \n Mutual Password\n Password reciproca\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Consultare la \n documentazione\n \n su come configurare e abilitare la funzionalit\xe0 di gestione delle destinazioni iSCSI.\n \n \n \n Available information:\n Informazioni disponibili:\n \n \n iSCSI Targets not available\n Destinazioni iSCSI non disponibili\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n Disponibile solo per le immagini RDB con \n fast-diff\n abilitata\n \n \n \n Pool\n Pool\n \n \n Data Pool\n Pool di dati\n \n \n Created\n Creato\n \n \n Size\n Dimensioni\n \n \n Object size\n Dimensioni oggetto\n \n \n Features\n Funzioni\n \n \n Provisioned\n Soggetto al provisioning\n \n \n N/A\n N/D\n \n \n Total provisioned\n Totale soggetto al provisioning\n \n \n Striping unit\n Unit\xe0 di striping\n \n \n Striping count\n Conteggio di striping\n \n \n Parent\n Superiore\n \n \n Block name prefix\n Prefisso nome blocco\n \n \n Order\n Ordine\n \n \n Snapshots\n Snapshot\n \n \n Image\n Immagine\n \n \n This setting overrides the global value\n Questa impostazione sostituisce il valore globale\n \n \n Global\n Globale\n \n \n This is the global value. No value for this option has been set for this image.\n Questo \xe8 il valore globale. Nessun valore di opzione \xe8 stato impostato per questa immagine.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \'/\' e \'@\' non sono consentiti.\n \n \n -- No rbd pools available --\n -- Nessun pool rbd disponibile --\n \n \n -- Select a pool --\n -- Selezionare un pool --\n \n \n Use a dedicated data pool\n Utilizza un pool di dati dedicato\n \n \n Data pool\n Pool di dati\n \n \n Dedicated pool that stores the object-data of the RBD.\n Pool dedicato che archivia i dati oggetto dell\'RBD.\n \n \n e.g., 10GiB\n ad es. 10 GiB\n \n \n You have to increase the size.\n \xc8 necessario aumentare le dimensioni.\n \n \n Advanced\n Avanzate\n \n \n Striping\n Striping\n \n \n Stripe unit\n Unit\xe0 di striping\n \n \n -- Select stripe unit --\n -- Selezionare l\'unit\xe0 di striping --\n \n \n This field is required because stripe count is defined!\n Questo campo \xe8 obbligatorio perch\xe9 \xe8 specificato il numero di striping.\n \n \n Stripe unit is greater than object size.\n L\'unit\xe0 di striping \xe8 maggiore delle dimensioni dell\'oggetto.\n \n \n Stripe count\n Numero di striping\n \n \n This field is required because stripe unit is defined!\n Questo campo \xe8 obbligatorio perch\xe9 \xe8 specificata l\'unit\xe0 di striping.\n \n \n Stripe count must be greater than 0.\n Il numero di striping deve essere maggiore di 0.\n \n \n \n RBD Snapshot\n \n \n Snapshot RBD\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Rename} other {Create} }\n \n \n \n Snapshot\n \n \n Snapshot\n \n \n \n PROTECTED\n PROTETTO\n \n \n UNPROTECTED\n NON PROTETTO\n \n \n You are about to rollback\n Si sta per eseguire il rollback\n \n \n Purge Trash\n Elimina definitivamente contenuto del cestino\n \n \n To purge, select one or All images and click\n Per eliminare definitivamente, selezionare una o tutte le immagini e fare clic su\n \n \n Pool:\n Pool:\n \n \n Pool name...\n Nome pool...\n \n \n All\n Tutto\n \n \n Restore Image\n Ripristina immagine\n \n \n To restore\n Per ripristinare,\n \n \n type the image\'s new name and click\n digitare il nuovo nome dell\'immagine e fare clic su\n \n \n New Name\n Nuovo nome\n \n \n Expired at\n Scaduto alle\n \n \n Protected until\n Protetto fino alle\n \n \n This image is protected until \n .\n \n Questa immagine \xe8 protetta fino alle \n .\n \n \n \n Trash\n Cestino\n \n \n iSCSI Topology\n Topologia iSCSI\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n Di solito non \xe8 necessario modificare questi parametri rispetto ai valori di default.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Impostazioni\n \n \n Backstore\n Backstore\n \n \n Confirm\n Conferma\n \n \n Advanced Settings\n Impostazioni avanzate\n \n \n Target IQN\n IQN di destinazione\n \n \n IQN has wrong pattern.\n IQN contiene un modello errato.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n Un IQN contiene la notazione seguente \'iqn.$year-$month.$reversedAddress:$definedName\'\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Ad esempio: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n Ulteriori informazioni\n \n \n This target has modified advanced settings.\n Questa destinazione contiene impostazioni avanzate modificate.\n \n \n Portals\n Portali\n \n \n At least \n gateways are required.\n \n Gateway richiesti: almeno \n .\n \n \n \n Add portal\n Aggiungi portale\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Questa immagine contiene impostazioni modificate.\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n Aggiungi immagine\n \n \n ACL authentication\n Autenticazione ACL\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Iniziatori\n \n \n Initiator\n Iniziatore\n \n \n Client IQN\n IQN client\n \n \n Initiator IQN needs to be unique.\n L\'IQN dell\'iniziatore deve essere univoco.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n I nomi utente devono avere una lunghezza compresa tra 8 e 64 caratteri e\n possono contenere solo lettere, \'.\', \'@\', \'-\', \'_\' o \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n L\'iniziatore appartiene a un gruppo. Le immagini verranno configurate nel gruppo.\n \n \n No items added.\n Nessun elemento aggiunto.\n \n \n Add initiator\n Aggiungi iniziatore\n \n \n Groups\n Gruppi\n \n \n Group\n Gruppo\n \n \n Add group\n Aggiungi gruppo\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n Configurazione RBD\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Rimuovere il valore della configurazione locale. Al suo posto verr\xe0 ereditato e utilizzato il valore della configurazione superiore.\n \n \n The mininum value is 0\n Il valore minimo \xe8 0\n \n \n Issues\n Problemi\n \n \n Syncing\n Sincronizzazione in corso\n \n \n Ready\n Pronto\n \n \n Edit pool mirror mode\n Modifica modalit\xe0 speculare per il pool\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n Per modificare la modalit\xe0 speculare per il pool\xa0\n \n \n , selezionare una nuova modalit\xe0 dall\'elenco e fare clic su\xa0\n Aggiorna\n .\n \n \n \n Mode\n Modalit\xe0\n \n \n Peer clusters must be removed prior to disabling mirror.\n \xc8 necessario rimuovere i cluster peer prima di disabilitare la copia speculare.\n \n \n \n \n pool mirror peer\n \n \n \n peer copia speculare del pool\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Edit} other {Add} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n gli attributi peer della\n copia speculare per il pool \n \n \n e fare clic su \n Invia\n .\n \n \n \n Cluster Name\n Nome cluster\n \n \n The cluster name is not valid.\n Il nome del cluster non \xe8 valido.\n \n \n CephX ID\n ID CephX\n \n \n CephX ID...\n ID CephX...\n \n \n The CephX ID is not valid.\n L\'ID CephX non \xe8 valido.\n \n \n Monitor Addresses\n Indirizzi dei monitor\n \n \n Comma-delimited addresses...\n Indirizzi con valori delimitati da virgole...\n \n \n The monitory address is not valid.\n L\'indirizzo del monitor non \xe8 valido.\n \n \n CephX Key\n Chiave CephX\n \n \n Base64-encoded key...\n Chiave con codifica Base64...\n \n \n CephX key must be base64 encoded.\n La chiave CephX deve essere con codifica Base64.\n \n \n Pools List\n Elenco dei pool\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n Il nome pu\xf2 contenere solo caratteri alfanumerici, trattini e caratteri di sottolineatura.\n \n \n The chosen erasure code profile name is already in use.\n Il nome del profilo del codice di cancellazione selezionato \xe8 gi\xe0 in uso.\n \n \n Plugin\n Plugin\n \n \n Data chunks (k)\n Porzioni di dati (k)\n \n \n Must be equal to or greater than 2.\n Deve essere uguale o maggiore di 2.\n \n \n Coding chunks (m)\n Porzioni di codice (m)\n \n \n Must be equal to or greater than 1.\n Deve essere uguale o maggiore di 1.\n \n \n Durability estimator (c)\n Stima durata (c)\n \n \n Locality (l)\n Localit\xe0 (l)\n \n \n Crush failure domain\n Dominio di errore Crush\n \n \n Crush Locality\n Localit\xe0 Crush\n \n \n None\n Nessuno\n \n \n Technique\n Tecnica\n \n \n Packetsize\n Dimensione del pacchetto\n \n \n Crush root\n Radice Crush\n \n \n Crush device class\n Classe dispositivo Crush\n \n \n any\n qualsiasi\n \n \n Directory\n Directory\n \n \n The chosen Ceph pool name is already in use.\n Il nome del pool Ceph scelto \xe8 gi\xe0 in uso.\n \n \n Pool type\n Tipo di pool\n \n \n -- Select a pool type --\n -- Selezionare un tipo di pool --\n \n \n Placement groups\n Gruppi di posizionamento\n \n \n At least one placement group is needed!\n \xc8 necessario almeno un gruppo di posizionamento.\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n Il cluster non pu\xf2 gestire questo numero eccessivo di gruppi di posizionamento. Ricalcolare il numero di gruppi di posizionamento necessari.\n \n \n Calculation help\n Guida per il calcolo\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n Sono state calcolate le impostazioni dei gruppi di posizionamento attuali;\n prima di inviare, assicurarsi che i valori soddisfino le proprie esigenze.\n \n \n Crush ruleset\n Set di regole Crush\n \n \n -- Select a crush rule --\n -- Selezionare una regola Crush --\n \n \n Crush rule\n Regola Crush\n \n \n Crush steps\n Passaggi Crush\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n Non \xe8 possibile utilizzare la regola nel cluster attuale perch\xe9 il numero degli\n OSD che contiene \xe8 troppo basso e non soddisfa il numero minimo di OSD richiesto da questa regola.\n \n \n Replicated size\n Dimensioni replicate\n \n \n Minimum: \n \n \n Minime: \n \n \n \n \n Maximum: \n \n \n Massime: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n Le dimensioni specificate non sono comprese nell\'intervallo. L\'intervallo valido \xe8 da\n a\n .\n \n \n \n Erasure code profile\n Profilo del codice di cancellazione\n \n \n -- No erasure code profile available --\n -- Nessun profilo del codice di cancellazione disponibile --\n \n \n -- Select an erasure code profile --\n -- Selezionare un profilo del codice di cancellazione --\n \n \n EC Overwrites\n Sovrascritture EC\n \n \n Applications\n Applicazioni\n \n \n Compression\n Compressione\n \n \n Algorithm\n Algoritmo\n \n \n -- No erasure compression algorithm available --\n -- Nessun algoritmo di compressione della cancellazione disponibile --\n \n \n Minimum blob size\n Dimensioni minime del blob\n \n \n e.g., 128KiB\n ad es. 128 KiB\n \n \n Value should be greater than 0\n Il valore deve essere maggiore di 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Dimensioni massime del blob\n \n \n e.g., 512KiB\n ad es. 512 KiB\n \n \n Value should be greater than the minimum blob size\n Il valore deve essere maggiore delle dimensioni minime del blob\n \n \n Ratio\n Rapporto\n \n \n Compression ratio\n Rapporto di compressione\n \n \n Value should be between 0.0 and 1.0\n Il valore deve essere compreso tra 0,0 e 1,0\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n Non \xe8 possibile creare un pool RBD con una \'/\' nel nome.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n Modificare il nome o rimuovere \'rbd\' dall\'elenco delle applicazioni.\n \n \n Cache Tiers Details\n Dettagli livelli cache\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Consultare la \n documentazione\n \n su come configurare e abilitare la funzionalit\xe0 di gestione di Object Gateway.\n \n \n \n Daemons List\n Elenco dei daemon\n \n \n Performance Counters\n Contatori delle prestazioni\n \n \n Loading bucket data...\n Caricamento dati compartimento in corso...\n \n \n The bucket data could not be loaded.\n Impossibile caricare i dati del compartimento.\n \n \n Id\n ID\n \n \n The value is not valid.\n Il valore non \xe8 valido.\n \n \n Owner\n Proprietario\n \n \n -- Select a user --\n -- Selezionare un utente --\n \n \n ID\n ID\n \n \n Index type\n Tipo di indice\n \n \n Placement rule\n Regola di posizionamento\n \n \n Marker\n Contrassegno\n \n \n Maximum marker\n Contrassegno massimo\n \n \n Version\n Versione\n \n \n Master version\n Versione master\n \n \n Modification time\n Ora di modifica\n \n \n Zonegroup\n Gruppo di zone\n \n \n Bucket quota\n Quota compartimenti\n \n \n Enabled\n Abilitato\n \n \n Maximum size\n Dimensioni massime\n \n \n Unlimited\n Illimitato\n \n \n Maximum objects\n Numero massimo di oggetti\n \n \n -- Select a username --\n -- Selezionare un nome utente --\n \n \n Auto-generate key\n Generazione automatica chiave\n \n \n Access key\n Chiave di accesso\n \n \n Secret key\n Chiave segreta\n \n \n Email address\n Indirizzo e-mail\n \n \n Suspended\n Sospeso\n \n \n System\n Sistema\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n \n \n Maximum buckets\n Numero massimo di compartimenti\n \n \n Subusers\n Sottoutenti\n \n \n Capabilities\n Capacit\xe0\n \n \n User quota\n Quota utenti\n \n \n Show\n Mostra\n \n \n Keys\n Chiavi\n \n \n -- Select a type --\n -- Selezionare un tipo --\n \n \n Permission\n Autorizzazione\n \n \n -- Select a permission --\n -- Selezionare un\'autorizzazione --\n \n \n Subuser\n Sottoutente\n \n \n The chosen subuser ID is already in use.\n L\'ID del sottoutente scelto \xe8 gi\xe0 in uso.\n \n \n read, write\n lettura, scrittura\n \n \n full\n pieno\n \n \n Swift key\n Chiave Swift\n \n \n Auto-generate secret\n Generazione automatica segreto\n \n \n Loading user data...\n Caricamento dati utente in corso...\n \n \n The user data could not be loaded.\n Impossibile caricare i dati utente.\n \n \n The chosen user ID is already in use.\n L\'ID utente scelto \xe8 gi\xe0 in uso.\n \n \n This is not a valid email address.\n Non \xe8 un indirizzo e-mail valido.\n \n \n The chosen email address is already in use.\n L\'indirizzo e-mail scelto \xe8 gi\xe0 in uso.\n \n \n Max. buckets\n Numero max. di compartimenti\n \n \n The entered value must be >= 0.\n Il valore immesso deve essere >= a 0.\n \n \n S3 key\n Chiave S3\n \n \n There are no subusers.\n Non esistono sottoutenti.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n Non esistono chiavi.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n Non esistono capacit\xe0.\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Dimensioni illimitate\n \n \n Max. size\n Dimensione max.\n \n \n Unlimited objects\n Oggetti illimitati\n \n \n Max. objects\n Numero max. di oggetti\n \n \n Current\n Attuale\n \n \n Updated discovery authentication\n Autenticazione rilevazione aggiornata\n \n \n There are no portals available.\n Non sono disponibili pool.\n \n \n There are no images available.\n Non sono disponibili immagini.\n \n \n There are no images available. Please make sure you add an image to the target.\n Non sono disponibili immagini. Assicurarsi di aggiungere un\'immagine alla destinazione.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n Non sono disponibili iniziatori. Assicurarsi di aggiungere un iniziatore alla destinazione.\n \n \n target\n target\n \n \n Target\n Destinazione\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n Stato\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Byte letti\n \n \n Write Bytes\n Byte scritti\n \n \n Read Ops\n Operazioni di lettura\n \n \n Write Ops\n Operazioni di scrittura\n \n \n A/O Since\n A/O da\n \n \n Instance\n Istanza\n \n \n Hostname\n Nome host\n \n \n Issue\n Problema\n \n \n Progress\n Avanzamento\n \n \n Disabled\n Disabilitato\n \n \n Edit Mode\n Modalit\xe0 di modifica\n \n \n Add Peer\n Aggiungi peer\n \n \n Edit Peer\n Modifica peer\n \n \n Delete Peer\n Elimina peer\n \n \n Leader\n Sequenza iniziale\n \n \n # Local\n # Locale\n \n \n # Remote\n # Remoto\n \n \n mirror peer\n peer copia speculare\n \n \n Key\n Chiave\n \n \n RBD\n RBD\n \n \n Deep flatten\n Appiattimento profondo\n \n \n Layering\n Su strati\n \n \n Exclusive lock\n Blocco esclusivo\n \n \n Object map (requires exclusive-lock)\n Mappa oggetti (richiede il blocco escluso)\n \n \n Journaling (requires exclusive-lock)\n Journaling (richiede il blocco esclusivo)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Rollback snapshot RBD\n \n \n Rollback\n Esegui rollback\n \n \n RBD snapshot\n Snapshot RBD\n \n \n Deleted At\n Eliminato alle\n \n \n id\n ID\n \n \n type\n tipo\n \n \n state\n stato\n \n \n version\n versione\n \n \n Host\n Host\n \n \n root\n root\n \n \n Rank\n Classificazione\n \n \n Daemon\n Daemon\n \n \n Activity\n Task\n \n \n Dentries\n Dentry\n \n \n Inodes\n Inode\n \n \n Usage\n Utilizzo\n \n \n Standby daemons\n Daemon in standby\n \n \n The value can be updated at runtime.\n \xc8 possibile aggiornare il valore al runtime.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n I daemon/client non estraggono questo valore dal\n database della configurazione di monitoraggio. Non \xe8 consentito impostare questa opzione tramite \'ceph config\n set ...\'. \xc8 necessario configurare questa opzione tramite ceph.conf o dalla\n riga di comando.\n \n \n Option takes effect only during daemon startup.\n L\'opzione diventa attiva solo all\'avvio del daemon.\n \n \n Option only affects cluster creation.\n L\'opzione interessa solo la creazione del cluster.\n \n \n Option only affects daemon creation.\n L\'opzione interessa solo la creazione del daemon.\n \n \n Updated config option \n \n \n Aggiornata opzione di configurazione \n \n \n \n \n Service\n Servizio\n \n \n Current value\n Valore attuale\n \n \n Editable\n Modificabile\n \n \n Updated options for module "\n ".\n \n Opzioni aggiornate per il modulo &quot;\n &quot;.\n \n \n \n Enable\n Abilita\n \n \n Disable\n Disabilita\n \n \n Reconnecting, please wait ...\n Riconnessione in corso. Attendere.\n \n \n Public Address\n Indirizzo pubblico\n \n \n Open Sessions\n Sessioni aperte\n \n \n No In\n Nessuno in entrata\n \n \n OSDs that were previously marked out will not be marked back in when they start\n Gli OSD che sono stati contrassegnati come disattivi in precedenza non verranno contrassegnati nuovamente come attivi all\'avvio\n \n \n No Out\n Nessuno in uscita\n \n \n OSDs will not automatically be marked out after the configured interval\n Gli OSD non verranno disattivati automaticamente dopo l\'intervallo configurato\n \n \n No Up\n Nessuno attivo\n \n \n OSDs are not allowed to start\n Non \xe8 consentito l\'avvio degli OSD\n \n \n No Down\n Nessuno disattivo\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n I rapporti di errore degli OSD vengono ignorati in modo che i monitor non disattivino gli OSD\n \n \n Pause\n Sospendi\n \n \n Pauses reads and writes\n Sospende le operazioni di lettura e scrittura\n \n \n No Scrub\n Nessuna pulitura\n \n \n Scrubbing is disabled\n Pulitura disabilitata\n \n \n No Deep Scrub\n Nessun pulitura approfondita\n \n \n Deep Scrubbing is disabled\n Pulitura approfondita disabilitata\n \n \n No Backfill\n Nessuna operazione di recupero\n \n \n Backfilling of PGs is suspended\n Recupero dei gruppi di posizionamento sospeso\n \n \n No Recover\n Nessun recupero\n \n \n Recovery of PGs is suspended\n Recupero dei gruppi di posizionamento sospeso\n \n \n Bitwise Sort\n Ordinamento bitwise\n \n \n Use bitwise sort\n Usa ordinamento bitwise\n \n \n Purged Snapdirs\n Snapdir eliminate definitivamente\n \n \n OSDs have converted snapsets\n Gli OSD contengono set di snap convertiti\n \n \n Recovery Deletes\n Eliminazioni recuperi\n \n \n Deletes performed during recovery instead of peering\n Eliminazioni eseguite durante il recupero invece del peering\n \n \n PG Log Hard Limit\n Limite rigido log gruppo di posizionamento\n \n \n Puts a hard limit on pg log length\n Inserisce un limite rigido alla lunghezza del log del gruppo di posizionamento\n \n \n Updated OSD Flags\n Flag OSD aggiornati\n \n \n out\n esterno\n \n \n in\n interno\n \n \n down\n in basso\n \n \n Mark\n Contrassegna\n \n \n OSD lost\n OSD perso\n \n \n marked lost\n contrassegnato come perso\n \n \n Purge\n Elimina definitivamente\n \n \n OSD\n OSD\n \n \n purged\n eliminato definitivamente\n \n \n destroy\n elimina definitivamente\n \n \n destroyed\n eliminato definitivamente\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n Gruppi di posizionamento\n \n \n Read bytes\n Byte letti\n \n \n Writes bytes\n Byte scritti\n \n \n Read ops\n Operazioni di lettura\n \n \n Write ops\n Operazioni di scrittura\n \n \n Mark OSD \n \n \n Contrassegna OSD \n \n \n \n \n Mark \n \n \n Contrassegna \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n Numero max di recuperi informazioni\n \n \n Recovery Max Active\n Numero max di recuperi attivi\n \n \n Recovery Max Single Start\n Avvio singolo numero max di recuperi\n \n \n Recovery Sleep\n Sospensione recupero\n \n \n Custom\n Personalizzato\n \n \n Updated OSD recovery speed priority "\n "\n \n Aggiornata la priorit\xe0 della velocit\xe0 di recupero dell\'OSD &quot;\n &quot;\n \n \n \n \n was initialized in the following OSD: \n \n \n \n \xe8 stato inizializzato dall\'OSD seguente: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n Lavoro\n \n \n Severity\n Gravit\xe0\n \n \n Started\n Avviato\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Aggiornato\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n Utilizzato\n \n \n Avail.\n Dispon.\n \n \n Clean\n Pulisci\n \n \n Working\n In funzione\n \n \n Warning\n Avviso\n \n \n Unknown\n Sconosciuto\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n su\n \n \n no filesystems\n nessun file system\n \n \n active\n attivo\n \n \n standby\n standby\n \n \n n/a\n n/d\n \n \n active daemon\n daemon attivo\n \n \n quorum\n quorum\n \n \n The NFS Ganesha service is not configured.\n Il servizio NFS Ganesha non \xe8 configurato.\n \n \n Transport\n Trasporto\n \n \n CephFS User\n Utente CephFS\n \n \n CephFS Filesystem\n File system CephFS\n \n \n (inherited from global config)\n (ereditato dalla configurazione globale)\n \n \n inherited from global config\n importato dalla configurazione globale\n \n \n -- Select what kind of user id squashing is performed --\n -- Selezionare il tipo di squash dell\'ID utente che viene eseguito --\n \n \n There are no daemons available.\n Non vi sono daemon disponibili.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Modalit\xe0 cache\n \n \n Min Evict Age\n Numero minimo di giorni per la rimozione\n \n \n Min Flush Age\n Numero minimo di giorni per la cancellazione\n \n \n Target Max Bytes\n Numero max di byte di destinazione\n \n \n Target Max Objects\n Numero max di oggetti di destinazione\n \n \n No applications added\n Non sono state aggiunte applicazioni.\n \n \n Applications limit reached\n Raggiunto il limite di applicazioni\n \n \n A pool can only have up to four applications definitions.\n Un pool pu\xf2 contenere solo fino a quattro definizioni delle applicazioni.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n Caratteri consentiti \'_a-zA-Z0-9\'\n \n \n Maximum length is 128 characters\n La lunghezza massima \xe8 di 128 caratteri\n \n \n Filter or add applications\n Filtra o aggiungi applicazioni\n \n \n Add application\n Aggiungi applicazione\n \n \n pool\n pool\n \n \n erasure code profile\n profilo del codice di cancellazione\n \n \n Replica Size\n Dimensioni della replica\n \n \n Last Change\n Ultima modifica\n \n \n Erasure Coded Profile\n Profilo con codice di cancellazione\n \n \n Crush Ruleset\n Set di regole Crush\n \n \n Write bytes\n Byte scritti\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n compartimento\n \n \n Updated Object Gateway bucket "\n "\n \n Aggiornato compartimento Object Gateway &quot;\n &quot;\n \n \n \n Created Object Gateway bucket "\n "\n \n Creato compartimento Object Gateway &quot;\n &quot;\n \n \n \n buckets\n compartimenti\n \n \n capability\n capability\n \n \n user\n utente\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Aggiornato utente Object Gateway &quot;\n &quot;\n \n \n \n Created Object Gateway user "\n "\n \n Creato utente Object Gateway &quot;\n &quot;\n \n \n \n users\n utenti\n \n \n Swift Key\n Swift Key\n \n \n Scope\n Ambito\n \n \n Read\n Lettura\n \n \n Create\n Crea\n \n \n role\n role\n \n \n Created role \'\n \'\n \n Creato ruolo \'\n \'\n \n \n \n Updated role \'\n \'\n \n Aggiornato ruolo \'\n \'\n \n \n \n System Role\n Ruolo di sistema\n \n \n Deleted role \'\n \'\n \n Eliminato ruolo \'\n \'\n \n \n \n Created user "\n "\n \n Creato utente &quot;\n &quot;\n \n \n \n Update user\n Aggiorna utente\n \n \n Continue\n Continua\n \n \n You were automatically logged out because your roles have been changed.\n Si \xe8 stati automaticamente disconnessi perch\xe9 i ruoli sono stati modificati.\n \n \n Updated user "\n "\n \n Aggiornato utente &quot;\n &quot;\n \n \n \n Deleted user "\n "\n \n Eliminato utente &quot;\n &quot;\n \n \n \n Failed to delete user "\n "\n \n Impossibile eliminare l\'utente &quot;\n &quot;\n \n \n \n You are currently logged in as "\n ".\n \n Si \xe8 attualmente connessi come &quot;\n &quot;.\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Ogni oggetto \xe8 suddiviso in porzioni di dati, ciascuna delle quali \xe8 memorizzata su un diverso OSD.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Calcola le porzioni di codice relative a ciascun oggetto e le memorizza su diversi OSD.\n Il numero di porzioni di codice \xe8 anche il numero degli OSD che \xe8 possibile disattivare senza perdere i dati.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Il plugin jerasure \xe8 il plugin pi\xf9 generico e flessibile,\n ed \xe8 anche il plugin di default dei pool con codice di cancellazione di Ceph.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n La tecnica pi\xf9 flessibile \xe8 reed_sol_van: \xe8 sufficiente impostare k\n ed m. La tecnica cauchy_good pu\xf2 essere pi\xf9 rapida ma occorre selezionare attentamente la dimensione del\n pacchetto. reed_sol_r6_op, liberation, blaum_roth, liber8tion sono tutti equivalenti a RAID6,\n nel senso che \xe8 possibile configurarli solo con m=2.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n La codifica viene eseguita su pacchetti di dimensioni in byte, uno alla volta.\n \xc8 difficile scegliere la dimensione del pacchetto corretta.\n La documentazione su jerasure fornisce informazioni esaustive su questo argomento.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n Con il plugin di jerasure, quando un oggetto con codice di cancellazione viene memorizzato su\n pi\xf9 OSD, il recupero della perdita di un OSD richiede la lettura di tutti gli altri.\n Ad esempio, se jerasure \xe8 configurato con k=8 e m=4, la perdita di un OSD richiede la lettura\n degli altri undici per il ripristino.\n\n Il plugin del codice di cancellazione lrc crea porzioni di parit\xe0 locali che \xe8 possibile recuperare utilizzando un\n minor numero di OSD. Ad esempio, se lrc \xe8 configurato con k=8, m=4 e l=4, crea\n una porzione di parit\xe0 aggiuntiva ogni quattro OSD. Quando si perde un singolo OSD, \xe8 possibile\n recuperarlo solo con quattro OSD invece che con undici.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Raggruppa le porzioni di codice e dati in set di localit\xe0 dimensione. Ad esempio,\n per k=4 e m=2, se localit\xe0=3 vengono creati due gruppi su tre. \xc8 possibile recuperare ciascun set\n senza leggere le porzioni di un altro set.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n Il tipo di compartimento Crush in cui viene memorizzato ciascun set di porzioni definito\n dall\'utente. Ad esempio, se \xe8 impostato su rack, ciascun gruppo di porzioni viene\n posizionato in un diverso rack. Viene utilizzato per creare un passaggio della regola CRUSH come il passaggio choose\n rack. Se non \xe8 impostato, il raggruppamento non viene eseguito.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n Il plugin ISA incapsula la libreria ISA. Viene eseguito solo su processori Intel.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n Il plugin ISA \xe8 disponibile in due formati Reed Solomon.\n Se \xe8 impostato reed_sol_van, il formato \xe8 Vandermonde, se \xe8 impostato cauchy, il formato \xe8 Cauchy.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n Il plugin shec incapsula la libreria SHEC multipla.\n Consente a Ceph di recuperare i dati in modo pi\xf9 efficiente rispetto ai codici Reed Solomon.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n Il numero di compartimenti di parit\xe0, ciascuno dei quali include i singoli compartimenti di dati\n nell\'intervallo di calcolo. Il numero viene utilizzato come strumento di stima della durabilit\xe0. Ad esempio, se c=2,\n \xe8 possibile disattivare 2 OSD senza perdere i dati.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n Il nome del compartimento Crush utilizzato per il primo passaggio della regola CRUSH.\n Ad esempio il passaggio take default.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n Assicurarsi che non esistano due porzioni in un compartimento con lo stesso dominio\n di errore. Ad esempio, se il dominio di errore \xe8 l\'host, non verranno memorizzate due porzioni sullo stesso\n host. Viene utilizzato per creare un passaggio della regola CRUSH come passaggio chooseleaf host.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Limitare il posizionamento ai dispositivi di una classe specifica\n (ad es. ssd o hdd) usando i nomi delle classi di dispositivi Crush nella mappa CRUSH.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n Impostare il nome della directory da cui viene caricato il plugin del codice di cancellazione.\n \n \n Allows all operations\n Consente tutte le operazioni\n \n \n Allows only operations that do not modify the server\n Consente solo le operazioni che non modificano il server\n \n \n Does not allow read or write operations, but allows any other operation\n Non consente operazioni di lettura o scrittura, ma consente qualsiasi altra operazione\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n Non consente operazioni di lettura o scrittura o qualsiasi operazione che modifichi gli attributi dei file o il contenuto della directory\n \n \n Allows no access at all\n Non consente alcun accesso\n \n \n -- Select the priority --\n -- Selezionare la priorit\xe0 --\n \n \n Low\n Bassa\n \n \n High\n Alta\n \n \n Last 5 minutes\n Ultimi 5 minuti\n \n \n Last 15 minutes\n Ultimi 15 minuti\n \n \n Last 30 minutes\n Ultimi 30 minuti\n \n \n Last 1 hour (Default)\n Ultima ora (Default)\n \n \n Last 3 hours\n Ultime 3 ore\n \n \n Last 6 hours\n Ultime 6 ore\n \n \n Last 12 hours\n Ultime 12 ore\n \n \n Last 24 hours\n Ultime 24 ore\n \n \n Yesterday\n Ieri\n \n \n Today\n Oggi\n \n \n Today so far\n Fino a oggi\n \n \n Day before yesterday\n Giorno prima di ieri\n \n \n Last 2 days\n Ultimi 2 giorni\n \n \n This day last week\n Questo giorno della scorsa settimana\n \n \n Previous week\n Settimana precedente\n \n \n This week\n Questa settimana\n \n \n This week so far\n Fino a questa settimana\n \n \n Last 7 days\n Ultimi 7 giorni\n \n \n Previous month\n Mese precedente\n \n \n This month\n Questo mese\n \n \n This month so far\n Fino a questo mese\n \n \n Last 30 days\n Ultimi 30 giorni\n \n \n Last 90 days\n Ultimi 90 giorni\n \n \n Last 6 months\n Ultimi 6 mesi\n \n \n Last 1 year\n Ultimo anno\n \n \n Previous year\n Anno precedente\n \n \n This year\n Quest\'anno\n \n \n This year so far\n Fino a quest\'anno\n \n \n Last 2 years\n Ultimi 2 anni\n \n \n Last 5 years\n Ultimi 5 anni\n \n \n Information\n Informazioni\n \n \n No items selected.\n Nessun elemento selezionato.\n \n \n Deselect item to select again\n Deselezionare l\'elemento per selezionare di nuovo\n \n \n Selection limit reached\n Raggiunto il limite per la selezione\n \n \n Filter tags\n Filtra tag\n \n \n Add badge\n Aggiungi badge\n \n \n There are no items available.\n Non vi sono elementi disponibili.\n \n \n Add\n Aggiungi\n \n \n Remove\n Remove\n \n \n Clone\n Clona\n \n \n Copy\n Copia\n \n \n Deep Scrub\n Pulitura approfondita\n \n \n Destroy\n Eliminazione definitiva\n \n \n Flatten\n Appiattisci\n \n \n Mark Down\n Declassa\n \n \n Mark In\n Attiva\n \n \n Mark Lost\n Contrassegna come perso\n \n \n Mark Out\n Disattiva\n \n \n Protect\n Proteggi\n \n \n Rename\n Rinomina\n \n \n Restore\n Ripristina\n \n \n Move to Trash\n Sposta nel cestino\n \n \n Unprotect\n Rimuovi protezione\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Eliminato\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Clonato\n \n \n Copied\n Copiato\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n S\xec\n \n \n No\n No\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Qualit\xe0 di servizio\n \n \n BPS Limit\n Limite di BPS\n \n \n The desired limit of IO bytes per second.\n Il limite desiderato di byte I/O al secondo.\n \n \n IOPS Limit\n Limite di IOPS\n \n \n The desired limit of IO operations per second.\n Il limite desiderato di operazioni I/O al secondo.\n \n \n Read BPS Limit\n Limite BPS in lettura\n \n \n The desired limit of read bytes per second.\n Il limite desiderato dei byte letti al secondo.\n \n \n Read IOPS Limit\n Limite di IOPS in lettura\n \n \n The desired limit of read operations per second.\n Il limite desiderato di operazioni di lettura al secondo.\n \n \n Write BPS Limit\n Limite di BPS in scrittura\n \n \n The desired limit of write bytes per second.\n Il limite desiderato di byte scritti al secondo.\n \n \n Write IOPS Limit\n Limite di IOPS in scrittura\n \n \n The desired limit of write operations per second.\n Il limite desiderato di operazioni di scrittura al secondo.\n \n \n BPS Burst\n Burst BPS\n \n \n The desired burst limit of IO bytes.\n Il limite di burst desiderato dei byte di I/O.\n \n \n IOPS Burst\n Burst IOPS\n \n \n The desired burst limit of IO operations.\n Il limite di burst desiderato delle operazioni di I/O.\n \n \n Read BPS Burst\n Burst BPS in lettura\n \n \n The desired burst limit of read bytes.\n Il limite di burst desiderato dei byte letti.\n \n \n Read IOPS Burst\n Burst IOPS in lettura\n \n \n The desired burst limit of read operations.\n Il limite di burst desiderato delle operazioni di lettura.\n \n \n Write BPS Burst\n Burst BPS in scrittura\n \n \n The desired burst limit of write bytes.\n Il limite di burst desiderato dei byte scritti.\n \n \n Write IOPS Burst\n Burst di IOPS in scrittura\n \n \n The desired burst limit of write operations.\n Il limite di burst desiderato delle operazioni di scrittura.\n \n \n Failed to \n \n \n \n Non \xe8 stato possibile \n \n \n \n \n \n Executing\n In esecuzione\n \n \n execute\n esegui\n \n \n Executed\n Eseguito\n \n \n unknown task\n task sconosciuto\n \n \n Creating\n Creazione in corso\n \n \n create\n crea\n \n \n Updating\n Aggiornamento in corso\n \n \n update\n aggiorna\n \n \n Deleting\n Eliminazione in corso\n \n \n delete\n elimina\n \n \n RBD \'\n \'\n \n RBD \'\n \'\n \n \n \n RBD snapshot \'\n \'\n \n Snapshot RBD \'\n \'\n \n \n \n mirror mode for pool \'\n \'\n \n modalit\xe0 speculare per il pool \'\n \'\n \n \n \n mirror peer for pool \'\n \'\n \n peer della copia speculare per il pool \'\n \'\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n Il nome \xe8 gi\xe0 utilizzato da \n .\n \n \n \n Name is already used by \n .\n \n Il nome \xe8 gi\xe0 utilizzato da \n .\n \n \n \n Name is already used by \n .\n \n Il nome \xe8 gi\xe0 utilizzato da \n .\n \n \n \n \n contains snapshots.\n \n \n contiene snapshot.\n \n \n \n Cloning\n Clonazione in corso\n \n \n clone\n clona\n \n \n Snapshot of \n must be protected.\n \n La snapshot di \n deve essere protetta.\n \n \n \n Copying\n Copia in corso\n \n \n copy\n copia\n \n \n Flattening\n Appiattimento\n \n \n flatten\n appiattisci\n \n \n Flattened\n Appiattito\n \n \n Name is already used by \n .\n \n Il nome \xe8 gi\xe0 utilizzato da \n .\n \n \n \n Cannot unprotect \n because it contains child images.\n \n Impossibile rimuovere la protezione da \n perch\xe9 contiene immagini figlio.\n \n \n \n Cannot delete \n because it\'s protected.\n \n Impossibile eliminare \n perch\xe9 \xe8 protetto.\n \n \n \n Rolling back\n Rollback in corso\n \n \n rollback\n rollback\n \n \n Rolled back\n Rollback eseguito\n \n \n Moving\n Spostamento in corso\n \n \n move\n sposta\n \n \n Moved\n Spostato\n \n \n image \'\n \' to trash\n \n immagine \'\n \' nel cestino\n \n \n \n Could not find image.\n Impossibile trovare l\'immagine.\n \n \n Restoring\n Ripristino in corso\n \n \n restore\n ripristina\n \n \n Restored\n Ripristinato\n \n \n image \'\n \' into \'\n \'\n \n immagine \'\n \' in \'\n \'\n \n \n \n Image name \'\n \' is already in use.\n \n Il nome dell\'immagine \'\n \' \xe8 gi\xe0 in uso.\n \n \n \n image \'\n \'\n \n immagine \'\n \'\n \n \n \n Purging\n Eliminazione in corso\n \n \n purge\n elimina definitivamente\n \n \n Purged\n Eliminato definitivamente\n \n \n all pools\n tutti i pool\n \n \n images from \n \n \n Immagini da \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n Impossibile disabilitare l\'esecuzione della copia speculare perch\xe9 contiene un peer.\n \n \n pool \'\n \'\n \n pool \'\n \'\n \n \n \n erasure code profile \'\n \'\n \n profilo del codice di cancellazione \'\n \'\n \n \n \n target \'\n \'\n \n destinazione \'\n \'\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},hKrs:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("bg",{months:"\u044f\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u044f\u043d\u0440_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u044f\u0434\u0430_\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a_\u043f\u0435\u0442\u044a\u043a_\u0441\u044a\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u044f_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u044a\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[\u0414\u043d\u0435\u0441 \u0432] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432] LT",nextWeek:"dddd [\u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0430\u0442\u0430] dddd [\u0432] LT";case 1:case 2:case 4:case 5:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0438\u044f] dddd [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0441\u043b\u0435\u0434 %s",past:"\u043f\u0440\u0435\u0434\u0438 %s",s:"\u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u043d\u0438",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0430",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0435\u0432|\u0435\u043d|\u0442\u0438|\u0432\u0438|\u0440\u0438|\u043c\u0438)/,ordinal:function(t){var e=t%10,n=t%100;return 0===t?t+"-\u0435\u0432":0===n?t+"-\u0435\u043d":n>10&&n<20?t+"-\u0442\u0438":1===e?t+"-\u0432\u0438":2===e?t+"-\u0440\u0438":7===e||8===e?t+"-\u043c\u0438":t+"-\u0442\u0438"},week:{dow:1,doy:7}})}()},honF:function(t,e,n){!function(t){"use strict";var e={1:"\u1041",2:"\u1042",3:"\u1043",4:"\u1044",5:"\u1045",6:"\u1046",7:"\u1047",8:"\u1048",9:"\u1049",0:"\u1040"},n={"\u1041":"1","\u1042":"2","\u1043":"3","\u1044":"4","\u1045":"5","\u1046":"6","\u1047":"7","\u1048":"8","\u1049":"9","\u1040":"0"};t.defineLocale("my",{months:"\u1007\u1014\u103a\u1014\u101d\u102b\u101b\u102e_\u1016\u1031\u1016\u1031\u102c\u103a\u101d\u102b\u101b\u102e_\u1019\u1010\u103a_\u1027\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u1007\u1030\u101c\u102d\u102f\u1004\u103a_\u101e\u103c\u1002\u102f\u1010\u103a_\u1005\u1000\u103a\u1010\u1004\u103a\u1018\u102c_\u1021\u1031\u102c\u1000\u103a\u1010\u102d\u102f\u1018\u102c_\u1014\u102d\u102f\u101d\u1004\u103a\u1018\u102c_\u1012\u102e\u1007\u1004\u103a\u1018\u102c".split("_"),monthsShort:"\u1007\u1014\u103a_\u1016\u1031_\u1019\u1010\u103a_\u1015\u103c\u102e_\u1019\u1031_\u1007\u103d\u1014\u103a_\u101c\u102d\u102f\u1004\u103a_\u101e\u103c_\u1005\u1000\u103a_\u1021\u1031\u102c\u1000\u103a_\u1014\u102d\u102f_\u1012\u102e".split("_"),weekdays:"\u1010\u1014\u1004\u103a\u1039\u1002\u1014\u103d\u1031_\u1010\u1014\u1004\u103a\u1039\u101c\u102c_\u1021\u1004\u103a\u1039\u1002\u102b_\u1017\u102f\u1012\u1039\u1013\u101f\u1030\u1038_\u1000\u103c\u102c\u101e\u1015\u1010\u1031\u1038_\u101e\u1031\u102c\u1000\u103c\u102c_\u1005\u1014\u1031".split("_"),weekdaysShort:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),weekdaysMin:"\u1014\u103d\u1031_\u101c\u102c_\u1002\u102b_\u101f\u1030\u1038_\u1000\u103c\u102c_\u101e\u1031\u102c_\u1014\u1031".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u101a\u1014\u1031.] LT [\u1019\u103e\u102c]",nextDay:"[\u1019\u1014\u1000\u103a\u1016\u103c\u1014\u103a] LT [\u1019\u103e\u102c]",nextWeek:"dddd LT [\u1019\u103e\u102c]",lastDay:"[\u1019\u1014\u1031.\u1000] LT [\u1019\u103e\u102c]",lastWeek:"[\u1015\u103c\u102e\u1038\u1001\u1032\u1037\u101e\u1031\u102c] dddd LT [\u1019\u103e\u102c]",sameElse:"L"},relativeTime:{future:"\u101c\u102c\u1019\u100a\u103a\u1037 %s \u1019\u103e\u102c",past:"\u101c\u103d\u1014\u103a\u1001\u1032\u1037\u101e\u1031\u102c %s \u1000",s:"\u1005\u1000\u1039\u1000\u1014\u103a.\u1021\u1014\u100a\u103a\u1038\u1004\u101a\u103a",ss:"%d \u1005\u1000\u1039\u1000\u1014\u1037\u103a",m:"\u1010\u1005\u103a\u1019\u102d\u1014\u1005\u103a",mm:"%d \u1019\u102d\u1014\u1005\u103a",h:"\u1010\u1005\u103a\u1014\u102c\u101b\u102e",hh:"%d \u1014\u102c\u101b\u102e",d:"\u1010\u1005\u103a\u101b\u1000\u103a",dd:"%d \u101b\u1000\u103a",M:"\u1010\u1005\u103a\u101c",MM:"%d \u101c",y:"\u1010\u1005\u103a\u1014\u103e\u1005\u103a",yy:"%d \u1014\u103e\u1005\u103a"},preparse:function(t){return t.replace(/[\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1040]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},week:{dow:1,doy:4}})}(n("wd/R"))},i3PA:function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("jvuA")),a(n("UReH"))},i4X3:function(t,e,n){"use strict";var a=n("6blF"),r=n("pugT"),i=n("xTla"),s=n("JF+6"),o=n("En8+"),u=n("/WYv"),c=n("2ePl");function l(t,e){if(null!=t){if(function(t){return t&&"function"==typeof t[i.a]}(t))return function(t,e){return new a.a(function(n){var a=new r.a;return a.add(e.schedule(function(){var r=t[i.a]();a.add(r.subscribe({next:function(t){a.add(e.schedule(function(){return n.next(t)}))},error:function(t){a.add(e.schedule(function(){return n.error(t)}))},complete:function(){a.add(e.schedule(function(){return n.complete()}))}}))})),a})}(t,e);if(Object(u.a)(t))return function(t,e){return new a.a(function(n){var a=new r.a;return a.add(e.schedule(function(){return t.then(function(t){a.add(e.schedule(function(){n.next(t),a.add(e.schedule(function(){return n.complete()}))}))},function(t){a.add(e.schedule(function(){return n.error(t)}))})})),a})}(t,e);if(Object(c.a)(t))return Object(s.a)(t,e);if(function(t){return t&&"function"==typeof t[o.a]}(t)||"string"==typeof t)return function(t,e){if(!t)throw new Error("Iterable cannot be null");return new a.a(function(n){var a,i=new r.a;return i.add(function(){a&&"function"==typeof a.return&&a.return()}),i.add(e.schedule(function(){a=t[o.a](),i.add(e.schedule(function(){if(!n.closed){var t,e;try{var r=a.next();t=r.value,e=r.done}catch(i){return void n.error(i)}e?n.complete():(n.next(t),this.schedule())}}))})),i})}(t,e)}throw new TypeError((null!==t&&typeof t||t)+" is not observable")}n.d(e,"a",function(){return l})},iEDd:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("gl",{months:"xaneiro_febreiro_marzo_abril_maio_xu\xf1o_xullo_agosto_setembro_outubro_novembro_decembro".split("_"),monthsShort:"xan._feb._mar._abr._mai._xu\xf1._xul._ago._set._out._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"domingo_luns_martes_m\xe9rcores_xoves_venres_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._m\xe9r._xov._ven._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_m\xe9_xo_ve_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextDay:function(){return"[ma\xf1\xe1 "+(1!==this.hours()?"\xe1s":"\xe1")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"\xe1s":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"\xe1":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"\xe1s":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(t){return 0===t.indexOf("un")?"n"+t:"en "+t},past:"hai %s",s:"uns segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}()},iExv:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(t){this.i18n=t}return t.prototype.transform=function(t,e,n){return void 0===e&&(e=this.i18n("Yes")),void 0===n&&(n=this.i18n("No")),Boolean(t)?e:n},t}()},iLxQ:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=!1,r={Promise:void 0,set useDeprecatedSynchronousErrorHandling(t){a=t},get useDeprecatedSynchronousErrorHandling(){return a}}},iM7B:function(t,e,n){"use strict";var a=n("RDha"),r=n("Hg4g"),i=n("q8Fl");t.exports=a.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},i._enabled?i:r)},iYGd:function(t,e,n){"use strict";t.exports=function(t){t.Radar=function(e,n){return n.type="radar",new t(e,n)}}},iYuL:function(t,e,n){!function(t){"use strict";var e="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),n="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),a=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],r=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;t.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(t,a){return t?/-MMM-/.test(a)?n[t.month()]:e[t.month()]:e},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:a,longMonthsParse:a,shortMonthsParse:a,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[ma\xf1ana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}})}(n("wd/R"))},ihYY:function(t,e,n){"use strict";n.d(e,"b",function(){return a}),n.d(e,"c",function(){return r}),n.d(e,"a",function(){return i}),n.d(e,"e",function(){return o}),n.d(e,"f",function(){return u}),n.d(e,"g",function(){return l}),n.d(e,"h",function(){return c}),n.d(e,"i",function(){return d}),n.d(e,"j",function(){return s}),n.d(e,"d",function(){return p}),n.d(e,"l",function(){return g}),n.d(e,"k",function(){return h});var a=function(){return function(){}}(),r=function(){return function(){}}(),i="*";function s(t,e){return{type:7,name:t,definitions:e,options:{}}}function o(t,e){return void 0===e&&(e=null),{type:4,styles:e,timings:t}}function u(t,e){return void 0===e&&(e=null),{type:2,steps:t,options:e}}function c(t){return{type:6,styles:t,offset:null}}function l(t,e,n){return{type:0,name:t,styles:e,options:n}}function d(t,e,n){return void 0===n&&(n=null),{type:1,expr:t,animation:e,options:n}}function f(t){Promise.resolve(null).then(t)}var p=function(){function t(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this._started=!1,this._destroyed=!1,this._finished=!1,this.parentPlayer=null,this.totalTime=t+e}return t.prototype._onFinish=function(){this._finished||(this._finished=!0,this._onDoneFns.forEach(function(t){return t()}),this._onDoneFns=[])},t.prototype.onStart=function(t){this._onStartFns.push(t)},t.prototype.onDone=function(t){this._onDoneFns.push(t)},t.prototype.onDestroy=function(t){this._onDestroyFns.push(t)},t.prototype.hasStarted=function(){return this._started},t.prototype.init=function(){},t.prototype.play=function(){this.hasStarted()||(this._onStart(),this.triggerMicrotask()),this._started=!0},t.prototype.triggerMicrotask=function(){var t=this;f(function(){return t._onFinish()})},t.prototype._onStart=function(){this._onStartFns.forEach(function(t){return t()}),this._onStartFns=[]},t.prototype.pause=function(){},t.prototype.restart=function(){},t.prototype.finish=function(){this._onFinish()},t.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.hasStarted()||this._onStart(),this.finish(),this._onDestroyFns.forEach(function(t){return t()}),this._onDestroyFns=[])},t.prototype.reset=function(){},t.prototype.setPosition=function(t){},t.prototype.getPosition=function(){return 0},t.prototype.triggerCallback=function(t){var e="start"==t?this._onStartFns:this._onDoneFns;e.forEach(function(t){return t()}),e.length=0},t}(),h=function(){function t(t){var e=this;this._onDoneFns=[],this._onStartFns=[],this._finished=!1,this._started=!1,this._destroyed=!1,this._onDestroyFns=[],this.parentPlayer=null,this.totalTime=0,this.players=t;var n=0,a=0,r=0,i=this.players.length;0==i?f(function(){return e._onFinish()}):this.players.forEach(function(t){t.onDone(function(){++n==i&&e._onFinish()}),t.onDestroy(function(){++a==i&&e._onDestroy()}),t.onStart(function(){++r==i&&e._onStart()})}),this.totalTime=this.players.reduce(function(t,e){return Math.max(t,e.totalTime)},0)}return t.prototype._onFinish=function(){this._finished||(this._finished=!0,this._onDoneFns.forEach(function(t){return t()}),this._onDoneFns=[])},t.prototype.init=function(){this.players.forEach(function(t){return t.init()})},t.prototype.onStart=function(t){this._onStartFns.push(t)},t.prototype._onStart=function(){this.hasStarted()||(this._started=!0,this._onStartFns.forEach(function(t){return t()}),this._onStartFns=[])},t.prototype.onDone=function(t){this._onDoneFns.push(t)},t.prototype.onDestroy=function(t){this._onDestroyFns.push(t)},t.prototype.hasStarted=function(){return this._started},t.prototype.play=function(){this.parentPlayer||this.init(),this._onStart(),this.players.forEach(function(t){return t.play()})},t.prototype.pause=function(){this.players.forEach(function(t){return t.pause()})},t.prototype.restart=function(){this.players.forEach(function(t){return t.restart()})},t.prototype.finish=function(){this._onFinish(),this.players.forEach(function(t){return t.finish()})},t.prototype.destroy=function(){this._onDestroy()},t.prototype._onDestroy=function(){this._destroyed||(this._destroyed=!0,this._onFinish(),this.players.forEach(function(t){return t.destroy()}),this._onDestroyFns.forEach(function(t){return t()}),this._onDestroyFns=[])},t.prototype.reset=function(){this.players.forEach(function(t){return t.reset()}),this._destroyed=!1,this._finished=!1,this._started=!1},t.prototype.setPosition=function(t){var e=t*this.totalTime;this.players.forEach(function(t){var n=t.totalTime?Math.min(1,e/t.totalTime):1;t.setPosition(n)})},t.prototype.getPosition=function(){var t=0;return this.players.forEach(function(e){var n=e.getPosition();t=Math.min(n,t)}),t},t.prototype.beforeDestroy=function(){this.players.forEach(function(t){t.beforeDestroy&&t.beforeDestroy()})},t.prototype.triggerCallback=function(t){var e="start"==t?this._onStartFns:this._onDoneFns;e.forEach(function(t){return t()}),e.length=0},t}(),g="!"},insk:function(t,e,n){"use strict";n.d(e,"a",function(){return a}),n("+0ag"),n("mSOc"),n("20UP");var a=function(){function t(t,e,n,a,r){this.summaryService=t,this.sanitizer=e,this.settingsService=n,this.cephReleaseNamePipe=a,this.i18n=r,this.grafanaExist=!1,this.mode="&kiosk",this.loading=!0,this.styles={},this.dashboardExist=!0,this.DEFAULT_TIME="from=now-1h&to=now",this.grafanaTimes=[{name:this.i18n("Last 5 minutes"),value:"from=now-5m&to=now"},{name:this.i18n("Last 15 minutes"),value:"from=now-15m&to=now"},{name:this.i18n("Last 30 minutes"),value:"from=now-30m&to=now"},{name:this.i18n("Last 1 hour (Default)"),value:"from=now-1h&to=now"},{name:this.i18n("Last 3 hours"),value:"from=now-3h&to=now"},{name:this.i18n("Last 6 hours"),value:"from=now-6h&to=now"},{name:this.i18n("Last 12 hours"),value:"from=now-12h&to=now"},{name:this.i18n("Last 24 hours"),value:"from=now-24h&to=now"},{name:this.i18n("Yesterday"),value:"from=now-1d%2Fd&to=now-1d%2Fd"},{name:this.i18n("Today so far"),value:"from=now%2Fd&to=now"},{name:this.i18n("Day before yesterday"),value:"from=now-2d%2Fd&to=now-2d%2Fd"},{name:this.i18n("Last 2 days"),value:"from=now-2d&to=now"},{name:this.i18n("This day last week"),value:"from=now-7d%2Fd&to=now-7d%2Fd"},{name:this.i18n("Previous week"),value:"from=now-1w%2Fw&to=now-1w%2Fw"},{name:this.i18n("This week so far"),value:"from=now%2Fw&to=now"},{name:this.i18n("Last 7 days"),value:"from=now-7d&to=now"},{name:this.i18n("Previous month"),value:"from=now-1M%2FM&to=now-1M%2FM"},{name:this.i18n("This month so far"),value:"from=now%2FM&to=now"},{name:this.i18n("Last 30 days"),value:"from=now-30d&to=now"},{name:this.i18n("Last 90 days"),value:"from=now-90d&to=now"},{name:this.i18n("Last 6 months"),value:"from=now-6M&to=now"},{name:this.i18n("Last 1 year"),value:"from=now-1y&to=now"},{name:this.i18n("Previous year"),value:"from=now-1y%2Fy&to=now-1y%2Fy"},{name:this.i18n("This year so far"),value:"from=now%2Fy&to=now"},{name:this.i18n("Last 2 years"),value:"from=now-2y&to=now"},{name:this.i18n("Last 5 years"),value:"from=now-5y&to=now"}]}return t.prototype.ngOnInit=function(){var t=this;this.time=this.DEFAULT_TIME,this.styles={one:"grafana_one",two:"grafana_two",three:"grafana_three"};var e=this.summaryService.subscribe(function(n){if(n){var a=t.cephReleaseNamePipe.transform(n.version);t.docsUrl="http://docs.ceph.com/docs/"+a+"/mgr/dashboard/#enabling-the-embedding-of-grafana-dashboards",setTimeout(function(){e.unsubscribe()},0)}});this.settingsService.ifSettingConfigured("api/grafana/url",function(e){t.grafanaExist=!0,t.loading=!1,t.baseUrl=e+"/d/",t.getFrame()}),this.panelStyle=this.styles[this.grafanaStyle]},t.prototype.getFrame=function(){var t=this;this.settingsService.validateGrafanaDashboardUrl(this.uid).subscribe(function(e){return t.dashboardExist=200===e}),this.url=this.baseUrl+this.uid+"/"+this.grafanaPath+"&refresh=2s"+this.mode+"&"+this.time,this.grafanaSrc=this.sanitizer.bypassSecurityTrustResourceUrl(this.url)},t.prototype.onTimepickerChange=function(){this.grafanaExist&&this.getFrame()},t.prototype.reset=function(){this.time=this.DEFAULT_TIME,this.grafanaExist&&this.getFrame()},t.prototype.ngOnChanges=function(){this.grafanaExist&&this.getFrame()},t}()},isby:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=Array.isArray||function(t){return t&&"number"==typeof t.length}},iutN:function(t,e,n){"use strict";n.d(e,"a",function(){return u});var a=n("CcnG"),r=n("xtZt"),i=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function s(t){return a["\u0275vid"](2,[(t()(),a["\u0275eld"](0,0,null,null,1,"div",[],[[2,"dropup",null],[2,"dropdown",null],[2,"show",null],[2,"open",null]],null,null,null,null)),a["\u0275ncd"](null,0)],null,function(t,e){var n=e.component;t(e,0,0,"up"===n.direction,"down"===n.direction,n.isOpen,n.isOpen)})}function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"bs-dropdown-container",[["style","display:block;position: absolute;"]],null,null,null,s,i)),a["\u0275did"](1,180224,null,0,r.b,[r.f,a.ChangeDetectorRef,a.Renderer2,a.ElementRef],null,null)],null,null)}var u=a["\u0275ccf"]("bs-dropdown-container",r.b,o,{},{},["*"])},j8L6:function(t,e,n){"use strict";var a=n("CcnG"),r=n("25BL"),i=n("uIqm"),s=n("xbqr"),o=n("9GXa"),u=n("o4+5"),c=n("aXbf"),l=n("Ip0R");n("b5OY"),n("pxLl"),n("Jm/i"),n.d(e,"a",function(){return d}),n.d(e,"b",function(){return g});var d=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function f(t){return a["\u0275vid"](0,[(t()(),a["\u0275ted"](0,null,[" "," "," "])),a["\u0275ppd"](1,1)],null,function(t,e){var n=a["\u0275unv"](e,0,0,t(e,1,0,a["\u0275nov"](e.parent.parent,0),e.context.row.value));t(e,0,0,n,e.context.row.unit)})}function p(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"cd-table",[["columnMode","flex"]],null,[[null,"fetchData"]],function(t,e,n){var a=!0;return"fetchData"===e&&(a=!1!==t.component.getCounters(n)&&a),a},r.b,r.a)),a["\u0275did"](1,2867200,null,0,i.a,[a.NgZone,a.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],autoSave:[3,"autoSave"]},{fetchData:"fetchData"}),(t()(),a["\u0275and"](0,[[1,2],["valueTpl",2]],null,0,null,f))],function(t,e){var n=e.component;t(e,1,0,n.counters,n.columns,"flex",!1)},null)}function h(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"cd-warning-panel",[],null,null,null,s.b,s.a)),a["\u0275did"](1,49152,null,0,o.a,[],null,null),(t()(),a["\u0275ted"](-1,0,["Performance counters not available"]))],null,null)}function g(t){return a["\u0275vid"](0,[a["\u0275pid"](0,u.a,[c.a]),a["\u0275qud"](671088640,1,{valueTpl:0}),(t()(),a["\u0275and"](16777216,null,null,1,null,p)),a["\u0275did"](3,16384,null,0,l.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(t()(),a["\u0275and"](0,[["warning",2]],null,0,null,h))],function(t,e){t(e,3,0,e.component.counters,a["\u0275nov"](e,4))},null)}},jFaF:function(t,e,n){"use strict";function a(t,e){function n(){return!n.pred.apply(n.thisArg,arguments)}return n.pred=t,n.thisArg=e,n}n.d(e,"a",function(){return a})},"jKX/":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=function(){return function(t){void 0===t&&(t=[]);var e=this;["read","create","update","delete"].forEach(function(n){return e[n]=t.includes(n)})}}(),r=function(){return function(t){this.hosts=new a(t.hosts),this.configOpt=new a(t["config-opt"]),this.pool=new a(t.pool),this.osd=new a(t.osd),this.monitor=new a(t.monitor),this.rbdImage=new a(t["rbd-image"]),this.iscsi=new a(t.iscsi),this.rbdMirroring=new a(t["rbd-mirroring"]),this.rgw=new a(t.rgw),this.cephfs=new a(t.cephfs),this.manager=new a(t.manager),this.log=new a(t.log),this.user=new a(t.user),this.grafana=new a(t.grafana),this.prometheus=new a(t.prometheus),this.nfs=new a(t["nfs-ganesha"])}}()},jUeY:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("el",{monthsNominativeEl:"\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2_\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2_\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2_\u039c\u03ac\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2_\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2_\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2_\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2_\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2_\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2".split("_"),monthsGenitiveEl:"\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5_\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5_\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5_\u039c\u03b1\u0390\u03bf\u03c5_\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5_\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5_\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5_\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5_\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5_\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5".split("_"),months:function(t,e){return t?"string"==typeof e&&/D/.test(e.substring(0,e.indexOf("MMMM")))?this._monthsGenitiveEl[t.month()]:this._monthsNominativeEl[t.month()]:this._monthsNominativeEl},monthsShort:"\u0399\u03b1\u03bd_\u03a6\u03b5\u03b2_\u039c\u03b1\u03c1_\u0391\u03c0\u03c1_\u039c\u03b1\u03ca_\u0399\u03bf\u03c5\u03bd_\u0399\u03bf\u03c5\u03bb_\u0391\u03c5\u03b3_\u03a3\u03b5\u03c0_\u039f\u03ba\u03c4_\u039d\u03bf\u03b5_\u0394\u03b5\u03ba".split("_"),weekdays:"\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae_\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1_\u03a4\u03c1\u03af\u03c4\u03b7_\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7_\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7_\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae_\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf".split("_"),weekdaysShort:"\u039a\u03c5\u03c1_\u0394\u03b5\u03c5_\u03a4\u03c1\u03b9_\u03a4\u03b5\u03c4_\u03a0\u03b5\u03bc_\u03a0\u03b1\u03c1_\u03a3\u03b1\u03b2".split("_"),weekdaysMin:"\u039a\u03c5_\u0394\u03b5_\u03a4\u03c1_\u03a4\u03b5_\u03a0\u03b5_\u03a0\u03b1_\u03a3\u03b1".split("_"),meridiem:function(t,e,n){return t>11?n?"\u03bc\u03bc":"\u039c\u039c":n?"\u03c0\u03bc":"\u03a0\u039c"},isPM:function(t){return"\u03bc"===(t+"").toLowerCase()[0]},meridiemParse:/[\u03a0\u039c]\.?\u039c?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 {}] LT",nextDay:"[\u0391\u03cd\u03c1\u03b9\u03bf {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[\u03a7\u03b8\u03b5\u03c2 {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[\u03c4\u03bf \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf] dddd [{}] LT";default:return"[\u03c4\u03b7\u03bd \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03b7] dddd [{}] LT"}},sameElse:"L"},calendar:function(t,e){var n,a=this._calendarEl[t],r=e&&e.hours();return((n=a)instanceof Function||"[object Function]"===Object.prototype.toString.call(n))&&(a=a.apply(e)),a.replace("{}",r%12==1?"\u03c3\u03c4\u03b7":"\u03c3\u03c4\u03b9\u03c2")},relativeTime:{future:"\u03c3\u03b5 %s",past:"%s \u03c0\u03c1\u03b9\u03bd",s:"\u03bb\u03af\u03b3\u03b1 \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",ss:"%d \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1",m:"\u03ad\u03bd\u03b1 \u03bb\u03b5\u03c0\u03c4\u03cc",mm:"%d \u03bb\u03b5\u03c0\u03c4\u03ac",h:"\u03bc\u03af\u03b1 \u03ce\u03c1\u03b1",hh:"%d \u03ce\u03c1\u03b5\u03c2",d:"\u03bc\u03af\u03b1 \u03bc\u03ad\u03c1\u03b1",dd:"%d \u03bc\u03ad\u03c1\u03b5\u03c2",M:"\u03ad\u03bd\u03b1\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2",MM:"%d \u03bc\u03ae\u03bd\u03b5\u03c2",y:"\u03ad\u03bd\u03b1\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2",yy:"%d \u03c7\u03c1\u03cc\u03bd\u03b9\u03b1"},dayOfMonthOrdinalParse:/\d{1,2}\u03b7/,ordinal:"%d\u03b7",week:{dow:1,doy:4}})}()},jVdC:function(t,e,n){!function(t){"use strict";var e="stycze\u0144_luty_marzec_kwiecie\u0144_maj_czerwiec_lipiec_sierpie\u0144_wrzesie\u0144_pa\u017adziernik_listopad_grudzie\u0144".split("_"),n="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_wrze\u015bnia_pa\u017adziernika_listopada_grudnia".split("_");function a(t){return t%10<5&&t%10>1&&~~(t/10)%10!=1}function r(t,e,n){var r=t+" ";switch(n){case"ss":return r+(a(t)?"sekundy":"sekund");case"m":return e?"minuta":"minut\u0119";case"mm":return r+(a(t)?"minuty":"minut");case"h":return e?"godzina":"godzin\u0119";case"hh":return r+(a(t)?"godziny":"godzin");case"MM":return r+(a(t)?"miesi\u0105ce":"miesi\u0119cy");case"yy":return r+(a(t)?"lata":"lat")}}t.defineLocale("pl",{months:function(t,a){return t?""===a?"("+n[t.month()]+"|"+e[t.month()]+")":/D MMMM/.test(a)?n[t.month()]:e[t.month()]:e},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_pa\u017a_lis_gru".split("_"),weekdays:"niedziela_poniedzia\u0142ek_wtorek_\u015broda_czwartek_pi\u0105tek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_\u015br_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_\u015ar_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dzi\u015b o] LT",nextDay:"[Jutro o] LT",nextWeek:function(){switch(this.day()){case 0:return"[W niedziel\u0119 o] LT";case 2:return"[We wtorek o] LT";case 3:return"[W \u015brod\u0119 o] LT";case 6:return"[W sobot\u0119 o] LT";default:return"[W] dddd [o] LT"}},lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zesz\u0142\u0105 niedziel\u0119 o] LT";case 3:return"[W zesz\u0142\u0105 \u015brod\u0119 o] LT";case 6:return"[W zesz\u0142\u0105 sobot\u0119 o] LT";default:return"[W zesz\u0142y] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",ss:r,m:r,mm:r,h:r,hh:r,d:"1 dzie\u0144",dd:"%d dni",M:"miesi\u0105c",MM:r,y:"rok",yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n("wd/R"))},jXIB:function(t,e,n){"use strict";t.exports={},t.exports.filler=n("vpM6"),t.exports.legend=n("AX6q"),t.exports.title=n("mjYD")},jfSC:function(t,e,n){!function(t){"use strict";var e={1:"\u06f1",2:"\u06f2",3:"\u06f3",4:"\u06f4",5:"\u06f5",6:"\u06f6",7:"\u06f7",8:"\u06f8",9:"\u06f9",0:"\u06f0"},n={"\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9","\u06f0":"0"};t.defineLocale("fa",{months:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),monthsShort:"\u0698\u0627\u0646\u0648\u06cc\u0647_\u0641\u0648\u0631\u06cc\u0647_\u0645\u0627\u0631\u0633_\u0622\u0648\u0631\u06cc\u0644_\u0645\u0647_\u0698\u0648\u0626\u0646_\u0698\u0648\u0626\u06cc\u0647_\u0627\u0648\u062a_\u0633\u067e\u062a\u0627\u0645\u0628\u0631_\u0627\u06a9\u062a\u0628\u0631_\u0646\u0648\u0627\u0645\u0628\u0631_\u062f\u0633\u0627\u0645\u0628\u0631".split("_"),weekdays:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysShort:"\u06cc\u06a9\u200c\u0634\u0646\u0628\u0647_\u062f\u0648\u0634\u0646\u0628\u0647_\u0633\u0647\u200c\u0634\u0646\u0628\u0647_\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647_\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647_\u062c\u0645\u0639\u0647_\u0634\u0646\u0628\u0647".split("_"),weekdaysMin:"\u06cc_\u062f_\u0633_\u0686_\u067e_\u062c_\u0634".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631|\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/,isPM:function(t){return/\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631/.test(t)},meridiem:function(t,e,n){return t<12?"\u0642\u0628\u0644 \u0627\u0632 \u0638\u0647\u0631":"\u0628\u0639\u062f \u0627\u0632 \u0638\u0647\u0631"},calendar:{sameDay:"[\u0627\u0645\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",nextDay:"[\u0641\u0631\u062f\u0627 \u0633\u0627\u0639\u062a] LT",nextWeek:"dddd [\u0633\u0627\u0639\u062a] LT",lastDay:"[\u062f\u06cc\u0631\u0648\u0632 \u0633\u0627\u0639\u062a] LT",lastWeek:"dddd [\u067e\u06cc\u0634] [\u0633\u0627\u0639\u062a] LT",sameElse:"L"},relativeTime:{future:"\u062f\u0631 %s",past:"%s \u067e\u06cc\u0634",s:"\u0686\u0646\u062f \u062b\u0627\u0646\u06cc\u0647",ss:"\u062b\u0627\u0646\u06cc\u0647 d%",m:"\u06cc\u06a9 \u062f\u0642\u06cc\u0642\u0647",mm:"%d \u062f\u0642\u06cc\u0642\u0647",h:"\u06cc\u06a9 \u0633\u0627\u0639\u062a",hh:"%d \u0633\u0627\u0639\u062a",d:"\u06cc\u06a9 \u0631\u0648\u0632",dd:"%d \u0631\u0648\u0632",M:"\u06cc\u06a9 \u0645\u0627\u0647",MM:"%d \u0645\u0627\u0647",y:"\u06cc\u06a9 \u0633\u0627\u0644",yy:"%d \u0633\u0627\u0644"},preparse:function(t){return t.replace(/[\u06f0-\u06f9]/g,function(t){return n[t]}).replace(/\u060c/g,",")},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]}).replace(/,/g,"\u060c")},dayOfMonthOrdinalParse:/\d{1,2}\u0645/,ordinal:"%d\u0645",week:{dow:6,doy:12}})}(n("wd/R"))},jnO4:function(t,e,n){!function(t){"use strict";var e={1:"\u0661",2:"\u0662",3:"\u0663",4:"\u0664",5:"\u0665",6:"\u0666",7:"\u0667",8:"\u0668",9:"\u0669",0:"\u0660"},n={"\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u0660":"0"},a=function(t){return 0===t?0:1===t?1:2===t?2:t%100>=3&&t%100<=10?3:t%100>=11?4:5},r={s:["\u0623\u0642\u0644 \u0645\u0646 \u062b\u0627\u0646\u064a\u0629","\u062b\u0627\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062b\u0627\u0646\u064a\u062a\u0627\u0646","\u062b\u0627\u0646\u064a\u062a\u064a\u0646"],"%d \u062b\u0648\u0627\u0646","%d \u062b\u0627\u0646\u064a\u0629","%d \u062b\u0627\u0646\u064a\u0629"],m:["\u0623\u0642\u0644 \u0645\u0646 \u062f\u0642\u064a\u0642\u0629","\u062f\u0642\u064a\u0642\u0629 \u0648\u0627\u062d\u062f\u0629",["\u062f\u0642\u064a\u0642\u062a\u0627\u0646","\u062f\u0642\u064a\u0642\u062a\u064a\u0646"],"%d \u062f\u0642\u0627\u0626\u0642","%d \u062f\u0642\u064a\u0642\u0629","%d \u062f\u0642\u064a\u0642\u0629"],h:["\u0623\u0642\u0644 \u0645\u0646 \u0633\u0627\u0639\u0629","\u0633\u0627\u0639\u0629 \u0648\u0627\u062d\u062f\u0629",["\u0633\u0627\u0639\u062a\u0627\u0646","\u0633\u0627\u0639\u062a\u064a\u0646"],"%d \u0633\u0627\u0639\u0627\u062a","%d \u0633\u0627\u0639\u0629","%d \u0633\u0627\u0639\u0629"],d:["\u0623\u0642\u0644 \u0645\u0646 \u064a\u0648\u0645","\u064a\u0648\u0645 \u0648\u0627\u062d\u062f",["\u064a\u0648\u0645\u0627\u0646","\u064a\u0648\u0645\u064a\u0646"],"%d \u0623\u064a\u0627\u0645","%d \u064a\u0648\u0645\u064b\u0627","%d \u064a\u0648\u0645"],M:["\u0623\u0642\u0644 \u0645\u0646 \u0634\u0647\u0631","\u0634\u0647\u0631 \u0648\u0627\u062d\u062f",["\u0634\u0647\u0631\u0627\u0646","\u0634\u0647\u0631\u064a\u0646"],"%d \u0623\u0634\u0647\u0631","%d \u0634\u0647\u0631\u0627","%d \u0634\u0647\u0631"],y:["\u0623\u0642\u0644 \u0645\u0646 \u0639\u0627\u0645","\u0639\u0627\u0645 \u0648\u0627\u062d\u062f",["\u0639\u0627\u0645\u0627\u0646","\u0639\u0627\u0645\u064a\u0646"],"%d \u0623\u0639\u0648\u0627\u0645","%d \u0639\u0627\u0645\u064b\u0627","%d \u0639\u0627\u0645"]},i=function(t){return function(e,n,i,s){var o=a(e),u=r[t][a(e)];return 2===o&&(u=u[n?0:1]),u.replace(/%d/i,e)}},s=["\u064a\u0646\u0627\u064a\u0631","\u0641\u0628\u0631\u0627\u064a\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064a\u0644","\u0645\u0627\u064a\u0648","\u064a\u0648\u0646\u064a\u0648","\u064a\u0648\u0644\u064a\u0648","\u0623\u063a\u0633\u0637\u0633","\u0633\u0628\u062a\u0645\u0628\u0631","\u0623\u0643\u062a\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062f\u064a\u0633\u0645\u0628\u0631"];t.defineLocale("ar",{months:s,monthsShort:s,weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0623\u062d\u062f_\u0625\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0623\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u062d_\u0646_\u062b_\u0631_\u062e_\u062c_\u0633".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/\u200fM/\u200fYYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0635|\u0645/,isPM:function(t){return"\u0645"===t},meridiem:function(t,e,n){return t<12?"\u0635":"\u0645"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u064b\u0627 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0646\u062f \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0628\u0639\u062f %s",past:"\u0645\u0646\u0630 %s",s:i("s"),ss:i("s"),m:i("m"),mm:i("m"),h:i("h"),hh:i("h"),d:i("d"),dd:i("d"),M:i("M"),MM:i("M"),y:i("y"),yy:i("y")},preparse:function(t){return t.replace(/[\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660]/g,function(t){return n[t]}).replace(/\u060c/g,",")},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]}).replace(/,/g,"\u060c")},week:{dow:6,doy:12}})}(n("wd/R"))},jvuA:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("UReH");e.DatatableRowDetailDirective=function(){function t(){this.rowHeight=0,this.toggle=new i.EventEmitter}return t.prototype.toggleExpandRow=function(t){this.toggle.emit({type:"row",value:t})},t.prototype.expandAllRows=function(){this.toggle.emit({type:"all",value:!0})},t.prototype.collapseAllRows=function(){this.toggle.emit({type:"all",value:!1})},a([i.Input(),r("design:type",Object)],t.prototype,"rowHeight",void 0),a([i.Input(),i.ContentChild(s.DatatableRowDetailTemplateDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"template",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"toggle",void 0),a([i.Directive({selector:"ngx-datatable-row-detail"})],t)}()},kEOa:function(t,e,n){!function(t){"use strict";var e={1:"\u09e7",2:"\u09e8",3:"\u09e9",4:"\u09ea",5:"\u09eb",6:"\u09ec",7:"\u09ed",8:"\u09ee",9:"\u09ef",0:"\u09e6"},n={"\u09e7":"1","\u09e8":"2","\u09e9":"3","\u09ea":"4","\u09eb":"5","\u09ec":"6","\u09ed":"7","\u09ee":"8","\u09ef":"9","\u09e6":"0"};t.defineLocale("bn",{months:"\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09c0_\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09bf_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0\u09bf\u09b2_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2\u09be\u0987_\u0986\u0997\u09b8\u09cd\u099f_\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0_\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0_\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0_\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0".split("_"),monthsShort:"\u099c\u09be\u09a8\u09c1_\u09ab\u09c7\u09ac_\u09ae\u09be\u09b0\u09cd\u099a_\u098f\u09aa\u09cd\u09b0_\u09ae\u09c7_\u099c\u09c1\u09a8_\u099c\u09c1\u09b2_\u0986\u0997_\u09b8\u09c7\u09aa\u09cd\u099f_\u0985\u0995\u09cd\u099f\u09cb_\u09a8\u09ad\u09c7_\u09a1\u09bf\u09b8\u09c7".split("_"),weekdays:"\u09b0\u09ac\u09bf\u09ac\u09be\u09b0_\u09b8\u09cb\u09ae\u09ac\u09be\u09b0_\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0_\u09ac\u09c1\u09a7\u09ac\u09be\u09b0_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0_\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0_\u09b6\u09a8\u09bf\u09ac\u09be\u09b0".split("_"),weekdaysShort:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997\u09b2_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),weekdaysMin:"\u09b0\u09ac\u09bf_\u09b8\u09cb\u09ae_\u09ae\u0999\u09cd\u0997_\u09ac\u09c1\u09a7_\u09ac\u09c3\u09b9\u0983_\u09b6\u09c1\u0995\u09cd\u09b0_\u09b6\u09a8\u09bf".split("_"),longDateFormat:{LT:"A h:mm \u09b8\u09ae\u09df",LTS:"A h:mm:ss \u09b8\u09ae\u09df",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm \u09b8\u09ae\u09df",LLLL:"dddd, D MMMM YYYY, A h:mm \u09b8\u09ae\u09df"},calendar:{sameDay:"[\u0986\u099c] LT",nextDay:"[\u0986\u0997\u09be\u09ae\u09c0\u0995\u09be\u09b2] LT",nextWeek:"dddd, LT",lastDay:"[\u0997\u09a4\u0995\u09be\u09b2] LT",lastWeek:"[\u0997\u09a4] dddd, LT",sameElse:"L"},relativeTime:{future:"%s \u09aa\u09b0\u09c7",past:"%s \u0986\u0997\u09c7",s:"\u0995\u09df\u09c7\u0995 \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",ss:"%d \u09b8\u09c7\u0995\u09c7\u09a8\u09cd\u09a1",m:"\u098f\u0995 \u09ae\u09bf\u09a8\u09bf\u099f",mm:"%d \u09ae\u09bf\u09a8\u09bf\u099f",h:"\u098f\u0995 \u0998\u09a8\u09cd\u099f\u09be",hh:"%d \u0998\u09a8\u09cd\u099f\u09be",d:"\u098f\u0995 \u09a6\u09bf\u09a8",dd:"%d \u09a6\u09bf\u09a8",M:"\u098f\u0995 \u09ae\u09be\u09b8",MM:"%d \u09ae\u09be\u09b8",y:"\u098f\u0995 \u09ac\u099b\u09b0",yy:"%d \u09ac\u099b\u09b0"},preparse:function(t){return t.replace(/[\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09e6]/g,function(t){return n[t]})},postformat:function(t){return t.replace(/\d/g,function(t){return e[t]})},meridiemParse:/\u09b0\u09be\u09a4|\u09b8\u0995\u09be\u09b2|\u09a6\u09c1\u09aa\u09c1\u09b0|\u09ac\u09bf\u0995\u09be\u09b2|\u09b0\u09be\u09a4/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u09b0\u09be\u09a4"===e&&t>=4||"\u09a6\u09c1\u09aa\u09c1\u09b0"===e&&t<5||"\u09ac\u09bf\u0995\u09be\u09b2"===e?t+12:t},meridiem:function(t,e,n){return t<4?"\u09b0\u09be\u09a4":t<10?"\u09b8\u0995\u09be\u09b2":t<17?"\u09a6\u09c1\u09aa\u09c1\u09b0":t<20?"\u09ac\u09bf\u0995\u09be\u09b2":"\u09b0\u09be\u09a4"},week:{dow:0,doy:6}})}(n("wd/R"))},kJI8:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},kOpN:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("zh-tw",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u51cc\u6668"===e||"\u65e9\u4e0a"===e||"\u4e0a\u5348"===e?t:"\u4e2d\u5348"===e?t>=11?t:t+12:"\u4e0b\u5348"===e||"\u665a\u4e0a"===e?t+12:void 0},meridiem:function(t,e,n){var a=100*t+e;return a<600?"\u51cc\u6668":a<900?"\u65e9\u4e0a":a<1130?"\u4e0a\u5348":a<1230?"\u4e2d\u5348":a<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929] LT",nextDay:"[\u660e\u5929] LT",nextWeek:"[\u4e0b]dddd LT",lastDay:"[\u6628\u5929] LT",lastWeek:"[\u4e0a]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u9031)/,ordinal:function(t,e){switch(e){case"d":case"D":case"DDD":return t+"\u65e5";case"M":return t+"\u6708";case"w":case"W":return t+"\u9031";default:return t}},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",ss:"%d \u79d2",m:"1 \u5206\u9418",mm:"%d \u5206\u9418",h:"1 \u5c0f\u6642",hh:"%d \u5c0f\u6642",d:"1 \u5929",dd:"%d \u5929",M:"1 \u500b\u6708",MM:"%d \u500b\u6708",y:"1 \u5e74",yy:"%d \u5e74"}})}()},kQXf:function(t,e,n){"use strict";function a(t){return"string"==typeof t?!/\S/.test(t):Array.isArray(t)?0===t.length:i(t)}function r(t,e){return!i(t)&&t.indexOf(e)>-1}function i(t){return null==t}Object.defineProperty(e,"__esModule",{value:!0}),e.isEmpty=a,e.trim=function(t){return i(t)?"":t.trim()},e.has=function(t,e){return t&&"object"==typeof t&&t.hasOwnProperty(e)},e.isFunction=function(t){return"function"==typeof t},e.get=function(t,e,n){for(var a=t,r=0,s=e.split(".");r20?e=40===t||50===t||60===t||80===t||100===t?"fed":"ain":t>0&&(e=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"][t]),t+e},week:{dow:1,doy:4}})}()},lHUG:function(t,e,n){"use strict";function a(t){return t<0?Math.ceil(t)||0:Math.floor(t)}function r(t){return"string"==typeof t}function i(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function s(t){return t&&t.getTime&&!isNaN(t.getTime())}function o(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function u(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function c(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function l(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function d(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function f(t){return void 0===t}function p(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=a(e)),n}n.d(e,"a",function(){return sn}),n.d(e,"b",function(){return un}),n.d(e,"c",function(){return oe}),n.d(e,"d",function(){return At}),n.d(e,"e",function(){return pn}),n.d(e,"f",function(){return Ne}),n.d(e,"g",function(){return hn}),n.d(e,"h",function(){return j}),n.d(e,"i",function(){return Y}),n.d(e,"j",function(){return G}),n.d(e,"k",function(){return ue}),n.d(e,"l",function(){return z}),n.d(e,"m",function(){return gn}),n.d(e,"n",function(){return Fe}),n.d(e,"o",function(){return c}),n.d(e,"p",function(){return ze}),n.d(e,"q",function(){return i}),n.d(e,"r",function(){return s}),n.d(e,"s",function(){return Ge}),n.d(e,"t",function(){return V}),n.d(e,"u",function(){return Ye}),n.d(e,"v",function(){return U}),n.d(e,"w",function(){return H}),n.d(e,"x",function(){return B}),n.d(e,"y",function(){return bn}),n.d(e,"z",function(){return mn}),n.d(e,"A",function(){return yn}),n.d(e,"B",function(){return qe}),n.d(e,"C",function(){return wn}),n.d(e,"D",function(){return Sn}),n.d(e,"E",function(){return Ot}),n.d(e,"F",function(){return St}),n.d(e,"G",function(){return Rt}),n.d(e,"H",function(){return On});var h={},g={date:"day",hour:"hours",minute:"minutes",second:"seconds",millisecond:"milliseconds"};function b(t,e){var n=t.toLowerCase(),a=t;n in g&&(a=g[n]),h[n]=h[n+"s"]=h[e]=a}function m(t){return r(t)?h[t]||h[t.toLowerCase()]:void 0}var y=0,v=1,_=2,x=3,T=4,w=5,S=6,O=7,I=8;function C(t,e,n){var a=""+Math.abs(t);return(t>=0?n?"+":"":"-")+Math.pow(10,Math.max(0,e-a.length)).toString().substr(1)+a}var k={},N={},R=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;function A(t,e,n,a){t&&(N[t]=a),e&&(N[e[0]]=function(){return C(a.apply(null,arguments),e[1],e[2])}),n&&(N[n]=function(e,n){return n.locale.ordinal(a.apply(null,arguments),t)})}function D(t,e,n){var a=new Date(Date.UTC.apply(null,arguments));return t<100&&t>=0&&isFinite(a.getUTCFullYear())&&a.setUTCFullYear(t),a}function E(t,e,n,a,r,i,s){void 0===e&&(e=0),void 0===n&&(n=1),void 0===a&&(a=0),void 0===r&&(r=0),void 0===i&&(i=0),void 0===s&&(s=0);var o=new Date(t,e,n,a,r,i,s);return t<100&&t>=0&&isFinite(o.getFullYear())&&o.setFullYear(t),o}function L(t,e){return void 0===e&&(e=!1),e?t.getUTCHours():t.getHours()}function P(t,e){return void 0===e&&(e=!1),e?t.getUTCMinutes():t.getMinutes()}function M(t,e){return void 0===e&&(e=!1),e?t.getUTCSeconds():t.getSeconds()}function q(t,e){return void 0===e&&(e=!1),e?t.getUTCMilliseconds():t.getMilliseconds()}function j(t,e){return void 0===e&&(e=!1),e?t.getUTCDay():t.getDay()}function F(t,e){return void 0===e&&(e=!1),e?t.getUTCDate():t.getDate()}function z(t,e){return void 0===e&&(e=!1),e?t.getUTCMonth():t.getMonth()}function G(t,e){return void 0===e&&(e=!1),e?t.getUTCFullYear():t.getFullYear()}function Y(t){return E(t.getFullYear(),t.getMonth(),1,t.getHours(),t.getMinutes(),t.getSeconds())}function V(t,e){return t.getDay()===e}function H(t,e){return!(!t||!e)&&B(t,e)&&z(t)===z(e)}function B(t,e){return!(!t||!e)&&G(t)===G(e)}function U(t,e){return!(!t||!e)&&B(t,e)&&H(t,e)&&F(t)===F(e)}var W=/\d/,K=/\d\d/,$=/\d{3}/,Z=/\d{4}/,X=/[+-]?\d{6}/,J=/\d\d?/,Q=/\d\d\d\d?/,tt=/\d\d\d\d\d\d?/,et=/\d{1,3}/,nt=/\d{1,4}/,at=/[+-]?\d{1,6}/,rt=/\d+/,it=/[+-]?\d+/,st=/Z|[+-]\d\d(?::?\d\d)?/gi,ot=/[+-]?\d+(\.\d{1,3})?/,ut=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ct={};function lt(t,e,n){ct[t]=o(e)?e:function(t,a){return t&&n?n:e}}function dt(t,e){return l(ct,t)?ct[t](!1,e):new RegExp(ft(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,a,r){return e||n||a||r})))}function ft(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var pt={};function ht(t,e){var n=r(t)?[t]:t,a=e;if(u(e)&&(a=function(t,n,a){return n[e]=p(t),a}),c(n)&&o(a)){var i=void 0;for(i=0;i68?1900:2e3)}function _t(t){return xt(t)?366:365}function xt(t){return t%4==0&&t%100!=0||t%400==0}function Tt(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=(e%12+12)%12;return 1===n?xt(t+(e-n)/12)?29:28:31-n%7%2}var wt={year:0,month:0,day:0,hour:0,minute:0,seconds:0};function St(t,e){var n=Object.assign({},wt,e),a=t.getFullYear()+(n.year||0),r=t.getMonth()+(n.month||0),i=t.getDate()+(n.day||0);return n.month&&!n.day&&(i=Math.min(i,Tt(a,r))),E(a,r,i,t.getHours()+(n.hour||0),t.getMinutes()+(n.minute||0),t.getSeconds()+(n.seconds||0))}function Ot(t,e){return E(It(t.getFullYear(),e.year),It(t.getMonth(),e.month),It(t.getDate(),e.day),It(t.getHours(),e.hour),It(t.getMinutes(),e.minute),It(t.getSeconds(),e.seconds),It(t.getMilliseconds(),e.milliseconds))}function It(t,e){return u(e)?e:t}function Ct(t,e,n){var a=Math.min(F(t),Tt(G(t),e));return n?t.setUTCMonth(e,a):t.setMonth(e,a),t}function kt(t,e,n){return n?t.setUTCDate(e):t.setDate(e),t}function Nt(t){return new Date(t.getTime())}function Rt(t,e,n){var a,i=Nt(t);switch(e){case"year":Ct(i,0,n);case"quarter":case"month":kt(i,1,n);case"week":case"isoWeek":case"day":case"date":!function(t,e,n){n?t.setUTCHours(0):t.setHours(0)}(i,0,n);case"hours":!function(t,e,n){n?t.setUTCMinutes(0):t.setMinutes(0)}(i,0,n);case"minutes":!function(t,e,n){n?t.setUTCSeconds(0):t.setSeconds(0)}(i,0,n);case"seconds":!function(t,e,n){n?t.setUTCMilliseconds(0):t.setMilliseconds(0)}(i,0,n)}return"week"===e&&(void 0===(a={isUTC:n})&&(a={}),Ke(i,0-Je(i,a.locale,a.isUTC),"day")),"isoWeek"===e&&function(t,e,n){void 0===n&&(n={});var a,i=(void 0===(a=n.locale)&&(a=ue()),r(1)?a.weekdaysParse(1)%7||7:u(1)&&isNaN(1)?null:1);Ze(t,Xe(t)%7?i:i-7)}(i),"quarter"===e&&Ct(i,3*Math.floor(z(i,n)/3),n),i}function At(t,e,n){var a=e;return"date"===a&&(a="day"),function(t,e,n,a){return $e(t,Be(1,"milliseconds"),-1,a)}(Ke(Rt(t,a,n),1,"isoWeek"===a?"week":a,n),0,0,n)}function Dt(t,e){var n=+Rt(t,"day",e),a=+Rt(t,"year",e);return Math.round((n-a)/864e5)+1}function Et(t,e,n){var a=e-n+7;return-(D(t,0,a).getUTCDay()-e+7)%7+a-1}function Lt(t,e,n,a){var r,i,s=Et(G(t,a),e,n),o=Math.floor((Dt(t,a)-s-1)/7)+1;return o<1?r=o+Pt(i=G(t,a)-1,e,n):o>Pt(G(t,a),e,n)?(r=o-Pt(G(t,a),e,n),i=G(t,a)+1):(i=G(t,a),r=o),{week:r,year:i}}function Pt(t,e,n){var a=Et(t,e,n),r=Et(t+1,e,n);return(_t(t)-a+r)/7}var Mt=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,qt="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),jt="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Ft="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),zt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Gt="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Yt={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Vt=ut,Ht=ut,Bt=function(){function t(t){t&&this.set(t)}return t.prototype.set=function(t){var e;for(e in t)if(t.hasOwnProperty(e)){var n=t[e];this[o(n)?e:"_"+e]=n}this._config=t},t.prototype.calendar=function(t,e,n){var a=this._calendar[t]||this._calendar.sameElse;return o(a)?a.call(null,e,n):a},t.prototype.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])},Object.defineProperty(t.prototype,"invalidDate",{get:function(){return this._invalidDate},set:function(t){this._invalidDate=t},enumerable:!0,configurable:!0}),t.prototype.ordinal=function(t,e){return this._ordinal.replace("%d",t.toString(10))},t.prototype.preparse=function(t){return t},t.prototype.postformat=function(t){return t},t.prototype.relativeTime=function(t,e,n,a){var r=this._relativeTime[n];return o(r)?r(t,e,n,a):r.replace(/%d/i,t.toString(10))},t.prototype.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return o(n)?n(e):n.replace(/%s/i,e)},t.prototype.months=function(t,e,n){if(void 0===n&&(n=!1),!t)return c(this._months)?this._months:this._months.standalone;if(c(this._months))return this._months[z(t,n)];var a=(this._months.isFormat||Mt).test(e)?"format":"standalone";return this._months[a][z(t,n)]},t.prototype.monthsShort=function(t,e,n){if(void 0===n&&(n=!1),!t)return c(this._monthsShort)?this._monthsShort:this._monthsShort.standalone;if(c(this._monthsShort))return this._monthsShort[z(t,n)];var a=Mt.test(e)?"format":"standalone";return this._monthsShort[a][z(t,n)]},t.prototype.monthsParse=function(t,e,n){var a,r,i;if(this._monthsParseExact)return this.handleMonthStrictParse(t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=new Date(Date.UTC(2e3,i)),n&&!this._longMonthsParse[i]){var s=this.months(a,"",!0).replace(".",""),o=this.monthsShort(a,"",!0).replace(".","");this._longMonthsParse[i]=new RegExp("^"+s+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+o+"$","i")}if(n||this._monthsParse[i]||(r="^"+this.months(a,"",!0)+"|^"+this.monthsShort(a,"",!0),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},t.prototype.monthsRegex=function(t){return this._monthsParseExact?(l(this,"_monthsRegex")||this.computeMonthsParse(),t?this._monthsStrictRegex:this._monthsRegex):(l(this,"_monthsRegex")||(this._monthsRegex=Ht),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},t.prototype.monthsShortRegex=function(t){return this._monthsParseExact?(l(this,"_monthsRegex")||this.computeMonthsParse(),t?this._monthsShortStrictRegex:this._monthsShortRegex):(l(this,"_monthsShortRegex")||(this._monthsShortRegex=Vt),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},t.prototype.week=function(t,e){return Lt(t,this._week.dow,this._week.doy,e).week},t.prototype.firstDayOfWeek=function(){return this._week.dow},t.prototype.firstDayOfYear=function(){return this._week.doy},t.prototype.weekdays=function(t,e,n){if(!t)return c(this._weekdays)?this._weekdays:this._weekdays.standalone;if(c(this._weekdays))return this._weekdays[j(t,n)];var a=this._weekdays.isFormat.test(e)?"format":"standalone";return this._weekdays[a][j(t,n)]},t.prototype.weekdaysMin=function(t,e,n){return t?this._weekdaysMin[j(t,n)]:this._weekdaysMin},t.prototype.weekdaysShort=function(t,e,n){return t?this._weekdaysShort[j(t,n)]:this._weekdaysShort},t.prototype.weekdaysParse=function(t,e,n){var a,r;if(this._weekdaysParseExact)return this.handleWeekStrictParse(t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),a=0;a<7;a++){var i=Ze(new Date(Date.UTC(2e3,1)),a,null,!0);if(n&&!this._fullWeekdaysParse[a]&&(this._fullWeekdaysParse[a]=new RegExp("^"+this.weekdays(i,"",!0).replace(".",".?")+"$","i"),this._shortWeekdaysParse[a]=new RegExp("^"+this.weekdaysShort(i,"",!0).replace(".",".?")+"$","i"),this._minWeekdaysParse[a]=new RegExp("^"+this.weekdaysMin(i,"",!0).replace(".",".?")+"$","i")),this._weekdaysParse[a]||(r="^"+this.weekdays(i,"",!0)+"|^"+this.weekdaysShort(i,"",!0)+"|^"+this.weekdaysMin(i,"",!0),this._weekdaysParse[a]=new RegExp(r.replace(".",""),"i")),!(c(this._fullWeekdaysParse)&&c(this._shortWeekdaysParse)&&c(this._minWeekdaysParse)&&c(this._weekdaysParse)))return;if(n&&"dddd"===e&&this._fullWeekdaysParse[a].test(t))return a;if(n&&"ddd"===e&&this._shortWeekdaysParse[a].test(t))return a;if(n&&"dd"===e&&this._minWeekdaysParse[a].test(t))return a;if(!n&&this._weekdaysParse[a].test(t))return a}},t.prototype.weekdaysRegex=function(t){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||this.computeWeekdaysParse(),t?this._weekdaysStrictRegex:this._weekdaysRegex):(l(this,"_weekdaysRegex")||(this._weekdaysRegex=ut),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},t.prototype.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||this.computeWeekdaysParse(),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(l(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ut),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},t.prototype.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||this.computeWeekdaysParse(),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(l(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ut),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},t.prototype.isPM=function(t){return"p"===t.toLowerCase().charAt(0)},t.prototype.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},t.prototype.formatLongDate=function(t){this._longDateFormat=this._longDateFormat?this._longDateFormat:Yt;var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])},t.prototype.handleMonthStrictParse=function(t,e,n){var a,r,i,s=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],a=0;a<12;++a)i=new Date(2e3,a),this._shortMonthsParse[a]=this.monthsShort(i,"").toLocaleLowerCase(),this._longMonthsParse[a]=this.months(i,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(r=this._shortMonthsParse.indexOf(s))?r:null:-1!==(r=this._longMonthsParse.indexOf(s))?r:null:"MMM"===e?-1!==(r=this._shortMonthsParse.indexOf(s))?r:-1!==(r=this._longMonthsParse.indexOf(s))?r:null:-1!==(r=this._longMonthsParse.indexOf(s))?r:-1!==(r=this._shortMonthsParse.indexOf(s))?r:null},t.prototype.handleWeekStrictParse=function(t,e,n){var a,r=t.toLocaleLowerCase();if(!this._weekdaysParse){this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[];var i=void 0;for(i=0;i<7;++i){var s=Ze(new Date(Date.UTC(2e3,1)),i,null,!0);this._minWeekdaysParse[i]=this.weekdaysMin(s).toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(s).toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(s,"").toLocaleLowerCase()}}if(c(this._weekdaysParse)&&c(this._shortWeekdaysParse)&&c(this._minWeekdaysParse))return n?"dddd"===e?-1!==(a=this._weekdaysParse.indexOf(r))?a:null:"ddd"===e?-1!==(a=this._shortWeekdaysParse.indexOf(r))?a:null:-1!==(a=this._minWeekdaysParse.indexOf(r))?a:null:"dddd"===e?-1!==(a=this._weekdaysParse.indexOf(r))?a:-1!==(a=this._shortWeekdaysParse.indexOf(r))?a:-1!==(a=this._minWeekdaysParse.indexOf(r))?a:null:"ddd"===e?-1!==(a=this._shortWeekdaysParse.indexOf(r))?a:-1!==(a=this._weekdaysParse.indexOf(r))?a:-1!==(a=this._minWeekdaysParse.indexOf(r))?a:null:-1!==(a=this._minWeekdaysParse.indexOf(r))?a:-1!==(a=this._weekdaysParse.indexOf(r))?a:-1!==(a=this._shortWeekdaysParse.indexOf(r))?a:null},t.prototype.computeMonthsParse=function(){var t,e,n=[],a=[],r=[];for(e=0;e<12;e++)t=new Date(2e3,e),n.push(this.monthsShort(t,"")),a.push(this.months(t,"")),r.push(this.months(t,"")),r.push(this.monthsShort(t,""));for(n.sort(Ut),a.sort(Ut),r.sort(Ut),e=0;e<12;e++)n[e]=ft(n[e]),a[e]=ft(a[e]);for(e=0;e<24;e++)r[e]=ft(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+n.join("|")+")","i")},t.prototype.computeWeekdaysParse=function(){var t,e=[],n=[],a=[],r=[];for(t=0;t<7;t++){var i=Ze(new Date(Date.UTC(2e3,1)),t,null,!0),s=this.weekdaysMin(i),o=this.weekdaysShort(i),u=this.weekdays(i);e.push(s),n.push(o),a.push(u),r.push(s),r.push(o),r.push(u)}for(e.sort(Ut),n.sort(Ut),a.sort(Ut),r.sort(Ut),t=0;t<7;t++)n[t]=ft(n[t]),a[t]=ft(a[t]),r[t]=ft(r[t]);this._weekdaysRegex=new RegExp("^("+r.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+n.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+e.join("|")+")","i")},t}();function Ut(t,e){return e.length-t.length}var Wt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:Yt,invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:qt,monthsShort:jt,week:{dow:0,doy:6},weekdays:Ft,weekdaysMin:Gt,weekdaysShort:zt,meridiemParse:/[ap]\.?m?\.?/i};function Kt(t,e,n){var a,r=Math.min(t.length,e.length),i=Math.abs(t.length-e.length),s=0;for(a=0;a0;){if(s=r.slice(0,i).join("-"),ae[s]||console.error('Khronos locale error: please load locale "'+s+'" before using it'),n=ae[s])return n;if(e&&e.length>=i&&Kt(r,e,!0)>=i-1)break;i--}a++}var s;return null}(c(t)?t:[t]):ee}var ce=["year","quarter","month","week","day","hours","minutes","seconds","milliseconds"],le=ce.reduce(function(t,e){return t[e]=!0,t},{});function de(t){return t<0?Math.floor(t):Math.ceil(t)}function fe(t){return 4800*t/146097}function pe(t){return 146097*t/4800}var he=Math.round,ge=function(){function t(t,e){void 0===e&&(e={}),this._data={},this._locale=ue(),this._locale=e&&e._locale||ue();var n=t.year||0,r=t.quarter||0,i=t.month||0,s=t.week||0,o=t.day||0,u=t.hours||0,c=t.minutes||0,l=t.seconds||0,d=t.milliseconds||0;return this._isValid=function(t){if(Object.keys(t).some(function(e){return e in le&&null===t[e]||isNaN(t[e])}))return!1;for(var e=!1,n=0;n=0&&n>=0&&r>=0||e<=0&&n<=0&&r<=0||(e+=864e5*de(pe(r)+n),n=0,r=0),i.milliseconds=e%1e3;var s=a(e/1e3);i.seconds=s%60;var o=a(s/60);i.minutes=o%60;var u=a(o/60);i.hours=u%24,n+=a(u/24);var c=a(fe(n));r+=c,n-=de(pe(c));var l=a(r/12);return r%=12,i.day=n,i.month=r,i.year=l,t}(this)}return t.prototype.isValid=function(){return this._isValid},t.prototype.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate;var e=this.localeData(),n=function(t,e,n){var a=Be(t).abs(),r=he(a.as("s")),i=he(a.as("m")),s=he(a.as("h")),o=he(a.as("d")),u=he(a.as("M")),c=he(a.as("y")),l=r<=44&&["s",r]||r<45&&["ss",r]||i<=1&&["m"]||i<45&&["mm",i]||s<=1&&["h"]||s<22&&["hh",s]||o<=1&&["d"]||o<26&&["dd",o]||u<=1&&["M"]||u<11&&["MM",u]||c<=1&&["y"]||["yy",c];return(function(t,e,n,a,r){return r.relativeTime(e||1,!!n,t,a)}).apply(null,[l[0],l[1],e,+t>0,n])}(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},t.prototype.localeData=function(){return this._locale},t.prototype.locale=function(t){return t?(this._locale=ue(t)||this._locale,this):this._locale._abbr},t.prototype.abs=function(){var t=Math.abs,e=this._data;return this._milliseconds=t(this._milliseconds),this._days=t(this._days),this._months=t(this._months),e.milliseconds=t(e.milliseconds),e.seconds=t(e.seconds),e.minutes=t(e.minutes),e.hours=t(e.hours),e.month=t(e.month),e.year=t(e.year),this},t.prototype.as=function(t){if(!this.isValid())return NaN;var e,n,a=this._milliseconds,r=m(t);if("month"===r||"year"===r)return n=this._months+fe(e=this._days+a/864e5),"month"===r?n:n/12;switch(e=this._days+Math.round(pe(this._months)),r){case"week":return e/7+a/6048e5;case"day":return e+a/864e5;case"hours":return 24*e+a/36e5;case"minutes":return 1440*e+a/6e4;case"seconds":return 86400*e+a/1e3;case"milliseconds":return Math.floor(864e5*e)+a;default:throw new Error("Unknown unit "+r)}},t.prototype.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*p(this._months/12):NaN},t}();function be(t){if(null==t._isValid){var e=mt(t),n=Array.prototype.some.call(e.parsedDateParts,function(t){return null!=t}),a=!isNaN(t._d&&t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.weekdayMismatch&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict&&(a=a&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return a;t._isValid=a}return t._isValid}function me(t,e){return t._d=new Date(NaN),Object.assign(mt(t),e||{userInvalidated:!0}),t}var ye=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ve=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_e=/Z|[+-]\d\d(?::?\d\d)?/,xe=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/,!0],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/,!0],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/,!0],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/,!0],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/,!0],["YYYYMMDD",/\d{8}/,!0],["GGGG[W]WWE",/\d{4}W\d{3}/,!0],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/,!0]],Te=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],we=/^\/?Date\((\-?\d+)/i,Se={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480},Oe=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;function Ie(t){if(!r(t._i))return t;var e,n,a,i,s,o,u=t._i,c=ye.exec(u)||ve.exec(u);if(!c)return t._isValid=!1,t;for(s=0,o=xe.length;s=0&&r.test(n);)n=n.replace(r,i),r.lastIndex=0,a-=1;return n}function Ae(t,e,n){return null!=t?t:null!=e?e:n}function De(t){var e,n,a,r,i,s=[];if(t._d)return t;for(a=function(t){var e=new Date;return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}(t),t._w&&null==t._a[_]&&null==t._a[v]&&function(t){var e,n,a,r,i,s,o,u;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)i=1,s=4,n=Ae(e.GG,t._a[y],Lt(new Date,1,4).year),a=Ae(e.W,1),((r=Ae(e.E,1))<1||r>7)&&(u=!0);else{i=t._locale._week.dow,s=t._locale._week.doy;var c=Lt(new Date,i,s);n=Ae(e.gg,t._a[y],c.year),a=Ae(e.w,c.week),null!=e.d?((r=e.d)<0||r>6)&&(u=!0):null!=e.e?(r=e.e+i,(e.e<0||e.e>6)&&(u=!0)):r=i}a<1||a>Pt(n,i,s)?mt(t)._overflowWeeks=!0:null!=u?mt(t)._overflowWeekday=!0:(o=function(t,e,n,a,r){var i,s,o=1+7*(e-1)+(7+n-a)%7+Et(t,a,r);return o<=0?s=_t(i=t-1)+o:o>_t(t)?(i=t+1,s=o-_t(t)):(i=t,s=o),{year:i,dayOfYear:s}}(n,a,r,i,s),t._a[y]=o.year,t._dayOfYear=o.dayOfYear)}(t),null!=t._dayOfYear&&(i=Ae(t._a[y],a[y]),(t._dayOfYear>_t(i)||0===t._dayOfYear)&&(mt(t)._overflowDayOfYear=!0),n=new Date(Date.UTC(i,0,t._dayOfYear)),t._a[v]=n.getUTCMonth(),t._a[_]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=a[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];return 24===t._a[x]&&0===t._a[T]&&0===t._a[w]&&0===t._a[S]&&(t._nextDay=!0,t._a[x]=0),t._d=(t._useUTC?D:E).apply(null,s),r=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[x]=24),t._w&&void 0!==t._w.d&&t._w.d!==r&&(mt(t).weekdayMismatch=!0),t}function Ee(t){var e,n=t._a;return n&&-2===mt(t).overflow&&(e=n[v]<0||n[v]>11?v:n[_]<1||n[_]>Tt(n[y],n[v])?_:n[x]<0||n[x]>24||24===n[x]&&(0!==n[T]||0!==n[w]||0!==n[S])?x:n[T]<0||n[T]>59?T:n[w]<0||n[w]>59?w:n[S]<0||n[S]>999?S:-1,mt(t)._overflowDayOfYear&&(e_)&&(e=_),mt(t)._overflowWeeks&&-1===e&&(e=O),mt(t)._overflowWeekday&&-1===e&&(e=I),mt(t).overflow=e),t}var Le="ISO_8601",Pe="RFC_2822";function Me(t){if(t._f===Le)return Ie(t);if(t._f===Pe)return ke(t);if(t._a=[],mt(t).empty=!0,c(t._f)||!t._i&&0!==t._i)return t;var e,n,a,r,i=t._i.toString(),s=0,o=i.length,u=Re(t._f,t._locale).match(R)||[];for(e=0;e0&&mt(t).unusedInput.push(r),i=i.slice(i.indexOf(a)+a.length),s+=a.length),N[n]?(a?mt(t).empty=!1:mt(t).unusedTokens.push(n),bt(n,a,t)):t._strict&&!a&&mt(t).unusedTokens.push(n);return mt(t).charsLeftOver=o-s,i.length>0&&mt(t).unusedInput.push(i),t._a[x]<=12&&!0===mt(t).bigHour&&t._a[x]>0&&(mt(t).bigHour=void 0),mt(t).parsedDateParts=t._a.slice(0),mt(t).meridiem=t._meridiem,t._a[x]=function(e,n,a){var r=t._a[x];if(null==a)return r;if(null!=e.meridiemHour)return e.meridiemHour(r,a);if(null==e.isPM)return r;var i=e.isPM(a);return i&&r<12&&(r+=12),i||12!==r||(r=0),r}(t._locale,0,t._meridiem),De(t),Ee(t)}function qe(t,e,n,a,s){return i(t)?t:function(t,e,n,a,s){var o={},p=t;return(d(p)&&function(t){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(t).length;var e;for(e in t)if(t.hasOwnProperty(e))return!1;return!0}(p)||c(p)&&0===p.length)&&(p=void 0),o._useUTC=o._isUTC=s,o._l=n,o._i=p,o._f=e,o._strict=a,function(t){var e=Ee(function(t){var e=t._i,n=t._f;return t._locale=t._locale||ue(t._l),null===e||void 0===n&&""===e?me(t,{nullInput:!0}):(r(e)&&(t._i=e=t._locale.preparse(e)),i(e)?(t._d=Nt(e),t):(c(n)?function(t){var e,n,a,r,i;if(!t._f||0===t._f.length)return mt(t).invalidFormat=!0,me(t);for(i=0;ie.valueOf():e.valueOf()1&&t<5&&1!=~~(t/10)}function nn(t,e,n,a){var r=t+" ";switch(n){case"s":return e||a?"p\xe1r sekund":"p\xe1r sekundami";case"ss":return e||a?r+(en(t)?"sekundy":"sekund"):r+"sekundami";case"m":return e?"minuta":a?"minutu":"minutou";case"mm":return e||a?r+(en(t)?"minuty":"minut"):r+"minutami";case"h":return e?"hodina":a?"hodinu":"hodinou";case"hh":return e||a?r+(en(t)?"hodiny":"hodin"):r+"hodinami";case"d":return e||a?"den":"dnem";case"dd":return e||a?r+(en(t)?"dny":"dn\xed"):r+"dny";case"M":return e||a?"m\u011bs\xedc":"m\u011bs\xedcem";case"MM":return e||a?r+(en(t)?"m\u011bs\xedce":"m\u011bs\xedc\u016f"):r+"m\u011bs\xedci";case"y":return e||a?"rok":"rokem";case"yy":return e||a?r+(en(t)?"roky":"let"):r+"lety"}}var an=function(t){var e,n=[];for(e=0;e<12;e++)n[e]=new RegExp("^"+t[e]+"$","i");return n},rn=function(t){var e,n=[];for(e=0;e<12;e++)n[e]=new RegExp("^"+t[e]+"$","i");return n},sn={abbr:"cs",months:Qe,monthsShort:tn,monthsParse:function(t,e){var n,a=[];for(n=0;n<12;n++)a[n]=new RegExp("^"+t[n]+"$|^"+e[n]+"$","i");return a}(Qe,tn),shortMonthsParse:an(tn),longMonthsParse:rn(Qe),weekdays:"ned\u011ble_pond\u011bl\xed_\xfater\xfd_st\u0159eda_\u010dtvrtek_p\xe1tek_sobota".split("_"),weekdaysShort:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),weekdaysMin:"ne_po_\xfat_st_\u010dt_p\xe1_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[z\xedtra v] LT",nextWeek:function(t){switch(Xe(t)){case 0:return"[v ned\u011bli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve st\u0159edu v] LT";case 4:return"[ve \u010dtvrtek v] LT";case 5:return"[v p\xe1tek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[v\u010dera v] LT",lastWeek:function(t){switch(Xe(t)){case 0:return"[minulou ned\u011bli v] LT";case 1:case 2:return"[minul\xe9] dddd [v] LT";case 3:return"[minulou st\u0159edu v] LT";case 4:case 5:return"[minul\xfd] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"p\u0159ed %s",s:nn,ss:nn,m:nn,mm:nn,h:nn,hh:nn,d:nn,dd:nn,M:nn,MM:nn,y:nn,yy:nn},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}};function on(t,e,n,a){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[t+" Tage",t+" Tagen"],M:["ein Monat","einem Monat"],MM:[t+" Monate",t+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[t+" Jahre",t+" Jahren"]};return e?r[n][0]:r[n][1]}var un={abbr:"de",months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:on,mm:"%d Minuten",h:on,hh:"%d Stunden",d:on,dd:on,M:on,MM:on,y:on,yy:on},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}},cn="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),ln="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),dn=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],fn=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,pn={abbr:"es",months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(t,e,n){return t?/-MMM-/.test(e)?ln[z(t,n)]:cn[z(t,n)]:cn},monthsRegex:fn,monthsShortRegex:fn,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:dn,longMonthsParse:dn,shortMonthsParse:dn,weekdays:"domingo_lunes_martes_mi\xe9rcoles_jueves_viernes_s\xe1bado".split("_"),weekdaysShort:"dom._lun._mar._mi\xe9._jue._vie._s\xe1b.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_s\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(t){return"[hoy a la"+(1!==L(t)?"s":"")+"] LT"},nextDay:function(t){return"[ma\xf1ana a la"+(1!==L(t)?"s":"")+"] LT"},nextWeek:function(t){return"dddd [a la"+(1!==L(t)?"s":"")+"] LT"},lastDay:function(t){return"[ayer a la"+(1!==L(t)?"s":"")+"] LT"},lastWeek:function(t){return"[el] dddd [pasado a la"+(1!==L(t)?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\xeda",dd:"%d d\xedas",M:"un mes",MM:"%d meses",y:"un a\xf1o",yy:"%d a\xf1os"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}},hn={abbr:"fr",months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|)/,ordinal:function(t,e){var n=Number(t);switch(e){case"D":return n+(1===n?"er":"");default:case"M":case"Q":case"DDD":case"d":return n+(1===n?"er":"e");case"w":case"W":return n+(1===n?"re":"e")}},week:{dow:1,doy:4}},gn={abbr:"id",months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(t,e){return 12===t&&(t=0),"pagi"===e?t:"siang"===e?t>=11?t:t+12:"sore"===e||"malam"===e?t+12:void 0},meridiem:function(t,e,n){return t<11?"pagi":t<15?"siang":t<19?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",ss:"%d detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}},bn={abbr:"it",months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_luned\xec_marted\xec_mercoled\xec_gioved\xec_venerd\xec_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(t){switch(Xe(t)){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(t){return(/^[0-9].+$/.test(t.toString(10))?"tra":"in")+" "+t},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba",week:{dow:1,doy:4}},mn={abbr:"ja",months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm",LLLL:"YYYY\u5e74M\u6708D\u65e5 HH:mm dddd",l:"YYYY/MM/DD",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5 HH:mm dddd"},meridiemParse:/\u5348\u524d|\u5348\u5f8c/i,isPM:function(t){return"\u5348\u5f8c"===t},meridiem:function(t,e,n){return t<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:"[\u6765\u9031]dddd LT",lastDay:"[\u6628\u65e5] LT",lastWeek:"[\u524d\u9031]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}\u65e5/,ordinal:function(t,e){switch(e){case"d":case"D":case"DDD":return t+"\u65e5";default:return t.toString(10)}},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",ss:"%d\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"}},yn={abbr:"ko",months:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),monthsShort:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),weekdays:"\uc77c\uc694\uc77c_\uc6d4\uc694\uc77c_\ud654\uc694\uc77c_\uc218\uc694\uc77c_\ubaa9\uc694\uc77c_\uae08\uc694\uc77c_\ud1a0\uc694\uc77c".split("_"),weekdaysShort:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),weekdaysMin:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"YYYY.MM.DD",LL:"YYYY\ub144 MMMM D\uc77c",LLL:"YYYY\ub144 MMMM D\uc77c A h:mm",LLLL:"YYYY\ub144 MMMM D\uc77c dddd A h:mm",l:"YYYY.MM.DD",ll:"YYYY\ub144 MMMM D\uc77c",lll:"YYYY\ub144 MMMM D\uc77c A h:mm",llll:"YYYY\ub144 MMMM D\uc77c dddd A h:mm"},calendar:{sameDay:"\uc624\ub298 LT",nextDay:"\ub0b4\uc77c LT",nextWeek:"dddd LT",lastDay:"\uc5b4\uc81c LT",lastWeek:"\uc9c0\ub09c\uc8fc dddd LT",sameElse:"L"},relativeTime:{future:"%s \ud6c4",past:"%s \uc804",s:"\uba87 \ucd08",ss:"%d\ucd08",m:"1\ubd84",mm:"%d\ubd84",h:"\ud55c \uc2dc\uac04",hh:"%d\uc2dc\uac04",d:"\ud558\ub8e8",dd:"%d\uc77c",M:"\ud55c \ub2ec",MM:"%d\ub2ec",y:"\uc77c \ub144",yy:"%d\ub144"},dayOfMonthOrdinalParse:/\d{1,2}(\uc77c|\uc6d4|\uc8fc)/,ordinal:function(t,e){switch(e){case"d":case"D":case"DDD":return t+"\uc77c";case"M":return t+"\uc6d4";case"w":case"W":return t+"\uc8fc";default:return t.toString(10)}},meridiemParse:/\uc624\uc804|\uc624\ud6c4/,isPM:function(t){return"\uc624\ud6c4"===t},meridiem:function(t,e,n){return t<12?"\uc624\uc804":"\uc624\ud6c4"}},vn="stycze\u0144_luty_marzec_kwiecie\u0144_maj_czerwiec_lipiec_sierpie\u0144_wrzesie\u0144_pa\u017adziernik_listopad_grudzie\u0144".split("_"),_n="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_wrze\u015bnia_pa\u017adziernika_listopada_grudnia".split("_");function xn(t){return t%10<5&&t%10>1&&~~(t/10)%10!=1}function Tn(t,e,n){var a=t+" ";switch(n){case"ss":return a+(xn(t)?"sekundy":"sekund");case"m":return e?"minuta":"minut\u0119";case"mm":return a+(xn(t)?"minuty":"minut");case"h":return e?"godzina":"godzin\u0119";case"hh":return a+(xn(t)?"godziny":"godzin");case"MM":return a+(xn(t)?"miesi\u0105ce":"miesi\u0119cy");case"yy":return a+(xn(t)?"lata":"lat")}}var wn={abbr:"pl",months:function(t,e,n){return t?""===e?"("+_n[z(t,n)]+"|"+vn[z(t,n)]+")":/D MMMM/.test(e)?_n[z(t,n)]:vn[z(t,n)]:vn},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_pa\u017a_lis_gru".split("_"),weekdays:"niedziela_poniedzia\u0142ek_wtorek_\u015broda_czwartek_pi\u0105tek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_\u015br_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_\u015ar_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dzi\u015b o] LT",nextDay:"[Jutro o] LT",nextWeek:function(t){switch(Xe(t)){case 0:return"[W niedziel\u0119 o] LT";case 2:return"[We wtorek o] LT";case 3:return"[W \u015brod\u0119 o] LT";case 5:return"[W pi\u0105tek o] LT";case 6:return"[W sobot\u0119 o] LT";default:return"[W] dddd [o] LT"}},lastDay:"[Wczoraj o] LT",lastWeek:function(t){switch(Xe(t)){case 0:return"[W zesz\u0142\u0105 niedziel\u0119 o] LT";case 3:return"[W zesz\u0142\u0105 \u015brod\u0119 o] LT";case 4:return"[W zesz\u0142\u0105 czwartek o] LT";case 5:return"[W zesz\u0142\u0105 pi\u0105tek o] LT";case 6:return"[W zesz\u0142\u0105 sobot\u0119 o] LT";default:return"[W zesz\u0142y] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",ss:Tn,m:Tn,mm:Tn,h:Tn,hh:Tn,d:"1 dzie\u0144",dd:"%d dni",M:"miesi\u0105c",MM:Tn,y:"rok",yy:Tn},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}},Sn={abbr:"pt-br",months:"Janeiro_Fevereiro_Mar\xe7o_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\xe7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\xe1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\xe1b".split("_"),weekdaysMin:"Do_2\xaa_3\xaa_4\xaa_5\xaa_6\xaa_S\xe1".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [\xe0s] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [\xe0s] HH:mm"},calendar:{sameDay:"[Hoje \xe0s] LT",nextDay:"[Amanh\xe3 \xe0s] LT",nextWeek:"dddd [\xe0s] LT",lastDay:"[Ontem \xe0s] LT",lastWeek:function(t){return 0===Xe(t)||6===Xe(t)?"[\xdaltimo] dddd [\xe0s] LT":"[\xdaltima] dddd [\xe0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atr\xe1s",s:"poucos segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\xeas",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}\xba/,ordinal:"%d\xba"},On={abbr:"zh-cn",months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u5468\u65e5_\u5468\u4e00_\u5468\u4e8c_\u5468\u4e09_\u5468\u56db_\u5468\u4e94_\u5468\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5Ah\u70b9mm\u5206",LLLL:"YYYY\u5e74M\u6708D\u65e5ddddAh\u70b9mm\u5206",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(t,e){return 12===t&&(t=0),"\u51cc\u6668"===e||"\u65e9\u4e0a"===e||"\u4e0a\u5348"===e?t:"\u4e0b\u5348"===e||"\u665a\u4e0a"===e?t+12:t>=11?t:t+12},meridiem:function(t,e,n){var a=100*t+e;return a<600?"\u51cc\u6668":a<900?"\u65e9\u4e0a":a<1130?"\u4e0a\u5348":a<1230?"\u4e2d\u5348":a<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u5468)/,ordinal:function(t,e){var n=Number(t);switch(e){case"d":case"D":case"DDD":return n+"\u65e5";case"M":return n+"\u6708";case"w":case"W":return n+"\u5468";default:return n.toString()}},relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",ss:"%d \u79d2",m:"1 \u5206\u949f",mm:"%d \u5206\u949f",h:"1 \u5c0f\u65f6",hh:"%d \u5c0f\u65f6",d:"1 \u5929",dd:"%d \u5929",M:"1 \u4e2a\u6708",MM:"%d \u4e2a\u6708",y:"1 \u5e74",yy:"%d \u5e74"},week:{dow:1,doy:4}}},lJMN:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("QG5k"),r=n("TCh0"),i=n("kQXf");e.TreeController=function(){function t(t){this.component=t,this.tree=this.component.tree,this.treeService=this.component.treeService}return t.prototype.select=function(){this.isSelected()||this.component.onNodeSelected({button:r.MouseButtons.Left})},t.prototype.unselect=function(){this.isSelected()&&this.component.onNodeUnselected({button:r.MouseButtons.Left})},t.prototype.isSelected=function(){return this.component.isSelected},t.prototype.expand=function(){this.isCollapsed()&&this.component.onSwitchFoldingType()},t.prototype.expandToParent=function(t){var e=this;if(void 0===t&&(t=this.tree),t){var n=this.treeService.getController(t.id);n&&requestAnimationFrame(function(){n.expand(),e.expandToParent(t.parent)})}},t.prototype.isExpanded=function(){return this.tree.isNodeExpanded()},t.prototype.collapse=function(){this.isExpanded()&&this.component.onSwitchFoldingType()},t.prototype.isCollapsed=function(){return this.tree.isNodeCollapsed()},t.prototype.toTreeModel=function(){return this.tree.toTreeModel()},t.prototype.rename=function(t){this.tree.markAsBeingRenamed(),this.component.applyNewValue({type:"keyup",value:t})},t.prototype.remove=function(){this.component.onMenuItemSelected({nodeMenuItemAction:a.NodeMenuItemAction.Remove})},t.prototype.addChild=function(t){if(!this.tree.hasDeferredChildren()||this.tree.childrenWereLoaded()){var e=this.tree.createNode(Array.isArray(t.children),t);this.treeService.fireNodeCreated(e)}},t.prototype.addChildAsync=function(t){if(this.tree.hasDeferredChildren()&&!this.tree.childrenWereLoaded())return Promise.reject(new Error("This node loads its children asynchronously, hence child cannot be added this way"));var e=this.tree.createNode(Array.isArray(t.children),t);return this.treeService.fireNodeCreated(e),new Promise(function(t){setTimeout(function(){t(e)})})},t.prototype.changeNodeId=function(t){if(!t)throw Error("You should supply an id!");if(this.treeService.hasController(t))throw Error("Controller already exists for the given id: "+t);this.treeService.deleteController(this.tree.id),this.tree.id=t,this.treeService.setController(this.tree.id,this)},t.prototype.reloadChildren=function(){this.tree.reloadChildren()},t.prototype.setChildren=function(t){this.tree.isLeaf()||this.tree.setChildren(t)},t.prototype.startRenaming=function(){this.tree.markAsBeingRenamed()},t.prototype.check=function(){this.component.onNodeChecked()},t.prototype.uncheck=function(){this.component.onNodeUnchecked()},t.prototype.isChecked=function(){return this.tree.checked},t.prototype.isIndetermined=function(){return i.get(this.component,"checkboxElementRef.nativeElement.indeterminate")},t.prototype.allowSelection=function(){this.tree.selectionAllowed=!0},t.prototype.forbidSelection=function(){this.tree.selectionAllowed=!1},t.prototype.isSelectionAllowed=function(){return this.tree.selectionAllowed},t}()},lTVp:function(t,e,n){"use strict";n.d(e,"a",function(){return o}),n.d(e,"b",function(){return s}),n.d(e,"c",function(){return u});var a=n("mrSG"),r=n("CcnG"),i=n("rpEJ"),s=function(){return function(){this.type="warning",this.dismissible=!1,this.dismissOnTimeout=void 0}}(),o=function(){function t(t,e){var n=this;this.changeDetection=e,this.type="warning",this.dismissible=!1,this.isOpen=!0,this.onClose=new r.EventEmitter,this.onClosed=new r.EventEmitter,this.classes="",this.dismissibleChange=new r.EventEmitter,Object.assign(this,t),this.dismissibleChange.subscribe(function(t){n.classes=n.dismissible?"alert-dismissible":"",n.changeDetection.markForCheck()})}return t.prototype.ngOnInit=function(){var t=this;this.dismissOnTimeout&&setTimeout(function(){return t.close()},parseInt(this.dismissOnTimeout,10))},t.prototype.close=function(){this.isOpen&&(this.onClose.emit(this),this.isOpen=!1,this.changeDetection.markForCheck(),this.onClosed.emit(this))},Object(a.__decorate)([Object(i.a)(),Object(a.__metadata)("design:type",Object)],t.prototype,"dismissible",void 0),t}(),u=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[s]}},t}()},lUjN:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("vxfy");e.DatatableFooterDirective=function(){function t(){}return a([i.Input(),r("design:type",Number)],t.prototype,"footerHeight",void 0),a([i.Input(),r("design:type",String)],t.prototype,"totalMessage",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"selectedMessage",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerLeftArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerRightArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerPreviousIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerNextIcon",void 0),a([i.Input(),i.ContentChild(s.DataTableFooterTemplateDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"template",void 0),a([i.Directive({selector:"ngx-datatable-footer"})],t)}()},lXzo:function(t,e,n){!function(t){"use strict";function e(t,e,n){var a,r;return"m"===n?e?"\u043c\u0438\u043d\u0443\u0442\u0430":"\u043c\u0438\u043d\u0443\u0442\u0443":t+" "+(a=+t,r={ss:e?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u044b_\u0441\u0435\u043a\u0443\u043d\u0434",mm:e?"\u043c\u0438\u043d\u0443\u0442\u0430_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442":"\u043c\u0438\u043d\u0443\u0442\u0443_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442",hh:"\u0447\u0430\u0441_\u0447\u0430\u0441\u0430_\u0447\u0430\u0441\u043e\u0432",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u044f_\u0434\u043d\u0435\u0439",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u0430_\u043c\u0435\u0441\u044f\u0446\u0435\u0432",yy:"\u0433\u043e\u0434_\u0433\u043e\u0434\u0430_\u043b\u0435\u0442"}[n].split("_"),a%10==1&&a%100!=11?r[0]:a%10>=2&&a%10<=4&&(a%100<10||a%100>=20)?r[1]:r[2])}var a=[/^\u044f\u043d\u0432/i,/^\u0444\u0435\u0432/i,/^\u043c\u0430\u0440/i,/^\u0430\u043f\u0440/i,/^\u043c\u0430[\u0439\u044f]/i,/^\u0438\u044e\u043d/i,/^\u0438\u044e\u043b/i,/^\u0430\u0432\u0433/i,/^\u0441\u0435\u043d/i,/^\u043e\u043a\u0442/i,/^\u043d\u043e\u044f/i,/^\u0434\u0435\u043a/i];n("wd/R").defineLocale("ru",{months:{format:"\u044f\u043d\u0432\u0430\u0440\u044f_\u0444\u0435\u0432\u0440\u0430\u043b\u044f_\u043c\u0430\u0440\u0442\u0430_\u0430\u043f\u0440\u0435\u043b\u044f_\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433\u0443\u0441\u0442\u0430_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f_\u043e\u043a\u0442\u044f\u0431\u0440\u044f_\u043d\u043e\u044f\u0431\u0440\u044f_\u0434\u0435\u043a\u0430\u0431\u0440\u044f".split("_"),standalone:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_")},monthsShort:{format:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440._\u0430\u043f\u0440._\u043c\u0430\u044f_\u0438\u044e\u043d\u044f_\u0438\u044e\u043b\u044f_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_"),standalone:"\u044f\u043d\u0432._\u0444\u0435\u0432\u0440._\u043c\u0430\u0440\u0442_\u0430\u043f\u0440._\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433._\u0441\u0435\u043d\u0442._\u043e\u043a\u0442._\u043d\u043e\u044f\u0431._\u0434\u0435\u043a.".split("_")},weekdays:{standalone:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0430_\u0441\u0443\u0431\u0431\u043e\u0442\u0430".split("_"),format:"\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440\u0433_\u043f\u044f\u0442\u043d\u0438\u0446\u0443_\u0441\u0443\u0431\u0431\u043e\u0442\u0443".split("_"),isFormat:/\[ ?[\u0412\u0432] ?(?:\u043f\u0440\u043e\u0448\u043b\u0443\u044e|\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e|\u044d\u0442\u0443)? ?\] ?dddd/},weekdaysShort:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u0432\u0441_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),monthsParse:a,longMonthsParse:a,shortMonthsParse:a,monthsRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsShortRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044c\u044f]|\u044f\u043d\u0432\.?|\u0444\u0435\u0432\u0440\u0430\u043b[\u044c\u044f]|\u0444\u0435\u0432\u0440?\.?|\u043c\u0430\u0440\u0442\u0430?|\u043c\u0430\u0440\.?|\u0430\u043f\u0440\u0435\u043b[\u044c\u044f]|\u0430\u043f\u0440\.?|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d[\u044c\u044f]|\u0438\u044e\u043d\.?|\u0438\u044e\u043b[\u044c\u044f]|\u0438\u044e\u043b\.?|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0430\u0432\u0433\.?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044c\u044f]|\u0441\u0435\u043d\u0442?\.?|\u043e\u043a\u0442\u044f\u0431\u0440[\u044c\u044f]|\u043e\u043a\u0442\.?|\u043d\u043e\u044f\u0431\u0440[\u044c\u044f]|\u043d\u043e\u044f\u0431?\.?|\u0434\u0435\u043a\u0430\u0431\u0440[\u044c\u044f]|\u0434\u0435\u043a\.?)/i,monthsStrictRegex:/^(\u044f\u043d\u0432\u0430\u0440[\u044f\u044c]|\u0444\u0435\u0432\u0440\u0430\u043b[\u044f\u044c]|\u043c\u0430\u0440\u0442\u0430?|\u0430\u043f\u0440\u0435\u043b[\u044f\u044c]|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044f\u044c]|\u0438\u044e\u043b[\u044f\u044c]|\u0430\u0432\u0433\u0443\u0441\u0442\u0430?|\u0441\u0435\u043d\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043e\u043a\u0442\u044f\u0431\u0440[\u044f\u044c]|\u043d\u043e\u044f\u0431\u0440[\u044f\u044c]|\u0434\u0435\u043a\u0430\u0431\u0440[\u044f\u044c])/i,monthsShortStrictRegex:/^(\u044f\u043d\u0432\.|\u0444\u0435\u0432\u0440?\.|\u043c\u0430\u0440[\u0442.]|\u0430\u043f\u0440\.|\u043c\u0430[\u044f\u0439]|\u0438\u044e\u043d[\u044c\u044f.]|\u0438\u044e\u043b[\u044c\u044f.]|\u0430\u0432\u0433\.|\u0441\u0435\u043d\u0442?\.|\u043e\u043a\u0442\.|\u043d\u043e\u044f\u0431?\.|\u0434\u0435\u043a\.)/i,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0433.",LLL:"D MMMM YYYY \u0433., H:mm",LLLL:"dddd, D MMMM YYYY \u0433., H:mm"},calendar:{sameDay:"[\u0421\u0435\u0433\u043e\u0434\u043d\u044f, \u0432] LT",nextDay:"[\u0417\u0430\u0432\u0442\u0440\u0430, \u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430, \u0432] LT",nextWeek:function(t){if(t.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd, [\u0432] LT":"[\u0412] dddd, [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435] dddd, [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439] dddd, [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e] dddd, [\u0432] LT"}},lastWeek:function(t){if(t.week()===this.week())return 2===this.day()?"[\u0412\u043e] dddd, [\u0432] LT":"[\u0412] dddd, [\u0432] LT";switch(this.day()){case 0:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0435] dddd, [\u0432] LT";case 1:case 2:case 4:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0439] dddd, [\u0432] LT";case 3:case 5:case 6:return"[\u0412 \u043f\u0440\u043e\u0448\u043b\u0443\u044e] dddd, [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0447\u0435\u0440\u0435\u0437 %s",past:"%s \u043d\u0430\u0437\u0430\u0434",s:"\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434",ss:e,m:e,mm:e,h:"\u0447\u0430\u0441",hh:e,d:"\u0434\u0435\u043d\u044c",dd:e,M:"\u043c\u0435\u0441\u044f\u0446",MM:e,y:"\u0433\u043e\u0434",yy:e},meridiemParse:/\u043d\u043e\u0447\u0438|\u0443\u0442\u0440\u0430|\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430/i,isPM:function(t){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u0435\u0440\u0430)$/.test(t)},meridiem:function(t,e,n){return t<4?"\u043d\u043e\u0447\u0438":t<12?"\u0443\u0442\u0440\u0430":t<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u0435\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e|\u044f)/,ordinal:function(t,e){switch(e){case"M":case"d":case"DDD":return t+"-\u0439";case"D":return t+"-\u0433\u043e";case"w":case"W":return t+"-\u044f";default:return t}},week:{dow:1,doy:4}})}()},lYZG:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("6blF"),r=n("0/uQ"),i=n("G5J1");function s(t){return new a.a(function(e){var n;try{n=t()}catch(a){return void e.error(a)}return(n?Object(r.a)(n):Object(i.b)()).subscribe(e)})}},lYtQ:function(t,e,n){!function(t){"use strict";function e(t,e,n,a){switch(n){case"s":return e?"\u0445\u044d\u0434\u0445\u044d\u043d \u0441\u0435\u043a\u0443\u043d\u0434":"\u0445\u044d\u0434\u0445\u044d\u043d \u0441\u0435\u043a\u0443\u043d\u0434\u044b\u043d";case"ss":return t+(e?" \u0441\u0435\u043a\u0443\u043d\u0434":" \u0441\u0435\u043a\u0443\u043d\u0434\u044b\u043d");case"m":case"mm":return t+(e?" \u043c\u0438\u043d\u0443\u0442":" \u043c\u0438\u043d\u0443\u0442\u044b\u043d");case"h":case"hh":return t+(e?" \u0446\u0430\u0433":" \u0446\u0430\u0433\u0438\u0439\u043d");case"d":case"dd":return t+(e?" \u04e9\u0434\u04e9\u0440":" \u04e9\u0434\u0440\u0438\u0439\u043d");case"M":case"MM":return t+(e?" \u0441\u0430\u0440":" \u0441\u0430\u0440\u044b\u043d");case"y":case"yy":return t+(e?" \u0436\u0438\u043b":" \u0436\u0438\u043b\u0438\u0439\u043d");default:return t}}n("wd/R").defineLocale("mn",{months:"\u041d\u044d\u0433\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0425\u043e\u0451\u0440\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0413\u0443\u0440\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0414\u04e9\u0440\u04e9\u0432\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0422\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0417\u0443\u0440\u0433\u0430\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0414\u043e\u043b\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u041d\u0430\u0439\u043c\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0415\u0441\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0410\u0440\u0430\u0432\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440_\u0410\u0440\u0432\u0430\u043d \u043d\u044d\u0433\u0434\u04af\u0433\u044d\u044d\u0440 \u0441\u0430\u0440_\u0410\u0440\u0432\u0430\u043d \u0445\u043e\u0451\u0440\u0434\u0443\u0433\u0430\u0430\u0440 \u0441\u0430\u0440".split("_"),monthsShort:"1 \u0441\u0430\u0440_2 \u0441\u0430\u0440_3 \u0441\u0430\u0440_4 \u0441\u0430\u0440_5 \u0441\u0430\u0440_6 \u0441\u0430\u0440_7 \u0441\u0430\u0440_8 \u0441\u0430\u0440_9 \u0441\u0430\u0440_10 \u0441\u0430\u0440_11 \u0441\u0430\u0440_12 \u0441\u0430\u0440".split("_"),monthsParseExact:!0,weekdays:"\u041d\u044f\u043c_\u0414\u0430\u0432\u0430\u0430_\u041c\u044f\u0433\u043c\u0430\u0440_\u041b\u0445\u0430\u0433\u0432\u0430_\u041f\u04af\u0440\u044d\u0432_\u0411\u0430\u0430\u0441\u0430\u043d_\u0411\u044f\u043c\u0431\u0430".split("_"),weekdaysShort:"\u041d\u044f\u043c_\u0414\u0430\u0432_\u041c\u044f\u0433_\u041b\u0445\u0430_\u041f\u04af\u0440_\u0411\u0430\u0430_\u0411\u044f\u043c".split("_"),weekdaysMin:"\u041d\u044f_\u0414\u0430_\u041c\u044f_\u041b\u0445_\u041f\u04af_\u0411\u0430_\u0411\u044f".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY \u043e\u043d\u044b MMMM\u044b\u043d D",LLL:"YYYY \u043e\u043d\u044b MMMM\u044b\u043d D HH:mm",LLLL:"dddd, YYYY \u043e\u043d\u044b MMMM\u044b\u043d D HH:mm"},meridiemParse:/\u04ae\u04e8|\u04ae\u0425/i,isPM:function(t){return"\u04ae\u0425"===t},meridiem:function(t,e,n){return t<12?"\u04ae\u04e8":"\u04ae\u0425"},calendar:{sameDay:"[\u04e8\u043d\u04e9\u04e9\u0434\u04e9\u0440] LT",nextDay:"[\u041c\u0430\u0440\u0433\u0430\u0430\u0448] LT",nextWeek:"[\u0418\u0440\u044d\u0445] dddd LT",lastDay:"[\u04e8\u0447\u0438\u0433\u0434\u04e9\u0440] LT",lastWeek:"[\u04e8\u043d\u0433\u04e9\u0440\u0441\u04e9\u043d] dddd LT",sameElse:"L"},relativeTime:{future:"%s \u0434\u0430\u0440\u0430\u0430",past:"%s \u04e9\u043c\u043d\u04e9",s:e,ss:e,m:e,mm:e,h:e,hh:e,d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2} \u04e9\u0434\u04e9\u0440/,ordinal:function(t,e){switch(e){case"d":case"D":case"DDD":return t+" \u04e9\u0434\u04e9\u0440";default:return t}}})}()},lZOh:function(t,e,n){"use strict";n.r(e);var a=n("6blF"),r=n("F/XL");a.a.of=r.a},lgnt:function(t,e,n){!function(t){"use strict";var e={0:"-\u0447\u04af",1:"-\u0447\u0438",2:"-\u0447\u0438",3:"-\u0447\u04af",4:"-\u0447\u04af",5:"-\u0447\u0438",6:"-\u0447\u044b",7:"-\u0447\u0438",8:"-\u0447\u0438",9:"-\u0447\u0443",10:"-\u0447\u0443",20:"-\u0447\u044b",30:"-\u0447\u0443",40:"-\u0447\u044b",50:"-\u0447\u04af",60:"-\u0447\u044b",70:"-\u0447\u0438",80:"-\u0447\u0438",90:"-\u0447\u0443",100:"-\u0447\u04af"};t.defineLocale("ky",{months:"\u044f\u043d\u0432\u0430\u0440\u044c_\u0444\u0435\u0432\u0440\u0430\u043b\u044c_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0435\u043b\u044c_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c_\u043e\u043a\u0442\u044f\u0431\u0440\u044c_\u043d\u043e\u044f\u0431\u0440\u044c_\u0434\u0435\u043a\u0430\u0431\u0440\u044c".split("_"),monthsShort:"\u044f\u043d\u0432_\u0444\u0435\u0432_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440_\u043c\u0430\u0439_\u0438\u044e\u043d\u044c_\u0438\u044e\u043b\u044c_\u0430\u0432\u0433_\u0441\u0435\u043d_\u043e\u043a\u0442_\u043d\u043e\u044f_\u0434\u0435\u043a".split("_"),weekdays:"\u0416\u0435\u043a\u0448\u0435\u043c\u0431\u0438_\u0414\u04af\u0439\u0448\u04e9\u043c\u0431\u04af_\u0428\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0428\u0430\u0440\u0448\u0435\u043c\u0431\u0438_\u0411\u0435\u0439\u0448\u0435\u043c\u0431\u0438_\u0416\u0443\u043c\u0430_\u0418\u0448\u0435\u043c\u0431\u0438".split("_"),weekdaysShort:"\u0416\u0435\u043a_\u0414\u04af\u0439_\u0428\u0435\u0439_\u0428\u0430\u0440_\u0411\u0435\u0439_\u0416\u0443\u043c_\u0418\u0448\u0435".split("_"),weekdaysMin:"\u0416\u043a_\u0414\u0439_\u0428\u0439_\u0428\u0440_\u0411\u0439_\u0416\u043c_\u0418\u0448".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0411\u04af\u0433\u04af\u043d \u0441\u0430\u0430\u0442] LT",nextDay:"[\u042d\u0440\u0442\u0435\u04a3 \u0441\u0430\u0430\u0442] LT",nextWeek:"dddd [\u0441\u0430\u0430\u0442] LT",lastDay:"[\u041a\u0435\u0447\u044d\u044d \u0441\u0430\u0430\u0442] LT",lastWeek:"[\u04e8\u0442\u043a\u04e9\u043d \u0430\u043f\u0442\u0430\u043d\u044b\u043d] dddd [\u043a\u04af\u043d\u04af] [\u0441\u0430\u0430\u0442] LT",sameElse:"L"},relativeTime:{future:"%s \u0438\u0447\u0438\u043d\u0434\u0435",past:"%s \u043c\u0443\u0440\u0443\u043d",s:"\u0431\u0438\u0440\u043d\u0435\u0447\u0435 \u0441\u0435\u043a\u0443\u043d\u0434",ss:"%d \u0441\u0435\u043a\u0443\u043d\u0434",m:"\u0431\u0438\u0440 \u043c\u04af\u043d\u04e9\u0442",mm:"%d \u043c\u04af\u043d\u04e9\u0442",h:"\u0431\u0438\u0440 \u0441\u0430\u0430\u0442",hh:"%d \u0441\u0430\u0430\u0442",d:"\u0431\u0438\u0440 \u043a\u04af\u043d",dd:"%d \u043a\u04af\u043d",M:"\u0431\u0438\u0440 \u0430\u0439",MM:"%d \u0430\u0439",y:"\u0431\u0438\u0440 \u0436\u044b\u043b",yy:"%d \u0436\u044b\u043b"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0447\u0438|\u0447\u044b|\u0447\u04af|\u0447\u0443)/,ordinal:function(t){return t+(e[t]||e[t%10]||e[t>=100?100:null])},week:{dow:1,doy:7}})}(n("wd/R"))},lmqd:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.single="single",t.multi="multi",t.multiClick="multiClick",t.cell="cell",t.checkbox="checkbox"}(e.SelectionType||(e.SelectionType={}))},lqqz:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("CcnG"),r=n("rpEJ"),i=function(){return function(t,e,n){this.nodes=t,this.viewRef=e,this.componentRef=n}}(),s=function(){function t(t,e,n,r,i,s,o,u){this._viewContainerRef=t,this._renderer=e,this._elementRef=n,this._injector=r,this._componentFactoryResolver=i,this._ngZone=s,this._applicationRef=o,this._posService=u,this.onBeforeShow=new a.EventEmitter,this.onShown=new a.EventEmitter,this.onBeforeHide=new a.EventEmitter,this.onHidden=new a.EventEmitter,this._providers=[],this._isHiding=!1,this.containerDefaultSelector="body",this._listenOpts={},this._globalListener=Function.prototype}return Object.defineProperty(t.prototype,"isShown",{get:function(){return!this._isHiding&&!!this._componentRef},enumerable:!0,configurable:!0}),t.prototype.attach=function(t){return this._componentFactory=this._componentFactoryResolver.resolveComponentFactory(t),this},t.prototype.to=function(t){return this.container=t||this.container,this},t.prototype.position=function(t){return this.attachment=t.attachment||this.attachment,this._elementRef=t.target||this._elementRef,this},t.prototype.provide=function(t){return this._providers.push(t),this},t.prototype.show=function(t){if(void 0===t&&(t={}),this._subscribePositioning(),this._innerComponent=null,!this._componentRef){this.onBeforeShow.emit(),this._contentRef=this._getContentRef(t.content,t.context,t.initialState);var e=a.Injector.create({providers:this._providers,parent:this._injector});this._componentRef=this._componentFactory.create(e,this._contentRef.nodes),this._applicationRef.attachView(this._componentRef.hostView),this.instance=this._componentRef.instance,Object.assign(this._componentRef.instance,t),this.container instanceof a.ElementRef&&this.container.nativeElement.appendChild(this._componentRef.location.nativeElement),"string"==typeof this.container&&"undefined"!=typeof document&&(document.querySelector(this.container)||document.querySelector(this.containerDefaultSelector)).appendChild(this._componentRef.location.nativeElement),!this.container&&this._elementRef&&this._elementRef.nativeElement.parentElement&&this._elementRef.nativeElement.parentElement.appendChild(this._componentRef.location.nativeElement),this._contentRef.componentRef&&(this._innerComponent=this._contentRef.componentRef.instance,this._contentRef.componentRef.changeDetectorRef.markForCheck(),this._contentRef.componentRef.changeDetectorRef.detectChanges()),this._componentRef.changeDetectorRef.markForCheck(),this._componentRef.changeDetectorRef.detectChanges(),this.onShown.emit(this._componentRef.instance)}return this._registerOutsideClick(),this._componentRef},t.prototype.hide=function(){if(!this._componentRef)return this;this._posService.deletePositionElement(this._componentRef.location),this.onBeforeHide.emit(this._componentRef.instance);var t=this._componentRef.location.nativeElement;return t.parentNode.removeChild(t),this._contentRef.componentRef&&this._contentRef.componentRef.destroy(),this._componentRef.destroy(),this._viewContainerRef&&this._contentRef.viewRef&&this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._contentRef.viewRef)),this._contentRef.viewRef&&this._contentRef.viewRef.destroy(),this._contentRef=null,this._componentRef=null,this._removeGlobalListener(),this.onHidden.emit(),this},t.prototype.toggle=function(){this.isShown?this.hide():this.show()},t.prototype.dispose=function(){this.isShown&&this.hide(),this._unsubscribePositioning(),this._unregisterListenersFn&&this._unregisterListenersFn()},t.prototype.listen=function(t){var e=this;this.triggers=t.triggers||this.triggers,this._listenOpts.outsideClick=t.outsideClick,this._listenOpts.outsideEsc=t.outsideEsc,t.target=t.target||this._elementRef.nativeElement;var n=this._listenOpts.hide=function(){return t.hide?t.hide():void e.hide()},a=this._listenOpts.show=function(n){t.show?t.show(n):e.show(n),n()};return this._unregisterListenersFn=Object(r.e)(this._renderer,{target:t.target,triggers:t.triggers,show:a,hide:n,toggle:function(t){e.isShown?n():a(t)}}),this},t.prototype._removeGlobalListener=function(){this._globalListener&&(this._globalListener(),this._globalListener=null)},t.prototype.attachInline=function(t,e){return this._inlineViewRef=t.createEmbeddedView(e),this},t.prototype._registerOutsideClick=function(){var t=this;if(this._componentRef&&this._componentRef.location){if(this._listenOpts.outsideClick){var e=this._componentRef.location.nativeElement;setTimeout(function(){t._globalListener=Object(r.h)(t._renderer,{targets:[e,t._elementRef.nativeElement],outsideClick:t._listenOpts.outsideClick,hide:function(){return t._listenOpts.hide()}})})}if(this._listenOpts.outsideEsc){var n=this._componentRef.location.nativeElement;this._globalListener=Object(r.g)(this._renderer,{targets:[n,this._elementRef.nativeElement],outsideEsc:this._listenOpts.outsideEsc,hide:function(){return t._listenOpts.hide()}})}}},t.prototype.getInnerComponent=function(){return this._innerComponent},t.prototype._subscribePositioning=function(){var t=this;!this._zoneSubscription&&this.attachment&&(this.onShown.subscribe(function(){t._posService.position({element:t._componentRef.location,target:t._elementRef,attachment:t.attachment,appendToBody:"body"===t.container})}),this._zoneSubscription=this._ngZone.onStable.subscribe(function(){t._componentRef&&t._posService.calcPosition()}))},t.prototype._unsubscribePositioning=function(){this._zoneSubscription&&(this._zoneSubscription.unsubscribe(),this._zoneSubscription=null)},t.prototype._getContentRef=function(t,e,n){if(!t)return new i([]);if(t instanceof a.TemplateRef){if(this._viewContainerRef){var r=this._viewContainerRef.createEmbeddedView(t,e);return r.markForCheck(),new i([r.rootNodes],r)}var s=t.createEmbeddedView({});return this._applicationRef.attachView(s),new i([s.rootNodes],s)}if("function"==typeof t){var o=this._componentFactoryResolver.resolveComponentFactory(t),u=a.Injector.create({providers:this._providers,parent:this._injector}),c=o.create(u);return Object.assign(c.instance,n),this._applicationRef.attachView(c.hostView),new i([[c.location.nativeElement]],c.hostView,c)}return new i([[this._renderer.createText(""+t)]])},t}(),o=function(){function t(t,e,n,a,r){this._componentFactoryResolver=t,this._ngZone=e,this._injector=n,this._posService=a,this._applicationRef=r}return t.prototype.createLoader=function(t,e,n){return new s(e,n,t,this._injector,this._componentFactoryResolver,this._ngZone,this._applicationRef,this._posService)},t}()},lyxo:function(t,e,n){!function(t){"use strict";function e(t,e,n){var a=" ";return(t%100>=20||t>=100&&t%100==0)&&(a=" de "),t+a+{ss:"secunde",mm:"minute",hh:"ore",dd:"zile",MM:"luni",yy:"ani"}[n]}n("wd/R").defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminic\u0103_luni_mar\u021bi_miercuri_joi_vineri_s\xe2mb\u0103t\u0103".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_S\xe2m".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_S\xe2".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[m\xe2ine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s \xeen urm\u0103",s:"c\xe2teva secunde",ss:e,m:"un minut",mm:e,h:"o or\u0103",hh:e,d:"o zi",dd:e,M:"o lun\u0103",MM:e,y:"un an",yy:e},week:{dow:1,doy:7}})}()},mChF:function(t,e,n){"use strict";function a(t){return t}n.d(e,"a",function(){return a})},mSOc:function(t,e,n){"use strict";n.d(e,"a",function(){return u});var a=n("LvDl"),r=n("26FU"),i=n("CcnG"),s=n("t/Na"),o=n("ZYCi"),u=function(){function t(t,e,n){this.http=t,this.router=e,this.ngZone=n,this.summaryDataSource=new r.a(null),this.summaryData$=this.summaryDataSource.asObservable(),this.enablePolling()}return t.prototype.enablePolling=function(){var t=this;this.refresh(),this.ngZone.runOutsideAngular(function(){t.polling=window.setInterval(function(){t.ngZone.run(function(){t.refresh()})},5e3)})},t.prototype.refresh=function(){var t=this;"/login"!==this.router.url&&this.http.get("api/summary").subscribe(function(e){t.summaryDataSource.next(e)})},t.prototype.getCurrentSummary=function(){return this.summaryDataSource.getValue()},t.prototype.subscribe=function(t,e){return this.summaryData$.subscribe(t,e)},t.prototype.addRunningTask=function(t){var e=this.summaryDataSource.getValue();e&&(a.isArray(e.executing_tasks)?e.executing_tasks.find(function(e){return e.name===t.name&&a.isEqual(e.metadata,t.metadata)})||e.executing_tasks.push(t):e.executing_tasks=[t],this.summaryDataSource.next(e))},t.ngInjectableDef=i.defineInjectable({factory:function(){return new t(i.inject(s.c),i.inject(o.l),i.inject(i.NgZone))},token:t,providedIn:"root"}),t}()},mZXl:function(t,e,n){"use strict";n.d(e,"b",function(){return s}),n.d(e,"a",function(){return u});var a=n("mrSG"),r=n("FFOo"),i=n("60iU");function s(t,e){return void 0===e&&(e=0),function(n){return n.lift(new o(t,e))}}var o=function(){function t(t,e){void 0===e&&(e=0),this.scheduler=t,this.delay=e}return t.prototype.call=function(t,e){return e.subscribe(new u(t,this.scheduler,this.delay))},t}(),u=function(t){function e(e,n,a){void 0===a&&(a=0);var r=t.call(this,e)||this;return r.scheduler=n,r.delay=a,r}return a.__extends(e,t),e.dispatch=function(t){t.notification.observe(t.destination),this.unsubscribe()},e.prototype.scheduleMessage=function(t){this.destination.add(this.scheduler.schedule(e.dispatch,this.delay,new c(t,this.destination)))},e.prototype._next=function(t){this.scheduleMessage(i.a.createNext(t))},e.prototype._error=function(t){this.scheduleMessage(i.a.createError(t)),this.unsubscribe()},e.prototype._complete=function(){this.scheduleMessage(i.a.createComplete()),this.unsubscribe()},e}(r.a),c=function(){return function(t,e){this.notification=t,this.destination=e}}()},mgIt:function(t,e,n){var a=n("T016");function r(t){if(t){var e=[0,0,0],n=1,r=t.match(/^#([a-fA-F0-9]{3,4})$/i),i="";if(r){i=(r=r[1])[3];for(var s=0;s=0&&e<1?d(Math.round(255*e)):"")},rgbString:function(t,e){return e<1||t[3]&&t[3]<1?o(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:o,percentString:function(t,e){return e<1||t[3]&&t[3]<1?u(t,e):"rgb("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%)"},percentaString:u,hslString:function(t,e){return e<1||t[3]&&t[3]<1?c(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:c,hwbString:function(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return f[t.slice(0,3)]}};var f={};for(var p in a)f[a[p]]=p},mjYD:function(t,e,n){"use strict";var a=n("CDJp"),r=n("K2E3"),i=n("RDha"),s=n("fELs"),o=i.noop;a._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}});var u=r.extend({initialize:function(t){i.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:o,update:function(t,e,n){var a=this;return a.beforeUpdate(),a.maxWidth=t,a.maxHeight=e,a.margins=n,a.beforeSetDimensions(),a.setDimensions(),a.afterSetDimensions(),a.beforeBuildLabels(),a.buildLabels(),a.afterBuildLabels(),a.beforeFit(),a.fit(),a.afterFit(),a.afterUpdate(),a.minSize},afterUpdate:o,beforeSetDimensions:o,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:o,beforeBuildLabels:o,buildLabels:o,afterBuildLabels:o,beforeFit:o,fit:function(){var t=this,e=t.options,n=e.display,r=(0,i.valueOrDefault)(e.fontSize,a.global.defaultFontSize),s=t.minSize,o=i.isArray(e.text)?e.text.length:1,u=i.options.toLineHeight(e.lineHeight,r),c=n?o*u+2*e.padding:0;t.isHorizontal()?(s.width=t.maxWidth,s.height=c):(s.width=c,s.height=t.maxHeight),t.width=s.width,t.height=s.height},afterFit:o,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=i.valueOrDefault,r=t.options,s=a.global;if(r.display){var o,u,c,l=n(r.fontSize,s.defaultFontSize),d=n(r.fontStyle,s.defaultFontStyle),f=n(r.fontFamily,s.defaultFontFamily),p=i.fontString(l,d,f),h=i.options.toLineHeight(r.lineHeight,l),g=h/2+r.padding,b=0,m=t.top,y=t.left,v=t.bottom,_=t.right;e.fillStyle=n(r.fontColor,s.defaultFontColor),e.font=p,t.isHorizontal()?(u=y+(_-y)/2,c=m+g,o=_-y):(u="left"===r.position?y+g:_-g,c=m+(v-m)/2,o=v-m,b=Math.PI*("left"===r.position?-.5:.5)),e.save(),e.translate(u,c),e.rotate(b),e.textAlign="center",e.textBaseline="middle";var x=r.text;if(i.isArray(x))for(var T=0,w=0;w0&&(c=t.getDatasetMeta(c[0]._datasetIndex).data),c},"x-axis":function(t,e){return c(t,e,{intersect:!1})},point:function(t,e){return s(t,r(e,t))},nearest:function(t,e,n){var a=r(e,t);n.axis=n.axis||"xy";var i=u(n.axis),s=o(t,a,n.intersect,i);return s.length>1&&s.sort(function(t,e){var n=t.getArea()-e.getArea();return 0===n&&(n=t._datasetIndex-e._datasetIndex),n}),s.slice(0,1)},x:function(t,e,n){var a=r(e,t),s=[],o=!1;return i(t,function(t){t.inXRange(a.x)&&s.push(t),t.inRange(a.x,a.y)&&(o=!0)}),n.intersect&&!o&&(s=[]),s},y:function(t,e,n){var a=r(e,t),s=[],o=!1;return i(t,function(t){t.inYRange(a.y)&&s.push(t),t.inRange(a.x,a.y)&&(o=!0)}),n.intersect&&!o&&(s=[]),s}}}},mn2k:function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("3MdB")),a(n("Cc8h")),a(n("ylLw")),a(n("M9eX")),a(n("uKs4"))},mrSG:function(t,e,n){"use strict";n.r(e),n.d(e,"__extends",function(){return r}),n.d(e,"__assign",function(){return i}),n.d(e,"__rest",function(){return s}),n.d(e,"__decorate",function(){return o}),n.d(e,"__param",function(){return u}),n.d(e,"__metadata",function(){return c}),n.d(e,"__awaiter",function(){return l}),n.d(e,"__generator",function(){return d}),n.d(e,"__exportStar",function(){return f}),n.d(e,"__values",function(){return p}),n.d(e,"__read",function(){return h}),n.d(e,"__spread",function(){return g}),n.d(e,"__await",function(){return b}),n.d(e,"__asyncGenerator",function(){return m}),n.d(e,"__asyncDelegator",function(){return y}),n.d(e,"__asyncValues",function(){return v}),n.d(e,"__makeTemplateObject",function(){return _}),n.d(e,"__importStar",function(){return x}),n.d(e,"__importDefault",function(){return T});var a=function(t,e){return(a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};function r(t,e){function n(){this.constructor=t}a(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var i=function(){return(i=Object.assign||function(t){for(var e,n=1,a=arguments.length;n=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s}function u(t,e){return function(n,a){e(n,a,t)}}function c(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)}function l(t,e,n,a){return new(n||(n=Promise))(function(r,i){function s(t){try{u(a.next(t))}catch(e){i(e)}}function o(t){try{u(a.throw(t))}catch(e){i(e)}}function u(t){t.done?r(t.value):new n(function(e){e(t.value)}).then(s,o)}u((a=a.apply(t,e||[])).next())})}function d(t,e){var n,a,r,i,s={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return i={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function o(i){return function(o){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,a&&(r=2&i[0]?a.return:i[0]?a.throw||((r=a.return)&&r.call(a),0):a.next)&&!(r=r.call(a,i[1])).done)return r;switch(a=0,r&&(i=[2&i[0],r.value]),i[0]){case 0:case 1:r=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,a=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(r=(r=s.trys).length>0&&r[r.length-1])&&(6===i[0]||2===i[0])){s=0;continue}if(3===i[0]&&(!r||i[1]>r[0]&&i[1]=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}}}function h(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var a,r,i=n.call(t),s=[];try{for(;(void 0===e||e-- >0)&&!(a=i.next()).done;)s.push(a.value)}catch(o){r={error:o}}finally{try{a&&!a.done&&(n=i.return)&&n.call(i)}finally{if(r)throw r.error}}return s}function g(){for(var t=[],e=0;e1||o(t,e)})})}function o(t,e){try{(n=r[t](e)).value instanceof b?Promise.resolve(n.value.v).then(u,c):l(i[0][2],n)}catch(a){l(i[0][3],a)}var n}function u(t){o("next",t)}function c(t){o("throw",t)}function l(t,e){t(e),i.shift(),i.length&&o(i[0][0],i[0][1])}}function y(t){var e,n;return e={},a("next"),a("throw",function(t){throw t}),a("return"),e[Symbol.iterator]=function(){return this},e;function a(a,r){e[a]=t[a]?function(e){return(n=!n)?{value:b(t[a](e)),done:"return"===a}:r?r(e):e}:r}}function v(t){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var e,n=t[Symbol.asyncIterator];return n?n.call(t):(t=p(t),e={},a("next"),a("throw"),a("return"),e[Symbol.asyncIterator]=function(){return this},e);function a(n){e[n]=t[n]&&function(e){return new Promise(function(a,r){!function(t,e,n,a){Promise.resolve(a).then(function(e){t({value:e,done:n})},e)}(a,r,(e=t[n](e)).done,e.value)})}}}function _(t,e){return Object.defineProperty?Object.defineProperty(t,"raw",{value:e}):t.raw=e,t}function x(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}function T(t){return t&&t.__esModule?t:{default:t}}},mtw6:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(t){return t[t.error=0]="error",t[t.info=1]="info",t[t.success=2]="success",t}({})},"n/D3":function(t,e,n){"use strict";n.d(e,"a",function(){return c}),n.d(e,"b",function(){return u});var a=n("VNr4"),r=(n("SgmB"),n("ZDA6"),n("0+/T")),i=(n("sne2"),n("x38r")),s=n("mtw6"),o=n("vCyI"),u=(n("nSDx"),n("aexS"),n("9nlD"),new(n("EgGo").a)("user-management/roles")),c=function(){function t(t,e,n,a,r,i,s,u,c){var l=this;this.roleService=t,this.scopeService=e,this.emptyPipe=n,this.authStorageService=a,this.modalService=r,this.notificationService=i,this.i18n=s,this.urlBuilder=u,this.actionLabels=c,this.selection=new o.a,this.permission=this.authStorageService.getPermissions().user,this.tableActions=[{permission:"create",icon:"fa-plus",routerLink:function(){return l.urlBuilder.getCreate()},name:this.actionLabels.CREATE},{permission:"update",icon:"fa-pencil",disable:function(){return!l.selection.hasSingleSelection||l.selection.first().system},routerLink:function(){return l.selection.first()&&l.urlBuilder.getEdit(l.selection.first().name)},name:this.actionLabels.EDIT},{permission:"delete",icon:"fa-times",disable:function(){return!l.selection.hasSingleSelection||l.selection.first().system},click:function(){return l.deleteRoleModal()},name:this.actionLabels.DELETE}]}return t.prototype.ngOnInit=function(){this.columns=[{name:this.i18n("Name"),prop:"name",flexGrow:3},{name:this.i18n("Description"),prop:"description",flexGrow:5,pipe:this.emptyPipe},{name:this.i18n("System Role"),prop:"system",cellClass:"text-center",flexGrow:1,cellTransformation:i.a.checkIcon}]},t.prototype.getRoles=function(){var t=this;Object(a.a)([this.roleService.list(),this.scopeService.list()]).subscribe(function(e){t.roles=e[0],t.scopes=e[1]})},t.prototype.updateSelection=function(t){this.selection=t},t.prototype.deleteRole=function(t){var e=this;this.roleService.delete(t).subscribe(function(){e.getRoles(),e.modalRef.hide(),e.notificationService.show(s.a.success,e.i18n("Deleted role '{{role_name}}'",{role_name:t}))},function(){e.modalRef.content.stopLoadingSpinner()})},t.prototype.deleteRoleModal=function(){var t=this,e=this.selection.first().name;this.modalRef=this.modalService.show(r.a,{initialState:{itemDescription:"Role",itemNames:[e],submitAction:function(){return t.deleteRole(e)}}})},t}()},n1nk:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.header="header",t.body="body"}(e.ContextmenuType||(e.ContextmenuType={}))},nDWh:function(t,e,n){"use strict";var a=n("6ww4"),r=n("CDJp"),i=n("RDha"),s=n("tjFV");t.exports=function(){function t(t,e,n){var a;return"string"==typeof t?(a=parseInt(t,10),-1!==t.indexOf("%")&&(a=a/100*e.parentNode[n])):a=t,a}function e(t){return null!=t&&"none"!==t}function n(n,a,r){var s=document.defaultView,o=i._getParentNode(n),u=s.getComputedStyle(n)[a],c=s.getComputedStyle(o)[a],l=e(u),d=e(c),f=Number.POSITIVE_INFINITY;return l||d?Math.min(l?t(u,n,r):f,d?t(c,o,r):f):"none"}i.configMerge=function(){return i.merge(i.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(t,e,n,a){var r=e[t]||{},o=n[t];"scales"===t?e[t]=i.scaleMerge(r,o):"scale"===t?e[t]=i.merge(r,[s.getScaleDefaults(o.type),o]):i._merger(t,e,n,a)}})},i.scaleMerge=function(){return i.merge(i.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(t,e,n,a){if("xAxes"===t||"yAxes"===t){var r,o,u,c=n[t].length;for(e[t]||(e[t]=[]),r=0;r=e[t].length&&e[t].push({}),i.merge(e[t][r],!e[t][r].type||u.type&&u.type!==e[t][r].type?[s.getScaleDefaults(o),u]:u)}else i._merger(t,e,n,a)}})},i.where=function(t,e){if(i.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return i.each(t,function(t){e(t)&&n.push(t)}),n},i.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var a=0,r=t.length;a=0;a--){var r=t[a];if(e(r))return r}},i.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},i.almostEquals=function(t,e,n){return Math.abs(t-e)t},i.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},i.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},i.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0==(t=+t)||isNaN(t)?t:t>0?1:-1},i.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,n=Math.round(e);return t===Math.pow(10,n)?n:e},i.toRadians=function(t){return t*(Math.PI/180)},i.toDegrees=function(t){return t*(180/Math.PI)},i.getAngleFromPoint=function(t,e){var n=e.x-t.x,a=e.y-t.y,r=Math.sqrt(n*n+a*a),i=Math.atan2(a,n);return i<-.5*Math.PI&&(i+=2*Math.PI),{angle:i,distance:r}},i.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},i.aliasPixel=function(t){return t%2==0?0:.5},i.splineCurve=function(t,e,n,a){var r=t.skip?e:t,i=e,s=n.skip?e:n,o=Math.sqrt(Math.pow(i.x-r.x,2)+Math.pow(i.y-r.y,2)),u=Math.sqrt(Math.pow(s.x-i.x,2)+Math.pow(s.y-i.y,2)),c=o/(o+u),l=u/(o+u),d=a*(c=isNaN(c)?0:c),f=a*(l=isNaN(l)?0:l);return{previous:{x:i.x-d*(s.x-r.x),y:i.y-d*(s.y-r.y)},next:{x:i.x+f*(s.x-r.x),y:i.y+f*(s.y-r.y)}}},i.EPSILON=Number.EPSILON||1e-14,i.splineCurveMonotone=function(t){var e,n,a,r,s,o,u,c,l,d=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),f=d.length;for(e=0;e0?d[e-1]:null,(r=e0?d[e-1]:null)&&!n.model.skip&&(a.model.controlPointPreviousX=a.model.x-(l=(a.model.x-n.model.x)/3),a.model.controlPointPreviousY=a.model.y-l*a.mK),r&&!r.model.skip&&(a.model.controlPointNextX=a.model.x+(l=(r.model.x-a.model.x)/3),a.model.controlPointNextY=a.model.y+l*a.mK))},i.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},i.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},i.niceNum=function(t,e){var n=Math.floor(i.log10(t)),a=t/Math.pow(10,n);return(e?a<1.5?1:a<3?2:a<7?5:10:a<=1?1:a<=2?2:a<=5?5:10)*Math.pow(10,n)},i.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},i.getRelativePosition=function(t,e){var n,a,r=t.originalEvent||t,s=t.target||t.srcElement,o=s.getBoundingClientRect(),u=r.touches;u&&u.length>0?(n=u[0].clientX,a=u[0].clientY):(n=r.clientX,a=r.clientY);var c=parseFloat(i.getStyle(s,"padding-left")),l=parseFloat(i.getStyle(s,"padding-top")),d=parseFloat(i.getStyle(s,"padding-right")),f=parseFloat(i.getStyle(s,"padding-bottom")),p=o.bottom-o.top-l-f;return{x:n=Math.round((n-o.left-c)/(o.right-o.left-c-d)*s.width/e.currentDevicePixelRatio),y:a=Math.round((a-o.top-l)/p*s.height/e.currentDevicePixelRatio)}},i.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},i.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},i._calculatePadding=function(t,e,n){return(e=i.getStyle(t,e)).indexOf("%")>-1?n/parseInt(e,10):parseInt(e,10)},i._getParentNode=function(t){var e=t.parentNode;return e&&e.host&&(e=e.host),e},i.getMaximumWidth=function(t){var e=i._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,a=n-i._calculatePadding(e,"padding-left",n)-i._calculatePadding(e,"padding-right",n),r=i.getConstraintWidth(t);return isNaN(r)?a:Math.min(a,r)},i.getMaximumHeight=function(t){var e=i._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,a=n-i._calculatePadding(e,"padding-top",n)-i._calculatePadding(e,"padding-bottom",n),r=i.getConstraintHeight(t);return isNaN(r)?a:Math.min(a,r)},i.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},i.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var a=t.canvas,r=t.height,i=t.width;a.height=r*n,a.width=i*n,t.ctx.scale(n,n),a.style.height||a.style.width||(a.style.height=r+"px",a.style.width=i+"px")}},i.fontString=function(t,e,n){return e+" "+t+"px "+n},i.longestText=function(t,e,n,a){var r=(a=a||{}).data=a.data||{},s=a.garbageCollect=a.garbageCollect||[];a.font!==e&&(r=a.data={},s=a.garbageCollect=[],a.font=e),t.font=e;var o=0;i.each(n,function(e){null!=e&&!0!==i.isArray(e)?o=i.measureText(t,r,s,o,e):i.isArray(e)&&i.each(e,function(e){null==e||i.isArray(e)||(o=i.measureText(t,r,s,o,e))})});var u=s.length/2;if(u>n.length){for(var c=0;ca&&(a=i),a},i.numberOfLabelLines=function(t){var e=1;return i.each(t,function(t){i.isArray(t)&&t.length>e&&(e=t.length)}),e},i.color=a?function(t){return t instanceof CanvasGradient&&(t=r.global.defaultColor),a(t)}:function(t){return console.error("Color.js not found!"),t},i.getHoverColor=function(t){return t instanceof CanvasPattern?t:i.color(t).saturate(.5).darken(.1).rgbString()}}},nSDx:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("LvDl"),r=function(){function t(){}return t.prototype.transform=function(t){return a.isUndefined(t)||a.isNull(t)?"-":t},t}()},nhM1:function(t,e,n){var a=n("mrSG").__decorate;Object.defineProperty(e,"__esModule",{value:!0});var r=n("CcnG");e.DimensionsHelper=function(){function t(){}return t.prototype.getDimensions=function(t){return t.getBoundingClientRect()},a([r.Injectable()],t)}()},nkY7:function(t,e,n){"use strict";function a(t){return t&&"function"==typeof t.schedule}n.d(e,"a",function(){return a})},nmKl:function(t,e){t.exports='\n \n \n \n Toggle navigation\n Pengalih navigasi\n \n \n Dashboard\n Dasbor\n \n \n Cluster\n Klaster\n \n \n Hosts\n Hos\n \n \n Monitors\n Monitor\n \n \n OSDs\n OSD\n \n \n Configuration\n Konfigurasi\n \n \n CRUSH map\n peta CRUSH\n \n \n Manager modules\n Modul Ceph Manajer\n \n \n Logs\n Log\n \n \n Alerts\n Peringatan\n \n \n Silences\n Silences\n \n \n Pools\n Pool\n \n \n Block\n Blok\n \n \n Images\n Image\n \n \n Mirroring\n Pencerminan\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n Sistemfile\n \n \n Object Gateway\n Gerbang Objek\n \n \n Daemons\n Daemon\n \n \n Users\n Pengguna\n \n \n Buckets\n Buket\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Menerima data \n untuk \n \n \n . Mohon tunggu...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Menampilkan data \n sebelumnya \nuntuk \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Gagal memuat data \n untuk\n \n \n .\nMohon periksa kesehatan klaster.\n \n \n \n Back\n Kembali\n \n \n Select a Language\n Pilih bahasa\n \n \n Loading panel data...\n Memuat data panel...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Silakan merujuk ke\n dokumentasi \n tentang\ncara mengonfigurasi dan mengaktifkan fungsi pemantauan.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Dasbor Grafana tidak ada. Mohon merujuk ke\n dokumentasi \n tentang cara\nmenambahkan dasbor ke Grafana.\n \n \n \n Grafana Time Picker\n Pemilih Waktu Grafana\n \n \n Reset Settings\n Reset Pengaturan\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n Gagal memuat data.\n \n \n selected\n dipilih\n X selected\n \n \n found\n ditemukan\n X found\n \n \n total\n total\n X total\n \n \n Edit\n Edit\n \n \n Name\n Nama\n \n \n Description\n Deskripsi\n \n \n Long description\n Deskripsi lengkap\n \n \n Default\n Bawaan\n \n \n Daemon default\n Daemon bawaan\n \n \n Services\n Layanan\n \n \n Values\n Nilai\n \n \n The entered value is too high! It must not be greater than \n .\n \n Nilai yang dimasukkan terlalu tinggi! Tidak boleh lebih besar dari \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Nilai yang dimasukkan terlalu rendah! Tidak boleh lebih rendah dari \n .\n \n \n \n Save\n Simpan\n \n \n CRUSH map viewer\n Penampil peta CRUSH\n \n \n Hosts List\n Daftar Hos\n \n \n Overall Performance\n Performa Keseluruhan\n \n \n No entries found\n Entri tidak ditemukan\n \n \n Cluster Logs\n Log Klaster\n \n \n Audit Logs\n Log Audit\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n Memuat konfigurasi...\n \n \n The configuration could not be loaded.\n Konfigurasi tidak dapat dimuat.\n \n \n Edit Manager module\n Edit modul Ceph Manajer\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n Nilai yang dimasukkan bukan UUID yang valid, cth: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n Nilai yang dimasukkan harus alamat IP yang valid.\n \n \n This field is required.\n Isian ini tidak boleh kosong.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n Nilai yang dimasukkan terlalu tinggi! Harus lebih kecil atau sama dengan \n .\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n Nilai yang dimasukkan terlalu rendah! Harus lebih besar atau sama dengan \n .\n \n \n \n The entered value needs to be a number.\n Nilai yang dimasukkan harus berupa angka.\n \n \n The entered value needs to be a number or decimal.\n Nilai yang dimasukkan harus berupa angka atau desimal.\n \n \n Update\n Perbarui\n \n \n Status\n Status\n \n \n Cluster ID\n ID Klaster\n \n \n monmap modified\n monmap diubah\n \n \n monmap epoch\n monmap epoch\n \n \n quorum con\n kuorum con\n \n \n quorum mon\n kuorum mon\n \n \n required con\n con yang dibutuhkan\n \n \n required mon\n mon yang dibutuhkan\n \n \n In Quorum\n Memenuhi Kuorum\n \n \n Not In Quorum\n Tidak dalam Kuorum\n \n \n Cancel\n Batal\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n Anda yakin ingin \n dari \n ?\n \n \n \n Yes, I am sure.\n Ya, saya yakin.\n \n \n Cluster-wide OSD Flags\n Flag OSD Klaster\n \n \n Submit\n Kirim\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Tingkat lanjut...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n Prioritas pemulihan OSD\n \n \n Priority\n Prioritas\n \n \n Customize priority values\n Ubah nilai prioritas\n \n \n This field is required!\n Isian ini harus diisi!\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n Nilai yang dimasukkan terlalu tinggi! Tidak boleh lebih tinggi dari \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n Nilai yang dimasukkan terlalu rendah! Tidak boleh lebih rendah dari \n .\n \n \n \n Reweight OSD\n Ubah bobot OSD\n \n \n The value needs to be between 0 and 1.\n Nilai harus antara 0 dan 1.\n \n \n Reweight\n Ubah bobot\n \n \n OSDs \n Scrub\n \n OSD \n Scrub\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {Dalam } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Anda akan menerapkan\n scrub pada\nOSD \n \n \n .\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {dalam } }\n \n \n OSDs List\n Daftar OSD\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \n OSD \n \n akan ditandai\n \n \n jika ingin melanjutkan.\n \n \n \n The OSD is not safe to destroy!\n OSD tidak aman untuk dihancurkan!\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \n OSD \n \n akan\n \n \n jika ingin melanjutkan.\n \n \n \n Details\n Detail\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Nilai\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Tutup\n \n \n Delete\n Hapus\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Kesehatan\n \n \n Statistics\n Statistik \n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Mohon periksa \n dokumentasi \n \ntentang cara mengonfigurasi dan aktfikan fungsi manajemen NFS Ganesha.\n \n \n \n Clients\n Klien\n \n \n Any client can access\n Semua klien dapat mengakses\n \n \n Addresses\n Alamat\n \n \n Required field\n Wajib diisi\n \n \n Must contain one or more comma-separated values\n Harus mengandung satu atau lebih nilai yang dipisahkan koma\n \n \n For example:\n Contoh:\n \n \n Access Type\n Tipe Akses\n \n \n Squash\n Squash\n \n \n Add clients\n Tambah klien\n \n \n Loading...\n Memuat...\n \n \n -- No cluster available --\n -- Klaster tidak tersedia --\n \n \n -- Select the cluster --\n -- Pilih klaster --\n \n \n Add daemon\n Tambah daemon\n \n \n Storage Backend\n Backend Penyimpanan\n \n \n -- No data pools available --\n -- Tidak ada pool data tersedia --\n \n \n -- Select the storage backend --\n -- Pilih backend penyimpanan --\n \n \n Object Gateway User\n Pengguna Gerbang Objek\n \n \n -- No users available --\n -- Pengguna tidak tersedia --\n \n \n -- Select the object gateway user --\n -- Pilih pengguna gerbang objek --\n \n \n CephFS User ID\n ID Pengguna CephFS\n \n \n -- No clients available --\n -- Klien tidak tersedia --\n \n \n -- Select the cephx client --\n -- Pilih klien cephx --\n \n \n CephFS Name\n Nama CephFS\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n Label Keamanan\n \n \n Enable security label\n Aktifkan label keamanan\n \n \n CephFS Path\n CephFS Path\n \n \n Path need to start with a \'/\' and can be followed by a word\n Lintasan atau path harus dimulai dengan \'/\' dan diikuti dengan kata\n \n \n New directory will be created\n Direktori baru akan dibuat\n \n \n Path\n Path\n \n \n Path can only be a single \'/\' or a word\n Path hanya boleh berupa \'/\' atau kata\n \n \n New bucket will be created\n Buket baru akan dibuat\n \n \n NFS Protocol\n Protokol NFS\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n Tag NFS\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Alternatif akses untuk mount \n NFSv3\n (tidak boleh diawali /).\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n Klien mungkin tidak dapat mount subdirektori (cth. jika Tag = foo, klien mungkin tidak bisa mount foo/baz).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n Dengan menggunakan opsi Tag yang berbeda, Path yang sama akan diekspor beberapa kali.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n Posisi dari \n NFS v4\n yang diekspor ini menempati \n Pseudo FS \n (ini harus unik).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n Dengan menggunakan opsi Pseudo yang berbeda, Path yang sama akan diekspor beberapa kali.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- Tipe akses tidak tersedia --\n \n \n -- Select the access type --\n -- Pilih tipe akses --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- Squash tidak tersedia --\n \n \n --Select what kind of user id squashing is performed --\n -- Pilih jenis squashing id pengguna yang akan dilakukan --\n \n \n Transport Protocol\n Protokol Transport\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Selamat datang di Ceph!\n The welcome message on the login page\n \n \n Username is required\n Nama pengguna harus diisi\n \n \n Password is required\n Kata sandi harus diisi\n \n \n Login\n Masuk\n \n \n Sorry, the user does not exist in Ceph.\n Maaf, pengguna tidak terdaftar di Ceph.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Kembali ke Halaman Masuk \n \n . Anda akan dikeluarkan dari Penyedia Identitas saat Anda mencoba masuk.\n \n \n \n Forbidden\n Terlarang\n \n \n Sorry, you are not allowed to see what you were looking for.\n Maaf, Anda tidak dizinkan melihat hal yang Anda inginkan.\n \n \n Sorry, we could not find what you were looking for\n Maaf, kami tidak dapat menemukan yang Anda cari\n \n \n Remove all\n Hapus semua\n \n \n Recent Notifications\n Notifikasi terkini\n \n \n There are no background tasks.\n Tidak ada tugas latar belakang.\n \n \n Background Tasks\n Tugas Latar Belakang\n \n \n Help\n Bantuan\n \n \n Documentation\n Dokumentasi \n \n \n API\n API\n \n \n About\n Tentang\n \n \n Dashboard Settings\n Pengaturan Dasbor\n \n \n User management\n Manajemen Pengguna\n \n \n Logged in user\n Pengguna masuk\n \n \n Signed in as\n \n \n \n \n Masuk sebagai\n \n \n \n \n \n \n Sign out\n Keluar\n \n \n Name...\n Nama...\n \n \n The chosen name is already in use.\n Nama yang dipilih sudah digunakan.\n \n \n Description...\n Deskripsi...\n \n \n Permissions\n Izin\n \n \n Roles\n Peran\n \n \n Username\n Nama pengguna\n \n \n Password\n Kata sandi\n \n \n Confirm password\n Konfirmasi kata sandi\n \n \n Password confirmation doesn\'t match the password.\n Konfirmasi kata sandi tidak sesuai dengan kata sandi.\n \n \n Full name\n Nama lengkap\n \n \n Email\n Email\n \n \n Invalid email.\n Email tidak valid.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Anda akan menghapus izin "pengguna baca / perbarui" dari diri Anda sendiri.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Jika melanjutkan, Anda tidak akan lagi dapat menambahkan atau menghapus peran dari pengguna manapun.\n \n \n Are you sure you want to continue?\n Anda yakin ingin melanjutkan?\n \n \n Performance counters not available\n Penghitung kinerja tidak tersedia\n \n \n Attributes (OSD map)\n Atribut (peta OSD)\n \n \n Metadata not available\n Metadata tidak tersedia\n \n \n Metadata\n Metadata\n \n \n Performance counter\n Penghitung kinerja\n \n \n Histogram not available: \n \n \n Histogram tidak tersedia: \n \n \n \n \n Writes\n Tulis\n \n \n Reads\n Baca\n \n \n Histogram\n Histogram\n \n \n Performance Details\n Detail Performa\n \n \n Current values\n Nilai saat ini\n \n \n Type\n Tipe\n \n \n Min\n Min\n \n \n Max\n Maks\n \n \n Flags\n Flag\n \n \n Source\n Sumber\n \n \n Level\n Level\n \n \n Can be updated at runtime (editable)\n Boleh diperbarui saat dijalankan (bisa diedit)\n \n \n Tags\n Tag\n \n \n Enum values\n Nilai Enum\n \n \n See also\n Lihat juga\n \n \n Cluster Status\n Status Klaster\n \n \n Manager Daemons\n Manajer Daemon\n \n \n Object Gateways\n Gerbang Objek\n \n \n Metadata Servers\n Server Metadata\n \n \n iSCSI Gateways\n Gateway iSCSI\n \n \n Client IOPS\n IOPS klien\n \n \n Client Throughput\n Throughput Pengguna\n \n \n Client Read/Write\n Baca/Tulis Klien\n \n \n Recovery Throughput\n Throughput Pemulihan\n \n \n Scrub\n Scrub\n \n \n Performance\n Kinerja\n \n \n Raw Capacity\n Kapasitas mentah\n \n \n Objects\n Objek\n \n \n PGs per OSD\n PG per OSD\n \n \n PG Status\n Status PG\n \n \n Capacity\n Kapasitas\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n Lihat \n \n Log untuk detil lainnya.\n \n \n \n Ranks\n Peringkat\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Klien: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n Pindahkan image ke tempat sampah\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n Untuk pindahkan \n \n /\n \n ke tempat sampah,\ntekan \n Pindah Image \n . Anda juga dapat memilih tanggal kedaluwarsa.\n \n \n \n Protection expires at\n Proteksi berakhir pada\n \n \n NOT PROTECTED\n TIDAK DIPROTEKSI\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Format tanggal salah. Mohon gunakan "TTTT-BB-HH JJ:mm:dd".\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n Proteksi telah kedaluarsa. Mohon pilih tanggal masa mendatang atau kosongkan.\n \n \n Move Image\n Pindahkan Image\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n Ikhtisar\n \n \n Targets\n Target\n \n \n Discovery Authentication\n Otentikasi Discovery\n \n \n User\n Pengguna\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Nama pengguna harus terdiri dari 8 hingga 64 karakter dan\nhanya boleh mengandung huruf, \'.\', \'@\', \'-\', \'_\' atau \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n Pengguna Bersama\n \n \n Mutual Password\n Kata sandi bersama\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Mohon cek ke \n dokumentasi \n \ntentang cara mengonfigurasi dan mengaktifkan fungsi manajemen iSCSI Target.\n \n \n \n Available information:\n Informasi tersedia:\n \n \n iSCSI Targets not available\n iSCSI Target tidak tersedia\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n Hanya tersedia untuk image RBD dengan \n fast-diff\n yang diaktifkan.\n \n \n \n Pool\n Pool\n \n \n Data Pool\n Pool Data\n \n \n Created\n Dibuat\n \n \n Size\n Ukuran\n \n \n Object size\n Ukuran objek\n \n \n Features\n Fitur\n \n \n Provisioned\n Disiapkan\n \n \n N/A\n N/A\n \n \n Total provisioned\n Total disiapkan\n \n \n Striping unit\n Unit setrip\n \n \n Striping count\n Jumlah setrip\n \n \n Parent\n Induk\n \n \n Block name prefix\n Awalan nama blok\n \n \n Order\n Urutan\n \n \n Snapshots\n Snapshot\n \n \n Image\n Image\n \n \n This setting overrides the global value\n Pengaturan ini akan membatalkan nilai global\n \n \n Global\n Global\n \n \n This is the global value. No value for this option has been set for this image.\n Ini adalah nilai global. Tidak ada nilai yang diset untuk image ini.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \'/\' dan \'@\' tidak diperbolehkan.\n \n \n -- No rbd pools available --\n -- Tidak ada pool rbd tersedia --\n \n \n -- Select a pool --\n -- Pilih pool --\n \n \n Use a dedicated data pool\n Gunakan pool data terdedikasi\n \n \n Data pool\n Pool data\n \n \n Dedicated pool that stores the object-data of the RBD.\n Pool terdedikasi yang menyimpan data-objek dari RBD.\n \n \n e.g., 10GiB\n cth. 10GiB\n \n \n You have to increase the size.\n Anda harus menaikkan ukuran.\n \n \n Advanced\n Tingkat lanjut\n \n \n Striping\n Setrip\n \n \n Stripe unit\n Unit setrip\n \n \n -- Select stripe unit --\n -- Pilih ukuran setrip --\n \n \n This field is required because stripe count is defined!\n Isian ini harus diisi karena jumlah setrip telah ditentukan!\n \n \n Stripe unit is greater than object size.\n Unit setrip lebih besar dari ukuran objek.\n \n \n Stripe count\n Jumlah setrip\n \n \n This field is required because stripe unit is defined!\n Isian wajib diisi karena unit setrip didefinisikan!\n \n \n Stripe count must be greater than 0.\n Jumlah setrip harus lebih besar dari 0.\n \n \n \n RBD Snapshot\n \n \n Snapshot RBD\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Ganti nama} other {Buat} }\n \n \n \n Snapshot\n \n \n Snapshot\n \n \n \n PROTECTED\n DIPROTEKSI\n \n \n UNPROTECTED\n TIDAK DIPROTEKSI\n \n \n You are about to rollback\n Anda akan mengembalikan semula\n \n \n Purge Trash\n Kosongkan Tempah Sampah\n \n \n To purge, select one or All images and click\n Untuk menghapus, pilih satu atau Semua image dan pilih\n \n \n Pool:\n Pool:\n \n \n Pool name...\n Nama Pool...\n \n \n All\n Semua\n \n \n Restore Image\n Pulihkan Image\n \n \n To restore\n Untuk memulihkan\n \n \n type the image\'s new name and click\n ketik nama baru image dan pilih\n \n \n New Name\n Nama Baru\n \n \n Expired at\n Kedaluwarsa pada\n \n \n Protected until\n Diproteksi hingga\n \n \n This image is protected until \n .\n \n Image ini diproteksi hingga \n .\n \n \n \n Trash\n Tempat sampah\n \n \n iSCSI Topology\n Topologi iSCSI\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n Mengganti parameter ini dari nilai bawaan biasanya tidak diperlukan.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Pengaturan\n \n \n Backstore\n Backstore\n \n \n Confirm\n Konfirmasi\n \n \n Advanced Settings\n Pengaturan Lanjut\n \n \n Target IQN\n Target IQN\n \n \n IQN has wrong pattern.\n Pola IQN salah.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n Suatu IQN memiliki notasi seperti ini \'iqn.$tahun-$bulan.$reversedAddress:$definedName\'\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Contoh: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n Informasi lainnya\n \n \n This target has modified advanced settings.\n Pengaturan lanjutan target ini telah dimodifikasi.\n \n \n Portals\n Portal\n \n \n At least \n gateways are required.\n \n Dibutuhkan min \n gerbang/gateway.\n \n \n \n Add portal\n Tambahkan portal\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Pengaturan Image ini telah dimodifikasi.\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n Tambahkan image\n \n \n ACL authentication\n Otentikasi ACL\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Inisiator\n \n \n Initiator\n Inisiator\n \n \n Client IQN\n Klien IQN\n \n \n Initiator IQN needs to be unique.\n Inisiator IQN harus unik.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Nama pengguna harus terdiri atas 8 hingga 64 karakter dan\nhanya boleh mengandung huruf, \'.\', \'@\', \'-\', \'_\' atau \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n Inisiator termasuk ke dalam grup. Image akan dikonfigurasi di dalam grup.\n \n \n No items added.\n Tidak ada yang ditambahkan.\n \n \n Add initiator\n Tambahkan inisiator\n \n \n Groups\n Grup\n \n \n Group\n Grup\n \n \n Add group\n Tambahkan grup\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n Konfigurasi RBD\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Menghapus nilai konfigurasi lokal. Nilai konfigurasi induk akan diturun dan digunakan.\n \n \n The mininum value is 0\n Nilai minimum adalah 0\n \n \n Issues\n Masalah\n \n \n Syncing\n Menyinkronkan\n \n \n Ready\n Siap\n \n \n Edit pool mirror mode\n Edit mode pencerminan pool\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n Untuk mengubah mode pencerminan pool\xa0\n \n \n , pilih mode baru dari daftar dan klik\xa0\n Perbarui\n .\n \n \n \n Mode\n Mode\n \n \n Peer clusters must be removed prior to disabling mirror.\n Klaster mitra harus dihapus sebelum menonaktfikan pencerminan.\n \n \n \n \n pool mirror peer\n \n \n \nmitra pencerminan pool\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Edit} other {Tambah} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n pool\natribut mitra pencerminan untuk pool \n \n \n dan klik \n Kirim\n .\n \n \n \n Cluster Name\n Nama Klaster\n \n \n The cluster name is not valid.\n Nama klaster tidak valid.\n \n \n CephX ID\n CephX ID\n \n \n CephX ID...\n CephX ID...\n \n \n The CephX ID is not valid.\n CephX ID tidak valid.\n \n \n Monitor Addresses\n Alamat Monitor\n \n \n Comma-delimited addresses...\n Alamat dengan pemisah-koma...\n \n \n The monitory address is not valid.\n Alamat monitor tidak valid.\n \n \n CephX Key\n CephX Key\n \n \n Base64-encoded key...\n Base64-encoded key...\n \n \n CephX key must be base64 encoded.\n Kunci CephX harus base64 encoded.\n \n \n Pools List\n Daftar pool\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n Nama hanya boleh terdiri dari alfanumerik, tanda hubung, dan garis bawah.\n \n \n The chosen erasure code profile name is already in use.\n Nama profil erasure code sudah digunakan.\n \n \n Plugin\n Plugin\n \n \n Data chunks (k)\n Pecahan data (k)\n \n \n Must be equal to or greater than 2.\n Harus sama dengan atau lebih dari 2.\n \n \n Coding chunks (m)\n Pecahan Coding (m)\n \n \n Must be equal to or greater than 1.\n Harus sama dengan atau lebih dari 1.\n \n \n Durability estimator (c)\n Penduga daya tahan (c)\n \n \n Locality (l)\n Lokalitas (l)\n \n \n Crush failure domain\n Domain kegagalan Crush\n \n \n Crush Locality\n Lokalitas Crush\n \n \n None\n Tidak ada\n \n \n Technique\n Teknik\n \n \n Packetsize\n Ukuran paket\n \n \n Crush root\n Crush root\n \n \n Crush device class\n Kelas perangkat Crush\n \n \n any\n apa saja\n \n \n Directory\n Direktori\n \n \n The chosen Ceph pool name is already in use.\n Nama pool Ceph yang dipilih sudah digunakan.\n \n \n Pool type\n Jenis pool\n \n \n -- Select a pool type --\n -- Pilih jenis pool --\n \n \n Placement groups\n Grup penempatan\n \n \n At least one placement group is needed!\n Dibutuhkan setidaknya satu grup penempatan!\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n Klaster Anda tidak dapat menangani PG sebanyak ini. Mohon hitung ulang jumlah PG yang dibutuhkan.\n \n \n Calculation help\n Bantuan penghitungan\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n Pengaturan PG saat ini telah dihitung untuk Anda, Anda\nharus memastikan nilai tersebut sesuai kebutuhan sebelum mengajukan.\n \n \n Crush ruleset\n Aturan CRUSH\n \n \n -- Select a crush rule --\n -- Pilih aturan crush --\n \n \n Crush rule\n Aturan crush\n \n \n Crush steps\n Crush steps\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n Aturan crush tidak dapat digunakan di klaster ini karena\njumlah OSD terlalu sedikit untuk memenuhi syarat minimal OSD untuk aturan ini.\n \n \n Replicated size\n Jumlah replikasi\n \n \n Minimum: \n \n \n Minimum: \n \n \n \n \n Maximum: \n \n \n Maksimum: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n Ukuran yang dimasukkan di luar jangkauan. Nilai yang valid\ndari \n hingga \n .\n \n \n \n Erasure code profile\n Profil erasure code\n \n \n -- No erasure code profile available --\n -- Tidak ada profil erasure code --\n \n \n -- Select an erasure code profile --\n -- Pilih profil erasure code --\n \n \n EC Overwrites\n EC Overwrites\n \n \n Applications\n Aplikasi\n \n \n Compression\n Kompresi\n \n \n Algorithm\n Algoritma\n \n \n -- No erasure compression algorithm available --\n -- Tidak ada algoritma pengompresian erasure --\n \n \n Minimum blob size\n Ukuran blob minimum\n \n \n e.g., 128KiB\n cth. 128KiB\n \n \n Value should be greater than 0\n Nilai harus lebih besar dari 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Ukuran maksimum blob\n \n \n e.g., 512KiB\n cth. 512KiB\n \n \n Value should be greater than the minimum blob size\n Nilai harus lebih besar dari ukuran minimum blob\n \n \n Ratio\n Rasio\n \n \n Compression ratio\n Rasio kompresi\n \n \n Value should be between 0.0 and 1.0\n Nilai harus antara 0.0 dan 1.0\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n Tidak boleh membuat pool RBD dengan nama yang mengandung \'/\'.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n Mohon ganti atau hapus \'rbd\' dari daftar aplikasi.\n \n \n Cache Tiers Details\n Detil Cache Bertingkat\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Silakan cek kembali \n dokumentasi \n \ntentang cara mengonfigurasi dan mengaktifkan fungsi manajemen Gerbang Objek.\n \n \n \n Daemons List\n Daftar Daemon\n \n \n Performance Counters\n Penghitung Performa\n \n \n Loading bucket data...\n Memuat data buket...\n \n \n The bucket data could not be loaded.\n Buket data tidak dapat dimuat.\n \n \n Id\n Id\n \n \n The value is not valid.\n Nilai tidak valid.\n \n \n Owner\n Pemilik\n \n \n -- Select a user --\n -- Pilih pengguna --\n \n \n ID\n ID\n \n \n Index type\n Jenis indeks\n \n \n Placement rule\n Aturan penempatan\n \n \n Marker\n Penanda\n \n \n Maximum marker\n Penanda maksimum\n \n \n Version\n Versi\n \n \n Master version\n Versi Master\n \n \n Modification time\n Modifikasi waktu\n \n \n Zonegroup\n Zona grup\n \n \n Bucket quota\n Kuota Buket\n \n \n Enabled\n Diaktifkan\n \n \n Maximum size\n Ukuran maksimum\n \n \n Unlimited\n Tak terbatas\n \n \n Maximum objects\n Objek maksimum\n \n \n -- Select a username --\n -- Pilih nama pengguna --\n \n \n Auto-generate key\n Kunci otomatis-dibuat\n \n \n Access key\n Kunci akses\n \n \n Secret key\n Kunci rahasia\n \n \n Email address\n Alamat email\n \n \n Suspended\n Dihentikan\n \n \n System\n Sistem\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {Tidak} 1 {Ya} }\n \n \n Maximum buckets\n Buket maksimum\n \n \n Subusers\n Subpengguna\n \n \n Capabilities\n Kemampuan\n \n \n User quota\n Kuota pengguna\n \n \n Show\n Tampilkan\n \n \n Keys\n Kunci\n \n \n -- Select a type --\n -- Pilih tipe --\n \n \n Permission\n Izin\n \n \n -- Select a permission --\n -- Pilih izin --\n \n \n Subuser\n Subpengguna\n \n \n The chosen subuser ID is already in use.\n ID subpengguna sudah digunakan.\n \n \n read, write\n baca, tulis\n \n \n full\n penuh\n \n \n Swift key\n Kunci Swift\n \n \n Auto-generate secret\n Sandi otomatis-dibuat\n \n \n Loading user data...\n Memuat data pengguna...\n \n \n The user data could not be loaded.\n Data pengguna tidak dapat dimuat.\n \n \n The chosen user ID is already in use.\n ID pengguna yang dipilih sudah digunakan.\n \n \n This is not a valid email address.\n Ini bukan alamat email yang valid.\n \n \n The chosen email address is already in use.\n Alamat email yang dipilih sudah digunakan.\n \n \n Max. buckets\n Maks. buket\n \n \n The entered value must be >= 0.\n Nilai yang dimasukkan harus >= 0.\n \n \n S3 key\n Kunci S3\n \n \n There are no subusers.\n Tidak ada sub-pengguna.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n Kunci tidak ditemukan.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n Kemampuan tidak ada.\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Ukuran tak terbatas\n \n \n Max. size\n Ukuran maks.\n \n \n Unlimited objects\n Objek tak terbatas\n \n \n Max. objects\n Objek maks.\n \n \n Current\n Terkini\n \n \n Updated discovery authentication\n Otentikasi penemuan telah diperbarui\n \n \n There are no portals available.\n Tidak ada portal yang tersedia.\n \n \n There are no images available.\n Tidak ada image yang tersedia.\n \n \n There are no images available. Please make sure you add an image to the target.\n Tidak ada image yang tersedia. Mohon pastikan Anda telah menambahkan image ke target.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n Tidak ada inisiator tersedia. Mohon pastikan Anda telah menambahkan inisiator ke target.\n \n \n target\n target\n \n \n Target\n Target\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n Keadaan\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Baca Bytes\n \n \n Write Bytes\n Tulis Bytes\n \n \n Read Ops\n Ops Baca\n \n \n Write Ops\n Ops Tulis\n \n \n A/O Since\n A/O Sejak\n \n \n Instance\n Instance\n \n \n Hostname\n Nama hos\n \n \n Issue\n Isu\n \n \n Progress\n Kemajuan\n \n \n Disabled\n Dimatikan\n \n \n Edit Mode\n Mode Edit\n \n \n Add Peer\n Tambahkan Mitra\n \n \n Edit Peer\n Edit Mitra\n \n \n Delete Peer\n Hapus Mitra\n \n \n Leader\n Pemimpin\n \n \n # Local\n # Lokal\n \n \n # Remote\n # Jauh\n \n \n mirror peer\n mitra pencerminan\n \n \n Key\n Kunci\n \n \n RBD\n RBD\n \n \n Deep flatten\n Perataan mendalam\n \n \n Layering\n Lapisan\n \n \n Exclusive lock\n Kunci eksklusif\n \n \n Object map (requires exclusive-lock)\n Peta objek (butuh kunci-eksklusif)\n \n \n Journaling (requires exclusive-lock)\n Penjurnalan (membutuhkan kunci-eksklusif)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Kembalikan snapshot RBD\n \n \n Rollback\n Kembalikan\n \n \n RBD snapshot\n Snapshot RBD\n \n \n Deleted At\n Dihapus pada\n \n \n id\n id\n \n \n type\n tipe\n \n \n state\n keadaan\n \n \n version\n versi\n \n \n Host\n Hos\n \n \n root\n induk\n \n \n Rank\n Peringkat\n \n \n Daemon\n Daemon\n \n \n Activity\n Aktivitas\n \n \n Dentries\n Dentries\n \n \n Inodes\n Inode\n \n \n Usage\n Penggunaan\n \n \n Standby daemons\n Daemon siaga\n \n \n The value can be updated at runtime.\n Nilai dapat diperbarui saat runtime.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n Daemon/klien tidak dapat mengambil nilai dari\nbasis data konfigurasi monitor. Kami tidak mengizinkan mengubah ini dari \'ceph config\nset ...\'. Pilihan ini harus dikonfigurasi melalui ceph.conf atau CLI.\n \n \n Option takes effect only during daemon startup.\n Pilihan hanya dapat bekerja selama daemon dimulai.\n \n \n Option only affects cluster creation.\n Pilihan hanya berpengaruh pada pembuatan klaster.\n \n \n Option only affects daemon creation.\n Pilihan hanya berpengaruh pada pembuatan daemon.\n \n \n Updated config option \n \n \n Perbarui opsi konfigurasi \n \n \n \n \n Service\n Layanan\n \n \n Current value\n Nilai saat ini\n \n \n Editable\n Dapat diedit\n \n \n Updated options for module "\n ".\n \n Opsi diperbarui untuk modul &quot;\n &quot;.\n \n \n \n Enable\n Aktifkan\n \n \n Disable\n Nonaktifkan\n \n \n Reconnecting, please wait ...\n Menghubungkan kembali, mohon tunggu...\n \n \n Public Address\n Alamat Publik\n \n \n Open Sessions\n Buka Sesi\n \n \n No In\n Tidak boleh Masuk\n \n \n OSDs that were previously marked out will not be marked back in when they start\n OSD yang telah ditandai keluar tidak akan ditandai masuk saat mereka menyala\n \n \n No Out\n Tidak boleh Keluar\n \n \n OSDs will not automatically be marked out after the configured interval\n OSD tidak akan otomatis ditandai keluar setelah interval dikonfigurasi\n \n \n No Up\n Tidak Nyala\n \n \n OSDs are not allowed to start\n OSD tidak diizinkan menyala\n \n \n No Down\n Tidak Mati\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n Laporan kegagalan OSD sedang diabaikan sehingga monitor tidak akan menandai OSD mati\n \n \n Pause\n Jeda\n \n \n Pauses reads and writes\n Jeda baca dan tulis\n \n \n No Scrub\n Nonaktifkan Scrub\n \n \n Scrubbing is disabled\n Scrubbing dinonaktifkan\n \n \n No Deep Scrub\n Nonaktifkan Deep Scrub\n \n \n Deep Scrubbing is disabled\n Deep Scrubing dinonaktifkan\n \n \n No Backfill\n Tidak ada Penambalan\n \n \n Backfilling of PGs is suspended\n Penambalan PG dihentikan\n \n \n No Recover\n Tidak ada Pemulihan\n \n \n Recovery of PGs is suspended\n Pemulihan PG dihentikan\n \n \n Bitwise Sort\n Urutan Bitwise\n \n \n Use bitwise sort\n Gunakan urutan bitwise\n \n \n Purged Snapdirs\n Buang Snapdirs\n \n \n OSDs have converted snapsets\n OSD memiliki snapset yang dikonversi\n \n \n Recovery Deletes\n Pulihkan yang telah dihapus\n \n \n Deletes performed during recovery instead of peering\n Penghapusan dilakukan saat pemulihan bukan saat bermitra\n \n \n PG Log Hard Limit\n Batas Maks Log PG\n \n \n Puts a hard limit on pg log length\n Taruh batas maks pada panjang log pg\n \n \n Updated OSD Flags\n Flag OSD diperbarui\n \n \n out\n keluar\n \n \n in\n masuk\n \n \n down\n gugur\n \n \n Mark\n Tandai\n \n \n OSD lost\n OSD hilang\n \n \n marked lost\n ditandai hilang\n \n \n Purge\n Buang\n \n \n OSD\n OSD\n \n \n purged\n dibuang\n \n \n destroy\n hancurkan\n \n \n destroyed\n dihancurkan\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n PG\n \n \n Read bytes\n Bita baca\n \n \n Writes bytes\n Bita tulis\n \n \n Read ops\n Ops baca\n \n \n Write ops\n Ops tulis\n \n \n Mark OSD \n \n \n Tandai OSD \n \n \n \n \n Mark \n \n \n Tandai \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n Maks Penambalan\n \n \n Recovery Max Active\n Maks Pemulihan Aktif\n \n \n Recovery Max Single Start\n Maks Menjalankan Pemulihan Tunggal\n \n \n Recovery Sleep\n Jeda Pemulihan\n \n \n Custom\n Ubahsuai\n \n \n Updated OSD recovery speed priority "\n "\n \n Piroritas &quot;\n &quot; kecepatan pemulihan OSD diperbarui.\n \n \n \n \n was initialized in the following OSD: \n \n \n \n telah diinisialisasi pada OSD berikut: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n Tugas\n \n \n Severity\n Keparahan\n \n \n Started\n Dimulai\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Diperbarui\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n Terpakai\n \n \n Avail.\n Tersedia\n \n \n Clean\n Bersih\n \n \n Working\n Bekerja\n \n \n Warning\n Peringatan\n \n \n Unknown\n Tidak diketahui\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n nyala\n \n \n no filesystems\n tidak ada filesistem\n \n \n active\n aktif\n \n \n standby\n siaga\n \n \n n/a\n n/a\n \n \n active daemon\n daemon aktif\n \n \n quorum\n kuorum\n \n \n The NFS Ganesha service is not configured.\n Layanan NFS Ganesha belum dikonfigurasi.\n \n \n Transport\n Transport\n \n \n CephFS User\n Pengguna CephFS\n \n \n CephFS Filesystem\n Filesistem CephFS\n \n \n (inherited from global config)\n (diturunkan dari konfig global)\n \n \n inherited from global config\n diturunkan dari konfig global\n \n \n -- Select what kind of user id squashing is performed --\n -- Pilih jenis squashing id pengguna yang akan dilakukan --\n \n \n There are no daemons available.\n Tidak ada daemon tersedia.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Mode Cache\n \n \n Min Evict Age\n Min Waktu Usir\n \n \n Min Flush Age\n Min Waktu Buang\n \n \n Target Max Bytes\n Target Maks Bita\n \n \n Target Max Objects\n Target Maks Objek\n \n \n No applications added\n Tidak ada aplikasi ditambahkan\n \n \n Applications limit reached\n Batas aplikasi tercapai\n \n \n A pool can only have up to four applications definitions.\n Sebuah pool hanya dapat memiliki empat definisi aplikasi.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n Karakter diperbolehkan \'_a-zA-Z0-9\'\n \n \n Maximum length is 128 characters\n Panjang maksimum 128 karakter\n \n \n Filter or add applications\n Saring atau tambah aplikasi\n \n \n Add application\n Tambah aplikasi\n \n \n pool\n pool\n \n \n erasure code profile\n profil erasure code\n \n \n Replica Size\n Ukuran Replikasi\n \n \n Last Change\n Perubahan Terakhir\n \n \n Erasure Coded Profile\n Profil Erasure Code\n \n \n Crush Ruleset\n Aturan Crush\n \n \n Write bytes\n Bita tulis\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n buket\n \n \n Updated Object Gateway bucket "\n "\n \n Buket Gerbang Objek &quot;\n &quot; diperbarui\n \n \n \n Created Object Gateway bucket "\n "\n \n Buat buket Gerbang Objek &quot;\n &quot;\n \n \n \n buckets\n buket\n \n \n capability\n capability\n \n \n user\n pengguna\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Perbarui pengguna Gerbang Objek &quot\n ;&quot;\n \n \n \n Created Object Gateway user "\n "\n \n Buat pengguna Gerbang Objek &quot;\n &quot;\n \n \n \n users\n pengguna\n \n \n Swift Key\n Swift Key\n \n \n Scope\n Cakupan\n \n \n Read\n Baca\n \n \n Create\n Buat\n \n \n role\n role\n \n \n Created role \'\n \'\n \n Peran \'\n \' dibuat\n \n \n \n Updated role \'\n \'\n \n Peran \'\n \' diperbarui\n \n \n \n System Role\n Peran Sistem\n \n \n Deleted role \'\n \'\n \n Peran \'\n \' dihapus\n \n \n \n Created user "\n "\n \n Pengguna &quot;\n &quot; dibuat\n \n \n \n Update user\n Perbarui pengguna\n \n \n Continue\n Lanjutkan\n \n \n You were automatically logged out because your roles have been changed.\n Anda dikeluarkan otomatis karena peran Anda telah berubah.\n \n \n Updated user "\n "\n \n Perbarui pengguna &quot;\n &quot;\n \n \n \n Deleted user "\n "\n \n Hapus pengguna &quot;\n &quot;\n \n \n \n Failed to delete user "\n "\n \n Gagal menghapus pengguna &quot;\n &quot;\n \n \n \n You are currently logged in as "\n ".\n \n Saat ini Anda masuk sebagai &quot;\n &quot;\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Tiap objek dipecah dalam pecahan-data, masing-masing disimpan pada OSD yang berbeda.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Hitung pecahan coding untuk tiap objek dan simpan pada OSD yang berbeda.\nJumlah pecahan data juga menjadi jumlah OSD yang diperbolehkan mati tanpa kehilangan data.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Plugin jerasure merupakan plugin paling umum dan fleksibel,\nserta merupakan plugin bawaan Ceph untuk pool erasure code.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n Teknik yang lebih fleksibel yaitu reed_sol_van : cukup mengeset k\ndan m. Teknik cauchy_good bisa lebih cepat, namun Anda harus memilih ukuran paket\ndengan seksama. Semua reed_sol_r6_op, liberation, blaum_roth, liber8tion setara dengan RAID6\ndalam hal mereka hanya bisa diatur dengan m=2.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n Penyandian dilakukan setiap saat pada ukuran bita paket.\nSulit untuk menentukan ukuran paket yang tepat.\nSilakan cek dokumentasi jerasure untuk informasi lebih mendalam.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n Pada plugin jerasure, saat objek dengan erasure code disimpan pada\nbanyak OSD, pemulihan dari OSD yang hilang membutuhkan akses dari OSD lainnya.\nContoh, saat jerasure dikonfigurasi dengan k=8 dan m=4, saat satu OSD mati, maka pemulihan akan membutuhkan pembacaan dari tujuh OSD lainnya.\n\nPlugin lrc erasure code membuat pecahan paritas lokal agar dapat memulihkan \ndengan OSD yang lebih sedikit. Contoh, jika lrc dikonfigurasi dengan k=8, m=4, dan l=4, maka lrc akan\nmembuat pecahan paritas tambahan tiap empat OSD. Saat satu OSD mati, maka pemulihan dapat dilakukan hanya dengan 4 OSD, alih-alih 7 OSD.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Kelompokkan pecahan data dan coding ke dalam ukuran lokalitas. Controh\nuntuk k=4 dan m=2, saat lokalitas=3 dua grup dari tiga akan dibuat. Setiap set akan\ndipulihkan tanpa membaca pecahan dari set lainnya.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n Tipe buket crush setiap set pecahan yang didefinisikan oleh l \nakan disimpan. Contoh, jika diset pada rak, tiap grup pecahan l akan \nditempatkan pada rak berbeda. Ini akan digunakan pada aturan step CRUSH yaitu \nmemilih tiap rak. Jika tidak diset, tidak akan ada pengelompokkan.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n Plugin isa menghimpun perpustakaan ISA. Hanya dapat berjalan pada prosesor Intel.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n Plugin ISA memiliki dua jenis Reed Solomon.\nJika reed_sol_van diset, maka menjadi Vandermonde, jika cauchy diset, maka menjadi Cauchy.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n Plugin shec mengenkapsulasi banyak pustaka SHEC.\nHal ini agar ceph dapat dipulihkan dengan lebih efisien dari kode Reed Solomon.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n Jumlah potongan paritas yang masing-masing mencakup setiap potongan data \ndalam rentang perhitungannya. Nilai ini digunakan untuk perkiraan daya tahan. Contoh, jika c=2, \n2 OSD dapat mati tanpa kehilangan data.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n Nama buket crush digunakan sebagai langkah pertama dari aturan CRUSH.\nContoh diambil langkah bawaan.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n Memastikan tidak ada pecahan data berada pada buket dengan domain kegagalan\nyang sama. Contoh, saat domain gagal adalah hos, maka tidak ada pecahan data yang akan disimpan \npada hos yang sama. Aturan CRUSH seperti step chooseleaf hos akan digunakan untuk hal tersebut.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Batasi penempatan ke perangkat dengan kelas tertentu\n(cth. ssd atau hdd), menggunakan nama kelas perangkat crush pada peta CRUSH.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n Set nama direktori empat plugin erasure code akan dimuat.\n \n \n Allows all operations\n Izinkan semua operasi\n \n \n Allows only operations that do not modify the server\n Izinkan hanya untuk operasi yang tidak mengubah server\n \n \n Does not allow read or write operations, but allows any other operation\n Tidak diizinkan untuk operasi baca dan tulis, namun izinkan operasi lainnya\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n Tidak diizinkan untuk baca, tulis, atau operasi lainnya yang mengubah atribut berkas atau konten direktori\n \n \n Allows no access at all\n Tidak diizinkan untuk semua hal\n \n \n -- Select the priority --\n -- Pilih prioritas --\n \n \n Low\n Rendah\n \n \n High\n Tinggi\n \n \n Last 5 minutes\n 5 menit terakhir\n \n \n Last 15 minutes\n 15 menit terakhir\n \n \n Last 30 minutes\n 30 menit terakhir\n \n \n Last 1 hour (Default)\n 1 Jam Terakhir (Bawaan)\n \n \n Last 3 hours\n 3 jam terakhir\n \n \n Last 6 hours\n 6 jam terakhir\n \n \n Last 12 hours\n 12 jam terakhir\n \n \n Last 24 hours\n 24 jam terakhir\n \n \n Yesterday\n Kemarin\n \n \n Today\n Hari ini\n \n \n Today so far\n Sejauh hari ini\n \n \n Day before yesterday\n Kemarin dulu\n \n \n Last 2 days\n 2 hari terakhir\n \n \n This day last week\n Hari ini minggu lalu\n \n \n Previous week\n Minggu lalu\n \n \n This week\n Minggu ini\n \n \n This week so far\n Sejauh minggu ini\n \n \n Last 7 days\n 7 hari terakhir\n \n \n Previous month\n Bulan lalu\n \n \n This month\n Bulan ini\n \n \n This month so far\n Sejauh bulan ini\n \n \n Last 30 days\n 30 hari terakhir\n \n \n Last 90 days\n 90 hari terakhir\n \n \n Last 6 months\n 6 bulan terakhir\n \n \n Last 1 year\n 1 tahun terakhir\n \n \n Previous year\n Tahun lalu\n \n \n This year\n Tahun ini\n \n \n This year so far\n Sejauh tahun ini\n \n \n Last 2 years\n 2 tahun terakhir\n \n \n Last 5 years\n 5 tahun terakhir\n \n \n Information\n Informasi\n \n \n No items selected.\n Tidak ada yang dipilih.\n \n \n Deselect item to select again\n Batalkan memilih untuk memilih ulang\n \n \n Selection limit reached\n Batas pemilihan tercapai\n \n \n Filter tags\n Tanda penyaringan\n \n \n Add badge\n Tambahkan lencana\n \n \n There are no items available.\n Tidak ada yang tersedia.\n \n \n Add\n Tambah\n \n \n Remove\n Remove\n \n \n Clone\n Klon\n \n \n Copy\n Salin\n \n \n Deep Scrub\n Deep Scrub\n \n \n Destroy\n Hancurkan\n \n \n Flatten\n Ratakan\n \n \n Mark Down\n Tandai Gugur\n \n \n Mark In\n Tandai Masuk\n \n \n Mark Lost\n Tandai Hilang\n \n \n Mark Out\n Tandai Keluar\n \n \n Protect\n Proteksi\n \n \n Rename\n Ubah nama\n \n \n Restore\n Pulihkan\n \n \n Move to Trash\n Pindahkan ke Tempat Sampah\n \n \n Unprotect\n Tidak diproteksi\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Dihapus\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Diklon\n \n \n Copied\n Disalin\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n Ya\n \n \n No\n Tidak\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Kualitas Layanan atau QoS\n \n \n BPS Limit\n Limit BPS\n \n \n The desired limit of IO bytes per second.\n Limit IO bytes per detik yang diinginkan.\n \n \n IOPS Limit\n Limit IOPS\n \n \n The desired limit of IO operations per second.\n Limit operasi IO per detik yang diinginkan.\n \n \n Read BPS Limit\n Limit Baca BPS \n \n \n The desired limit of read bytes per second.\n Limit byte baca per detik yang diinginkan.\n \n \n Read IOPS Limit\n Limit IOPS Baca\n \n \n The desired limit of read operations per second.\n Limit operasi baca per detik yang diinginkan.\n \n \n Write BPS Limit\n Limit Tulis BPS\n \n \n The desired limit of write bytes per second.\n Limit tulis byte per detik yang diinginkan.\n \n \n Write IOPS Limit\n Limit IOPS Tulis\n \n \n The desired limit of write operations per second.\n Limit operasi tulis per detik yang diinginkan.\n \n \n BPS Burst\n Letupan BPS\n \n \n The desired burst limit of IO bytes.\n Limit yang diinginkan untuk letupan atau burst dari IO byte.\n \n \n IOPS Burst\n Letupan IOPS\n \n \n The desired burst limit of IO operations.\n Limit yang diinginkan untuk letupan atau burst operasi IO.\n \n \n Read BPS Burst\n Letupan Baca BPS\n \n \n The desired burst limit of read bytes.\n Limit yang diinginkan untuk letupan atau burst dari baca byte.\n \n \n Read IOPS Burst\n Letupan IOPS Baca\n \n \n The desired burst limit of read operations.\n Limit yang diinginkan untuk letupan atau burst operasi baca.\n \n \n Write BPS Burst\n Letupan BPS Tulis\n \n \n The desired burst limit of write bytes.\n Limit yang diinginkan untuk letupan atau burst dari tulis byte.\n \n \n Write IOPS Burst\n Letupan IOPS Tulis\n \n \n The desired burst limit of write operations.\n Limit yang diinginkan untuk letupan atau burst dari operasi baca.\n \n \n Failed to \n \n \n \n Gagal untuk \n \n \n \n \n \n Executing\n Mengeksekusi\n \n \n execute\n eksekusi\n \n \n Executed\n Dieksekusi\n \n \n unknown task\n tugas tak diketahui\n \n \n Creating\n Membuat\n \n \n create\n buat\n \n \n Updating\n Memperbarui\n \n \n update\n perbarui\n \n \n Deleting\n Menghapus\n \n \n delete\n hapus\n \n \n RBD \'\n \'\n \n RBD \'\n \'\n \n \n \n RBD snapshot \'\n \'\n \n Snapshot RBD \'\n \'\n \n \n \n mirror mode for pool \'\n \'\n \n mode pencerminan untuk pool \'\n \'\n \n \n \n mirror peer for pool \'\n \'\n \n mitra pencerminan untuk pool \'\n \'\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n Nama telah digunakan oleh \n .\n \n \n \n Name is already used by \n .\n \n Nama telah digunakan oleh \n .\n \n \n \n Name is already used by \n .\n \n Nama telah digunakan oleh \n .\n \n \n \n \n contains snapshots.\n \n \n berisi snapshot.\n \n \n \n Cloning\n Pengklonan\n \n \n clone\n klon\n \n \n Snapshot of \n must be protected.\n \n Snapshot \n harus diproteksi.\n \n \n \n Copying\n Menyalin\n \n \n copy\n salin\n \n \n Flattening\n Meratakan\n \n \n flatten\n ratakan\n \n \n Flattened\n Diratakan\n \n \n Name is already used by \n .\n \n Nama telah digunakan oleh \n .\n \n \n \n Cannot unprotect \n because it contains child images.\n \n Tidak dapat menghapus proteksi \n karena mengandung child image.\n \n \n \n Cannot delete \n because it\'s protected.\n \n Tidak dapat menghapus \n karena diproteksi.\n \n \n \n Rolling back\n Mengembalikan\n \n \n rollback\n kembalikan\n \n \n Rolled back\n Dikembalikan\n \n \n Moving\n Memindahkan\n \n \n move\n pindah\n \n \n Moved\n dipindahkan\n \n \n image \'\n \' to trash\n \n image \'\n \' ke tempat sampah\n \n \n \n Could not find image.\n Tidak dapat menemukan image.\n \n \n Restoring\n Memulihkan\n \n \n restore\n pulihkan\n \n \n Restored\n Dipulihkan\n \n \n image \'\n \' into \'\n \'\n \n image \'\n \' ke \'\n \'\n \n \n \n Image name \'\n \' is already in use.\n \n Nama image \'\n \' sudah digunakan.\n \n \n \n image \'\n \'\n \n image \'\n \'\n \n \n \n Purging\n Membuang\n \n \n purge\n buang\n \n \n Purged\n Dibuang\n \n \n all pools\n semua pool\n \n \n images from \n \n \n image dari \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n Gagal menonaktifkan pencerminan karena sedang bermitra.\n \n \n pool \'\n \'\n \n pool \'\n \'\n \n \n \n erasure code profile \'\n \'\n \n profil erasure code \'\n \'\n \n \n \n target \'\n \'\n \n target \'\n \'\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},nuQ0:function(t,e,n){"use strict";var a=n("CcnG"),r=n("Ip0R"),i=n("ty8c"),s=n("FYBg"),o=n("JZ5S"),u=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function c(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"li",[["class","node-menu-item"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.onMenuItemSelected(n,t.context.$implicit)&&a),a},null,null)),(t()(),a["\u0275eld"](1,0,null,null,0,"div",[],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275eld"](2,0,null,null,1,"span",[["class","node-menu-item-value"]],null,null,null,null,null)),(t()(),a["\u0275ted"](3,null,["",""]))],null,function(t,e){t(e,1,0,a["\u0275inlineInterpolate"](1,"node-menu-item-icon ",e.context.$implicit.cssClass,"")),t(e,3,0,e.context.$implicit.name)})}function l(t){return a["\u0275vid"](0,[a["\u0275qud"](402653184,1,{menuContainer:0}),(t()(),a["\u0275eld"](1,0,null,null,3,"div",[["class","node-menu"]],null,null,null,null,null)),(t()(),a["\u0275eld"](2,0,[[1,0],["menuContainer",1]],null,2,"ul",[["class","node-menu-content"]],null,null,null,null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,c)),a["\u0275did"](4,278528,null,0,r.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,4,0,e.component.availableMenuItems)},null)}var d=n("HHO+"),f=n("Tff5"),p=n("/TVo"),h=n("urB8"),g=n("VUo1"),b=n("ZYjt"),m=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function y(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"div",[["class","node-checkbox"]],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,[[1,0],["checkbox",1]],null,0,"input",[["checkbox",""],["type","checkbox"]],[[8,"disabled",0],[8,"checked",0]],[[null,"change"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==t.component.switchNodeCheckStatus()&&a),a},null,null))],null,function(t,e){var n=e.component;t(e,1,0,n.isReadOnly,n.tree.checked)})}function v(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"div",[["class","node-template"]],[[8,"innerHTML",1]],null,null,null,null)),a["\u0275ppd"](1,1)],null,function(t,e){var n=e.component,r=a["\u0275unv"](e,0,0,t(e,1,0,a["\u0275nov"](e.parent.parent.parent,0),n.tree.nodeTemplate));t(e,0,0,r)})}function _(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"span",[["class","node-name"]],[[8,"innerHTML",1]],null,null,null,null)),a["\u0275ppd"](1,1)],null,function(t,e){var n=e.component,r=a["\u0275unv"](e,0,0,t(e,1,0,a["\u0275nov"](e.parent.parent.parent,0),n.tree.value));t(e,0,0,r)})}function x(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"span",[["class","loading-children"]],null,null,null,null,null))],null,null)}function T(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](0,null,null,0))],null,null)}function w(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,9,"div",[["class","node-value"]],[[2,"node-selected",null]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.onNodeSelected(n)&&a),a},null,null)),(t()(),a["\u0275and"](16777216,null,null,1,null,v)),a["\u0275did"](2,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,_)),a["\u0275did"](4,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,x)),a["\u0275did"](6,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,2,null,T)),a["\u0275did"](8,540672,null,0,r.NgTemplateOutlet,[a.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),a["\u0275pod"](9,{$implicit:0})],function(t,e){var n=e.component;t(e,2,0,n.tree.nodeTemplate),t(e,4,0,!n.template),t(e,6,0,n.tree.childrenAreBeingLoaded());var a=t(e,9,0,n.tree.node);t(e,8,0,a,n.template)},function(t,e){t(e,0,0,e.component.isSelected)})}function S(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"input",[["class","node-value"],["type","text"]],null,[[null,"valueChanged"],[null,"keyup.enter"],[null,"blur"],[null,"keyup.esc"]],function(t,e,n){var r=!0,i=t.component;return"keyup.enter"===e&&(r=!1!==a["\u0275nov"](t,1).applyNewValue(n.target.value)&&r),"blur"===e&&(r=!1!==a["\u0275nov"](t,1).applyNewValueByLoosingFocus(n.target.value)&&r),"keyup.esc"===e&&(r=!1!==a["\u0275nov"](t,1).cancelEditing()&&r),"valueChanged"===e&&(r=!1!==i.applyNewValue(n)&&r),r},null,null)),a["\u0275did"](1,81920,null,0,i.NodeEditableDirective,[a.Renderer2,a.ElementRef],{nodeValue:[0,"nodeValue"]},{valueChanged:"valueChanged"})],function(t,e){t(e,1,0,e.component.tree.value)},null)}function O(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,0,"div",[["class","node-left-menu"]],[[8,"innerHTML",1]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.showLeftMenu(n)&&a),a},null,null))],null,function(t,e){t(e,0,0,e.component.tree.leftMenuTemplate)})}function I(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"node-menu",[],null,[[null,"menuItemSelected"]],function(t,e,n){var a=!0;return"menuItemSelected"===e&&(a=!1!==t.component.onMenuItemSelected(n)&&a),a},l,u)),a["\u0275did"](1,245760,null,0,s.NodeMenuComponent,[a.Renderer2,o.NodeMenuService],null,{menuItemSelected:"menuItemSelected"})],function(t,e){t(e,1,0)},null)}function C(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"node-menu",[],null,[[null,"menuItemSelected"]],function(t,e,n){var a=!0;return"menuItemSelected"===e&&(a=!1!==t.component.onMenuItemSelected(n)&&a),a},l,u)),a["\u0275did"](1,245760,null,0,s.NodeMenuComponent,[a.Renderer2,o.NodeMenuService],null,{menuItemSelected:"menuItemSelected"})],function(t,e){t(e,1,0)},null)}function k(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"node-menu",[],null,[[null,"menuItemSelected"]],function(t,e,n){var a=!0;return"menuItemSelected"===e&&(a=!1!==t.component.onMenuItemSelected(n)&&a),a},l,u)),a["\u0275did"](1,245760,null,0,s.NodeMenuComponent,[a.Renderer2,o.NodeMenuService],{menuItems:[0,"menuItems"]},{menuItemSelected:"menuItemSelected"})],function(t,e){t(e,1,0,e.component.tree.menuItems)},null)}function N(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"tree-internal",[],null,null,null,L,m)),a["\u0275did"](1,4964352,null,0,d.TreeInternalComponent,[o.NodeMenuService,f.TreeService,a.ElementRef],{tree:[0,"tree"],settings:[1,"settings"],template:[2,"template"]},null)],function(t,e){var n=e.component;t(e,1,0,e.context.$implicit,n.settings,n.template)},null)}function R(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,5,"div",[],null,null,null,null,null)),a["\u0275did"](1,278528,null,0,r.NgStyle,[a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngStyle:[0,"ngStyle"]},null),a["\u0275pod"](2,{display:0}),(t()(),a["\u0275and"](16777216,null,null,2,null,N)),a["\u0275did"](4,278528,null,0,r.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,r.AsyncPipe,[a.ChangeDetectorRef])],function(t,e){var n=e.component,r=t(e,2,0,n.tree.isNodeExpanded()?"block":"none");t(e,1,0,r),t(e,4,0,a["\u0275unv"](e,4,0,a["\u0275nov"](e,5).transform(n.tree.childrenAsync)))},null)}function A(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"tree-internal",[],null,null,null,L,m)),a["\u0275did"](1,4964352,null,0,d.TreeInternalComponent,[o.NodeMenuService,f.TreeService,a.ElementRef],{tree:[0,"tree"],settings:[1,"settings"],template:[2,"template"]},null)],function(t,e){var n=e.component;t(e,1,0,e.context.$implicit,n.settings,n.template)},null)}function D(t){return a["\u0275vid"](0,[(t()(),a["\u0275and"](16777216,null,null,2,null,A)),a["\u0275did"](1,278528,null,0,r.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),a["\u0275pid"](131072,r.AsyncPipe,[a.ChangeDetectorRef]),(t()(),a["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,1,0,a["\u0275unv"](e,1,0,a["\u0275nov"](e,2).transform(n.tree.childrenAsync)))},null)}function E(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,27,"ul",[["class","tree"]],null,null,null,null,null)),a["\u0275did"](1,278528,null,0,r.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a["\u0275pod"](2,{rootless:0}),(t()(),a["\u0275eld"](3,0,null,null,24,"li",[],null,null,null,null,null)),(t()(),a["\u0275eld"](4,0,null,null,15,"div",[["class","value-container"]],[[2,"selected",null]],[[null,"contextmenu"]],function(t,e,n){var a=!0;return"contextmenu"===e&&(a=!1!==t.component.showRightMenu(n)&&a),a},null,null)),a["\u0275did"](5,278528,null,0,r.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a["\u0275pod"](6,{rootless:0}),a["\u0275did"](7,212992,null,0,p.NodeDraggableDirective,[a.ElementRef,h.NodeDraggableService,a.Renderer2],{nodeDraggable:[0,"nodeDraggable"],tree:[1,"tree"]},null),(t()(),a["\u0275eld"](8,0,null,null,1,"div",[["class","folding"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.onSwitchFoldingType()&&a),a},null,null)),a["\u0275did"](9,278528,null,0,r.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,y)),a["\u0275did"](11,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,w)),a["\u0275did"](13,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,S)),a["\u0275did"](15,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,O)),a["\u0275did"](17,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,I)),a["\u0275did"](19,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,C)),a["\u0275did"](21,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,k)),a["\u0275did"](23,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,R)),a["\u0275did"](25,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,D)),a["\u0275did"](27,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.isRootHidden());t(e,1,0,"tree",a);var r=t(e,6,0,n.isRootHidden());t(e,5,0,"value-container",r),t(e,7,0,n.nodeElementRef,n.tree),t(e,9,0,"folding",n.tree.foldingCssClass),t(e,11,0,n.settings.showCheckboxes),t(e,13,0,!n.shouldShowInputForTreeValue()),t(e,15,0,n.shouldShowInputForTreeValue()),t(e,17,0,n.tree.hasLeftMenu()),t(e,19,0,n.tree.hasLeftMenu()&&n.isLeftMenuVisible&&!n.hasCustomMenu()),t(e,21,0,n.isRightMenuVisible&&!n.hasCustomMenu()),t(e,23,0,n.hasCustomMenu()&&(n.isRightMenuVisible||n.isLeftMenuVisible)),t(e,25,0,n.tree.keepNodesInDOM()),t(e,27,0,n.tree.isNodeExpanded()&&!n.tree.keepNodesInDOM())},function(t,e){t(e,4,0,e.component.isSelected)})}function L(t){return a["\u0275vid"](0,[a["\u0275pid"](0,g.SafeHtmlPipe,[b.DomSanitizer]),a["\u0275qud"](671088640,1,{checkboxElementRef:0}),(t()(),a["\u0275and"](16777216,null,null,1,null,E)),a["\u0275did"](3,16384,null,0,r.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,3,0,e.component.tree)},null)}n("xtUU"),n.d(e,"a",function(){return P}),n.d(e,"b",function(){return M});var P=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function M(t){return a["\u0275vid"](0,[a["\u0275qud"](402653184,1,{rootComponent:0}),(t()(),a["\u0275eld"](1,0,null,null,1,"tree-internal",[],null,null,null,L,m)),a["\u0275did"](2,4964352,[[1,4],["rootComponent",4]],0,d.TreeInternalComponent,[o.NodeMenuService,f.TreeService,a.ElementRef],{tree:[0,"tree"],settings:[1,"settings"],template:[2,"template"]},null)],function(t,e){var n=e.component;t(e,2,0,n.tree,n.settings,n.template)},null)}},nyYc:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("fr",{months:"janvier_f\xe9vrier_mars_avril_mai_juin_juillet_ao\xfbt_septembre_octobre_novembre_d\xe9cembre".split("_"),monthsShort:"janv._f\xe9vr._mars_avr._mai_juin_juil._ao\xfbt_sept._oct._nov._d\xe9c.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd\u2019hui \xe0] LT",nextDay:"[Demain \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[Hier \xe0] LT",lastWeek:"dddd [dernier \xe0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|)/,ordinal:function(t,e){switch(e){case"D":return t+(1===t?"er":"");default:case"M":case"Q":case"DDD":case"d":return t+(1===t?"er":"e");case"w":case"W":return t+(1===t?"re":"e")}},week:{dow:1,doy:4}})}()},o1bE:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("ar-dz",{months:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),monthsShort:"\u062c\u0627\u0646\u0641\u064a_\u0641\u064a\u0641\u0631\u064a_\u0645\u0627\u0631\u0633_\u0623\u0641\u0631\u064a\u0644_\u0645\u0627\u064a_\u062c\u0648\u0627\u0646_\u062c\u0648\u064a\u0644\u064a\u0629_\u0623\u0648\u062a_\u0633\u0628\u062a\u0645\u0628\u0631_\u0623\u0643\u062a\u0648\u0628\u0631_\u0646\u0648\u0641\u0645\u0628\u0631_\u062f\u064a\u0633\u0645\u0628\u0631".split("_"),weekdays:"\u0627\u0644\u0623\u062d\u062f_\u0627\u0644\u0625\u062b\u0646\u064a\u0646_\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621_\u0627\u0644\u062e\u0645\u064a\u0633_\u0627\u0644\u062c\u0645\u0639\u0629_\u0627\u0644\u0633\u0628\u062a".split("_"),weekdaysShort:"\u0627\u062d\u062f_\u0627\u062b\u0646\u064a\u0646_\u062b\u0644\u0627\u062b\u0627\u0621_\u0627\u0631\u0628\u0639\u0627\u0621_\u062e\u0645\u064a\u0633_\u062c\u0645\u0639\u0629_\u0633\u0628\u062a".split("_"),weekdaysMin:"\u0623\u062d_\u0625\u062b_\u062b\u0644\u0627_\u0623\u0631_\u062e\u0645_\u062c\u0645_\u0633\u0628".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u0627\u0644\u064a\u0648\u0645 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextDay:"[\u063a\u062f\u0627 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",nextWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastDay:"[\u0623\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",lastWeek:"dddd [\u0639\u0644\u0649 \u0627\u0644\u0633\u0627\u0639\u0629] LT",sameElse:"L"},relativeTime:{future:"\u0641\u064a %s",past:"\u0645\u0646\u0630 %s",s:"\u062b\u0648\u0627\u0646",ss:"%d \u062b\u0627\u0646\u064a\u0629",m:"\u062f\u0642\u064a\u0642\u0629",mm:"%d \u062f\u0642\u0627\u0626\u0642",h:"\u0633\u0627\u0639\u0629",hh:"%d \u0633\u0627\u0639\u0627\u062a",d:"\u064a\u0648\u0645",dd:"%d \u0623\u064a\u0627\u0645",M:"\u0634\u0647\u0631",MM:"%d \u0623\u0634\u0647\u0631",y:"\u0633\u0646\u0629",yy:"%d \u0633\u0646\u0648\u0627\u062a"},week:{dow:0,doy:4}})}()},"o4+5":function(t,e,n){"use strict";n.d(e,"a",function(){return a}),n("aXbf");var a=function(){function t(t){this.formatter=t}return t.prototype.transform=function(t){return this.formatter.format_number(t,1e3,["","k","M","G","T","P","E","Z","Y"])},t}()},obpP:function(t,e){t.exports='\n \n \n \n Toggle navigation\n Activer/D\xe9sactiver la navigation\n \n \n Dashboard\n Tableau de bord\n \n \n Cluster\n Grappe\n \n \n Hosts\n Serveurs\n \n \n Monitors\n Moniteurs\n \n \n OSDs\n OSD\n \n \n Configuration\n Configuration\n \n \n CRUSH map\n Carte CRUSH\n \n \n Manager modules\n Modules Manager\n \n \n Logs\n Journaux\n \n \n Alerts\n Alertes\n \n \n Silences\n Silences\n \n \n Pools\n R\xe9serves\n \n \n Block\n Bloc\n \n \n Images\n Images\n \n \n Mirroring\n Mise en miroir\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n Syst\xe8mes de fichiers\n \n \n Object Gateway\n Object Gateway\n \n \n Daemons\n Daemons\n \n \n Users\n Utilisateurs\n \n \n Buckets\n Compartiments\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n R\xe9cup\xe9ration des donn\xe9es\n pour\n \n \n . Veuillez patienter...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Affichage des donn\xe9es\n pr\xe9c\xe9demment mises en cache\n pour \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Impossible de charger les donn\xe9es\n pour\n \n \n .\n Veuillez v\xe9rifier l\'\xe9tat de sant\xe9 de la grappe.\n \n \n \n Back\n Retour\n \n \n Select a Language\n S\xe9lectionner une langue\n \n \n Loading panel data...\n Chargement des donn\xe9es du panneau...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n Veuillez consulter la\n documentation\n relative \xe0\n la configuration et \xe0 l\'activation de la fonctionnalit\xe9 de surveillance.\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Le tableau de bord Grafana n\'existe pas. Veuillez consulter\n la \n documentation\n relative \xe0\n l\'ajout de tableaux de bord \xe0 Grafana.\n \n \n \n Grafana Time Picker\n S\xe9lecteur d\'heure Grafana\n \n \n Reset Settings\n R\xe9initialiser les param\xe8tres\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n \xc9chec du chargement des donn\xe9es.\n \n \n selected\n s\xe9lectionn\xe9(e)(s)\n X selected\n \n \n found\n trouv\xe9(e)(s)\n X found\n \n \n total\n total\n X total\n \n \n Edit\n Modifier\n \n \n Name\n Nom\n \n \n Description\n Description\n \n \n Long description\n Description longue\n \n \n Default\n Valeur par d\xe9faut\n \n \n Daemon default\n Valeur par d\xe9faut du daemon\n \n \n Services\n Services\n \n \n Values\n Valeurs\n \n \n The entered value is too high! It must not be greater than \n .\n \n La valeur entr\xe9e est trop \xe9lev\xe9e ! Elle ne peut pas \xeatre sup\xe9rieure \xe0 \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n La valeur entr\xe9e est trop faible ! Elle ne peut pas \xeatre inf\xe9rieure \xe0 \n .\n \n \n \n Save\n Sauvegarder\n \n \n CRUSH map viewer\n Visionneuse de carte CRUSH\n \n \n Hosts List\n Liste d\'h\xf4tes\n \n \n Overall Performance\n Performance globale\n \n \n No entries found\n Aucune entr\xe9e trouv\xe9e\n \n \n Cluster Logs\n Journaux de grappes\n \n \n Audit Logs\n Journaux d\'audit\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n Chargement de la configuration...\n \n \n The configuration could not be loaded.\n La configuration n\'a pas pu \xeatre charg\xe9e.\n \n \n Edit Manager module\n Modifier le module Manager\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n La valeur entr\xe9e n\'est pas un UUID valide, par exemple : 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \n \n The entered value needs to be a valid IP address.\n La valeur entr\xe9e doit \xeatre une adresse IP valide.\n \n \n This field is required.\n Ce champs est requis.\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n La valeur entr\xe9e est trop \xe9lev\xe9e ! Elle doit \xeatre inf\xe9rieure ou \xe9gale \xe0 \n .\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n La valeur entr\xe9e est trop faible ! Elle doit \xeatre sup\xe9rieure ou \xe9gale \xe0 \n .\n \n \n \n The entered value needs to be a number.\n La valeur entr\xe9e doit \xeatre un nombre.\n \n \n The entered value needs to be a number or decimal.\n La valeur entr\xe9e doit \xeatre un nombre ou une valeur d\xe9cimale.\n \n \n Update\n Mise \xe0 jour\n \n \n Status\n Statut\n \n \n Cluster ID\n ID de grappe\n \n \n monmap modified\n monmap modifi\xe9\n \n \n monmap epoch\n monmap epoch\n \n \n quorum con\n quorum con\n \n \n quorum mon\n quorum mon\n \n \n required con\n required con\n \n \n required mon\n required mon\n \n \n In Quorum\n Dans le quorum\n \n \n Not In Quorum\n Hors quorum\n \n \n Cancel\n Annuler\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n Voulez-vous vraiment \n l\'\xe9l\xe9ment s\xe9lectionn\xe9 \n ?\n \n \n \n Yes, I am sure.\n Oui.\n \n \n Cluster-wide OSD Flags\n Drapeaux OSD \xe0 l\'\xe9chelle de la grappe\n \n \n Submit\n Soumettre\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n Avanc\xe9...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n Priorit\xe9 de r\xe9cup\xe9ration des OSD\n \n \n Priority\n Priorit\xe9\n \n \n Customize priority values\n Personnaliser les valeurs de priorit\xe9\n \n \n This field is required!\n Ce champ est obligatoire !\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n La valeur entr\xe9e est trop \xe9lev\xe9e ! Elle ne peut pas \xeatre sup\xe9rieure \xe0 \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n La valeur entr\xe9e est trop faible ! Elle ne peut pas \xeatre inf\xe9rieure \xe0 \n .\n \n \n \n Reweight OSD\n R\xe9\xe9valuer l\'OSD\n \n \n The value needs to be between 0 and 1.\n La valeur doit \xeatre comprise entre 0 et 1.\n \n \n Reweight\n R\xe9\xe9valuer\n \n \n OSDs \n Scrub\n \n Nettoyage des \n OSD\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {Profondeur } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n Vous \xeates sur le point d\'appliquer un nettoyage \n \n \xe0 l\'OSD \n \n \n .\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {profondeur } }\n \n \n OSDs List\n Liste des OSD\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n L\'\n OSD \n \n sera marqu\xe9\n \n \n si vous continuez.\n \n \n \n The OSD is not safe to destroy!\n L\'OSD ne peut pas \xeatre d\xe9truit de fa\xe7on s\xe9curis\xe9e !\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \n L\'OSD \n \n sera\n \n \n si vous continuez.\n \n \n \n Details\n D\xe9tails\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n Valeur\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n Fermer\n \n \n Delete\n Supprimer\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n Sant\xe9\n \n \n Statistics\n Statistiques\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n Veuillez consulter la \n documentation\n \n relative \xe0 la configuration et \xe0 l\'activation de la fonctionnalit\xe9 de gestion du NFS Ganesha.\n \n \n \n Clients\n Clients\n \n \n Any client can access\n Acc\xe8s possible par tous les clients\n \n \n Addresses\n Adresses\n \n \n Required field\n Champ obligatoire\n \n \n Must contain one or more comma-separated values\n Doit contenir une ou plusieurs valeurs s\xe9par\xe9es par une virgule\n \n \n For example:\n Par exemple :\n \n \n Access Type\n Type d\'acc\xe8s\n \n \n Squash\n Squash\n \n \n Add clients\n Ajouter des clients\n \n \n Loading...\n Chargement...\n \n \n -- No cluster available --\n -- Aucune grappe disponible --\n \n \n -- Select the cluster --\n -- S\xe9lectionner la grappe --\n \n \n Add daemon\n Ajouter un daemon\n \n \n Storage Backend\n Backend de stockage\n \n \n -- No data pools available --\n -- Aucune r\xe9serve de donn\xe9es disponible --\n \n \n -- Select the storage backend --\n -- S\xe9lectionner le backend de stockage --\n \n \n Object Gateway User\n Utilisateur Object Gateway\n \n \n -- No users available --\n -- Aucun utilisateur disponible --\n \n \n -- Select the object gateway user --\n -- S\xe9lectionner l\'utilisateur Object Gateway --\n \n \n CephFS User ID\n ID utilisateur CephFS\n \n \n -- No clients available --\n -- Aucun client disponible --\n \n \n -- Select the cephx client --\n -- S\xe9lectionner le client cephx --\n \n \n CephFS Name\n Nom CephFS\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n Libell\xe9 de s\xe9curit\xe9\n \n \n Enable security label\n Activer le libell\xe9 de s\xe9curit\xe9\n \n \n CephFS Path\n Chemin CephFS\n \n \n Path need to start with a \'/\' and can be followed by a word\n Le chemin doit commencer par \'/\' et peut \xeatre suivi d\'un mot\n \n \n New directory will be created\n Un nouveau r\xe9pertoire sera cr\xe9\xe9\n \n \n Path\n Chemin\n \n \n Path can only be a single \'/\' or a word\n Le chemin peut \xeatre constitu\xe9 d\'un seul \'/\' ou d\'un seul mot\n \n \n New bucket will be created\n Un compartiment sera cr\xe9\xe9\n \n \n NFS Protocol\n Protocole NFS\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n Balise NFS\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n Autre chemin d\'acc\xe8s aux montages \n NFS v3\n (doit commencer par /).\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n Les clients ne peuvent pas monter de sous-r\xe9pertoires (si la balise = foo, le client ne peut pas monter foo/baz).\n \n \n By using different Tag options, the same Path may be exported multiple times.\n En utilisant diff\xe9rentes options de balise, il est possible d\'exporter plusieurs fois le m\xeame chemin.\n \n \n Pseudo\n Pseudo\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n Position occup\xe9e par cet export \n NFS v4\n \n dans le \n syst\xe8me de fichiers Pseudo\n (doit \xeatre unique).\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n En utilisant diff\xe9rentes options de pseudo, il est possible d\'exporter exporter plusieurs fois le m\xeame chemin.\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- Aucun type d\'acc\xe8s disponible --\n \n \n -- Select the access type --\n -- S\xe9lectionner le type d\'acc\xe8s --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- Aucun squash disponible --\n \n \n --Select what kind of user id squashing is performed --\n -- S\xe9lectionnez le type de squash d\'ID utilisateur qui est effectu\xe9 --\n \n \n Transport Protocol\n Protocole de transport\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Bienvenue dans Ceph !\n The welcome message on the login page\n \n \n Username is required\n Nom d\'utilisateur requis\n \n \n Password is required\n Mot de passe requis\n \n \n Login\n Connexion\n \n \n Sorry, the user does not exist in Ceph.\n D\xe9sol\xe9, l\'utilisateur n\'existe pas dans Ceph.\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n Retournez \xe0 la \n page de connexion\n . Vous serez d\xe9connect\xe9 du fournisseur d\'identit\xe9 lorsque vous tenterez de vous reconnecter.\n \n \n \n Forbidden\n Interdit\n \n \n Sorry, you are not allowed to see what you were looking for.\n D\xe9sol\xe9, vous n\'\xeates pas autoris\xe9 \xe0 voir ce que vous cherchez.\n \n \n Sorry, we could not find what you were looking for\n D\xe9sol\xe9s, nous ne parvenons pas \xe0 trouver ce que vous cherchez.\n \n \n Remove all\n Tout supprimer\n \n \n Recent Notifications\n Notifications r\xe9centes\n \n \n There are no background tasks.\n Il n\'y a aucune t\xe2che en arri\xe8re-plan.\n \n \n Background Tasks\n T\xe2ches en arri\xe8re-plan\n \n \n Help\n Aide\n \n \n Documentation\n Documentation\n \n \n API\n API\n \n \n About\n \xc0 propos de\n \n \n Dashboard Settings\n Param\xe8tres du tableau de bord\n \n \n User management\n Gestion des utilisateurs\n \n \n Logged in user\n Utilisateur connect\xe9\n \n \n Signed in as\n \n \n \n \n Connect\xe9 en tant que\n \n \n \n \n \n \n Sign out\n Se d\xe9connecter\n \n \n Name...\n Nom...\n \n \n The chosen name is already in use.\n Le nom s\xe9lectionn\xe9 est d\xe9j\xe0 en cours d\'utilisation.\n \n \n Description...\n Description...\n \n \n Permissions\n Autorisations\n \n \n Roles\n R\xf4les\n \n \n Username\n Nom d\'utilisateur\n \n \n Password\n Mot de passe\n \n \n Confirm password\n Confirmer le mot de passe\n \n \n Password confirmation doesn\'t match the password.\n Le mot de passe de confirmation ne correspond pas au mot de passe.\n \n \n Full name\n Nom complet\n \n \n Email\n Adresse \xe9lectronique\n \n \n Invalid email.\n L\'adresse \xe9lectronique n\'est pas valide.\n \n \n You are about to remove "user read / update" permissions from your own user.\n Vous \xeates sur le point de supprimer les autorisations "lecture/mise \xe0 jour utilisateur" de votre propre utilisateur.\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n Si vous continuez, vous ne serez plus en mesure d\'ajouter ni de supprimer des r\xf4les pour n\'importe quel utilisateur.\n \n \n Are you sure you want to continue?\n Voulez-vous vraiment continuer ?\n \n \n Performance counters not available\n Compteurs de performance non disponibles\n \n \n Attributes (OSD map)\n Attributs (carte OSD)\n \n \n Metadata not available\n M\xe9tadonn\xe9es non disponibles\n \n \n Metadata\n M\xe9tadonn\xe9es\n \n \n Performance counter\n Compteur de performance\n \n \n Histogram not available: \n \n \n Histogramme non disponible : \n \n \n \n \n Writes\n \xc9critures\n \n \n Reads\n Lectures\n \n \n Histogram\n Histogramme\n \n \n Performance Details\n D\xe9tails des performances\n \n \n Current values\n Valeurs actuelles\n \n \n Type\n Type\n \n \n Min\n Minimum\n \n \n Max\n Maximum\n \n \n Flags\n Drapeaux\n \n \n Source\n Source\n \n \n Level\n Niveau\n \n \n Can be updated at runtime (editable)\n Mise \xe0 jour possible lors de l\'ex\xe9cution (modifiable)\n \n \n Tags\n Balises\n \n \n Enum values\n Valeurs d\'\xe9num\xe9nation\n \n \n See also\n Voir aussi\n \n \n Cluster Status\n Statut de la grappe\n \n \n Manager Daemons\n Daemons du gestionnaire\n \n \n Object Gateways\n Passerelles d\'objet\n \n \n Metadata Servers\n Serveurs de m\xe9tadonn\xe9es\n \n \n iSCSI Gateways\n Passerelles iSCSI\n \n \n Client IOPS\n IOPS client\n \n \n Client Throughput\n D\xe9bit client\n \n \n Client Read/Write\n Lectures/\xc9critures client\n \n \n Recovery Throughput\n D\xe9bit de r\xe9cup\xe9ration\n \n \n Scrub\n Nettoyer\n \n \n Performance\n Performance\n \n \n Raw Capacity\n Capacit\xe9 brute\n \n \n Objects\n Objets\n \n \n PGs per OSD\n Groupes de placements par OSD\n \n \n PG Status\n Statut du groupe de placements\n \n \n Capacity\n Capacit\xe9\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n Consultez les \n journaux\n pour plus d\'informations.\n \n \n \n Ranks\n Rangs\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n Clients : \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n D\xe9placer une image vers la corbeille.\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n Pour d\xe9placer \n \n /\n \n vers la corbeille,\n cliquez sur \n D\xe9placer une image\n . Vous pouvez \xe9galement s\xe9lectionner une date d\'expiration.\n \n \n \n Protection expires at\n La protection expire le \n \n \n NOT PROTECTED\n NON PROT\xc9G\xc9\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n Format de date incorrect. Veuillez utiliser "AAAA-MM-JJ HH:mm:ss"\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n La protection a d\xe9j\xe0 expir\xe9. Veuillez s\xe9lectionner une date ult\xe9rieure ou laisser le champ vide.\n \n \n Move Image\n D\xe9placer une image\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n Pr\xe9sentation\n \n \n Targets\n Cibles\n \n \n Discovery Authentication\n Authentification de la d\xe9couverte\n \n \n User\n Utilisateur\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Les noms d\'utilisateur doivent comporter entre 8 et 64 caract\xe8res et\n ne peuvent contenir que des lettres et les caract\xe8res \'.\', \'@\', \'-\', \'_\' ou \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n Utilisateur commun\n \n \n Mutual Password\n Mot de passe commun\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n Veuillez consulter la \n documentation\n \nrelative \xe0 la configuration et \xe0 l\'activation de la fonctionnalit\xe9 de gestion des cibles iSCSI.\n \n \n \n Available information:\n Informations disponibles :\n \n \n iSCSI Targets not available\n Cibles iSCSI non disponibles\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n Disponible uniquement pour les images RBD pour lesquelles \n fast-diff\n est activ\xe9\n \n \n \n Pool\n R\xe9serve\n \n \n Data Pool\n R\xe9serve de donn\xe9es\n \n \n Created\n Cr\xe9\xe9\n \n \n Size\n Taille\n \n \n Object size\n Taille de l\'objet\n \n \n Features\n Fonctionnalit\xe9s\n \n \n Provisioned\n Provisionn\xe9\n \n \n N/A\n N/A\n \n \n Total provisioned\n Provisionnement total\n \n \n Striping unit\n Unit\xe9 de segmentation\n \n \n Striping count\n Nombre de segmentations\n \n \n Parent\n Parent\n \n \n Block name prefix\n Pr\xe9fixe du nom de bloc\n \n \n Order\n Tri\n \n \n Snapshots\n Instantan\xe9s\n \n \n Image\n Image\n \n \n This setting overrides the global value\n Ce param\xe8tre remplace la valeur globale\n \n \n Global\n Global\n \n \n This is the global value. No value for this option has been set for this image.\n Il s\'agit de la valeur globale. Aucune valeur de cette option n\'a \xe9t\xe9 d\xe9finie pour cette image.\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n Les caract\xe8res \'/\' et \'@\' ne sont pas autoris\xe9s.\n \n \n -- No rbd pools available --\n -- Aucune r\xe9serve RBD disponible --\n \n \n -- Select a pool --\n -- S\xe9lectionner une r\xe9serve --\n \n \n Use a dedicated data pool\n Utiliser une r\xe9serve de donn\xe9es d\xe9di\xe9e\n \n \n Data pool\n R\xe9serve de donn\xe9es\n \n \n Dedicated pool that stores the object-data of the RBD.\n R\xe9serve d\xe9di\xe9e qui stocke les donn\xe9es objet du RBD.\n \n \n e.g., 10GiB\n par exemple, 10 Gio\n \n \n You have to increase the size.\n Vous devez augmenter la taille.\n \n \n Advanced\n Avanc\xe9\n \n \n Striping\n Segmentation\n \n \n Stripe unit\n Unit\xe9 de segmentation\n \n \n -- Select stripe unit --\n -- S\xe9lectionner une unit\xe9 de segmentation --\n \n \n This field is required because stripe count is defined!\n Ce champ est obligatoire, car le nombre de segments est d\xe9fini.\n \n \n Stripe unit is greater than object size.\n L\'unit\xe9 de segmentation est sup\xe9rieure \xe0 la taille de l\'objet.\n \n \n Stripe count\n Nombre de segments\n \n \n This field is required because stripe unit is defined!\n Ce champ est obligatoire, car l\'unit\xe9 de segmentation est d\xe9finie.\n \n \n Stripe count must be greater than 0.\n Le nombre de segments doit \xeatre sup\xe9rieur \xe0 0.\n \n \n \n RBD Snapshot\n \n \n instantan\xe9 RDB \n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Renommer} other {Cr\xe9er} }\n \n \n \n Snapshot\n \n \n instantan\xe9\n \n \n \n PROTECTED\n PROT\xc9G\xc9\n \n \n UNPROTECTED\n NON PROT\xc9G\xc9\n \n \n You are about to rollback\n Vous \xeates sur le point de revenir \xe0 l\'\xe9tat initial\n \n \n Purge Trash\n Vider la corbeille\n \n \n To purge, select one or All images and click\n Pour purger, s\xe9lectionner une image ou toutes, puis cliquez sur\n \n \n Pool:\n R\xe9serve :\n \n \n Pool name...\n Nom de la r\xe9serve...\n \n \n All\n Tout\n \n \n Restore Image\n Restaurer l\'image\n \n \n To restore\n Pour restaurer\n \n \n type the image\'s new name and click\n saisissez le nouveau nom de l\'image, puis cliquez sur\n \n \n New Name\n Nouveau nom\n \n \n Expired at\n Expiration le \n \n \n Protected until\n Protection jusqu\'au\n \n \n This image is protected until \n .\n \n Cette image est prot\xe9g\xe9e jusqu\'au \n .\n \n \n \n Trash\n Corbeille\n \n \n iSCSI Topology\n Topologie iSCSI\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n Il n\'est g\xe9n\xe9ralement pas n\xe9cessaire de modifier ces param\xe8tres par d\xe9faut.\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n Param\xe8tres\n \n \n Backstore\n Backstore\n \n \n Confirm\n Confirmer\n \n \n Advanced Settings\n Param\xe8tres avanc\xe9s\n \n \n Target IQN\n IQN cible\n \n \n IQN has wrong pattern.\n Mod\xe8le IQN incorrect.\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n Un IQN est associ\xe9 \xe0 la notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n Par exemple : iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n Plus d\'informations\n \n \n This target has modified advanced settings.\n Des param\xe8tres avanc\xe9s de cette cible ont \xe9t\xe9 modifi\xe9s.\n \n \n Portals\n Portails\n \n \n At least \n gateways are required.\n \n Au moins \n passerelles sont n\xe9cessaires.\n \n \n \n Add portal\n Ajouter un portail\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n Des param\xe8tres avanc\xe9s de cette image ont \xe9t\xe9 modifi\xe9s.\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n Ajouter une image\n \n \n ACL authentication\n Authentification ACL\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n Initiateurs\n \n \n Initiator\n Initiateur\n \n \n Client IQN\n IQN client\n \n \n Initiator IQN needs to be unique.\n L\'IQN de l\'initiateur doit \xeatre unique.\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Les noms d\'utilisateur doivent comporter entre 8 et 64 caract\xe8res et\n ne peuvent contenir que des lettres et les caract\xe8res \'.\', \'@\', \'-\', \'_\' ou \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n L\'initiateur appartient \xe0 un groupe dans lequel les images seront configur\xe9es.\n \n \n No items added.\n Aucun \xe9l\xe9ment ajout\xe9.\n \n \n Add initiator\n Ajouter un initiateur\n \n \n Groups\n Groupes\n \n \n Group\n Groupe\n \n \n Add group\n Ajouter un groupe\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n Configuration RBD\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n Supprimez la valeur de configuration locale. La valeur de configuration parent sera h\xe9rit\xe9e et utilis\xe9e \xe0 la place.\n \n \n The mininum value is 0\n La valeur minimale est 0.\n \n \n Issues\n Probl\xe8mes\n \n \n Syncing\n Synchronisation en cours\n \n \n Ready\n Pr\xeat\n \n \n Edit pool mirror mode\n Modifier le mode de mise en miroir de la r\xe9serve\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n Pour modifier le mode de mise en miroir de la r\xe9serve\xa0\n \n \n , s\xe9lectionnez un nouveau mode dans la liste, puis cliquez sur \n Mettre \xe0 jour\n .\n \n \n \n Mode\n Mode\n \n \n Peer clusters must be removed prior to disabling mirror.\n Les grappes d\'homologues doivent \xeatre supprim\xe9es avant de d\xe9sactiver la mise en miroir.\n \n \n \n \n pool mirror peer\n \n \n \n homologue de mise en miroir de la r\xe9serve\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Modifier} other {Ajouter} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n les attributs\n de mise en miroir de la r\xe9serve \n \n \n et cliquez sur \n Soumettre\n .\n \n \n \n Cluster Name\n Nom de grappe\n \n \n The cluster name is not valid.\n Le nom de grappe n\'est pas valide.\n \n \n CephX ID\n ID CephX\n \n \n CephX ID...\n ID CephX\n \n \n The CephX ID is not valid.\n L\'ID CephX n\'est pas valide.\n \n \n Monitor Addresses\n Adresses du moniteur\n \n \n Comma-delimited addresses...\n Adresses s\xe9par\xe9es par une virgule...\n \n \n The monitory address is not valid.\n L\'adresse du moniteur n\'est pas valide.\n \n \n CephX Key\n Clef CephX\n \n \n Base64-encoded key...\n Clef Base64...\n \n \n CephX key must be base64 encoded.\n La clef CephX doit \xeatre cod\xe9e en base64.\n \n \n Pools List\n Liste des r\xe9serves\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n Le nom doit \xeatre exclusivement compos\xe9 de caract\xe8res alphanum\xe9riques, de tirets et de traits de soulignement.\n \n \n The chosen erasure code profile name is already in use.\n Le nom de profil du code d\'effacement s\xe9lectionn\xe9 est d\xe9j\xe0 utilis\xe9.\n \n \n Plugin\n Plug-in\n \n \n Data chunks (k)\n Blocs de donn\xe9es (k)\n \n \n Must be equal to or greater than 2.\n Doit \xeatre \xe9gal ou sup\xe9rieur \xe0 2.\n \n \n Coding chunks (m)\n Blocs de codage (m)\n \n \n Must be equal to or greater than 1.\n Doit \xeatre \xe9gal ou sup\xe9rieur \xe0 1.\n \n \n Durability estimator (c)\n Estimateur de durabilit\xe9 (c)\n \n \n Locality (l)\n Localit\xe9 (l)\n \n \n Crush failure domain\n Domaine de d\xe9faillance Crush\n \n \n Crush Locality\n Localit\xe9 Crush\n \n \n None\n Aucun\n \n \n Technique\n Technique\n \n \n Packetsize\n Taille de paquet\n \n \n Crush root\n Racine Crush\n \n \n Crush device class\n Classe de p\xe9riph\xe9rique Crush\n \n \n any\n tout\n \n \n Directory\n R\xe9pertoire\n \n \n The chosen Ceph pool name is already in use.\n Le nom de r\xe9serve Ceph s\xe9lectionn\xe9 est d\xe9j\xe0 utilis\xe9.\n \n \n Pool type\n Type de r\xe9serve\n \n \n -- Select a pool type --\n -- S\xe9lectionner un type de r\xe9serve --\n \n \n Placement groups\n Groupes de placements\n \n \n At least one placement group is needed!\n Au moins un groupe de placements est n\xe9cessaire.\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n Votre grappe ne peut pas g\xe9rer autant de groupes de placements. Veuillez recalculer le nombre de groupes de placements n\xe9cessaires.\n \n \n Calculation help\n Aide au calcul\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n Les param\xe8tres actuels des groupes de placements ont \xe9t\xe9 calcul\xe9s pour vous.\nV\xe9rifiez que les valeurs correspondent \xe0 vos besoins avant de les soumettre.\n \n \n Crush ruleset\n Jeu de r\xe8gles Crush\n \n \n -- Select a crush rule --\n -- S\xe9lectionner une r\xe8gle crush --\n \n \n Crush rule\n R\xe8gle Crush\n \n \n Crush steps\n \xc9tapes Crush\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n La r\xe8gle ne peut pas \xeatre utilis\xe9e dans la grappe active, car celle-ci\n comporte un nombre d\'OSD inf\xe9rieur au nombre d\'OSD minimum requis par cette r\xe8gle.\n \n \n Replicated size\n Taille de r\xe9plication\n \n \n Minimum: \n \n \n Minimum : \n \n \n \n \n Maximum: \n \n \n Maximum : \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n La taille sp\xe9cifi\xe9e est en dehors de la plage. Une valeur comprise entre\n et \n est valide.\n \n \n \n Erasure code profile\n Profil de code d\'effacement\n \n \n -- No erasure code profile available --\n -- Aucun profil de code d\'effacement n\'est disponible --\n \n \n -- Select an erasure code profile --\n -- S\xe9lectionner un profil de code d\'effacement --\n \n \n EC Overwrites\n \xc9crasements EC\n \n \n Applications\n Applications\n \n \n Compression\n Compression\n \n \n Algorithm\n Algorithme\n \n \n -- No erasure compression algorithm available --\n -- Aucun algorithme de compression d\'effacement n\'est disponible --\n \n \n Minimum blob size\n Taille de blob minimale\n \n \n e.g., 128KiB\n par ex. 128 Kio\n \n \n Value should be greater than 0\n La valeur doit \xeatre sup\xe9rieure \xe0 0\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n Taille de blob maximale\n \n \n e.g., 512KiB\n par ex., 512 Kio\n \n \n Value should be greater than the minimum blob size\n La valeur doit \xeatre sup\xe9rieure \xe0 la taille de blob minimale.\n \n \n Ratio\n Rapport\n \n \n Compression ratio\n Rapport de compression\n \n \n Value should be between 0.0 and 1.0\n La valeur doit se situer entre 0.0 et 1.0\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n Il n\'est pas possible de cr\xe9er une r\xe9serve RBD dont le nom contient \'/\'.\n \n \n Please change the name or remove \'rbd\' from the applications list.\n Modifiez le nom ou supprimez \'rbd\' de la liste des applications.\n \n \n Cache Tiers Details\n D\xe9tails des niveaux de mise en cache\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n Veuillez consulter la \n documentation\n \n relative \xe0 la configuration et \xe0 l\'activation de la fonctionnalit\xe9 de gestion Object Gateway.\n \n \n \n Daemons List\n Liste de daemons\n \n \n Performance Counters\n Compteurs de performance\n \n \n Loading bucket data...\n Chargement des donn\xe9es de compartiment...\n \n \n The bucket data could not be loaded.\n Les donn\xe9es du compartiment n\'ont pas pu \xeatre charg\xe9es.\n \n \n Id\n ID\n \n \n The value is not valid.\n La valeur n\'est pas valide.\n \n \n Owner\n Propri\xe9taire\n \n \n -- Select a user --\n -- S\xe9lectionner un utilisateur --\n \n \n ID\n ID\n \n \n Index type\n Type d\'index\n \n \n Placement rule\n R\xe8gle de placement\n \n \n Marker\n Marqueur\n \n \n Maximum marker\n Marqueur maximum\n \n \n Version\n Version\n \n \n Master version\n Version principale\n \n \n Modification time\n Date de modification\n \n \n Zonegroup\n Groupe de zones\n \n \n Bucket quota\n Quota de compartiments\n \n \n Enabled\n Activ\xe9\n \n \n Maximum size\n Taille maximale\n \n \n Unlimited\n Illimit\xe9\n \n \n Maximum objects\n Nombre maximal d\'objets\n \n \n -- Select a username --\n -- S\xe9lectionner un nom d\'utilisateur --\n \n \n Auto-generate key\n G\xe9n\xe9rer automatiquement la clef\n \n \n Access key\n Clef d\'acc\xe8s\n \n \n Secret key\n Clef secr\xe8te\n \n \n Email address\n Adresse \xe9lectronique\n \n \n Suspended\n Suspendu\n \n \n System\n Syst\xe8me\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {Non} 1 {Oui} }\n \n \n Maximum buckets\n Nombre maximal de compartiments\n \n \n Subusers\n Utilisateurs secondaires\n \n \n Capabilities\n Fonctionnalit\xe9s\n \n \n User quota\n Quota utilisateur\n \n \n Show\n Afficher\n \n \n Keys\n Clefs\n \n \n -- Select a type --\n -- S\xe9lectionner un type --\n \n \n Permission\n Autorisation\n \n \n -- Select a permission --\n -- S\xe9lectionner une autorisation --\n \n \n Subuser\n Utilisateur secondaire\n \n \n The chosen subuser ID is already in use.\n L\'ID d\'utilisateur secondaire s\xe9lectionn\xe9 est d\xe9j\xe0 utilis\xe9.\n \n \n read, write\n lire, \xe9crire\n \n \n full\n complet\n \n \n Swift key\n Cl\xe9 Swift\n \n \n Auto-generate secret\n G\xe9n\xe9rer automatiquement le secret\n \n \n Loading user data...\n Chargement des donn\xe9s utilisateur\u2026\n \n \n The user data could not be loaded.\n Les donn\xe9s utilisateur n\'ont pas pu \xeatre charg\xe9es.\n \n \n The chosen user ID is already in use.\n L\'ID utilisateur sp\xe9cifi\xe9 est d\xe9j\xe0 utilis\xe9.\n \n \n This is not a valid email address.\n Ceci n\'est pas une adresse \xe9lectronique valide.\n \n \n The chosen email address is already in use.\n L\'adresse \xe9lectronique sp\xe9cifi\xe9e est d\xe9j\xe0 utilis\xe9e.\n \n \n Max. buckets\n Nombre max. de compartiments\n \n \n The entered value must be >= 0.\n La valeur saisie doit \xeatre >= 0.\n \n \n S3 key\n Clef S3\n \n \n There are no subusers.\n Il n\'y a aucun utilisateur secondaire.\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n Il n\'y a pas de clefs.\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n Swift\n \n \n There are no capabilities.\n Il n\'y a aucune fonctionnalit\xe9.\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n Taille illimit\xe9e\n \n \n Max. size\n Taille max.\n \n \n Unlimited objects\n Objets illimit\xe9s\n \n \n Max. objects\n Nombre max. d\'objets\n \n \n Current\n Actuel\n \n \n Updated discovery authentication\n Authentification de la d\xe9couverte mise \xe0 jour\n \n \n There are no portals available.\n Il n\'y a aucun portail disponible.\n \n \n There are no images available.\n Il n\'y a aucune image disponible.\n \n \n There are no images available. Please make sure you add an image to the target.\n Il n\'y a aucune image disponible. Veillez \xe0 ajouter une image \xe0 la cible.\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n Il n\'y a aucun initiateur disponible. Veillez \xe0 ajouter un initiateur \xe0 la cible.\n \n \n target\n target\n \n \n Target\n Cible\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n \xc9tat\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n Octets de lecture\n \n \n Write Bytes\n Octets d\'\xe9criture\n \n \n Read Ops\n Op\xe9rations de lecture\n \n \n Write Ops\n Op\xe9rations d\'\xe9criture\n \n \n A/O Since\n A/O depuis\n \n \n Instance\n Instance\n \n \n Hostname\n Nom d\'h\xf4te\n \n \n Issue\n Probl\xe8me\n \n \n Progress\n Avancement\n \n \n Disabled\n D\xe9sactiv\xe9\n \n \n Edit Mode\n Mode d\'\xe9dition\n \n \n Add Peer\n Ajouter un homologue\n \n \n Edit Peer\n Modifier un homologue\n \n \n Delete Peer\n Supprimer un homologue\n \n \n Leader\n Leader\n \n \n # Local\n nb en local\n \n \n # Remote\n nb \xe0 distance\n \n \n mirror peer\n mettre en miroir l\'homologue\n \n \n Key\n Clef\n \n \n RBD\n RBD\n \n \n Deep flatten\n Aplatissement en profondeur\n \n \n Layering\n Superposition\n \n \n Exclusive lock\n Verrou exclusif\n \n \n Object map (requires exclusive-lock)\n Assignation d\'objet (n\xe9cessite exclusive-lock)\n \n \n Journaling (requires exclusive-lock)\n Journalisation (n\xe9cessite exclusive-lock)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n Retour \xe0 l\'\xe9tat initial de l\'instantan\xe9 RBD\n \n \n Rollback\n Revenir \xe0 l\'\xe9tat initial\n \n \n RBD snapshot\n Intantan\xe9 RBD\n \n \n Deleted At\n Supprim\xe9 le\n \n \n id\n ID\n \n \n type\n type\n \n \n state\n \xe9tat\n \n \n version\n version\n \n \n Host\n H\xf4te\n \n \n root\n racine\n \n \n Rank\n Rang\n \n \n Daemon\n Daemon\n \n \n Activity\n Activit\xe9\n \n \n Dentries\n Dentries\n \n \n Inodes\n Inodes\n \n \n Usage\n Utilisation\n \n \n Standby daemons\n Daemons en veille\n \n \n The value can be updated at runtime.\n La valeur peut \xeatre mise \xe0 jour au moment de l\'ex\xe9cution.\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n Les daemons/clients ne tirent pas cette valeur de\n\xa0 la base de donn\xe9es de configuration de Monitor. Nous n\'autorisons pas le r\xe9glage de cette option via \'ceph config\n\xa0 set ...\'. Cette option doit \xeatre configur\xe9e via ceph.conf ou via\n\xa0 la ligne de commande.\n \n \n Option takes effect only during daemon startup.\n L\'option ne prend effet qu\'au d\xe9marrage du daemon.\n \n \n Option only affects cluster creation.\n L\'option n\'affecte que la cr\xe9ation des grappes.\n \n \n Option only affects daemon creation.\n L\'option n\'affecte que la cr\xe9ation des daemons.\n \n \n Updated config option \n \n \n Option de configuration mise \xe0 jour \n \n \n \n \n Service\n Service\n \n \n Current value\n Valeur actuelle\n \n \n Editable\n Modifiable\n \n \n Updated options for module "\n ".\n \n Options mises \xe0 jour pour le module &quot;\n &quot;.\n \n \n \n Enable\n Activer\n \n \n Disable\n D\xe9sactiver\n \n \n Reconnecting, please wait ...\n Reconnexion en cours\u2026 Veuillez patienter.\n \n \n Public Address\n Adresse publique\n \n \n Open Sessions\n Sessions ouvertes\n \n \n No In\n Pas rentr\xe9s\n \n \n OSDs that were previously marked out will not be marked back in when they start\n Les OSD qui ont \xe9t\xe9 marqu\xe9s comme sortis ne seront pas marqu\xe9s comme rentr\xe9s \xe0 leur d\xe9marrage.\n \n \n No Out\n Pas sortis\n \n \n OSDs will not automatically be marked out after the configured interval\n Les OSD ne seront pas marqu\xe9s automatiquement comme sortis apr\xe8s l\'intervalle configur\xe9.\n \n \n No Up\n Pas d\xe9marr\xe9s\n \n \n OSDs are not allowed to start\n Les OSD ne sont pas autoris\xe9s \xe0 d\xe9marrer.\n \n \n No Down\n Pas arr\xeat\xe9s\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n Les rapports de d\xe9faillance des OSD sont ignor\xe9s, de sorte que les moniteurs ne marquent pas les OSD comme \xe9tant arr\xeat\xe9s.\n \n \n Pause\n Pause\n \n \n Pauses reads and writes\n Met en pause les lectures et \xe9critures\n \n \n No Scrub\n Pas de nettoyage\n \n \n Scrubbing is disabled\n Nettoyage d\xe9sactiv\xe9\n \n \n No Deep Scrub\n Pas de nettoyage en profondeur\n \n \n Deep Scrubbing is disabled\n Le nettoyage en profondeur est d\xe9sactiv\xe9\n \n \n No Backfill\n Pas de renvoi\n \n \n Backfilling of PGs is suspended\n Le renvoi des groupes de placements est suspendu\n \n \n No Recover\n Pas de r\xe9cup\xe9ration\n \n \n Recovery of PGs is suspended\n La r\xe9cup\xe9ration des groupes de placements est suspendue\n \n \n Bitwise Sort\n Tri au niveau du bit\n \n \n Use bitwise sort\n Utiliser le tri au niveau du bit\n \n \n Purged Snapdirs\n Variables snapdir purg\xe9es\n \n \n OSDs have converted snapsets\n Les OSD ont converti les variables snapset\n \n \n Recovery Deletes\n Suppressions des r\xe9cup\xe9rations\n \n \n Deletes performed during recovery instead of peering\n Suppressions effectu\xe9es pendant la restauration et non l\'homologation\n \n \n PG Log Hard Limit\n Limite stricte de journalisation des groupes de placements\n \n \n Puts a hard limit on pg log length\n Impose une limite stricte \xe0 la longueur du journal des groupes de placements\n \n \n Updated OSD Flags\n Drapeaux OSD mis \xe0 jour\n \n \n out\n sorti\n \n \n in\n rentr\xe9\n \n \n down\n arr\xeat\xe9\n \n \n Mark\n Marquer\n \n \n OSD lost\n OSD perdu\n \n \n marked lost\n marqu\xe9 comme perdu\n \n \n Purge\n Purger\n \n \n OSD\n OSD\n \n \n purged\n purg\xe9\n \n \n destroy\n d\xe9truire\n \n \n destroyed\n d\xe9truit\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n Groupes de placements\n \n \n Read bytes\n Octets de lecture\n \n \n Writes bytes\n Octets d\'\xe9criture\n \n \n Read ops\n Op\xe9rations de lecture\n \n \n Write ops\n Op\xe9rations d\'\xe9criture\n \n \n Mark OSD \n \n \n Marquer l\'OSD comme \n \n \n \n \n Mark \n \n \n Marquer comme \n \n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n Nbre max. de renvois\n \n \n Recovery Max Active\n Nombre maximum de r\xe9cup\xe9rations actives\n \n \n Recovery Max Single Start\n Nombre maximum de d\xe9marrages uniques de r\xe9cup\xe9rations\n \n \n Recovery Sleep\n Mise en veille de la r\xe9cup\xe9ration\n \n \n Custom\n Personnalis\xe9\n \n \n Updated OSD recovery speed priority "\n "\n \n Priorit\xe9 de la vitesse de r\xe9cup\xe9ration des OSD&quot;\n &quot; mise \xe0 jour\n \n \n \n \n was initialized in the following OSD: \n \n \n \n a \xe9t\xe9 initialis\xe9(e) sur l\'OSD suivant : \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n Travail\n \n \n Severity\n Gravit\xe9\n \n \n Started\n D\xe9marr\xe9\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n Mis \xe0 jour\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n Utilis\xe9\n \n \n Avail.\n Dispo.\n \n \n Clean\n Nettoy\xe9\n \n \n Working\n En cours\n \n \n Warning\n Avertissement\n \n \n Unknown\n Inconnu\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n op\xe9rationnel\n \n \n no filesystems\n aucun syst\xe8me de fichiers\n \n \n active\n actif\n \n \n standby\n veille\n \n \n n/a\n n/a\n \n \n active daemon\n daemon actif\n \n \n quorum\n quorum\n \n \n The NFS Ganesha service is not configured.\n Le service NFS Ganesha n\'est pas configur\xe9.\n \n \n Transport\n Transport\n \n \n CephFS User\n Utilisateur CephFS\n \n \n CephFS Filesystem\n Syst\xe8me de fichiers CephFS\n \n \n (inherited from global config)\n (h\xe9rit\xe9 de la configuration globale)\n \n \n inherited from global config\n h\xe9rit\xe9 de la configuration globale\n \n \n -- Select what kind of user id squashing is performed --\n -- S\xe9lectionner le type de squashing d\'ID utilisateur effectu\xe9 --\n \n \n There are no daemons available.\n Aucun daemon n\'est disponible.\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n Mode cache\n \n \n Min Evict Age\n \xc2ge \xe9vict min.\n \n \n Min Flush Age\n \xc2ge vidage min.\n \n \n Target Max Bytes\n Nombre max d\'octets cibles\n \n \n Target Max Objects\n Nombre max. d\'objets cibles\n \n \n No applications added\n Aucune application ajout\xe9e\n \n \n Applications limit reached\n Limite d\'applications atteinte\n \n \n A pool can only have up to four applications definitions.\n Une r\xe9serve peut avoir quatre d\xe9finitions d\'application maximum.\n \n \n Allowed characters \'_a-zA-Z0-9\'\n Caract\xe8re autoris\xe9s \'_a-zA-Z0-9\'\n \n \n Maximum length is 128 characters\n La longueur maximale est de 128 caract\xe8res.\n \n \n Filter or add applications\n Filtrer ou ajouter des applications\n \n \n Add application\n Ajouter une application\n \n \n pool\n pool\n \n \n erasure code profile\n profil de code d\'effacement\n \n \n Replica Size\n Taille de la r\xe9plique\n \n \n Last Change\n Dernier changement\n \n \n Erasure Coded Profile\n Profil de code d\'effacement\n \n \n Crush Ruleset\n Jeu de r\xe8gles Crush\n \n \n Write bytes\n Octets d\'\xe9criture\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n compartiment\n \n \n Updated Object Gateway bucket "\n "\n \n Compartiment Object Gateway &quot;\n &quot; mis \xe0 jour\n \n \n \n Created Object Gateway bucket "\n "\n \n Compartiment Object Gateway &quot;\n &quot; cr\xe9\xe9\n \n \n \n buckets\n compartiments\n \n \n capability\n capability\n \n \n user\n utilisateur\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n Utilisateur Object Gateway &quot;\n &quot; mis \xe0 jour\n \n \n \n Created Object Gateway user "\n "\n \n Utilisateur Object Gateway &quot;\n &quot; cr\xe9\xe9\n \n \n \n users\n utilisateurs\n \n \n Swift Key\n Swift Key\n \n \n Scope\n P\xe9rim\xe8tre\n \n \n Read\n Lecture\n \n \n Create\n Cr\xe9er\n \n \n role\n role\n \n \n Created role \'\n \'\n \n R\xf4le \'\n \' cr\xe9\xe9\n \n \n \n Updated role \'\n \'\n \n R\xf4le \'\n \' mis \xe0 jour\n \n \n \n System Role\n R\xf4le syst\xe8me\n \n \n Deleted role \'\n \'\n \n R\xf4le \'\n \' supprim\xe9\n \n \n \n Created user "\n "\n \n Utilisateur &quot;\n &quot; cr\xe9\xe9\n \n \n \n Update user\n Mettre \xe0 jour l\'utilisateur\n \n \n Continue\n Continuer\n \n \n You were automatically logged out because your roles have been changed.\n Vous avez \xe9t\xe9 automatiquement d\xe9connect\xe9, car vos r\xf4les ont chang\xe9.\n \n \n Updated user "\n "\n \n Utilisateur &quot;\n &quot; mis \xe0 jour\n \n \n \n Deleted user "\n "\n \n Utilisateur &quot;\n &quot; supprim\xe9\n \n \n \n Failed to delete user "\n "\n \n \xc9chec de la suppression de l\'utilisateur &quot;\n &quot;\n \n \n \n You are currently logged in as "\n ".\n \n Vous \xeates connect\xe9 en tant que &quot;\n &quot;.\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n Chaque objet est divis\xe9 en parties de blocs de donn\xe9es, chacune \xe9tant stock\xe9e sur un OSD diff\xe9rent.\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n Calculez des blocs de codage pour chaque objet et stockez-les sur diff\xe9rents OSD.\n Le nombre de blocs de codage correspond \xe9galement au nombre d\'OSD qui peuvent \xeatre arr\xeat\xe9s sans perdre de donn\xe9es.\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n Le plugin jerasure est le plugin le plus g\xe9n\xe9rique et le plus flexible,\n\xa0 c\'est aussi la valeur par d\xe9faut des r\xe9serves cod\xe9es \xe0 effacement Ceph.\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n La technique la plus flexible est reed_sol_van_van : il suffit de d\xe9finir k\n et m. La technique cauchy_good peut \xeatre plus rapide, mais vous devez choisir la taille du paquet\n avec pr\xe9caution. reed_sol_r6_op, liberation, blaum_roth et liber8tion sont des \xe9quivalents RAID6\n en ce sens qu\'ils ne peuvent \xeatre configur\xe9s qu\'avec m=2.\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n L\'encodage se fera sur des paquets de taille d\'octets.\n\xa0 Choisir la bonne taille de paquet est difficile.\n\xa0 La documentation de jerasure contient de nombreuses informations \xe0 ce sujet.\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n Avec le plugin jerasure, lorsqu\'un objet cod\xe9 \xe0 effacement est stock\xe9 sur\n plusieurs OSD, la r\xe9cup\xe9ration \xe0 la suite de la perte d\'un OSD n\xe9cessite la lecture de tous les autres.\n Par exemple, si jerasure est configur\xe9 avec k=8 et m=4, la perte d\'un OSD n\xe9cessite de lire\n les onze autres pour pouvoir effectuer une r\xe9paration.\n\n Le plugin de code d\'effacement lrc cr\xe9e des blocs de parit\xe9 locale pour permettre la r\xe9cup\xe9ration avec\n moins d\'OSD. Par exemple, si lrc est configur\xe9 avec k=8, m=4 et l=4,\n un bloc de parit\xe9 suppl\xe9mentaire est cr\xe9\xe9 pour chaque groupe de quatre OSD. Lorsqu\'un seul OSD est perdu, il peut \xeatre\n r\xe9cup\xe9r\xe9 avec seulement quatre OSD au lieu de onze.\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n Regroupez les blocs de donn\xe9es et de codage en ensembles de localit\xe9 de taille. Par exemple,\n pour k=4 et m=2, lorsque locality=3, deux groupes de trois sont cr\xe9\xe9s. Chaque ensemble peut\n \xeatre r\xe9cup\xe9r\xe9 sans lire les blocs d\'un autre jeu.\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n Type de compartiment Crush dans lequel chaque ensemble de blocs d\xe9fini\n par I sera stock\xe9. Par exemple, s\'il est r\xe9gl\xe9 sur rack, chaque groupe de blocs I sera\n plac\xe9 dans un rack diff\xe9rent. Il est utilis\xe9 pour cr\xe9er une \xe9tape de la r\xe8gle CRUSH telle que l\'\xe9tape de choix\n d\'un rack. S\'il n\'est pas d\xe9fini, aucun regroupement de ce type n\'est effectu\xe9.\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n Le plug-in isa encapsule la biblioth\xe8que ISA. Il ne fonctionne qu\'avec des processeurs Intel.\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n Le plugin ISA se pr\xe9sente sous deux formes Reed Solomon.\n Si reed_sol_van est d\xe9fini, il \xe9quivaut \xe0 Vandermonde. Si cauchy est configur\xe9, il \xe9quivaut \xe0 Cauchy.\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n Le plug-in shec encapsule la biblioth\xe8que SHEC multiple.\n Il permet \xe0 Ceph de r\xe9cup\xe9rer les donn\xe9es plus efficacement qu\'avec les codes Reed Solomon.\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n Nombre de blocs de parit\xe9, chacun incluant chaque bloc de donn\xe9es dans sa\n plage de calcul. Ce nombre est utilis\xe9 comme estimateur de durabilit\xe9. Par exemple, si c=2,\n 2 OSD peuvent \xeatre arr\xeat\xe9s sans perte de donn\xe9es.\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n Nom du compartiment crush utilis\xe9 pour la premi\xe8re \xe9tape de la r\xe8gle CRUSH.\n Par exemple, l\'\xe9tape de d\xe9finition des valeurs par d\xe9faut.\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n V\xe9rifiez qu\'il n\'existe pas deux blocs dans un compartiment avec le m\xeame domaine de\n d\xe9faillance. Par exemple, si le domaine de d\xe9faillance est un h\xf4te, deux blocs ne seront pas stock\xe9s sur le m\xeame\n h\xf4te. Cette option est utilis\xe9e pour cr\xe9er une \xe9tape de la r\xe8gle CRUSH telle que chooseleaf host.\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n Restreindre le placement aux p\xe9riph\xe9riques d\'une classe sp\xe9cifique\n (par exemple, ssd ou hdd), en utilisant les noms des classes de p\xe9riph\xe9riques crush dans la carte CRUSH.\n \n \n Set the directory name from which the erasure code plugin is loaded.\n D\xe9finissez le nom du r\xe9pertoire \xe0 partir duquel le plug-in de code d\'effacement est charg\xe9.\n \n \n Allows all operations\n Autoriser toutes les op\xe9rations\n \n \n Allows only operations that do not modify the server\n Autorise uniquement les op\xe9rations qui ne modifient pas le serveur\n \n \n Does not allow read or write operations, but allows any other operation\n N\'autorise pas les op\xe9rations de lecture ou d\'\xe9criture, mais toutes les autres.\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n N\'autorise pas la lecture, l\'\xe9criture ni aucune autre op\xe9ration modifiant les attributs d\'un fichier ou le contenu d\'un r\xe9pertoire.\n \n \n Allows no access at all\n N\'autorise aucun acc\xe8s\n \n \n -- Select the priority --\n -- S\xe9lectionner la priorit\xe9 --\n \n \n Low\n Faible\n \n \n High\n \xc9lev\xe9e\n \n \n Last 5 minutes\n Les 5 derni\xe8res minutes\n \n \n Last 15 minutes\n Les 15 derni\xe8res minutes\n \n \n Last 30 minutes\n Les 30 derni\xe8res minutes\n \n \n Last 1 hour (Default)\n La derni\xe8re heure (par d\xe9faut)\n \n \n Last 3 hours\n Les 3 derni\xe8res heures\n \n \n Last 6 hours\n Les 6 derni\xe8res heures\n \n \n Last 12 hours\n Les 12 derni\xe8res heures\n \n \n Last 24 hours\n Les 24 derni\xe8res heures\n \n \n Yesterday\n Hier\n \n \n Today\n Aujourd\'hui\n \n \n Today so far\n Depuis le d\xe9but de la journ\xe9e\n \n \n Day before yesterday\n Avant-hier\n \n \n Last 2 days\n Les 2 derniers jours\n \n \n This day last week\n Il y a huit jours\n \n \n Previous week\n La semaine derni\xe8re\n \n \n This week\n Cette semaine\n \n \n This week so far\n Depuis le d\xe9but de la semaine\n \n \n Last 7 days\n Les 7 derniers jours\n \n \n Previous month\n Le mois dernier\n \n \n This month\n Ce mois\n \n \n This month so far\n Depuis le d\xe9but du mois\n \n \n Last 30 days\n Les 30 derniers jours\n \n \n Last 90 days\n Les 90 derniers jours\n \n \n Last 6 months\n Les 6 derniers mois\n \n \n Last 1 year\n L\'ann\xe9e \xe9coul\xe9e\n \n \n Previous year\n L\'ann\xe9e derni\xe8re\n \n \n This year\n Cette ann\xe9e\n \n \n This year so far\n Depuis le d\xe9but de l\'ann\xe9e\n \n \n Last 2 years\n Les 2 derni\xe8res ann\xe9es\n \n \n Last 5 years\n Les 5 derni\xe8res ann\xe9es\n \n \n Information\n Informations\n \n \n No items selected.\n Aucun \xe9l\xe9ment s\xe9lectionn\xe9.\n \n \n Deselect item to select again\n D\xe9s\xe9lectionnez l\'\xe9l\xe9ment pour le s\xe9lectionner \xe0 nouveau.\n \n \n Selection limit reached\n Limite de s\xe9lection atteinte\n \n \n Filter tags\n Balises de filtre\n \n \n Add badge\n Ajouter un badge\n \n \n There are no items available.\n Aucun \xe9l\xe9ment disponible.\n \n \n Add\n Ajouter\n \n \n Remove\n Remove\n \n \n Clone\n Cloner\n \n \n Copy\n Copier\n \n \n Deep Scrub\n Nettoyage en profondeur\n \n \n Destroy\n D\xe9truire\n \n \n Flatten\n Aplatir\n \n \n Mark Down\n Marquer comme arr\xeat\xe9\n \n \n Mark In\n Marquer comme rentr\xe9\n \n \n Mark Lost\n Marquer comme perdu\n \n \n Mark Out\n Marquer comme sorti\n \n \n Protect\n Prot\xe9ger\n \n \n Rename\n Renommer\n \n \n Restore\n Restaurer\n \n \n Move to Trash\n D\xe9placer vers la corbeille\n \n \n Unprotect\n Annuler la protection\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n Supprim\xe9\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n Clon\xe9\n \n \n Copied\n Copi\xe9\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n Oui\n \n \n No\n Non\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n Qualit\xe9 de service\n \n \n BPS Limit\n Limite de bits/s\n \n \n The desired limit of IO bytes per second.\n Limite souhait\xe9e d\'octets E/S par seconde.\n \n \n IOPS Limit\n Limite E/S par seconde\n \n \n The desired limit of IO operations per second.\n Limite souhait\xe9e d\'op\xe9rations E/S par seconde.\n \n \n Read BPS Limit\n Limite de bits/s en lecture\n \n \n The desired limit of read bytes per second.\n Limite souhait\xe9e de lecture d\'octets par seconde.\n \n \n Read IOPS Limit\n Limite E/S par seconde en lecture\n \n \n The desired limit of read operations per second.\n Limite souhait\xe9e d\'op\xe9rations de lecture par seconde.\n \n \n Write BPS Limit\n Limite de bits/s en \xe9criture\n \n \n The desired limit of write bytes per second.\n Limite souhait\xe9e d\'\xe9criture d\'octets par seconde.\n \n \n Write IOPS Limit\n Limite E/S par seconde en \xe9criture\n \n \n The desired limit of write operations per second.\n Limite souhait\xe9e d\'op\xe9rations d\'\xe9criture par seconde.\n \n \n BPS Burst\n Rafale de bits/s\n \n \n The desired burst limit of IO bytes.\n Limite de rafale d\'octets en E/S souhait\xe9e.\n \n \n IOPS Burst\n Rafale E/S par seconde\n \n \n The desired burst limit of IO operations.\n Limite de rafale d\'op\xe9rations E/S souhait\xe9e.\n \n \n Read BPS Burst\n Rafale E/S par seconde en lecture\n \n \n The desired burst limit of read bytes.\n Limite de rafale d\'octets lus par seconde.\n \n \n Read IOPS Burst\n Rafale E/S par seconde en lecture\n \n \n The desired burst limit of read operations.\n Limite de rafale d\'op\xe9rations de lecture\n \n \n Write BPS Burst\n Rafale E/S par seconde en \xe9criture\n \n \n The desired burst limit of write bytes.\n Limite de rafale de lectures d\'octets souhait\xe9e.\n \n \n Write IOPS Burst\n Rafale d\'E/S par seconde en \xe9criture\n \n \n The desired burst limit of write operations.\n Limite de rafale d\'op\xe9rations d\'\xe9criture souhait\xe9e.\n \n \n Failed to \n \n \n \n Impossible de \n \n \n \n \n \n Executing\n En cours d\'ex\xe9cution\n \n \n execute\n ex\xe9cuter\n \n \n Executed\n Ex\xe9cut\xe9\n \n \n unknown task\n t\xe2che inconnue\n \n \n Creating\n En cours de cr\xe9ation\n \n \n create\n cr\xe9er\n \n \n Updating\n En cours de mise \xe0 jour\n \n \n update\n mettre \xe0 jour\n \n \n Deleting\n En cours de suppression\n \n \n delete\n supprimer\n \n \n RBD \'\n \'\n \n RBD \'\n \'\n \n \n \n RBD snapshot \'\n \'\n \n Instantan\xe9 RBD \'\n \'\n \n \n \n mirror mode for pool \'\n \'\n \n mode miroir pour la r\xe9serve \'\n \'\n \n \n \n mirror peer for pool \'\n \'\n \n mettre en miroir l\'homologue pour la r\xe9serve \'\n \'\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n Le nom est d\xe9j\xe0 utilis\xe9 par \n .\n \n \n \n Name is already used by \n .\n \n Le nom est d\xe9j\xe0 utilis\xe9 par \n .\n \n \n \n Name is already used by \n .\n \n Le nom est d\xe9j\xe0 utilis\xe9 par \n .\n \n \n \n \n contains snapshots.\n \n \n contient des instantan\xe9s.\n \n \n \n Cloning\n Clonage en cours\n \n \n clone\n cloner\n \n \n Snapshot of \n must be protected.\n \n L\'instantan\xe9 de \n doit \xeatre prot\xe9g\xe9.\n \n \n \n Copying\n En cours de copie\n \n \n copy\n copie\n \n \n Flattening\n Aplatissement\n \n \n flatten\n aplatir\n \n \n Flattened\n Applati\n \n \n Name is already used by \n .\n \n Nom d\xe9j\xe0 utilis\xe9 par \n .\n \n \n \n Cannot unprotect \n because it contains child images.\n \n Impossible d\'annuler la protection de \n , car cet \xe9l\xe9ment contient des images enfants.\n \n \n \n Cannot delete \n because it\'s protected.\n \n Impossible de supprimer \n , car cet \xe9l\xe9ment est prot\xe9g\xe9.\n \n \n \n Rolling back\n Retour \xe0 l\'\xe9tat initial\n \n \n rollback\n r\xe9tablir l\'\xe9tat initial\n \n \n Rolled back\n R\xe9tabli \xe0 l\'\xe9tat initial\n \n \n Moving\n En cours de d\xe9placement\n \n \n move\n d\xe9placer\n \n \n Moved\n D\xe9plac\xe9\n \n \n image \'\n \' to trash\n \n image \'\n \' d\xe9plac\xe9e vers la corbeille\n \n \n \n Could not find image.\n Impossible de trouver l\'image.\n \n \n Restoring\n En cours de restauration.\n \n \n restore\n restaurer\n \n \n Restored\n Restaur\xe9\n \n \n image \'\n \' into \'\n \'\n \n image \'\n \' vers \'\n \'\n \n \n \n Image name \'\n \' is already in use.\n \n Le nom d\'image \'\n \' est d\xe9j\xe0 utilis\xe9.\n \n \n \n image \'\n \'\n \n image \'\n \'\n \n \n \n Purging\n En cours de purge\n \n \n purge\n purger\n \n \n Purged\n Purg\xe9\n \n \n all pools\n toutes les r\xe9serves\n \n \n images from \n \n \n images de \n \n \n \n \n Cannot disable mirroring because it contains a peer.\n Impossible de d\xe9sactiver la mise en miroir, car l\'\xe9l\xe9ment contient un homologue.\n \n \n pool \'\n \'\n \n r\xe9serve \'\n \'\n \n \n \n erasure code profile \'\n \'\n \n profil de code d\'effacement \'\n \'\n \n \n \n target \'\n \'\n \n cible \'\n \'\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},ohIB:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("ae7Z");function r(t){for(var e=0,n=0,a=t;n=e;for(var g=0,b=o;gm.maxWidth?(m.width=m.maxWidth,h.push(m)):m.width=y}m.width=Math.max(0,m.width)}p=e-(f=s(t)),i(o,h)}while(p>0&&0!==o.length)}},ou9H:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("mrSG"),r=n("MGBS"),i=n("zotm");function s(t,e){return function(n){return n.lift(new o(t,e))}}var o=function(){function t(t,e){this.keySelector=t,this.flushes=e}return t.prototype.call=function(t,e){return e.subscribe(new u(t,this.keySelector,this.flushes))},t}(),u=function(t){function e(e,n,a){var r=t.call(this,e)||this;return r.keySelector=n,r.values=new Set,a&&r.add(Object(i.a)(r,a)),r}return a.__extends(e,t),e.prototype.notifyNext=function(t,e,n,a,r){this.values.clear()},e.prototype.notifyError=function(t,e){this._error(t)},e.prototype._next=function(t){this.keySelector?this._useKeySelector(t):this._finalizeNext(t,t)},e.prototype._useKeySelector=function(t){var e,n=this.destination;try{e=this.keySelector(t)}catch(a){return void n.error(a)}this._finalizeNext(e,t)},e.prototype._finalizeNext=function(t,e){var n=this.values;n.has(t)||(n.add(t),this.destination.next(e))},e}(r.a)},"p/rL":function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("bm",{months:"Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_M\u025bkalo_Zuw\u025bnkalo_Zuluyekalo_Utikalo_S\u025btanburukalo_\u0254kut\u0254burukalo_Nowanburukalo_Desanburukalo".split("_"),monthsShort:"Zan_Few_Mar_Awi_M\u025b_Zuw_Zul_Uti_S\u025bt_\u0254ku_Now_Des".split("_"),weekdays:"Kari_Nt\u025bn\u025bn_Tarata_Araba_Alamisa_Juma_Sibiri".split("_"),weekdaysShort:"Kar_Nt\u025b_Tar_Ara_Ala_Jum_Sib".split("_"),weekdaysMin:"Ka_Nt_Ta_Ar_Al_Ju_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"MMMM [tile] D [san] YYYY",LLL:"MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm",LLLL:"dddd MMMM [tile] D [san] YYYY [l\u025br\u025b] HH:mm"},calendar:{sameDay:"[Bi l\u025br\u025b] LT",nextDay:"[Sini l\u025br\u025b] LT",nextWeek:"dddd [don l\u025br\u025b] LT",lastDay:"[Kunu l\u025br\u025b] LT",lastWeek:"dddd [t\u025bm\u025bnen l\u025br\u025b] LT",sameElse:"L"},relativeTime:{future:"%s k\u0254n\u0254",past:"a b\u025b %s b\u0254",s:"sanga dama dama",ss:"sekondi %d",m:"miniti kelen",mm:"miniti %d",h:"l\u025br\u025b kelen",hh:"l\u025br\u025b %d",d:"tile kelen",dd:"tile %d",M:"kalo kelen",MM:"kalo %d",y:"san kelen",yy:"san %d"},week:{dow:1,doy:4}})}()},p0Sj:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("dEwP"),r=n("nkY7");function i(){for(var t=[],e=0;e1&&"number"==typeof t[t.length-1]&&(n=t.pop())):"number"==typeof u&&(n=t.pop()),null===o&&1===t.length&&t[0]instanceof a.a?t[0]:Object(i.a)(n)(Object(s.a)(t,o))}},p4Cf:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},pKUh:function(t,e,n){"use strict";n.d(e,"a",function(){return s}),n.d(e,"b",function(){return c});var a=n("CcnG"),r=n("YAQW"),i=n("Ip0R"),s=a["\u0275crt"]({encapsulation:0,styles:["[_nghost-%COMP%] .nav-tabs[_ngcontent-%COMP%] .nav-item.disabled[_ngcontent-%COMP%] a.disabled[_ngcontent-%COMP%]{cursor:default}"],data:{}});function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"span",[["class","bs-remove-tab"]],null,[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(n.preventDefault(),a=!1!==r.removeTab(t.parent.context.$implicit)&&a),a},null,null)),(t()(),a["\u0275ted"](-1,null,[" \u274c"]))],null,null)}function u(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,8,"li",[],[[2,"active",null],[2,"disabled",null]],[[null,"keydown"]],function(t,e,n){var a=!0;return"keydown"===e&&(a=!1!==t.component.keyNavActions(n,t.context.index)&&a),a},null,null)),a["\u0275did"](1,278528,null,0,i.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{ngClass:[0,"ngClass"]},null),a["\u0275pad"](2,2),(t()(),a["\u0275eld"](3,0,null,null,5,"a",[["class","nav-link"],["href","javascript:void(0);"]],[[1,"id",0],[2,"active",null],[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=0!=(t.context.$implicit.active=!0)&&a),a},null,null)),(t()(),a["\u0275eld"](4,16777216,null,null,2,"span",[],null,null,null,null,null)),a["\u0275did"](5,16384,null,0,r.a,[a.ViewContainerRef],{ngTransclude:[0,"ngTransclude"]},null),(t()(),a["\u0275ted"](6,null,["",""])),(t()(),a["\u0275and"](16777216,null,null,1,null,o)),a["\u0275did"](8,16384,null,0,i.NgIf,[a.ViewContainerRef,a.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=t(e,2,0,"nav-item",e.context.$implicit.customClass||"");t(e,1,0,n),t(e,5,0,e.context.$implicit.headingRef),t(e,8,0,e.context.$implicit.removable)},function(t,e){t(e,0,0,e.context.$implicit.active,e.context.$implicit.disabled),t(e,3,0,e.context.$implicit.id?e.context.$implicit.id+"-link":"",e.context.$implicit.active,e.context.$implicit.disabled),t(e,6,0,e.context.$implicit.heading)})}function c(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,3,"ul",[["class","nav"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==n.preventDefault()&&a),a},null,null)),a["\u0275did"](1,278528,null,0,i.NgClass,[a.IterableDiffers,a.KeyValueDiffers,a.ElementRef,a.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),a["\u0275and"](16777216,null,null,1,null,u)),a["\u0275did"](3,278528,null,0,i.NgForOf,[a.ViewContainerRef,a.TemplateRef,a.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),a["\u0275eld"](4,0,null,null,1,"div",[["class","tab-content"]],null,null,null,null,null)),a["\u0275ncd"](null,0)],function(t,e){var n=e.component;t(e,1,0,"nav",n.classMap),t(e,3,0,n.tabs)},null)}},pL04:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(){}}()},pMnS:function(t,e,n){"use strict";n.d(e,"a",function(){return u});var a=n("CcnG"),r=n("ZYCi"),i=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function s(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,16777216,null,null,1,"router-outlet",[],null,null,null,null,null)),a["\u0275did"](1,212992,null,0,r.q,[r.b,a.ViewContainerRef,a.ComponentFactoryResolver,[8,null],a.ChangeDetectorRef],null,null)],function(t,e){t(e,1,0)},null)}function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"ng-component",[],null,null,null,s,i)),a["\u0275did"](1,49152,null,0,r.u,[],null,null)],null,null)}var u=a["\u0275ccf"]("ng-component",r.u,o,{},{},[])},paOr:function(t,e,n){"use strict";var a=n("RDha"),r=n("cdu6");t.exports=function(t){var e=a.noop;t.LinearScaleBase=r.extend({getRightValue:function(t){return"string"==typeof t?+t:r.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=a.sign(t.min),r=a.sign(t.max);n<0&&r<0?t.max=0:n>0&&r>0&&(t.min=0)}var i=void 0!==e.min||void 0!==e.suggestedMin,s=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(t.min=null===t.min?e.suggestedMin:Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(t.max=null===t.max?e.suggestedMax:Math.max(t.max,e.suggestedMax)),i!==s&&t.min>=t.max&&(i?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),r={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:a.valueOrDefault(e.fixedStepSize,e.stepSize)},i=t.ticks=function(t,e){var n,r,i,s=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var o=a.niceNum(e.max-e.min,!1);i=a.niceNum(o/(t.maxTicks-1),!0),void 0!==(r=t.precision)&&(n=Math.pow(10,r),i=Math.ceil(i*n)/n)}var u=Math.floor(e.min/i)*i,c=Math.ceil(e.max/i)*i;a.isNullOrUndef(t.min)||a.isNullOrUndef(t.max)||!t.stepSize||a.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(u=t.min,c=t.max);var l=(c-u)/i;l=a.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l),r=1,i<1&&(r=Math.pow(10,1-Math.floor(a.log10(i))),u=Math.round(u*r)/r,c=Math.round(c*r)/r),s.push(void 0!==t.min?t.min:u);for(var d=1;d0?this._next(e.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},e}(i.a)},pugT:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("isby"),r=n("McSo"),i=n("2Bdj"),s=n("awvh"),o=function(){function t(t){this.closed=!1,this._parentOrParents=null,this._subscriptions=null,t&&(this._unsubscribe=t)}var e;return t.prototype.unsubscribe=function(){var e;if(!this.closed){var n=this._parentOrParents,o=this._unsubscribe,c=this._subscriptions;if(this.closed=!0,this._parentOrParents=null,this._subscriptions=null,n instanceof t)n.remove(this);else if(null!==n)for(var l=0;l
';var r=e.childNodes[0],i=e.childNodes[1];e._reset=function(){r.scrollLeft=1e6,r.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var s=function(){e._reset(),t()};return u(r,"scroll",s.bind(r,"expand")),u(i,"scroll",s.bind(i,"shrink")),e}((i=function(){if(d.resizer)return e(l("resize",n))},o=!1,c=[],function(){c=Array.prototype.slice.call(arguments),s=s||this,o||(o=!0,a.requestAnimFrame.call(window,function(){o=!1,i.apply(s,c)}))}));!function(t,e){var n=t.$chartjs||(t.$chartjs={}),i=n.renderProxy=function(t){"chartjs-render-animation"===t.animationName&&e()};a.each(r,function(e){u(t,e,i)}),n.reflow=!!t.offsetParent,t.classList.add("chartjs-render-monitor")}(t,function(){if(d.resizer){var e=t.parentNode;e&&e!==f.parentNode&&e.insertBefore(f,e.firstChild),f._reset()}})}(s,n,t)},removeEventListener:function(t,e,n){var i,s,o,u=t.canvas;if("resize"!==e){var l=((n.$chartjs||{}).proxies||{})[t.id+"_"+e];l&&c(u,e,l)}else o=(s=(i=u).$chartjs||{}).resizer,delete s.resizer,function(t){var e=t.$chartjs||{},n=e.renderProxy;n&&(a.each(r,function(e){c(t,e,n)}),delete e.renderProxy),t.classList.remove("chartjs-render-monitor")}(i),o&&o.parentNode&&o.parentNode.removeChild(o)}},a.addEvent=u,a.removeEvent=c},qwkt:function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("ejVf")),a(n("aTeT")),a(n("WOoz")),a(n("lmqd")),a(n("ILDN")),a(n("n1nk"))},qzaf:function(t,e,n){"use strict";t.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},rLYq:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata,i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,n=1,a=arguments.length;n\n \n ',host:{class:"datatable-summary-row"}})],t)}()},rPjj:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("mrSG"),r=function(t){function e(e,n,a){var r=t.call(this)||this;return r.parent=e,r.outerValue=n,r.outerIndex=a,r.index=0,r}return a.__extends(e,t),e.prototype._next=function(t){this.parent.notifyNext(this.outerValue,t,this.outerIndex,this.index++,this)},e.prototype._error=function(t){this.parent.notifyError(t,this),this.unsubscribe()},e.prototype._complete=function(){this.parent.notifyComplete(this),this.unsubscribe()},e}(n("FFOo").a)},raLr:function(t,e,n){!function(t){"use strict";function e(t,e,n){var a,r;return"m"===n?e?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443":"h"===n?e?"\u0433\u043e\u0434\u0438\u043d\u0430":"\u0433\u043e\u0434\u0438\u043d\u0443":t+" "+(a=+t,r={ss:e?"\u0441\u0435\u043a\u0443\u043d\u0434\u0430_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434":"\u0441\u0435\u043a\u0443\u043d\u0434\u0443_\u0441\u0435\u043a\u0443\u043d\u0434\u0438_\u0441\u0435\u043a\u0443\u043d\u0434",mm:e?"\u0445\u0432\u0438\u043b\u0438\u043d\u0430_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d":"\u0445\u0432\u0438\u043b\u0438\u043d\u0443_\u0445\u0432\u0438\u043b\u0438\u043d\u0438_\u0445\u0432\u0438\u043b\u0438\u043d",hh:e?"\u0433\u043e\u0434\u0438\u043d\u0430_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d":"\u0433\u043e\u0434\u0438\u043d\u0443_\u0433\u043e\u0434\u0438\u043d\u0438_\u0433\u043e\u0434\u0438\u043d",dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u0456_\u0434\u043d\u0456\u0432",MM:"\u043c\u0456\u0441\u044f\u0446\u044c_\u043c\u0456\u0441\u044f\u0446\u0456_\u043c\u0456\u0441\u044f\u0446\u0456\u0432",yy:"\u0440\u0456\u043a_\u0440\u043e\u043a\u0438_\u0440\u043e\u043a\u0456\u0432"}[n].split("_"),a%10==1&&a%100!=11?r[0]:a%10>=2&&a%10<=4&&(a%100<10||a%100>=20)?r[1]:r[2])}function a(t){return function(){return t+"\u043e"+(11===this.hours()?"\u0431":"")+"] LT"}}n("wd/R").defineLocale("uk",{months:{format:"\u0441\u0456\u0447\u043d\u044f_\u043b\u044e\u0442\u043e\u0433\u043e_\u0431\u0435\u0440\u0435\u0437\u043d\u044f_\u043a\u0432\u0456\u0442\u043d\u044f_\u0442\u0440\u0430\u0432\u043d\u044f_\u0447\u0435\u0440\u0432\u043d\u044f_\u043b\u0438\u043f\u043d\u044f_\u0441\u0435\u0440\u043f\u043d\u044f_\u0432\u0435\u0440\u0435\u0441\u043d\u044f_\u0436\u043e\u0432\u0442\u043d\u044f_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430_\u0433\u0440\u0443\u0434\u043d\u044f".split("_"),standalone:"\u0441\u0456\u0447\u0435\u043d\u044c_\u043b\u044e\u0442\u0438\u0439_\u0431\u0435\u0440\u0435\u0437\u0435\u043d\u044c_\u043a\u0432\u0456\u0442\u0435\u043d\u044c_\u0442\u0440\u0430\u0432\u0435\u043d\u044c_\u0447\u0435\u0440\u0432\u0435\u043d\u044c_\u043b\u0438\u043f\u0435\u043d\u044c_\u0441\u0435\u0440\u043f\u0435\u043d\u044c_\u0432\u0435\u0440\u0435\u0441\u0435\u043d\u044c_\u0436\u043e\u0432\u0442\u0435\u043d\u044c_\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434_\u0433\u0440\u0443\u0434\u0435\u043d\u044c".split("_")},monthsShort:"\u0441\u0456\u0447_\u043b\u044e\u0442_\u0431\u0435\u0440_\u043a\u0432\u0456\u0442_\u0442\u0440\u0430\u0432_\u0447\u0435\u0440\u0432_\u043b\u0438\u043f_\u0441\u0435\u0440\u043f_\u0432\u0435\u0440_\u0436\u043e\u0432\u0442_\u043b\u0438\u0441\u0442_\u0433\u0440\u0443\u0434".split("_"),weekdays:function(t,e){var n={nominative:"\u043d\u0435\u0434\u0456\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0430_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044f_\u0441\u0443\u0431\u043e\u0442\u0430".split("_"),accusative:"\u043d\u0435\u0434\u0456\u043b\u044e_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a_\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a_\u0441\u0435\u0440\u0435\u0434\u0443_\u0447\u0435\u0442\u0432\u0435\u0440_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u044e_\u0441\u0443\u0431\u043e\u0442\u0443".split("_"),genitive:"\u043d\u0435\u0434\u0456\u043b\u0456_\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043a\u0430_\u0432\u0456\u0432\u0442\u043e\u0440\u043a\u0430_\u0441\u0435\u0440\u0435\u0434\u0438_\u0447\u0435\u0442\u0432\u0435\u0440\u0433\u0430_\u043f\u2019\u044f\u0442\u043d\u0438\u0446\u0456_\u0441\u0443\u0431\u043e\u0442\u0438".split("_")};return!0===t?n.nominative.slice(1,7).concat(n.nominative.slice(0,1)):t?n[/(\[[\u0412\u0432\u0423\u0443]\]) ?dddd/.test(e)?"accusative":/\[?(?:\u043c\u0438\u043d\u0443\u043b\u043e\u0457|\u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u0457)? ?\] ?dddd/.test(e)?"genitive":"nominative"][t.day()]:n.nominative},weekdaysShort:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY \u0440.",LLL:"D MMMM YYYY \u0440., HH:mm",LLLL:"dddd, D MMMM YYYY \u0440., HH:mm"},calendar:{sameDay:a("[\u0421\u044c\u043e\u0433\u043e\u0434\u043d\u0456 "),nextDay:a("[\u0417\u0430\u0432\u0442\u0440\u0430 "),lastDay:a("[\u0412\u0447\u043e\u0440\u0430 "),nextWeek:a("[\u0423] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return a("[\u041c\u0438\u043d\u0443\u043b\u043e\u0457] dddd [").call(this);case 1:case 2:case 4:return a("[\u041c\u0438\u043d\u0443\u043b\u043e\u0433\u043e] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"\u0437\u0430 %s",past:"%s \u0442\u043e\u043c\u0443",s:"\u0434\u0435\u043a\u0456\u043b\u044c\u043a\u0430 \u0441\u0435\u043a\u0443\u043d\u0434",ss:e,m:e,mm:e,h:"\u0433\u043e\u0434\u0438\u043d\u0443",hh:e,d:"\u0434\u0435\u043d\u044c",dd:e,M:"\u043c\u0456\u0441\u044f\u0446\u044c",MM:e,y:"\u0440\u0456\u043a",yy:e},meridiemParse:/\u043d\u043e\u0447\u0456|\u0440\u0430\u043d\u043a\u0443|\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430/,isPM:function(t){return/^(\u0434\u043d\u044f|\u0432\u0435\u0447\u043e\u0440\u0430)$/.test(t)},meridiem:function(t,e,n){return t<4?"\u043d\u043e\u0447\u0456":t<12?"\u0440\u0430\u043d\u043a\u0443":t<17?"\u0434\u043d\u044f":"\u0432\u0435\u0447\u043e\u0440\u0430"},dayOfMonthOrdinalParse:/\d{1,2}-(\u0439|\u0433\u043e)/,ordinal:function(t,e){switch(e){case"M":case"d":case"DDD":case"w":case"W":return t+"-\u0439";case"D":return t+"-\u0433\u043e";default:return t}},week:{dow:1,doy:7}})}()},rdkg:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("CVuo"),r={},i="undefined"!=typeof document?document.createElement("div").style:void 0,s=function(){var t="undefined"!=typeof window?window.getComputedStyle(document.documentElement,""):void 0,e=void 0!==t?Array.prototype.slice.call(t).join("").match(/-(moz|webkit|ms)-/):null,n=null!==e?e[1]:void 0,a=void 0!==n?"WebKit|Moz|MS|O".match(new RegExp("("+n+")","i"))[1]:void 0;return a?{dom:a,lowercase:n,css:"-"+n+"-",js:n[0].toUpperCase()+n.substr(1)}:void 0};e.\u02750=s;var o=s();e.getVendorPrefixedName=function(t){var e=a.camelCase(t);return r[e]||(void 0!==o&&void 0!==i[o.css+t]?r[e]=o.css+t:void 0!==i[t]&&(r[e]=t)),r[e]}},rpEJ:function(t,e,n){"use strict";n.d(e,"a",function(){return h}),n.d(e,"b",function(){return g}),n.d(e,"c",function(){return f}),n.d(e,"d",function(){return p}),n.d(e,"e",function(){return o}),n.d(e,"f",function(){return s}),n.d(e,"g",function(){return c}),n.d(e,"h",function(){return u}),n.d(e,"i",function(){return y}),n.d(e,"j",function(){return d});var a=n("CcnG"),r=function(){function t(t,e){this.open=t,this.close=e||t}return t.prototype.isManual=function(){return"manual"===this.open||"manual"===this.close},t}(),i={hover:["mouseover","mouseout"],focus:["focusin","focusout"]};function s(t,e){void 0===e&&(e=i);var n=(t||"").trim();if(0===n.length)return[];var a=n.split(/\s+/).map(function(t){return t.split(":")}).map(function(t){var n=e[t[0]]||t;return new r(n[0],n[1])}),s=a.filter(function(t){return t.isManual()});if(s.length>1)throw new Error("Triggers parse error: only one manual trigger is allowed");if(1===s.length&&a.length>1)throw new Error("Triggers parse error: manual trigger can't be mixed with other triggers");return a}function o(t,e){var n=s(e.triggers),a=e.target;if(1===n.length&&n[0].isManual())return Function.prototype;var r=[],i=[],o=function(){i.forEach(function(t){return r.push(t())}),i.length=0};return n.forEach(function(n){var s=n.open===n.close,u=s?e.toggle:e.show;s||i.push(function(){return t.listen(a,n.close,e.hide)}),r.push(t.listen(a,n.open,function(){return u(o)}))}),function(){r.forEach(function(t){return t()})}}function u(t,e){return e.outsideClick?t.listen("document","click",function(t){e.target&&e.target.contains(t.target)||e.targets&&e.targets.some(function(e){return e.contains(t.target)})||e.hide()}):Function.prototype}function c(t,e){return e.outsideEsc?t.listen("document","keyup.esc",function(t){e.target&&e.target.contains(t.target)||e.targets&&e.targets.some(function(e){return e.contains(t.target)})||e.hide()}):Function.prototype}var l,d="undefined"!=typeof window&&window||{},f=d.document;function p(){return void 0===d||(void 0===d.__theme?l?"bs3"===l:"bs3"===(l=function(){if("undefined"==typeof document)return null;var t=document.createElement("span");t.innerText="test bs version",document.body.appendChild(t),t.classList.add("d-none");var e=t.getBoundingClientRect();return document.body.removeChild(t),e&&0===e.top?"bs4":"bs3"}()):"bs4"!==d.__theme)}function h(t){return function(t,e){var n=" __"+e+"Value";Object.defineProperty(t,e,{get:function(){return this[n]},set:function(t){var a=this[n];this[n]=t,a!==t&&this[e+"Change"]&&this[e+"Change"].emit(t)}})}}var g=function(){function t(){}return t.reflow=function(t){},t.getStyles=function(t){var e=t.ownerDocument.defaultView;return e&&e.opener||(e=d),e.getComputedStyle(t)},t}(),b={},m="undefined"==typeof console||!("warn"in console);function y(t){!Object(a.isDevMode)()||m||t in b||(b[t]=!0,console.warn(t))}},"s+uk":function(t,e,n){!function(t){"use strict";function e(t,e,n,a){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[t+" Tage",t+" Tagen"],M:["ein Monat","einem Monat"],MM:[t+" Monate",t+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[t+" Jahre",t+" Jahren"]};return e?r[n][0]:r[n][1]}n("wd/R").defineLocale("de-at",{months:"J\xe4nner_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"J\xe4n._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:e,mm:"%d Minuten",h:e,hh:"%d Stunden",d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},sLuX:function(t,e,n){"use strict";var a=n("CcnG"),r=n("25BL"),i=n("uIqm");n("FSuO"),n("a0VL"),n.d(e,"a",function(){return s}),n.d(e,"b",function(){return o});var s=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function o(t){return a["\u0275vid"](0,[a["\u0275qud"](402653184,1,{table:0}),(t()(),a["\u0275eld"](1,0,null,null,1,"cd-table",[["columnMode","flex"]],null,null,null,r.b,r.a)),a["\u0275did"](2,2867200,[[1,4],["table",4]],0,i.a,[a.NgZone,a.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],toolHeader:[3,"toolHeader"],header:[4,"header"],footer:[5,"footer"],limit:[6,"limit"],autoReload:[7,"autoReload"],autoSave:[8,"autoSave"],customCss:[9,"customCss"]},null)],function(t,e){var n=e.component;t(e,2,0,n.tableData,n.columns,"flex",!1,!1,!1,0,n.autoReload,!1,n.customCss)},null)}},sb0X:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("CcnG"),r=n("gIcY"),i=n("LvDl"),s=function(){function t(t){this.elRef=t,this.type="submit",this.submitAction=new a.EventEmitter,this.disabled=!1,this.loading=!1}return t.prototype.ngOnInit=function(){var t=this;this.form.statusChanges.subscribe(function(){i.has(t.form.errors,"cdSubmitButton")&&(t.loading=!1,i.unset(t.form.errors,"cdSubmitButton"),t.form instanceof r.a&&t.form.updateValueAndValidity())})},t.prototype.submit=function(t){this.focusButton(),this.form instanceof r.l&&this.form.onSubmit(t),this.form.invalid?this.focusInvalid():(this.loading=!0,this.submitAction.emit())},t.prototype.focusButton=function(){this.elRef.nativeElement.offsetParent.querySelector('button[type="'+this.type+'"]').focus()},t.prototype.focusInvalid=function(){var t=this.elRef.nativeElement.offsetParent.querySelector("input.ng-invalid, select.ng-invalid");t&&t.focus()},t}()},siIJ:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(e,n){void 0===n&&(n=t.now),this.SchedulerAction=e,this.now=n}return t.prototype.schedule=function(t,e,n){return void 0===e&&(e=0),new this.SchedulerAction(this,t).schedule(n,e)},t.now=function(){return Date.now()},t}()},sne2:function(t,e,n){"use strict";n.d(e,"c",function(){return o}),n.d(e,"e",function(){return a}),n.d(e,"a",function(){return r}),n.d(e,"b",function(){return u}),n.d(e,"d",function(){return c});var a,r,i=n("CcnG"),s=n("Jm/i"),o=function(){function t(){}return t.organization="ceph",t.projectName="Ceph Manager Dashboard",t.license="Free software (LGPL 2.1).",t}();!function(t){t.CREATE="create",t.EDIT="edit",t.UPDATE="update",t.REMOVE="remove",t.DELETE="delete",t.ADD="add",t.COPY="copy",t.CLONE="clone",t.RECREATE="recreate",t.EXPIRE="expire"}(a||(a={})),function(t){t.CREATE="Create",t.DELETE="Delete",t.ADD="Add",t.REMOVE="Remove",t.EDIT="Edit",t.CANCEL="Cancel",t.COPY="Copy",t.CLONE="Clone",t.SHOW="Show",t.RECREATE="Recreate",t.EXPIRE="Expire"}(r||(r={}));var u=function(){function t(t){this.i18n=t,this.CREATE=this.i18n("Create"),this.DELETE=this.i18n("Delete"),this.ADD=this.i18n("Add"),this.REMOVE=this.i18n("Remove"),this.EDIT=this.i18n("Edit"),this.CANCEL=this.i18n("Cancel"),this.CLONE=this.i18n("Clone"),this.COPY=this.i18n("Copy"),this.DEEP_SCRUB=this.i18n("Deep Scrub"),this.DESTROY=this.i18n("Destroy"),this.FLATTEN=this.i18n("Flatten"),this.MARK_DOWN=this.i18n("Mark Down"),this.MARK_IN=this.i18n("Mark In"),this.MARK_LOST=this.i18n("Mark Lost"),this.MARK_OUT=this.i18n("Mark Out"),this.PROTECT=this.i18n("Protect"),this.PURGE=this.i18n("Purge"),this.RENAME=this.i18n("Rename"),this.RESTORE=this.i18n("Restore"),this.REWEIGHT=this.i18n("Reweight"),this.ROLLBACK=this.i18n("Rollback"),this.SCRUB=this.i18n("Scrub"),this.SHOW=this.i18n("Show"),this.TRASH=this.i18n("Move to Trash"),this.UNPROTECT=this.i18n("Unprotect"),this.RECREATE=this.i18n("Recreate"),this.EXPIRE=this.i18n("Expire")}return t.ngInjectableDef=i.defineInjectable({factory:function(){return new t(i.inject(s.a))},token:t,providedIn:"root"}),t}(),c=function(){function t(t){this.i18n=t,this.CREATED=this.i18n("Created"),this.DELETED=this.i18n("Deleted"),this.ADDED=this.i18n("Added"),this.REMOVED=this.i18n("Removed"),this.EDITED=this.i18n("Edited"),this.CANCELED=this.i18n("Canceled"),this.CLONED=this.i18n("Cloned"),this.COPIED=this.i18n("Copied"),this.SHOWED=this.i18n("Showed"),this.TRASHED=this.i18n("Moved to Trash"),this.UNPROTECTED=this.i18n("Unprotected"),this.RECREATED=this.i18n("Recreated"),this.EXPIRED=this.i18n("Expired")}return t.ngInjectableDef=i.defineInjectable({factory:function(){return new t(i.inject(s.a))},token:t,providedIn:"root"}),t}()},sp3z:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("lo",{months:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),monthsShort:"\u0ea1\u0eb1\u0e87\u0e81\u0ead\u0e99_\u0e81\u0eb8\u0ea1\u0e9e\u0eb2_\u0ea1\u0eb5\u0e99\u0eb2_\u0ec0\u0ea1\u0eaa\u0eb2_\u0e9e\u0eb6\u0e94\u0eaa\u0eb0\u0e9e\u0eb2_\u0ea1\u0eb4\u0e96\u0eb8\u0e99\u0eb2_\u0e81\u0ecd\u0ea5\u0eb0\u0e81\u0ebb\u0e94_\u0eaa\u0eb4\u0e87\u0eab\u0eb2_\u0e81\u0eb1\u0e99\u0e8d\u0eb2_\u0e95\u0eb8\u0ea5\u0eb2_\u0e9e\u0eb0\u0e88\u0eb4\u0e81_\u0e97\u0eb1\u0e99\u0ea7\u0eb2".split("_"),weekdays:"\u0ead\u0eb2\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysShort:"\u0e97\u0eb4\u0e94_\u0e88\u0eb1\u0e99_\u0ead\u0eb1\u0e87\u0e84\u0eb2\u0e99_\u0e9e\u0eb8\u0e94_\u0e9e\u0eb0\u0eab\u0eb1\u0e94_\u0eaa\u0eb8\u0e81_\u0ec0\u0eaa\u0ebb\u0eb2".split("_"),weekdaysMin:"\u0e97_\u0e88_\u0ead\u0e84_\u0e9e_\u0e9e\u0eab_\u0eaa\u0e81_\u0eaa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"\u0ea7\u0eb1\u0e99dddd D MMMM YYYY HH:mm"},meridiemParse:/\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2|\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87/,isPM:function(t){return"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"===t},meridiem:function(t,e,n){return t<12?"\u0e95\u0ead\u0e99\u0ec0\u0e8a\u0ebb\u0ec9\u0eb2":"\u0e95\u0ead\u0e99\u0ec1\u0ea5\u0e87"},calendar:{sameDay:"[\u0ea1\u0eb7\u0ec9\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextDay:"[\u0ea1\u0eb7\u0ec9\u0ead\u0eb7\u0ec8\u0e99\u0ec0\u0ea7\u0ea5\u0eb2] LT",nextWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0edc\u0ec9\u0eb2\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastDay:"[\u0ea1\u0eb7\u0ec9\u0ea7\u0eb2\u0e99\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",lastWeek:"[\u0ea7\u0eb1\u0e99]dddd[\u0ec1\u0ea5\u0ec9\u0ea7\u0e99\u0eb5\u0ec9\u0ec0\u0ea7\u0ea5\u0eb2] LT",sameElse:"L"},relativeTime:{future:"\u0ead\u0eb5\u0e81 %s",past:"%s\u0e9c\u0ec8\u0eb2\u0e99\u0ea1\u0eb2",s:"\u0e9a\u0ecd\u0ec8\u0ec0\u0e97\u0ebb\u0ec8\u0eb2\u0ec3\u0e94\u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",ss:"%d \u0ea7\u0eb4\u0e99\u0eb2\u0e97\u0eb5",m:"1 \u0e99\u0eb2\u0e97\u0eb5",mm:"%d \u0e99\u0eb2\u0e97\u0eb5",h:"1 \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",hh:"%d \u0e8a\u0ebb\u0ec8\u0ea7\u0ec2\u0ea1\u0e87",d:"1 \u0ea1\u0eb7\u0ec9",dd:"%d \u0ea1\u0eb7\u0ec9",M:"1 \u0ec0\u0e94\u0eb7\u0ead\u0e99",MM:"%d \u0ec0\u0e94\u0eb7\u0ead\u0e99",y:"1 \u0e9b\u0eb5",yy:"%d \u0e9b\u0eb5"},dayOfMonthOrdinalParse:/(\u0e97\u0eb5\u0ec8)\d{1,2}/,ordinal:function(t){return"\u0e97\u0eb5\u0ec8"+t}})}()},svcd:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("mrSG"),r=n("K9Ia"),i=n("pugT"),s=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.value=null,e.hasNext=!1,e.hasCompleted=!1,e}return a.__extends(e,t),e.prototype._subscribe=function(e){return this.hasError?(e.error(this.thrownError),i.a.EMPTY):this.hasCompleted&&this.hasNext?(e.next(this.value),e.complete(),i.a.EMPTY):t.prototype._subscribe.call(this,e)},e.prototype.next=function(t){this.hasCompleted||(this.value=t,this.hasNext=!0)},e.prototype.error=function(e){this.hasCompleted||t.prototype.error.call(this,e)},e.prototype.complete=function(){this.hasCompleted=!0,this.hasNext&&t.prototype.next.call(this,this.value),t.prototype.complete.call(this)},e}(r.a)},syrc:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("5tze");n("bpWZ"),n("czA5"),e.DataTableBodyRowComponent=function(){function t(t,e,n,a){this.differs=t,this.scrollbarHelper=e,this.cd=n,this.treeStatus="collapsed",this.activate=new i.EventEmitter,this.treeAction=new i.EventEmitter,this._groupStyles={left:{},center:{},right:{}},this._element=a.nativeElement,this._rowDiffer=t.find({}).create()}return Object.defineProperty(t.prototype,"columns",{get:function(){return this._columns},set:function(t){this._columns=t,this.recalculateColumns(t),this.buildStylesByGroup()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"innerWidth",{get:function(){return this._innerWidth},set:function(t){if(this._columns){var e=s.columnsByPin(this._columns);this._columnGroupWidths=s.columnGroupWidths(e,e)}this._innerWidth=t,this.recalculateColumns(),this.buildStylesByGroup()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"offsetX",{get:function(){return this._offsetX},set:function(t){this._offsetX=t,this.buildStylesByGroup()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"cssClass",{get:function(){var t="datatable-body-row";if(this.isSelected&&(t+=" active"),this.rowIndex%2!=0&&(t+=" datatable-row-odd"),this.rowIndex%2==0&&(t+=" datatable-row-even"),this.rowClass){var e=this.rowClass(this.row);if("string"==typeof e)t+=" "+e;else if("object"==typeof e)for(var n=0,a=Object.keys(e);n\n \n \n \n '})],t)}()},"t/Na":function(t,e,n){"use strict";n.d(e,"m",function(){return E}),n.d(e,"p",function(){return j}),n.d(e,"q",function(){return F}),n.d(e,"n",function(){return P}),n.d(e,"o",function(){return M}),n.d(e,"b",function(){return f}),n.d(e,"g",function(){return d}),n.d(e,"c",function(){return C}),n.d(e,"a",function(){return N}),n.d(e,"d",function(){return Y}),n.d(e,"e",function(){return G}),n.d(e,"l",function(){return z}),n.d(e,"h",function(){return b}),n.d(e,"f",function(){return O}),n.d(e,"i",function(){return L}),n.d(e,"k",function(){return D}),n.d(e,"j",function(){return q});var a=n("mrSG"),r=n("CcnG"),i=n("F/XL"),s=n("6blF"),o=n("Phjn"),u=n("VnD/"),c=n("67Y/"),l=n("Ip0R"),d=function(){return function(){}}(),f=function(){return function(){}}(),p=function(){function t(t){var e=this;this.normalizedNames=new Map,this.lazyUpdate=null,t?this.lazyInit="string"==typeof t?function(){e.headers=new Map,t.split("\n").forEach(function(t){var n=t.indexOf(":");if(n>0){var a=t.slice(0,n),r=a.toLowerCase(),i=t.slice(n+1).trim();e.maybeSetNormalizedName(a,r),e.headers.has(r)?e.headers.get(r).push(i):e.headers.set(r,[i])}})}:function(){e.headers=new Map,Object.keys(t).forEach(function(n){var a=t[n],r=n.toLowerCase();"string"==typeof a&&(a=[a]),a.length>0&&(e.headers.set(r,a),e.maybeSetNormalizedName(n,r))})}:this.headers=new Map}return t.prototype.has=function(t){return this.init(),this.headers.has(t.toLowerCase())},t.prototype.get=function(t){this.init();var e=this.headers.get(t.toLowerCase());return e&&e.length>0?e[0]:null},t.prototype.keys=function(){return this.init(),Array.from(this.normalizedNames.values())},t.prototype.getAll=function(t){return this.init(),this.headers.get(t.toLowerCase())||null},t.prototype.append=function(t,e){return this.clone({name:t,value:e,op:"a"})},t.prototype.set=function(t,e){return this.clone({name:t,value:e,op:"s"})},t.prototype.delete=function(t,e){return this.clone({name:t,value:e,op:"d"})},t.prototype.maybeSetNormalizedName=function(t,e){this.normalizedNames.has(e)||this.normalizedNames.set(e,t)},t.prototype.init=function(){var e=this;this.lazyInit&&(this.lazyInit instanceof t?this.copyFrom(this.lazyInit):this.lazyInit(),this.lazyInit=null,this.lazyUpdate&&(this.lazyUpdate.forEach(function(t){return e.applyUpdate(t)}),this.lazyUpdate=null))},t.prototype.copyFrom=function(t){var e=this;t.init(),Array.from(t.headers.keys()).forEach(function(n){e.headers.set(n,t.headers.get(n)),e.normalizedNames.set(n,t.normalizedNames.get(n))})},t.prototype.clone=function(e){var n=new t;return n.lazyInit=this.lazyInit&&this.lazyInit instanceof t?this.lazyInit:this,n.lazyUpdate=(this.lazyUpdate||[]).concat([e]),n},t.prototype.applyUpdate=function(t){var e=t.name.toLowerCase();switch(t.op){case"a":case"s":var n=t.value;if("string"==typeof n&&(n=[n]),0===n.length)return;this.maybeSetNormalizedName(t.name,e);var r=("a"===t.op?this.headers.get(e):void 0)||[];r.push.apply(r,Object(a.__spread)(n)),this.headers.set(e,r);break;case"d":var i=t.value;if(i){var s=this.headers.get(e);if(!s)return;0===(s=s.filter(function(t){return-1===i.indexOf(t)})).length?(this.headers.delete(e),this.normalizedNames.delete(e)):this.headers.set(e,s)}else this.headers.delete(e),this.normalizedNames.delete(e)}},t.prototype.forEach=function(t){var e=this;this.init(),Array.from(this.normalizedNames.keys()).forEach(function(n){return t(e.normalizedNames.get(n),e.headers.get(n))})},t}(),h=function(){function t(){}return t.prototype.encodeKey=function(t){return g(t)},t.prototype.encodeValue=function(t){return g(t)},t.prototype.decodeKey=function(t){return decodeURIComponent(t)},t.prototype.decodeValue=function(t){return decodeURIComponent(t)},t}();function g(t){return encodeURIComponent(t).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/gi,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%2B/gi,"+").replace(/%3D/gi,"=").replace(/%3F/gi,"?").replace(/%2F/gi,"/")}var b=function(){function t(t){void 0===t&&(t={});var e,n,r,i=this;if(this.updates=null,this.cloneFrom=null,this.encoder=t.encoder||new h,t.fromString){if(t.fromObject)throw new Error("Cannot specify both fromString and fromObject.");this.map=(e=t.fromString,n=this.encoder,r=new Map,e.length>0&&e.split("&").forEach(function(t){var e=t.indexOf("="),i=Object(a.__read)(-1==e?[n.decodeKey(t),""]:[n.decodeKey(t.slice(0,e)),n.decodeValue(t.slice(e+1))],2),s=i[0],o=i[1],u=r.get(s)||[];u.push(o),r.set(s,u)}),r)}else t.fromObject?(this.map=new Map,Object.keys(t.fromObject).forEach(function(e){var n=t.fromObject[e];i.map.set(e,Array.isArray(n)?n:[n])})):this.map=null}return t.prototype.has=function(t){return this.init(),this.map.has(t)},t.prototype.get=function(t){this.init();var e=this.map.get(t);return e?e[0]:null},t.prototype.getAll=function(t){return this.init(),this.map.get(t)||null},t.prototype.keys=function(){return this.init(),Array.from(this.map.keys())},t.prototype.append=function(t,e){return this.clone({param:t,value:e,op:"a"})},t.prototype.set=function(t,e){return this.clone({param:t,value:e,op:"s"})},t.prototype.delete=function(t,e){return this.clone({param:t,value:e,op:"d"})},t.prototype.toString=function(){var t=this;return this.init(),this.keys().map(function(e){var n=t.encoder.encodeKey(e);return t.map.get(e).map(function(e){return n+"="+t.encoder.encodeValue(e)}).join("&")}).join("&")},t.prototype.clone=function(e){var n=new t({encoder:this.encoder});return n.cloneFrom=this.cloneFrom||this,n.updates=(this.updates||[]).concat([e]),n},t.prototype.init=function(){var t=this;null===this.map&&(this.map=new Map),null!==this.cloneFrom&&(this.cloneFrom.init(),this.cloneFrom.keys().forEach(function(e){return t.map.set(e,t.cloneFrom.map.get(e))}),this.updates.forEach(function(e){switch(e.op){case"a":case"s":var n=("a"===e.op?t.map.get(e.param):void 0)||[];n.push(e.value),t.map.set(e.param,n);break;case"d":if(void 0===e.value){t.map.delete(e.param);break}var a=t.map.get(e.param)||[],r=a.indexOf(e.value);-1!==r&&a.splice(r,1),a.length>0?t.map.set(e.param,a):t.map.delete(e.param)}}),this.cloneFrom=null)},t}();function m(t){return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer}function y(t){return"undefined"!=typeof Blob&&t instanceof Blob}function v(t){return"undefined"!=typeof FormData&&t instanceof FormData}var _=function(){function t(t,e,n,a){var r;if(this.url=e,this.body=null,this.reportProgress=!1,this.withCredentials=!1,this.responseType="json",this.method=t.toUpperCase(),function(t){switch(t){case"DELETE":case"GET":case"HEAD":case"OPTIONS":case"JSONP":return!1;default:return!0}}(this.method)||a?(this.body=void 0!==n?n:null,r=a):r=n,r&&(this.reportProgress=!!r.reportProgress,this.withCredentials=!!r.withCredentials,r.responseType&&(this.responseType=r.responseType),r.headers&&(this.headers=r.headers),r.params&&(this.params=r.params)),this.headers||(this.headers=new p),this.params){var i=this.params.toString();if(0===i.length)this.urlWithParams=e;else{var s=e.indexOf("?");this.urlWithParams=e+(-1===s?"?":s=200&&this.status<300}}(),w=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.type=x.ResponseHeader,n}return Object(a.__extends)(e,t),e.prototype.clone=function(t){return void 0===t&&(t={}),new e({headers:t.headers||this.headers,status:void 0!==t.status?t.status:this.status,statusText:t.statusText||this.statusText,url:t.url||this.url||void 0})},e}(T),S=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.type=x.Response,n.body=void 0!==e.body?e.body:null,n}return Object(a.__extends)(e,t),e.prototype.clone=function(t){return void 0===t&&(t={}),new e({body:void 0!==t.body?t.body:this.body,headers:t.headers||this.headers,status:void 0!==t.status?t.status:this.status,statusText:t.statusText||this.statusText,url:t.url||this.url||void 0})},e}(T),O=function(t){function e(e){var n=t.call(this,e,0,"Unknown Error")||this;return n.name="HttpErrorResponse",n.ok=!1,n.message=n.status>=200&&n.status<300?"Http failure during parsing for "+(e.url||"(unknown url)"):"Http failure response for "+(e.url||"(unknown url)")+": "+e.status+" "+e.statusText,n.error=e.error||null,n}return Object(a.__extends)(e,t),e}(T);function I(t,e){return{body:e,headers:t.headers,observe:t.observe,params:t.params,reportProgress:t.reportProgress,responseType:t.responseType,withCredentials:t.withCredentials}}var C=function(){function t(t){this.handler=t}return t.prototype.request=function(t,e,n){var a,r=this;if(void 0===n&&(n={}),t instanceof _)a=t;else{var s;s=n.headers instanceof p?n.headers:new p(n.headers);var l=void 0;n.params&&(l=n.params instanceof b?n.params:new b({fromObject:n.params})),a=new _(t,e,void 0!==n.body?n.body:null,{headers:s,params:l,reportProgress:n.reportProgress,responseType:n.responseType||"json",withCredentials:n.withCredentials})}var d=Object(i.a)(a).pipe(Object(o.a)(function(t){return r.handler.handle(t)}));if(t instanceof _||"events"===n.observe)return d;var f=d.pipe(Object(u.a)(function(t){return t instanceof S}));switch(n.observe||"body"){case"body":switch(a.responseType){case"arraybuffer":return f.pipe(Object(c.a)(function(t){if(null!==t.body&&!(t.body instanceof ArrayBuffer))throw new Error("Response is not an ArrayBuffer.");return t.body}));case"blob":return f.pipe(Object(c.a)(function(t){if(null!==t.body&&!(t.body instanceof Blob))throw new Error("Response is not a Blob.");return t.body}));case"text":return f.pipe(Object(c.a)(function(t){if(null!==t.body&&"string"!=typeof t.body)throw new Error("Response is not a string.");return t.body}));case"json":default:return f.pipe(Object(c.a)(function(t){return t.body}))}case"response":return f;default:throw new Error("Unreachable: unhandled observe type "+n.observe+"}")}},t.prototype.delete=function(t,e){return void 0===e&&(e={}),this.request("DELETE",t,e)},t.prototype.get=function(t,e){return void 0===e&&(e={}),this.request("GET",t,e)},t.prototype.head=function(t,e){return void 0===e&&(e={}),this.request("HEAD",t,e)},t.prototype.jsonp=function(t,e){return this.request("JSONP",t,{params:(new b).append(e,"JSONP_CALLBACK"),observe:"body",responseType:"json"})},t.prototype.options=function(t,e){return void 0===e&&(e={}),this.request("OPTIONS",t,e)},t.prototype.patch=function(t,e,n){return void 0===n&&(n={}),this.request("PATCH",t,I(n,e))},t.prototype.post=function(t,e,n){return void 0===n&&(n={}),this.request("POST",t,I(n,e))},t.prototype.put=function(t,e,n){return void 0===n&&(n={}),this.request("PUT",t,I(n,e))},t}(),k=function(){function t(t,e){this.next=t,this.interceptor=e}return t.prototype.handle=function(t){return this.interceptor.intercept(t,this.next)},t}(),N=new r.InjectionToken("HTTP_INTERCEPTORS"),R=function(){function t(){}return t.prototype.intercept=function(t,e){return e.handle(t)},t}(),A=/^\)\]\}',?\n/,D=function(){return function(){}}(),E=function(){function t(){}return t.prototype.build=function(){return new XMLHttpRequest},t}(),L=function(){function t(t){this.xhrFactory=t}return t.prototype.handle=function(t){var e=this;if("JSONP"===t.method)throw new Error("Attempted to construct Jsonp request without JsonpClientModule installed.");return new s.a(function(n){var a=e.xhrFactory.build();if(a.open(t.method,t.urlWithParams),t.withCredentials&&(a.withCredentials=!0),t.headers.forEach(function(t,e){return a.setRequestHeader(t,e.join(","))}),t.headers.has("Accept")||a.setRequestHeader("Accept","application/json, text/plain, */*"),!t.headers.has("Content-Type")){var r=t.detectContentTypeHeader();null!==r&&a.setRequestHeader("Content-Type",r)}if(t.responseType){var i=t.responseType.toLowerCase();a.responseType="json"!==i?i:"text"}var s=t.serializeBody(),o=null,u=function(){if(null!==o)return o;var e=1223===a.status?204:a.status,n=a.statusText||"OK",r=new p(a.getAllResponseHeaders()),i=function(t){return"responseURL"in t&&t.responseURL?t.responseURL:/^X-Request-URL:/m.test(t.getAllResponseHeaders())?t.getResponseHeader("X-Request-URL"):null}(a)||t.url;return o=new w({headers:r,status:e,statusText:n,url:i})},c=function(){var e=u(),r=e.headers,i=e.status,s=e.statusText,o=e.url,c=null;204!==i&&(c=void 0===a.response?a.responseText:a.response),0===i&&(i=c?200:0);var l=i>=200&&i<300;if("json"===t.responseType&&"string"==typeof c){var d=c;c=c.replace(A,"");try{c=""!==c?JSON.parse(c):null}catch(f){c=d,l&&(l=!1,c={error:f,text:c})}}l?(n.next(new S({body:c,headers:r,status:i,statusText:s,url:o||void 0})),n.complete()):n.error(new O({error:c,headers:r,status:i,statusText:s,url:o||void 0}))},l=function(t){var e=u().url,r=new O({error:t,status:a.status||0,statusText:a.statusText||"Unknown Error",url:e||void 0});n.error(r)},d=!1,f=function(e){d||(n.next(u()),d=!0);var r={type:x.DownloadProgress,loaded:e.loaded};e.lengthComputable&&(r.total=e.total),"text"===t.responseType&&a.responseText&&(r.partialText=a.responseText),n.next(r)},h=function(t){var e={type:x.UploadProgress,loaded:t.loaded};t.lengthComputable&&(e.total=t.total),n.next(e)};return a.addEventListener("load",c),a.addEventListener("error",l),t.reportProgress&&(a.addEventListener("progress",f),null!==s&&a.upload&&a.upload.addEventListener("progress",h)),a.send(s),n.next({type:x.Sent}),function(){a.removeEventListener("error",l),a.removeEventListener("load",c),t.reportProgress&&(a.removeEventListener("progress",f),null!==s&&a.upload&&a.upload.removeEventListener("progress",h)),a.abort()}})},t}(),P=new r.InjectionToken("XSRF_COOKIE_NAME"),M=new r.InjectionToken("XSRF_HEADER_NAME"),q=function(){return function(){}}(),j=function(){function t(t,e,n){this.doc=t,this.platform=e,this.cookieName=n,this.lastCookieString="",this.lastToken=null,this.parseCount=0}return t.prototype.getToken=function(){if("server"===this.platform)return null;var t=this.doc.cookie||"";return t!==this.lastCookieString&&(this.parseCount++,this.lastToken=Object(l["\u0275parseCookieValue"])(t,this.cookieName),this.lastCookieString=t),this.lastToken},t}(),F=function(){function t(t,e){this.tokenService=t,this.headerName=e}return t.prototype.intercept=function(t,e){var n=t.url.toLowerCase();if("GET"===t.method||"HEAD"===t.method||n.startsWith("http://")||n.startsWith("https://"))return e.handle(t);var a=this.tokenService.getToken();return null===a||t.headers.has(this.headerName)||(t=t.clone({headers:t.headers.set(this.headerName,a)})),e.handle(t)},t}(),z=function(){function t(t,e){this.backend=t,this.injector=e,this.chain=null}return t.prototype.handle=function(t){if(null===this.chain){var e=this.injector.get(N,[]);this.chain=e.reduceRight(function(t,e){return new k(t,e)},this.backend)}return this.chain.handle(t)},t}(),G=function(){function t(){}var e;return e=t,t.disable=function(){return{ngModule:e,providers:[{provide:F,useClass:R}]}},t.withOptions=function(t){return void 0===t&&(t={}),{ngModule:e,providers:[t.cookieName?{provide:P,useValue:t.cookieName}:[],t.headerName?{provide:M,useValue:t.headerName}:[]]}},t}(),Y=function(){return function(){}}()},"t/zF":function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){return function(t,e){this.name=t,this.metadata=e}}()},t1N5:function(t,e){function n(t){var e,n,a=t[0]/255,r=t[1]/255,i=t[2]/255,s=Math.min(a,r,i),o=Math.max(a,r,i),u=o-s;return o==s?e=0:a==o?e=(r-i)/u:r==o?e=2+(i-a)/u:i==o&&(e=4+(a-r)/u),(e=Math.min(60*e,360))<0&&(e+=360),n=(s+o)/2,[e,100*(o==s?0:n<=.5?u/(o+s):u/(2-o-s)),100*n]}function a(t){var e,n,a=t[0],r=t[1],i=t[2],s=Math.min(a,r,i),o=Math.max(a,r,i),u=o-s;return n=0==o?0:u/o*1e3/10,o==s?e=0:a==o?e=(r-i)/u:r==o?e=2+(i-a)/u:i==o&&(e=4+(a-r)/u),(e=Math.min(60*e,360))<0&&(e+=360),[e,n,o/255*1e3/10]}function i(t){var e=t[0],a=t[1],r=t[2];return[n(t)[0],1/255*Math.min(e,Math.min(a,r))*100,100*(r=1-1/255*Math.max(e,Math.max(a,r)))]}function s(t){var e,n=t[0]/255,a=t[1]/255,r=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-a,1-r)))/(1-e)||0),100*((1-a-e)/(1-e)||0),100*((1-r-e)/(1-e)||0),100*e]}function o(t){return S[JSON.stringify(t)]}function u(t){var e=t[0]/255,n=t[1]/255,a=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92)),100*(.2126*e+.7152*n+.0722*a),100*(.0193*e+.1192*n+.9505*a)]}function c(t){var e=u(t),n=e[0],a=e[1],r=e[2];return a/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116)-16,500*(n-a),200*(a-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]}function l(t){var e,n,a,r,i,s=t[0]/360,o=t[1]/100,u=t[2]/100;if(0==o)return[i=255*u,i,i];e=2*u-(n=u<.5?u*(1+o):u+o-u*o),r=[0,0,0];for(var c=0;c<3;c++)(a=s+1/3*-(c-1))<0&&a++,a>1&&a--,r[c]=255*(i=6*a<1?e+6*(n-e)*a:2*a<1?n:3*a<2?e+(n-e)*(2/3-a)*6:e);return r}function d(t){var e=t[0]/60,n=t[1]/100,a=t[2]/100,r=Math.floor(e)%6,i=e-Math.floor(e),s=255*a*(1-n),o=255*a*(1-n*i),u=255*a*(1-n*(1-i));switch(a*=255,r){case 0:return[a,u,s];case 1:return[o,a,s];case 2:return[s,a,u];case 3:return[s,o,a];case 4:return[u,s,a];case 5:return[a,s,o]}}function f(t){var e,n,a,i,s=t[0]/360,o=t[1]/100,u=t[2]/100,c=o+u;switch(c>1&&(o/=c,u/=c),a=6*s-(e=Math.floor(6*s)),0!=(1&e)&&(a=1-a),i=o+a*((n=1-u)-o),e){default:case 6:case 0:r=n,g=i,b=o;break;case 1:r=i,g=n,b=o;break;case 2:r=o,g=n,b=i;break;case 3:r=o,g=i,b=n;break;case 4:r=i,g=o,b=n;break;case 5:r=n,g=o,b=i}return[255*r,255*g,255*b]}function p(t){var e=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,t[0]/100*(1-a)+a)),255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]}function h(t){var e,n,a,r=t[0]/100,i=t[1]/100,s=t[2]/100;return n=-.9689*r+1.8758*i+.0415*s,a=.0557*r+-.204*i+1.057*s,e=(e=3.2406*r+-1.5372*i+-.4986*s)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(a=Math.min(Math.max(0,a),1))]}function m(t){var e=t[0],n=t[1],a=t[2];return n/=100,a/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function y(t){var e,n,a,r,i=t[0],s=t[1],o=t[2];return i<=8?r=(n=100*i/903.3)/100*7.787+16/116:(n=100*Math.pow((i+16)/116,3),r=Math.pow(n/100,1/3)),[e=e/95.047<=.008856?e=95.047*(s/500+r-16/116)/7.787:95.047*Math.pow(s/500+r,3),n,a=a/108.883<=.008859?a=108.883*(r-o/200-16/116)/7.787:108.883*Math.pow(r-o/200,3)]}function v(t){var e,n=t[0],a=t[1],r=t[2];return(e=360*Math.atan2(r,a)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(a*a+r*r),e]}function _(t){return h(y(t))}function x(t){var e,n=t[1];return e=t[2]/360*2*Math.PI,[t[0],n*Math.cos(e),n*Math.sin(e)]}function T(t){return w[t]}t.exports={rgb2hsl:n,rgb2hsv:a,rgb2hwb:i,rgb2cmyk:s,rgb2keyword:o,rgb2xyz:u,rgb2lab:c,rgb2lch:function(t){return v(c(t))},hsl2rgb:l,hsl2hsv:function(t){var e=t[1]/100,n=t[2]/100;return 0===n?[0,0,0]:[t[0],2*(e*=(n*=2)<=1?n:2-n)/(n+e)*100,(n+e)/2*100]},hsl2hwb:function(t){return i(l(t))},hsl2cmyk:function(t){return s(l(t))},hsl2keyword:function(t){return o(l(t))},hsv2rgb:d,hsv2hsl:function(t){var e,n,a=t[1]/100,r=t[2]/100;return e=a*r,[t[0],100*(e=(e/=(n=(2-a)*r)<=1?n:2-n)||0),100*(n/=2)]},hsv2hwb:function(t){return i(d(t))},hsv2cmyk:function(t){return s(d(t))},hsv2keyword:function(t){return o(d(t))},hwb2rgb:f,hwb2hsl:function(t){return n(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return o(f(t))},cmyk2rgb:p,cmyk2hsl:function(t){return n(p(t))},cmyk2hsv:function(t){return a(p(t))},cmyk2hwb:function(t){return i(p(t))},cmyk2keyword:function(t){return o(p(t))},keyword2rgb:T,keyword2hsl:function(t){return n(T(t))},keyword2hsv:function(t){return a(T(t))},keyword2hwb:function(t){return i(T(t))},keyword2cmyk:function(t){return s(T(t))},keyword2lab:function(t){return c(T(t))},keyword2xyz:function(t){return u(T(t))},xyz2rgb:h,xyz2lab:m,xyz2lch:function(t){return v(m(t))},lab2xyz:y,lab2rgb:_,lab2lch:v,lch2lab:x,lch2xyz:function(t){return y(x(t))},lch2rgb:function(t){return _(x(t))}};var w={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},S={};for(var O in w)S[JSON.stringify(w[O])]=O},t9fZ:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("mrSG"),r=n("FFOo"),i=n("b7mW"),s=n("G5J1");function o(t){return function(e){return 0===t?Object(s.b)():e.lift(new u(t))}}var u=function(){function t(t){if(this.total=t,this.total<0)throw new i.a}return t.prototype.call=function(t,e){return e.subscribe(new c(t,this.total))},t}(),c=function(t){function e(e,n){var a=t.call(this,e)||this;return a.total=n,a.count=0,a}return a.__extends(e,t),e.prototype._next=function(t){var e=this.total,n=++this.count;n<=e&&(this.destination.next(t),n===e&&(this.destination.complete(),this.unsubscribe()))},e}(r.a)},tAZD:function(t,e,n){var a,r,i;!function(s){if("object"==typeof t.exports){var o=s(0,e);void 0!==o&&(t.exports=o)}else r=[n,e],void 0===(i="function"==typeof(a=s)?a.apply(e,r):a)||(t.exports=i)}(function(t,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=void 0;e.default=["en",[["a","p"],["AM","PM"],n],[["AM","PM"],n,n],[["S","M","T","W","T","F","S"],["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["Su","Mo","Tu","We","Th","Fr","Sa"]],n,[["J","F","M","A","M","J","J","A","S","O","N","D"],["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],["January","February","March","April","May","June","July","August","September","October","November","December"]],n,[["B","A"],["BC","AD"],["Before Christ","Anno Domini"]],0,[6,0],["M/d/yy","MMM d, y","MMMM d, y","EEEE, MMMM d, y"],["h:mm a","h:mm:ss a","h:mm:ss a z","h:mm:ss a zzzz"],["{1}, {0}",n,"{1} 'at' {0}",n],[".",",",";","%","+","-","E","\xd7","\u2030","\u221e","NaN",":"],["#,##0.###","#,##0%","\xa4#,##0.00","#E0"],"$","US Dollar",{},function(t){var e=Math.floor(Math.abs(t)),n=t.toString().replace(/^[^.]*\.?/,"").length;return 1===e&&0===n?1:5}]})},tFKq:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata,i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,n=1,a=arguments.length;n=e.maxWidth&&(t=e.maxWidth),this.resize.emit({column:e,prevValue:e.width,newValue:t})},t.prototype.onColumnReordered=function(t){var e=t.prevIndex,n=t.newIndex,a=t.model,r=this.getColumn(n);r.isTarget=!1,r.targetMarkerContext=void 0,this.reorder.emit({column:a,prevValue:e,newValue:n})},t.prototype.onTargetChanged=function(t){var e=t.prevIndex,n=t.newIndex,a=t.initialIndex;if(e||0===e){var r=this.getColumn(e);r.isTarget=!1,r.targetMarkerContext=void 0}if(n||0===n){var i=this.getColumn(n);i.isTarget=!0,a!==n&&(i.targetMarkerContext={class:"targetMarker ".concat(a>n?"dragFromRight":"dragFromLeft")})}},t.prototype.getColumn=function(t){var e=this._columnsByPin[0].columns.length;if(t\n \n \n \n \n \n ',host:{class:"datatable-header"},changeDetection:s.ChangeDetectionStrategy.OnPush})],t)}()},tGlX:function(t,e,n){!function(t){"use strict";function e(t,e,n,a){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[t+" Tage",t+" Tagen"],M:["ein Monat","einem Monat"],MM:[t+" Monate",t+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[t+" Jahre",t+" Jahren"]};return e?r[n][0]:r[n][1]}n("wd/R").defineLocale("de",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:e,mm:"%d Minuten",h:e,hh:"%d Stunden",d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},tHPV:function(t,e,n){"use strict";var a=n("mrSG"),r=function(t){function e(e,n){var a=t.call(this,e,n)||this;return a.scheduler=e,a.work=n,a}return a.__extends(e,t),e.prototype.requestAsyncId=function(e,n,a){return void 0===a&&(a=0),null!==a&&a>0?t.prototype.requestAsyncId.call(this,e,n,a):(e.actions.push(this),e.scheduled||(e.scheduled=requestAnimationFrame(function(){return e.flush(null)})))},e.prototype.recycleAsyncId=function(e,n,a){if(void 0===a&&(a=0),null!==a&&a>0||null===a&&this.delay>0)return t.prototype.recycleAsyncId.call(this,e,n,a);0===e.actions.length&&(cancelAnimationFrame(n),e.scheduled=void 0)},e}(n("h9Dq").a),i=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return a.__extends(e,t),e.prototype.flush=function(t){this.active=!0,this.scheduled=void 0;var e,n=this.actions,a=-1,r=n.length;t=t||n.shift();do{if(e=t.execute(t.state,t.delay))break}while(++a=11?t:t+12:"sonten"===e||"ndalu"===e?t+12:void 0},meridiem:function(t,e,n){return t<11?"enjing":t<15?"siyang":t<19?"sonten":"ndalu"},calendar:{sameDay:"[Dinten puniko pukul] LT",nextDay:"[Mbenjang pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kala wingi pukul] LT",lastWeek:"dddd [kepengker pukul] LT",sameElse:"L"},relativeTime:{future:"wonten ing %s",past:"%s ingkang kepengker",s:"sawetawis detik",ss:"%d detik",m:"setunggal menit",mm:"%d menit",h:"setunggal jam",hh:"%d jam",d:"sedinten",dd:"%d dinten",M:"sewulan",MM:"%d wulan",y:"setaun",yy:"%d taun"},week:{dow:1,doy:7}})}()},tjFV:function(t,e,n){"use strict";var a=n("CDJp"),r=n("RDha"),i=n("fELs");t.exports={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=r.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?r.merge({},[a.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=r.extend(this.defaults[t],e))},addScalesToLayout:function(t){r.each(t.scales,function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,i.addBox(t,e)})}}},ty8c:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("CcnG"),r=n("1PfE");e.NodeEditableDirective=function(){function t(t,e){this.renderer=t,this.elementRef=e,this.valueChanged=new a.EventEmitter(!1)}return t.prototype.ngOnInit=function(){var t=this.elementRef.nativeElement;t&&t.focus(),this.renderer.setProperty(t,"value",this.nodeValue)},t.prototype.applyNewValue=function(t){this.valueChanged.emit({type:"keyup",value:t})},t.prototype.applyNewValueByLoosingFocus=function(t){this.valueChanged.emit({type:"blur",value:t})},t.prototype.cancelEditing=function(){this.valueChanged.emit({type:"keyup",value:this.nodeValue,action:r.NodeEditableEventAction.Cancel})},t.decorators=[{type:a.Directive,args:[{selector:"[nodeEditable]"}]}],t.propDecorators={nodeValue:[{type:a.Input,args:["nodeEditable"]}],valueChanged:[{type:a.Output}],applyNewValue:[{type:a.HostListener,args:["keyup.enter",["$event.target.value"]]}],applyNewValueByLoosingFocus:[{type:a.HostListener,args:["blur",["$event.target.value"]]}],cancelEditing:[{type:a.HostListener,args:["keyup.esc"]}]},t}()},u0Op:function(t,e,n){"use strict";var a=n("TC34"),r={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,a=1;return 0===t?0:1===t?1:(n||(n=.3),a<1?(a=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/a),-a*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,a=1;return 0===t?0:1===t?1:(n||(n=.3),a<1?(a=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/a),a*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,a=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),a<1?(a=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/a),t<1?a*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:a*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-r.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*r.easeInBounce(2*t):.5*r.easeOutBounce(2*t-1)+.5}};t.exports={effects:r},a.easingEffects=r},u3GI:function(t,e,n){!function(t){"use strict";function e(t,e,n,a){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[t+" Tage",t+" Tagen"],M:["ein Monat","einem Monat"],MM:[t+" Monate",t+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[t+" Jahre",t+" Jahren"]};return e?r[n][0]:r[n][1]}n("wd/R").defineLocale("de-ch",{months:"Januar_Februar_M\xe4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._M\xe4rz_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:e,mm:"%d Minuten",h:e,hh:"%d Stunden",d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},uEye:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sundag_m\xe5ndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"sun_m\xe5n_tys_ons_tor_fre_lau".split("_"),weekdaysMin:"su_m\xe5_ty_on_to_fr_l\xf8".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I g\xe5r klokka] LT",lastWeek:"[F\xf8reg\xe5ande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s sidan",s:"nokre sekund",ss:"%d sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",M:"ein m\xe5nad",MM:"%d m\xe5nader",y:"eit \xe5r",yy:"%d \xe5r"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},uIqm:function(t,e,n){"use strict";var a=n("CcnG"),r=n("y9jh"),i=n("LvDl"),s=n("gI3B"),o=n("6blF"),u=n("x38r"),c=function(){return function(t){this.errorConfig={resetData:!0,displayError:!0},this.error=t}}(),l=n("vCyI");n.d(e,"a",function(){return d});var d=function(){function t(t,e){this.ngZone=t,this.cdRef=e,this.columnMode="flex",this.toolHeader=!0,this.header=!0,this.footer=!0,this.limit=10,this.autoReload=5e3,this.identifier="id",this.forceIdentifier=!1,this.selectionType=void 0,this.updateSelectionOnRefresh="onChange",this.autoSave=!0,this.searchableObjects=!1,this.fetchData=new a.EventEmitter,this.updateSelection=new a.EventEmitter,this.selection=new l.a,this.cellTemplates={},this.search="",this.rows=[],this.loadingIndicator=!0,this.loadingError=!1,this.paginationClasses={pagerLeftArrow:"i fa fa-angle-double-left",pagerRightArrow:"i fa fa-angle-double-right",pagerPrevious:"i fa fa-angle-left",pagerNext:"i fa fa-angle-right"},this.userConfig={},this.localStorage=window.localStorage,this.updating=!1}return t.prototype.ngOnInit=function(){var t=this;if(window.addEventListener("mouseenter",function(t){t.stopPropagation()},!0),this._addTemplates(),!this.sorts){var e=-1!==i.findIndex(this.columns,["prop",this.identifier]);this.sorts=this.createSortingDefinition(e?this.identifier:this.columns[0].prop+""),e||this.forceIdentifier||(this.identifier=this.columns[0].prop+"")}this.initUserConfig(),this.columns.forEach(function(e){e.cellTransformation&&(e.cellTemplate=t.cellTemplates[e.cellTransformation]),e.flexGrow||(e.flexGrow=e.prop+""===t.identifier?1:2),e.resizeable||(e.resizeable=!1)}),this.filterHiddenColumns(),this.fetchData.observers.length>0&&(this.loadingIndicator=!0),i.isInteger(this.autoReload)&&this.autoReload>0?this.ngZone.runOutsideAngular(function(){t.reloadSubscriber=Object(s.a)(0,t.autoReload).subscribe(function(){t.ngZone.run(function(){return t.reloadData()})})}):this.reloadData()},t.prototype.initUserConfig=function(){var t=this;this.autoSave&&(this.tableName=this._calculateUniqueTableName(this.columns),this._loadUserConfig(),this._initUserConfigAutoSave()),this.userConfig.limit||(this.userConfig.limit=this.limit),this.userConfig.sorts||(this.userConfig.sorts=this.sorts),this.userConfig.columns?this.columns.forEach(function(e,n){e.isHidden=t.userConfig.columns[n].isHidden}):this.updateUserColumns()},t.prototype._calculateUniqueTableName=function(t){var e=function(t){if(!i.isString(t))return 0;for(var e=0,n=0;n0&&(this.userConfig.limit=e)},t.prototype.reloadData=function(){var t=this;if(!this.updating){this.loadingError=!1;var e=new c(function(){t.loadingError=e.errorConfig.displayError,e.errorConfig.resetData&&(t.data=[]),t.useData()});this.fetchData.emit(e),this.updating=!0}},t.prototype.refreshBtn=function(){this.loadingIndicator=!0,this.reloadData()},t.prototype.rowIdentity=function(){var t=this;return function(e){var n=e[t.identifier];if(i.isUndefined(n))throw new Error('Wrong identifier "'+t.identifier+'" -> "'+n+'"');return n}},t.prototype.useData=function(){this.data&&(this.search.length>0?this.updateFilter():this.rows=this.data.slice(),this.reset(),this.updateSelected())},t.prototype.reset=function(){this.loadingIndicator=!1,this.updating=!1},t.prototype.updateSelected=function(){var t=this;if("never"!==this.updateSelectionOnRefresh){var e=[];this.selection.selected.forEach(function(n){for(var a=0,r=t.data;a0}),n),this.table.offset=0},t.prototype.subSearch=function(t,e,n){if(0===e.length||0===t.length)return t;var a=e.pop().replace("+"," ").split(":"),r=n.slice();return 2===a.length&&(n=r.filter(function(t){return-1!==t.name.toLowerCase().indexOf(a[0])})),t=this.basicDataSearch(i.last(a),t,n),this.subSearch(t,e,r)},t.prototype.basicDataSearch=function(t,e,n){var a=this;return 0===t.length?e:e.filter(function(e){return n.filter(function(n){var r=i.get(e,n.prop);if(i.isUndefined(n.pipe)||(r=n.pipe.transform(r)),i.isUndefined(r)||i.isNull(r))return!1;if(i.isArray(r)?r=r.join(" "):(i.isNumber(r)||i.isBoolean(r))&&(r=r.toString()),i.isObjectLike(r)){if(!a.searchableObjects)return!1;r=JSON.stringify(r)}return-1!==r.toLowerCase().indexOf(t)}).length>0})},t.prototype.getRowClass=function(){var t=this;return function(){return{clickable:!i.isUndefined(t.selectionType)}}},t}()},uKs4:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG");e.VisibilityDirective=function(){function t(t,e){this.element=t,this.zone=e,this.isVisible=!1,this.visible=new i.EventEmitter}return t.prototype.ngOnInit=function(){this.runCheck()},t.prototype.ngOnDestroy=function(){clearTimeout(this.timeout)},t.prototype.onVisibilityChange=function(){var t=this;this.zone.run(function(){t.isVisible=!0,t.visible.emit(!0)})},t.prototype.runCheck=function(){var t=this,e=function(){var n=t.element.nativeElement;n.offsetHeight&&n.offsetWidth?(clearTimeout(t.timeout),t.onVisibilityChange()):(clearTimeout(t.timeout),t.zone.runOutsideAngular(function(){t.timeout=setTimeout(function(){return e()},50)}))};this.timeout=setTimeout(function(){return e()})},a([i.HostBinding("class.visible"),r("design:type",Boolean)],t.prototype,"isVisible",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"visible",void 0),a([i.Directive({selector:"[visibilityObserver]"})],t)}()},uMaO:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("mrSG"),r=function(t){function e(e,n){var a=t.call(this)||this;return a.subject=e,a.subscriber=n,a.closed=!1,a}return a.__extends(e,t),e.prototype.unsubscribe=function(){if(!this.closed){this.closed=!0;var t=this.subject,e=t.observers;if(this.subject=null,e&&0!==e.length&&!t.isStopped&&!t.closed){var n=e.indexOf(this.subscriber);-1!==n&&e.splice(n,1)}}},e}(n("pugT").a)},uXwI:function(t,e,n){!function(t){"use strict";var e={ss:"sekundes_sekund\u0113m_sekunde_sekundes".split("_"),m:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),mm:"min\u016btes_min\u016bt\u0113m_min\u016bte_min\u016btes".split("_"),h:"stundas_stund\u0101m_stunda_stundas".split("_"),hh:"stundas_stund\u0101m_stunda_stundas".split("_"),d:"dienas_dien\u0101m_diena_dienas".split("_"),dd:"dienas_dien\u0101m_diena_dienas".split("_"),M:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),MM:"m\u0113ne\u0161a_m\u0113ne\u0161iem_m\u0113nesis_m\u0113ne\u0161i".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")};function n(t,e,n){return n?e%10==1&&e%100!=11?t[2]:t[3]:e%10==1&&e%100!=11?t[0]:t[1]}function a(t,a,r){return t+" "+n(e[r],t,a)}function r(t,a,r){return n(e[r],t,a)}t.defineLocale("lv",{months:"janv\u0101ris_febru\u0101ris_marts_apr\u012blis_maijs_j\u016bnijs_j\u016blijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_j\u016bn_j\u016bl_aug_sep_okt_nov_dec".split("_"),weekdays:"sv\u0113tdiena_pirmdiena_otrdiena_tre\u0161diena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[\u0160odien pulksten] LT",nextDay:"[R\u012bt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pag\u0101ju\u0161\u0101] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"p\u0113c %s",past:"pirms %s",s:function(t,e){return e?"da\u017eas sekundes":"da\u017e\u0101m sekund\u0113m"},ss:a,m:r,mm:a,h:r,hh:a,d:r,dd:a,M:r,MM:a,y:r,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n("wd/R"))},uYzU:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){}return t.prototype.transform=function(t){switch(t){case"user:rbd":return"user:rbd (tcmu-runner)";default:return t}},t}()},ufoC:function(t,e,n){"use strict";var a;!function(t){t.auth="Login",t.cephfs="CephFS",t.rbd="RBD",t.pool="Pool",t.osd="OSD",t.role="Role",t.user="User"}(a||(a={}));var r=n("CcnG"),i=n("Jm/i");n.d(e,"a",function(){return u});var s=function(){return function(t,e,n){this.running=t,this.failure=e,this.success=n}}(),o=function(){function t(t,e,n,a){this.i18n=t,this.operation=e,this.involves=n,this.errors=a||function(){return{}}}return t.prototype.failure=function(t){return this.i18n("Failed to {{failure}} {{metadata}}",{failure:this.operation.failure,metadata:this.involves(t)})},t.prototype.running=function(t){return this.operation.running+" "+this.involves(t)},t.prototype.success=function(t){return this.operation.success+" "+this.involves(t)},t}(),u=function(){function t(t){var e=this;this.i18n=t,this.defaultMessage=this.newTaskMessage(new s(this.i18n("Executing"),this.i18n("execute"),this.i18n("Executed")),function(t){return t&&(a[t.component]||t.component)||e.i18n("unknown task")},function(){return{}}),this.commonOperations={create:new s(this.i18n("Creating"),this.i18n("create"),this.i18n("Created")),update:new s(this.i18n("Updating"),this.i18n("update"),this.i18n("Updated")),delete:new s(this.i18n("Deleting"),this.i18n("delete"),this.i18n("Deleted"))},this.rbd={default:function(t){return e.i18n("RBD '{{id}}'",{id:t.pool_name+"/"+t.image_name})},child:function(t){return e.i18n("RBD '{{id}}'",{id:t.child_pool_name+"/"+t.child_image_name})},destination:function(t){return e.i18n("RBD '{{id}}'",{id:t.dest_pool_name+"/"+t.dest_image_name})},snapshot:function(t){return e.i18n("RBD snapshot '{{id}}'",{id:t.pool_name+"/"+t.image_name+"@"+t.snapshot_name})}},this.rbd_mirroring={pool:function(t){return e.i18n("mirror mode for pool '{{id}}'",{id:""+t.pool_name})},pool_peer:function(t){return e.i18n("mirror peer for pool '{{id}}'",{id:""+t.pool_name})}},this.grafana={update_dashboards:function(){return e.i18n("all dashboards")}},this.messages={"pool/create":this.newTaskMessage(this.commonOperations.create,function(t){return e.pool(t)},function(t){return{17:e.i18n("Name is already used by {{pool_name}}.",{pool_name:e.pool(t)})}}),"pool/edit":this.newTaskMessage(this.commonOperations.update,function(t){return e.pool(t)},function(t){return{17:e.i18n("Name is already used by {{pool_name}}.",{pool_name:e.pool(t)})}}),"pool/delete":this.newTaskMessage(this.commonOperations.delete,function(t){return e.pool(t)}),"ecp/create":this.newTaskMessage(this.commonOperations.create,function(t){return e.ecp(t)},function(t){return{17:e.i18n("Name is already used by {{name}}.",{name:e.ecp(t)})}}),"ecp/delete":this.newTaskMessage(this.commonOperations.delete,function(t){return e.ecp(t)}),"rbd/create":this.newTaskMessage(this.commonOperations.create,this.rbd.default,function(t){return{17:e.i18n("Name is already used by {{rbd_name}}.",{rbd_name:e.rbd.default(t)})}}),"rbd/edit":this.newTaskMessage(this.commonOperations.update,this.rbd.default,function(t){return{17:e.i18n("Name is already used by {{rbd_name}}.",{rbd_name:e.rbd.default(t)})}}),"rbd/delete":this.newTaskMessage(this.commonOperations.delete,this.rbd.default,function(t){return{39:e.i18n("{{rbd_name}} contains snapshots.",{rbd_name:e.rbd.default(t)})}}),"rbd/clone":this.newTaskMessage(new s(this.i18n("Cloning"),this.i18n("clone"),this.i18n("Cloned")),this.rbd.child,function(t){return{17:e.i18n("Name is already used by {{rbd_name}}.",{rbd_name:e.rbd.child(t)}),22:e.i18n("Snapshot of {{rbd_name}} must be protected.",{rbd_name:e.rbd.child(t)})}}),"rbd/copy":this.newTaskMessage(new s(this.i18n("Copying"),this.i18n("copy"),this.i18n("Copied")),this.rbd.destination,function(t){return{17:e.i18n("Name is already used by {{rbd_name}}.",{rbd_name:e.rbd.destination(t)})}}),"rbd/flatten":this.newTaskMessage(new s(this.i18n("Flattening"),this.i18n("flatten"),this.i18n("Flattened")),this.rbd.default),"rbd/snap/create":this.newTaskMessage(this.commonOperations.create,this.rbd.snapshot,function(t){return{17:e.i18n("Name is already used by {{snap_name}}.",{snap_name:e.rbd.snapshot(t)})}}),"rbd/snap/edit":this.newTaskMessage(this.commonOperations.update,this.rbd.snapshot,function(t){return{16:e.i18n("Cannot unprotect {{snap_name}} because it contains child images.",{snap_name:e.rbd.snapshot(t)})}}),"rbd/snap/delete":this.newTaskMessage(this.commonOperations.delete,this.rbd.snapshot,function(t){return{16:e.i18n("Cannot delete {{snap_name}} because it's protected.",{snap_name:e.rbd.snapshot(t)})}}),"rbd/snap/rollback":this.newTaskMessage(new s(this.i18n("Rolling back"),this.i18n("rollback"),this.i18n("Rolled back")),this.rbd.snapshot),"rbd/trash/move":this.newTaskMessage(new s(this.i18n("Moving"),this.i18n("move"),this.i18n("Moved")),function(t){return e.i18n("image '{{id}}' to trash",{id:t.pool_name+"/"+t.image_name})},function(){return{2:e.i18n("Could not find image.")}}),"rbd/trash/restore":this.newTaskMessage(new s(this.i18n("Restoring"),this.i18n("restore"),this.i18n("Restored")),function(t){return e.i18n("image '{{id}}' into '{{new_id}}'",{id:t.pool_name+"@"+t.image_id,new_id:t.pool_name+"/"+t.new_image_name})},function(t){return{17:e.i18n("Image name '{{id}}' is already in use.",{id:t.pool_name+"/"+t.new_image_name})}}),"rbd/trash/remove":this.newTaskMessage(new s(this.i18n("Deleting"),this.i18n("delete"),this.i18n("Deleted")),function(t){return e.i18n("image '{{id}}'",{id:t.pool_name+"/"+t.image_name+"@"+t.image_id})}),"rbd/trash/purge":this.newTaskMessage(new s(this.i18n("Purging"),this.i18n("purge"),this.i18n("Purged")),function(t){var n=e.i18n("all pools");return t.pool_name&&(n="'"+t.pool_name+"'"),e.i18n("images from {{message}}",{message:n})}),"rbd/mirroring/pool/edit":this.newTaskMessage(this.commonOperations.update,this.rbd_mirroring.pool,function(){return{16:e.i18n("Cannot disable mirroring because it contains a peer.")}}),"rbd/mirroring/peer/add":this.newTaskMessage(this.commonOperations.create,this.rbd_mirroring.pool_peer,function(){return{}}),"rbd/mirroring/peer/edit":this.newTaskMessage(this.commonOperations.update,this.rbd_mirroring.pool_peer,function(){return{}}),"rbd/mirroring/peer/delete":this.newTaskMessage(this.commonOperations.delete,this.rbd_mirroring.pool_peer,function(){return{}}),"iscsi/target/create":this.newTaskMessage(this.commonOperations.create,function(t){return e.iscsiTarget(t)}),"iscsi/target/edit":this.newTaskMessage(this.commonOperations.update,function(t){return e.iscsiTarget(t)}),"iscsi/target/delete":this.newTaskMessage(this.commonOperations.delete,function(t){return e.iscsiTarget(t)}),"nfs/create":this.newTaskMessage(this.commonOperations.create,function(t){return e.nfs(t)}),"nfs/edit":this.newTaskMessage(this.commonOperations.update,function(t){return e.nfs(t)}),"nfs/delete":this.newTaskMessage(this.commonOperations.delete,function(t){return e.nfs(t)}),"grafana/dashboards/update":this.newTaskMessage(this.commonOperations.update,this.grafana.update_dashboards,function(){return{}})}}return t.prototype.newTaskMessage=function(t,e,n){return new o(this.i18n,t,e,n)},t.prototype.pool=function(t){return this.i18n("pool '{{pool_name}}'",{pool_name:t.pool_name})},t.prototype.ecp=function(t){return this.i18n("erasure code profile '{{name}}'",{name:t.name})},t.prototype.iscsiTarget=function(t){return this.i18n("target '{{target_iqn}}'",{target_iqn:t.target_iqn})},t.prototype.nfs=function(t){return this.i18n("NFS {{nfs_id}}",{nfs_id:"'"+t.cluster_id+":"+(t.export_id?t.export_id:t.path)+"'"})},t.prototype._getTaskTitle=function(t){return this.messages[t.name]||this.defaultMessage},t.prototype.getSuccessTitle=function(t){return this._getTaskTitle(t).success(t.metadata)},t.prototype.getErrorMessage=function(t){return this._getTaskTitle(t).errors(t.metadata)[t.exception.code]||t.exception.detail},t.prototype.getErrorTitle=function(t){return this._getTaskTitle(t).failure(t.metadata)},t.prototype.getRunningTitle=function(t){return this._getTaskTitle(t).running(t.metadata)},t.prototype.getRunningText=function(t){return this._getTaskTitle(t).operation.running},t.ngInjectableDef=r.defineInjectable({factory:function(){return new t(r.inject(i.a))},token:t,providedIn:"root"}),t}()},uhwM:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(){function t(){}return t.prototype.transform=function(t){return t.join(", ")},t}()},urB8:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("CcnG"),r=n("buEt"),i=n("QGcS");e.NodeDraggableService=function(){function t(){this.draggableNodeEvents$=new r.Subject}return t.prototype.fireNodeDragged=function(t,e){t.tree&&!t.tree.isStatic()&&this.draggableNodeEvents$.next(new i.NodeDraggableEvent(t,e))},t.prototype.captureNode=function(t){this.capturedNode=t},t.prototype.getCapturedNode=function(){return this.capturedNode},t.prototype.releaseCapturedNode=function(){this.capturedNode=null},t.decorators=[{type:a.Injectable}],t}()},uxXc:function(t,e,n){var a=n("t1N5"),r=function(){return new c};for(var i in a){r[i+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),a[t](e)}}(i);var s=/(\w+)2(\w+)/.exec(i),o=s[1],u=s[2];(r[o]=r[o]||{})[u]=r[i]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=a[t](e);if("string"==typeof n||void 0===n)return n;for(var r=0;r0,this.hasSingleSelection=1===this.selected.length,this.hasMultiSelection=this.selected.length>1},t.prototype.first=function(){return this.hasSelection?this.selected[0]:null},t}()},vOVK:function(t,e,n){var a={"./messages.cs.xlf":"MaEZ","./messages.de-DE.xlf":"BY/9","./messages.es-ES.xlf":"csGn","./messages.fr-FR.xlf":"obpP","./messages.id-ID.xlf":"nmKl","./messages.it-IT.xlf":"hHou","./messages.ja-JP.xlf":"waXJ","./messages.ko-KR.xlf":"Q3dv","./messages.pl-PL.xlf":"/6aS","./messages.pt-BR.xlf":"OWV/","./messages.zh-CN.xlf":"fB8H","./messages.zh-TW.xlf":"Dysq"};function r(t){var e=i(t);return n(e)}function i(t){var e=a[t];if(!(e+1)){var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}return e}r.keys=function(){return Object.keys(a)},r.resolve=i,t.exports=r,r.id="vOVK"},vpM6:function(t,e,n){"use strict";var a=n("CDJp"),r=n("vvH+"),i=n("RDha");a._set("global",{plugins:{filler:{propagate:!0}}});var s={dataset:function(t){var e=t.fill,n=t.chart,a=n.getDatasetMeta(e),r=a&&n.isDatasetVisible(e)&&a.dataset._children||[],i=r.length||0;return i?function(t,e){return e=n)&&a;switch(i){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return i;default:return!1}}function u(t){var e,n=t.el._model||{},a=t.el._scale||{},r=t.fill,i=null;if(isFinite(r))return null;if("start"===r?i=void 0===n.scaleBottom?a.bottom:n.scaleBottom:"end"===r?i=void 0===n.scaleTop?a.top:n.scaleTop:void 0!==n.scaleZero?i=n.scaleZero:a.getBasePosition?i=a.getBasePosition():a.getBasePixel&&(i=a.getBasePixel()),null!=i){if(void 0!==i.x&&void 0!==i.y)return i;if("number"==typeof i&&isFinite(i))return{x:(e=a.isHorizontal())?i:null,y:e?null:i}}return null}function c(t,e,n){var a,r=t[e].fill,i=[e];if(!n)return r;for(;!1!==r&&-1===i.indexOf(r);){if(!isFinite(r))return r;if(!(a=t[r]))return!1;if(a.visible)return r;i.push(r),r=a.fill}return!1}function l(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),s[n](t))}function d(t){return t&&!t.skip}function f(t,e,n,a,r){var s;if(a&&r){for(t.moveTo(e[0].x,e[0].y),s=1;s0;--s)i.canvas.lineTo(t,n[s],n[s-1],!0)}}t.exports={id:"filler",afterDatasetsUpdate:function(t,e){var n,a,i,s,d=(t.data.datasets||[]).length,f=e.propagate,p=[];for(a=0;a=2;return function(c){return c.pipe(t?Object(r.a)(function(e,n){return t(e,n,c)}):u.a,Object(i.a)(1),n?Object(o.a)(e):Object(s.a)(function(){return new a.a}))}}},wQk9:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("tzm",{months:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),monthsShort:"\u2d49\u2d4f\u2d4f\u2d30\u2d62\u2d54_\u2d31\u2d55\u2d30\u2d62\u2d55_\u2d4e\u2d30\u2d55\u2d5a_\u2d49\u2d31\u2d54\u2d49\u2d54_\u2d4e\u2d30\u2d62\u2d62\u2d53_\u2d62\u2d53\u2d4f\u2d62\u2d53_\u2d62\u2d53\u2d4d\u2d62\u2d53\u2d63_\u2d56\u2d53\u2d5b\u2d5c_\u2d5b\u2d53\u2d5c\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d3d\u2d5f\u2d53\u2d31\u2d55_\u2d4f\u2d53\u2d61\u2d30\u2d4f\u2d31\u2d49\u2d54_\u2d37\u2d53\u2d4a\u2d4f\u2d31\u2d49\u2d54".split("_"),weekdays:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysShort:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),weekdaysMin:"\u2d30\u2d59\u2d30\u2d4e\u2d30\u2d59_\u2d30\u2d62\u2d4f\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4f\u2d30\u2d59_\u2d30\u2d3d\u2d54\u2d30\u2d59_\u2d30\u2d3d\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d4e\u2d61\u2d30\u2d59_\u2d30\u2d59\u2d49\u2d39\u2d62\u2d30\u2d59".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[\u2d30\u2d59\u2d37\u2d45 \u2d34] LT",nextDay:"[\u2d30\u2d59\u2d3d\u2d30 \u2d34] LT",nextWeek:"dddd [\u2d34] LT",lastDay:"[\u2d30\u2d5a\u2d30\u2d4f\u2d5c \u2d34] LT",lastWeek:"dddd [\u2d34] LT",sameElse:"L"},relativeTime:{future:"\u2d37\u2d30\u2d37\u2d45 \u2d59 \u2d62\u2d30\u2d4f %s",past:"\u2d62\u2d30\u2d4f %s",s:"\u2d49\u2d4e\u2d49\u2d3d",ss:"%d \u2d49\u2d4e\u2d49\u2d3d",m:"\u2d4e\u2d49\u2d4f\u2d53\u2d3a",mm:"%d \u2d4e\u2d49\u2d4f\u2d53\u2d3a",h:"\u2d59\u2d30\u2d44\u2d30",hh:"%d \u2d5c\u2d30\u2d59\u2d59\u2d30\u2d44\u2d49\u2d4f",d:"\u2d30\u2d59\u2d59",dd:"%d o\u2d59\u2d59\u2d30\u2d4f",M:"\u2d30\u2d62o\u2d53\u2d54",MM:"%d \u2d49\u2d62\u2d62\u2d49\u2d54\u2d4f",y:"\u2d30\u2d59\u2d33\u2d30\u2d59",yy:"%d \u2d49\u2d59\u2d33\u2d30\u2d59\u2d4f"},week:{dow:6,doy:12}})}()},waXJ:function(t,e){t.exports='\n \n \n \n Toggle navigation\n \u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u306e\u5207\u308a\u66ff\u3048\n \n \n Dashboard\n \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\n \n \n Cluster\n \u30af\u30e9\u30b9\u30bf\n \n \n Hosts\n \u30db\u30b9\u30c8\n \n \n Monitors\n \u30e2\u30cb\u30bf\u30fc\n \n \n OSDs\n OSD\n \n \n Configuration\n \u8a2d\u5b9a\n \n \n CRUSH map\n CRUSH\u30de\u30c3\u30d7\n \n \n Manager modules\n \u30de\u30cd\u30fc\u30b8\u30e3\u30e2\u30b8\u30e5\u30fc\u30eb\n \n \n Logs\n \u30ed\u30b0\n \n \n Alerts\n \u30a2\u30e9\u30fc\u30c8\n \n \n Silences\n Silences\n \n \n Pools\n \u30d7\u30fc\u30eb\n \n \n Block\n \u30d6\u30ed\u30c3\u30af\n \n \n Images\n \u30a4\u30e1\u30fc\u30b8\n \n \n Mirroring\n \u30df\u30e9\u30fc\u30ea\u30f3\u30b0\n \n \n iSCSI\n iSCSI\n \n \n NFS\n NFS\n \n \n Filesystems\n \u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\n \n \n Object Gateway\n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\n \n \n Daemons\n \u30c7\u30fc\u30e2\u30f3\n \n \n Users\n \u30e6\u30fc\u30b6\n \n \n Buckets\n \u30d0\u30b1\u30c3\u30c8\n \n \n Retrieving data\n for\n \n \n . Please wait...\n \n Retrieving data\n for\n \n \n . Please wait...\n \n \n \n Displaying previously cached data\n \n for \n \n \n .\n \n Displaying previously cached data\n \n for \n \n \n .\n \n \n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n Could not load data\n for\n \n \n .\n Please check the cluster health.\n \n \n \n Back\n \u623b\u308b\n \n \n Select a Language\n \u8a00\u8a9e\u306e\u9078\u629e\n \n \n Loading panel data...\n \u30d1\u30cd\u30eb\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n \n \n Please consult the\n documentation\n on how to\n configure and enable the monitoring functionality.\n \n \u76e3\u8996\u6a5f\u80fd\u3092\u8a2d\u5b9a\u304a\u3088\u3073\u6709\u52b9\u5316\n\u3059\u308b\u65b9\u6cd5\u306b\u95a2\u3059\u308b\n \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\n \u3092\n\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n \n Grafana Dashboard doesn\'t exist. Please refer to\n documentation\n on how to\n add dashboards to Grafana.\n \n Grafana\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u304c\u5b58\u5728\u3057\u3066\u3044\u307e\u305b\u3093\u3002\nGrafana\u306b\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u3092\u8ffd\u52a0\u3059\u308b\u65b9\u6cd5\u306b\u95a2\u3059\u308b\n \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\n \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n \n Grafana Time Picker\n Grafana Time Picker\n \n \n Reset Settings\n \u8a2d\u5b9a\u306e\u30ea\u30bb\u30c3\u30c8\n \n \n Refresh\n Refresh\n \n \n Remove the custom configuration value. The default configuration will be inherited and used instead.\n Remove the custom configuration value. The default configuration will be inherited and used instead.\n \n \n The entered value is too high! It must not be greater than \n .\n \n The entered value is too high! It must not be greater than \n .\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n The entered value is too low! It must not be lower than \n .\n \n \n \n Failed to load data.\n \u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n \n \n selected\n \u9078\u629e\u6e08\u307f\n X selected\n \n \n found\n \u691c\u51fa\u6e08\u307f\n X found\n \n \n total\n \u5408\u8a08\n X total\n \n \n Edit\n \u7de8\u96c6\n \n \n Name\n \u540d\u524d\n \n \n Description\n \u8aac\u660e\n \n \n Long description\n \u9577\u3044\u8aac\u660e\n \n \n Default\n \u30c7\u30d5\u30a9\u30eb\u30c8\n \n \n Daemon default\n \u30c7\u30fc\u30e2\u30f3\u306e\u30c7\u30d5\u30a9\u30eb\u30c8\n \n \n Services\n \u30b5\u30fc\u30d3\u30b9\n \n \n Values\n \u5024\n \n \n The entered value is too high! It must not be greater than \n .\n \n \u5165\u529b\u3055\u308c\u305f\u5024\u306f\u5927\u304d\u3059\u304e\u307e\u3059\u3002\n \u3088\u308a\u5927\u304d\u3044\u5024\u3092\u5165\u529b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \u5165\u529b\u3055\u308c\u305f\u5024\u306f\u5c0f\u3055\u3059\u304e\u307e\u3059\u3002\n \u3088\u308a\u5c0f\u3055\u3044\u5024\u3092\u5165\u529b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n \n Save\n \u4fdd\u5b58\n \n \n CRUSH map viewer\n CRUSH\u30de\u30c3\u30d7\u30d3\u30e5\u30fc\u30a2\n \n \n Hosts List\n \u30db\u30b9\u30c8\u30ea\u30b9\u30c8\n \n \n Overall Performance\n \u5168\u4f53\u7684\u306a\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\n \n \n No entries found\n \u30a8\u30f3\u30c8\u30ea\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\n \n \n Cluster Logs\n \u30af\u30e9\u30b9\u30bf\u30ed\u30b0\n \n \n Audit Logs\n \u76e3\u67fb\u30ed\u30b0\n \n \n Priority:\n Priority:\n \n \n Keyword:\n Keyword:\n \n \n Date:\n Date:\n \n \n Datepicker\n Datepicker\n \n \n Time range:\n Time range:\n \n \n Loading configuration...\n \u8a2d\u5b9a\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n \n \n The configuration could not be loaded.\n \u8a2d\u5b9a\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n \n \n Edit Manager module\n \u30de\u30cd\u30fc\u30b8\u30e3\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u7de8\u96c6\n \n \n The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8\n \u5165\u529b\u3055\u308c\u305f\u5024\u306f\u6709\u52b9\u306aUUID\u3067\u306f\u3042\u308a\u307e\u305b\u3093(\u6709\u52b9\u306aUUID\u306e\u4f8b: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8)\u3002\n \n \n The entered value needs to be a valid IP address.\n \u6709\u52b9\u306aIP\u30a2\u30c9\u30ec\u30b9\u3092\u5165\u529b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n This field is required.\n \u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u306f\u5fc5\u9808\u3067\u3059\u3002\n \n \n The entered value is too high! It must be lower or equal to \n .\n \n \u5165\u529b\u3055\u308c\u305f\u5024\u306f\u5927\u304d\u3059\u304e\u307e\u3059\u3002\n \u4ee5\u4e0b\u306e\u5024\u3092\u5165\u529b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n \n The entered value is too low! It must be greater or equal to \n .\n \n \u5165\u529b\u3055\u308c\u305f\u5024\u306f\u5c0f\u3055\u3059\u304e\u307e\u3059\u3002\n \u4ee5\u4e0a\u306e\u5024\u3092\u5165\u529b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n \n The entered value needs to be a number.\n \u6570\u5b57\u3092\u5165\u529b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n The entered value needs to be a number or decimal.\n \u6570\u5b57\u307e\u305f\u306f\u5c0f\u6570\u3092\u5165\u529b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Update\n \u66f4\u65b0\n \n \n Status\n \u30b9\u30c6\u30fc\u30bf\u30b9\n \n \n Cluster ID\n \u30af\u30e9\u30b9\u30bfID\n \n \n monmap modified\n monmap\u304c\u5909\u66f4\u3055\u308c\u307e\u3057\u305f\n \n \n monmap epoch\n monmap\u30a8\u30dd\u30c3\u30af\n \n \n quorum con\n \u5b9a\u6570con\n \n \n quorum mon\n \u5b9a\u6570mon\n \n \n required con\n \u5fc5\u9808\u306econ\n \n \n required mon\n \u5fc5\u9808\u306emon\n \n \n In Quorum\n \u5b9a\u6570\u5185\n \n \n Not In Quorum\n \u975e\u5b9a\u6570\u5185\n \n \n Cancel\n \u30ad\u30e3\u30f3\u30bb\u30eb\n \n \n Are you sure that you want to \n \n \n \n ?\n \n Are you sure that you want to \n \n \n \n ?\n \n \n \n Are you sure that you want to \n the selected items?\n \n Are you sure that you want to \n the selected items?\n \n \n \n Are you sure that you want to \n the selected \n ?\n \n \u9078\u629e\u3055\u308c\u305f\n \u3092\n \u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?\n \n \n \n Yes, I am sure.\n \u306f\u3044\u3002\n \n \n Cluster-wide OSD Flags\n \u30af\u30e9\u30b9\u30bf\u5168\u4f53\u306eOSD\u30d5\u30e9\u30b0\n \n \n Submit\n \u9001\u4fe1\n \n \n \n \n \n \n \n \n \n \n form title\n \n \n Advanced...\n \u8a73\u7d30...\n \n \n Advanced configuration options\n Advanced configuration options\n \n \n \n \n \n \n \n \n \n \n form action button\n \n \n OSD Recovery Priority\n OSD\u56de\u5fa9\u512a\u5148\u5ea6\n \n \n Priority\n \u512a\u5148\u5ea6\n \n \n Customize priority values\n \u512a\u5148\u5ea6\u5024\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\n \n \n This field is required!\n \u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u306f\u5fc5\u9808\u3067\u3059\u3002\n \n \n [object Object]\n [object Object]\n \n \n The entered value is too high! It must not be greater than \n .\n \n \u5165\u529b\u3055\u308c\u305f\u5024\u306f\u5927\u304d\u3059\u304e\u307e\u3059\u3002\n \u3088\u308a\u5927\u304d\u3044\u5024\u3092\u5165\u529b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n \n The entered value is too low! It must not be lower than \n .\n \n \u5165\u529b\u3055\u308c\u305f\u5024\u306f\u5c0f\u3055\u3059\u304e\u307e\u3059\u3002\n \u3088\u308a\u5c0f\u3055\u3044\u5024\u3092\u5165\u529b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n \n Reweight OSD\n \u518d\u91cd\u307f\u3065\u3051OSD\n \n \n The value needs to be between 0 and 1.\n \u5024\u306f0\u30681\u306e\u9593\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Reweight\n \u518d\u91cd\u307f\u3065\u3051\n \n \n OSDs \n Scrub\n \n OSD \n \u30b9\u30af\u30e9\u30d6\n \n \n \n {VAR_SELECT, select, 1 {Deep } }\n {VAR_SELECT, select, 1 {Deep } }\n \n \n You are about to apply a \n scrub to\n the OSD \n \n \n .\n \n \n \u30b9\u30af\u30e9\u30d6\u3092OSD \n \n \n \u306b\n\u9069\u7528\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307e\u3059\u3002\n \n \n \n {VAR_SELECT, select, 1 {deep } }\n {VAR_SELECT, select, 1 {deep } }\n \n \n OSDs List\n OSD\u30ea\u30b9\u30c8\n \n \n \n OSD \n \n will be marked\n \n \n if you proceed.\n \n \u7d9a\u884c\u3057\u305f\u5834\u5408\u306f\u3001\n OSD \n \n \u306f\n \n \n \u3068\u30de\u30fc\u30af\u3055\u308c\u307e\u3059\u3002\n \n \n \n The OSD is not safe to destroy!\n \u3053\u306eOSD\u3092\u5b89\u5168\u306b\u7834\u68c4\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n \n OSD \n \n will be\n \n \n if you proceed.\n \n \u7d9a\u884c\u3057\u305f\u5834\u5408\u306f\u3001\n OSD \n \n \u306f\n \n \n \u3055\u308c\u307e\u3059\u3002\n \n \n \n Details\n \u8a73\u7d30\n \n \n Matcher\n Matcher\n \n \n -- Select an attribute to match against --\n -- Select an attribute to match against --\n \n \n Value\n \u5024\n \n \n Use regular expression\n Use regular expression\n \n \n {VAR_SELECT, select, 1 {Update} other {Add} }\n {VAR_SELECT, select, 1 {Update} other {Add} }\n \n \n Close\n \u9589\u3058\u308b\n \n \n Delete\n \u524a\u9664\n \n \n Editing a silence will expire the old silence and recreate it as a new silence\n Editing a silence will expire the old silence and recreate it as a new silence\n \n \n Creator\n Creator\n \n \n Comment\n Comment\n \n \n Start time\n Start time\n \n \n If the start time lies in the past the creation time will be used\n If the start time lies in the past the creation time will be used\n \n \n Duration\n Duration\n \n \n End time\n End time\n \n \n Matchers\n *\n \n \n Matchers\n *\n \n \n \n \n A silence requires at least one matcher\n A silence requires at least one matcher\n \n \n Add matcher\n Add matcher\n \n \n Health\n \u30d8\u30eb\u30b9\n \n \n Statistics\n \u7d71\u8a08\u60c5\u5831\n \n \n Please consult the \n documentation\n \n on how to configure and enable the NFS Ganesha management functionality.\n \n NFS Ganesha\u306e\u7ba1\u7406\u6a5f\u80fd\u3092\u8a2d\u5b9a\u304a\u3088\u3073\u6709\u52b9\u5316\n\u3059\u308b\u65b9\u6cd5\u306b\u95a2\u3059\u308b\n \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\n \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n \n Clients\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\n \n \n Any client can access\n \u4efb\u610f\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304b\u3089\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u3059\n \n \n Addresses\n \u30a2\u30c9\u30ec\u30b9\n \n \n Required field\n \u5fc5\u9808\u30d5\u30a3\u30fc\u30eb\u30c9\n \n \n Must contain one or more comma-separated values\n 1\u3064\u4ee5\u4e0a\u306e\u30ab\u30f3\u30de\u533a\u5207\u308a\u5024\u3092\u542b\u3093\u3067\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\n \n \n For example:\n \u4f8b:\n \n \n Access Type\n \u30a2\u30af\u30bb\u30b9\u30bf\u30a4\u30d7\n \n \n Squash\n \u30b9\u30ab\u30c3\u30b7\u30e5\n \n \n Add clients\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u8ffd\u52a0\n \n \n Loading...\n \u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n \n \n -- No cluster available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30af\u30e9\u30b9\u30bf\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n -- Select the cluster --\n -- \u30af\u30e9\u30b9\u30bf\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Add daemon\n \u30c7\u30fc\u30e2\u30f3\u306e\u8ffd\u52a0\n \n \n Storage Backend\n \u30b9\u30c8\u30ec\u30fc\u30b8\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\n \n \n -- No data pools available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30c7\u30fc\u30bf\u30d7\u30fc\u30eb\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n -- Select the storage backend --\n -- \u30b9\u30c8\u30ec\u30fc\u30b8\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Object Gateway User\n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30e6\u30fc\u30b6\n \n \n -- No users available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30e6\u30fc\u30b6\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n -- Select the object gateway user --\n -- \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30e6\u30fc\u30b6\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n CephFS User ID\n CephFS\u30e6\u30fc\u30b6ID\n \n \n -- No clients available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n -- Select the cephx client --\n -- cephx\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n CephFS Name\n CephFS\u540d\n \n \n -- No CephFS filesystem available --\n -- No CephFS filesystem available --\n \n \n -- Select the CephFS filesystem --\n -- Select the CephFS filesystem --\n \n \n Security Label\n \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30e9\u30d9\u30eb\n \n \n Enable security label\n \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30e9\u30d9\u30eb\u306e\u6709\u52b9\u5316\n \n \n CephFS Path\n CephFS\u30d1\u30b9\n \n \n Path need to start with a \'/\' and can be followed by a word\n \u30d1\u30b9\u306f\u300c/\u300d\u3067\u59cb\u307e\u308b\u5fc5\u8981\u304c\u3042\u308a\u3001\u305d\u306e\u5f8c\u308d\u306b1\u3064\u306e\u5358\u8a9e\u3092\u914d\u7f6e\u3067\u304d\u307e\u3059\n \n \n New directory will be created\n \u65b0\u3057\u3044\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304c\u4f5c\u6210\u3055\u308c\u307e\u3059\n \n \n Path\n \u30d1\u30b9\n \n \n Path can only be a single \'/\' or a word\n \u30d1\u30b9\u306f\u5358\u4e00\u306e\u300c/\u300d\u307e\u305f\u306f1\u3064\u306e\u5358\u8a9e\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\n \n \n New bucket will be created\n \u65b0\u3057\u3044\u30d0\u30b1\u30c3\u30c8\u304c\u4f5c\u6210\u3055\u308c\u307e\u3059\n \n \n NFS Protocol\n NFS\u30d7\u30ed\u30c8\u30b3\u30eb\n \n \n NFSv3\n NFSv3\n \n \n NFSv4\n NFSv4\n \n \n NFS Tag\n NFS\u30bf\u30b0\n \n \n Alternative access for \n NFS v3\n mounts (it must not have a leading /).\n \n \n NFS v3\n \u30de\u30a6\u30f3\u30c8\u306e\u4ee3\u66ff\u30a2\u30af\u30bb\u30b9(\u5148\u982d\u306b\u300c/\u300d\u304c\u3042\u3063\u3066\u306f\u3044\u3051\u307e\u305b\u3093)\u3002\n \n \n \n Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz).\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u30b5\u30d6\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u30de\u30a6\u30f3\u30c8\u3067\u304d\u307e\u305b\u3093(\u305f\u3068\u3048\u3070\u3001\uff3b\u30bf\u30b0\uff3d = foo\u306e\u5834\u5408\u306f\u3001\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306ffoo/baz\u3092\u30de\u30a6\u30f3\u30c8\u3067\u304d\u307e\u305b\u3093)\u3002\n \n \n By using different Tag options, the same Path may be exported multiple times.\n \u7570\u306a\u308b\uff3b\u30bf\u30b0\uff3d\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u540c\u3058\u30d1\u30b9\u3092\u8907\u6570\u56de\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3067\u304d\u307e\u3059\u3002\n \n \n Pseudo\n \u7591\u4f3c\n \n \n The position that this \n NFS v4\n export occupies\n in the \n Pseudo FS\n (it must be unique).\n \n \u3053\u306e\n NFS v4\n \u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u304c\n \u7591\u4f3cFS\n \u5185\u3067\n\u5360\u6709\u3059\u308b\u4f4d\u7f6e(\u3053\u306e\u4f4d\u7f6e\u306f\u4e00\u610f\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059)\u3002\n \n \n \n By using different Pseudo options, the same Path may be exported multiple times.\n \u7570\u306a\u308b\uff3b\u7591\u4f3c\uff3d\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u540c\u3058\u30d1\u30b9\u3092\u8907\u6570\u56de\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u3067\u304d\u307e\u3059\u3002\n \n \n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n Pseudo needs to start with a \'/\' and can\'t contain any of the following: >, <, |, &, ( or ).\n \n \n -- No access type available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30a2\u30af\u30bb\u30b9\u30bf\u30a4\u30d7\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n -- Select the access type --\n -- \u30a2\u30af\u30bb\u30b9\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n The Object Gateway NFS backend has a number of\n limitations which will seriously affect applications writing to\n the share. Please consult the\n documentation\n for details before enabling write access.\n \n \n \n -- No squash available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30b9\u30ab\u30c3\u30b7\u30e5\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n --Select what kind of user id squashing is performed --\n -- \u5b9f\u884c\u3055\u308c\u308b\u30e6\u30fc\u30b6ID\u30b9\u30ab\u30c3\u30b7\u30e5\u64cd\u4f5c\u306e\u7a2e\u985e\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Transport Protocol\n \u30c8\u30e9\u30f3\u30b9\u30dd\u30fc\u30c8\u30d7\u30ed\u30c8\u30b3\u30eb\n \n \n UDP\n UDP\n \n \n TCP\n TCP\n \n \n CephFS\n CephFS\n \n \n Welcome to Ceph!\n Ceph\u306b\u3088\u3046\u3053\u305d!\n The welcome message on the login page\n \n \n Username is required\n \u30e6\u30fc\u30b6\u540d\u306f\u5fc5\u9808\u3067\u3059\n \n \n Password is required\n \u30d1\u30b9\u30ef\u30fc\u30c9\u306f\u5fc5\u9808\u3067\u3059\n \n \n Login\n \u30ed\u30b0\u30a4\u30f3\n \n \n Sorry, the user does not exist in Ceph.\n \u3053\u306e\u30e6\u30fc\u30b6\u306fCeph\u306b\u5b58\u5728\u3057\u307e\u305b\u3093\u3002\n \n \n Return to \n Login Page\n . You\'ll be logged out from the Identity Provider when you retry logging in.\n \n \n \uff3b\u30ed\u30b0\u30a4\u30f3\uff3d\u30da\u30fc\u30b8\n \u306b\u623b\u308a\u307e\u3059\u3002\u30ed\u30b0\u30a4\u30f3\u3092\u518d\u8a66\u884c\u3059\u308b\u3068\u3001Identity Provider\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3055\u308c\u307e\u3059\u3002\n \n \n \n Forbidden\n \u7981\u6b62\n \n \n Sorry, you are not allowed to see what you were looking for.\n \u691c\u7d22\u3057\u3066\u3044\u305f\u5185\u5bb9\u3092\u8868\u793a\u3059\u308b\u3053\u3068\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\n \n \n Sorry, we could not find what you were looking for\n \u691c\u7d22\u3057\u3066\u3044\u305f\u5185\u5bb9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\n \n \n Remove all\n \u3059\u3079\u3066\u524a\u9664\n \n \n Recent Notifications\n \u6700\u8fd1\u306e\u901a\u77e5\n \n \n There are no background tasks.\n \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u30bf\u30b9\u30af\u304c\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n Background Tasks\n \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u30bf\u30b9\u30af\n \n \n Help\n \u30d8\u30eb\u30d7\n \n \n Documentation\n \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\n \n \n API\n API\n \n \n About\n \u30d0\u30fc\u30b8\u30e7\u30f3\u60c5\u5831\n \n \n Dashboard Settings\n \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u8a2d\u5b9a\n \n \n User management\n \u30e6\u30fc\u30b6\u7ba1\u7406\n \n \n Logged in user\n \u30ed\u30b0\u30a4\u30f3\u6e08\u307f\u30e6\u30fc\u30b6\n \n \n Signed in as\n \n \n \n \n \n \n \n \n\u3068\u3057\u3066\u30b5\u30a4\u30f3\u30a4\u30f3\u6e08\u307f\n \n \n \n Sign out\n \u30b5\u30a4\u30f3\u30a2\u30a6\u30c8\n \n \n Name...\n \u540d\u524d...\n \n \n The chosen name is already in use.\n \u9078\u629e\u3055\u308c\u305f\u540d\u524d\u306f\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n Description...\n \u8aac\u660e...\n \n \n Permissions\n \u8a31\u53ef\n \n \n Roles\n \u5f79\u5272\n \n \n Username\n \u30e6\u30fc\u30b6\u540d\n \n \n Password\n \u30d1\u30b9\u30ef\u30fc\u30c9\n \n \n Confirm password\n \u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u78ba\u8a8d\u5165\u529b\n \n \n Password confirmation doesn\'t match the password.\n \u78ba\u8a8d\u5165\u529b\u3055\u308c\u305f\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u30d1\u30b9\u30ef\u30fc\u30c9\u3068\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\n \n \n Full name\n \u6c0f\u540d\n \n \n Email\n \u96fb\u5b50\u30e1\u30fc\u30eb\n \n \n Invalid email.\n \u7121\u52b9\u306a\u96fb\u5b50\u30e1\u30fc\u30eb\u3067\u3059\u3002\n \n \n You are about to remove "user read / update" permissions from your own user.\n \u81ea\u8eab\u306e\u30e6\u30fc\u30b6\u304b\u3089\u300cuser read / update\u300d\u3068\u3044\u3046\u8a31\u53ef\u3092\u524a\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307e\u3059\u3002\n \n \n If you continue, you will no longer be able to add or remove roles from any user.\n \u7d9a\u884c\u3057\u305f\u5834\u5408\u306f\u3001\u3069\u306e\u30e6\u30fc\u30b6\u306e\u5f79\u5272\u3082\u8ffd\u52a0\u304a\u3088\u3073\u524a\u9664\u3067\u304d\u306a\u304f\u306a\u308a\u307e\u3059\u3002\n \n \n Are you sure you want to continue?\n \u7d9a\u884c\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b?\n \n \n Performance counters not available\n \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30ab\u30a6\u30f3\u30bf\u3092\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093\n \n \n Attributes (OSD map)\n \u5c5e\u6027(OSD\u30de\u30c3\u30d7)\n \n \n Metadata not available\n \u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093\n \n \n Metadata\n \u30e1\u30bf\u30c7\u30fc\u30bf\n \n \n Performance counter\n \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30ab\u30a6\u30f3\u30bf\n \n \n Histogram not available: \n \n \n \u30d2\u30b9\u30c8\u30b0\u30e9\u30e0\u3092\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093: \n \n \n \n \n Writes\n \u66f8\u304d\u8fbc\u307f\u56de\u6570\n \n \n Reads\n \u8aad\u307f\u53d6\u308a\u56de\u6570\n \n \n Histogram\n \u30d2\u30b9\u30c8\u30b0\u30e9\u30e0\n \n \n Performance Details\n \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306e\u8a73\u7d30\n \n \n Current values\n \u73fe\u884c\u5024\n \n \n Type\n \u30bf\u30a4\u30d7\n \n \n Min\n \u6700\u5c0f\n \n \n Max\n \u6700\u5927\n \n \n Flags\n \u30d5\u30e9\u30b0\n \n \n Source\n \u30bd\u30fc\u30b9\n \n \n Level\n \u30ec\u30d9\u30eb\n \n \n Can be updated at runtime (editable)\n \u5b9f\u884c\u6642\u306b\u66f4\u65b0\u3067\u304d\u307e\u3059(\u7de8\u96c6\u53ef\u80fd)\n \n \n Tags\n \u30bf\u30b0\n \n \n Enum values\n \u5217\u6319\u5024\n \n \n See also\n \u95a2\u9023\u9805\u76ee\n \n \n Cluster Status\n \u30af\u30e9\u30b9\u30bf\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\n \n \n Manager Daemons\n \u30de\u30cd\u30fc\u30b8\u30e3\u30c7\u30fc\u30e2\u30f3\n \n \n Object Gateways\n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\n \n \n Metadata Servers\n \u30e1\u30bf\u30c7\u30fc\u30bf\u30b5\u30fc\u30d0\n \n \n iSCSI Gateways\n iSCSI\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\n \n \n Client IOPS\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306eIOPS\n \n \n Client Throughput\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u30b9\u30eb\u30fc\u30d7\u30c3\u30c8\n \n \n Client Read/Write\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u8aad\u307f\u53d6\u308a/\u66f8\u304d\u8fbc\u307f\n \n \n Recovery Throughput\n \u56de\u5fa9\u30b9\u30eb\u30fc\u30d7\u30c3\u30c8\n \n \n Scrub\n \u30b9\u30af\u30e9\u30d6\n \n \n Performance\n \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\n \n \n Raw Capacity\n \u672a\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u6642\u306e\u5bb9\u91cf\n \n \n Objects\n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6570\n \n \n PGs per OSD\n OSD\u3042\u305f\u308a\u306e\u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u6570\n \n \n PG Status\n \u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\n \n \n Capacity\n \u5bb9\u91cf\n \n \n \n \n See \n Logs\n for more details.\n \n \n \n \u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001\u300c\n \u30ed\u30b0\n \u300d\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n \n Ranks\n \u30e9\u30f3\u30af\n \n \n MDS performance counters\n MDS performance counters\n \n \n Clients: \n \n \n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u6570: \n \n \n \n \n Clients (\n )\n \n Clients (\n )\n \n \n \n Move an image to trash\n \u30a4\u30e1\u30fc\u30b8\u3092\u3054\u307f\u7bb1\u306b\u79fb\u52d5\u3059\u308b\n \n \n To move \n \n /\n \n to trash,\n click \n Move Image\n . Optionally, you can pick an expiration date.\n \n \n \n /\n \n \u3092\u3054\u307f\u7bb1\u306b\u79fb\u52d5\u3059\u308b\u306b\u306f\u3001\n \uff3b\u30a4\u30e1\u30fc\u30b8\u306e\u79fb\u52d5\uff3d\n \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002\u5e0c\u671b\u306b\u5fdc\u3058\u3066\u3001\u5931\u52b9\u65e5\u3092\u9078\u629e\u3067\u304d\u307e\u3059\u3002\n \n \n \n Protection expires at\n \u4fdd\u8b77\u306e\u5931\u52b9\u65e5\n \n \n NOT PROTECTED\n \u4fdd\u8b77\u3055\u308c\u3066\u3044\u307e\u305b\u3093\n \n \n Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".\n \u65e5\u4ed8\u306e\u5f62\u5f0f\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002\u300cYYYY-MM-DD HH:mm:ss\u300d\u3068\u3044\u3046\u5f62\u5f0f\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n Protection has already expired. Please pick a future date or leave it empty.\n \u4fdd\u8b77\u306f\u3059\u3067\u306b\u5931\u52b9\u3057\u3066\u3044\u307e\u3059\u3002\u5c06\u6765\u306e\u65e5\u4ed8\u3092\u9078\u629e\u3059\u308b\u304b\u3001\u65e5\u4ed8\u3092\u7a7a\u767d\u306e\u307e\u307e\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n Move Image\n \u30a4\u30e1\u30fc\u30b8\u306e\u79fb\u52d5\n \n \n Gateways\n Gateways\n \n \n Must be greater than or equal to \n .\n \n Must be greater than or equal to \n .\n \n \n \n Must be less than or equal to \n .\n \n Must be less than or equal to \n .\n \n \n \n Overview\n \u6982\u8981\n \n \n Targets\n \u30bf\u30fc\u30b2\u30c3\u30c8\n \n \n Discovery Authentication\n \u691c\u51fa\u8a8d\u8a3c\n \n \n User\n \u30e6\u30fc\u30b6\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \u30e6\u30fc\u30b6\u540d\u306f8\uff5e64\u6587\u5b57\u306e\u9577\u3055\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u3001\n\u82f1\u5b57\u3001\u300c.\u300d\u3001\u300c@\u300d\u3001\u300c-\u300d\u3001\u300c_\u300d\u3001\u307e\u305f\u306f\u300c:\u300d\u306e\u307f\u3067\u69cb\u6210\u3055\u308c\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Mutual User\n \u76f8\u4e92\u30e6\u30fc\u30b6\n \n \n Mutual Password\n \u76f8\u4e92\u30d1\u30b9\u30ef\u30fc\u30c9\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Please consult the \n documentation\n \n on how to configure and enable the iSCSI Targets management functionality.\n \n iSCSI\u30bf\u30fc\u30b2\u30c3\u30c8\u306e\u7ba1\u7406\u6a5f\u80fd\u3092\u8a2d\u5b9a\u304a\u3088\u3073\u6709\u52b9\u5316\n\u3059\u308b\u65b9\u6cd5\u306b\u95a2\u3059\u308b\n \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\n \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n \n Available information:\n \u53d6\u5f97\u53ef\u80fd\u306a\u60c5\u5831:\n \n \n iSCSI Targets not available\n \u4f7f\u7528\u53ef\u80fd\u306aiSCSI\u30bf\u30fc\u30b2\u30c3\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\n \n \n Discovery authentication\n Discovery authentication\n \n \n Only available for RBD images with \n fast-diff\n enabled\n \n \n fast-diff\n \u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u308bRBD\u30a4\u30e1\u30fc\u30b8\u306e\u307f\u306b\u4f7f\u7528\u3067\u304d\u307e\u3059\n \n \n \n Pool\n \u30d7\u30fc\u30eb\n \n \n Data Pool\n \u30c7\u30fc\u30bf\u30d7\u30fc\u30eb\n \n \n Created\n \u4f5c\u6210\u6e08\u307f\n \n \n Size\n \u30b5\u30a4\u30ba\n \n \n Object size\n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b5\u30a4\u30ba\n \n \n Features\n \u6a5f\u80fd\n \n \n Provisioned\n \u30d7\u30ed\u30d3\u30b8\u30e7\u30cb\u30f3\u30b0\u6e08\u307f\n \n \n N/A\n \u306a\u3057\n \n \n Total provisioned\n \u30d7\u30ed\u30d3\u30b8\u30e7\u30cb\u30f3\u30b0\u6e08\u307f\u5408\u8a08\n \n \n Striping unit\n \u30b9\u30c8\u30e9\u30a4\u30d4\u30f3\u30b0\u5358\u4f4d\n \n \n Striping count\n \u30b9\u30c8\u30e9\u30a4\u30d4\u30f3\u30b0\u6570\n \n \n Parent\n \u89aa\n \n \n Block name prefix\n \u30d6\u30ed\u30c3\u30af\u540d\u306e\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\n \n \n Order\n \u9806\u756a\n \n \n Snapshots\n \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\n \n \n Image\n \u30a4\u30e1\u30fc\u30b8\n \n \n This setting overrides the global value\n \u3053\u306e\u8a2d\u5b9a\u306f\u30b0\u30ed\u30fc\u30d0\u30eb\u5024\u3088\u308a\u3082\u512a\u5148\u3055\u308c\u307e\u3059\n \n \n Global\n \u30b0\u30ed\u30fc\u30d0\u30eb\n \n \n This is the global value. No value for this option has been set for this image.\n \u3053\u308c\u306f\u30b0\u30ed\u30fc\u30d0\u30eb\u5024\u3067\u3059\u3002\u3053\u306e\u30a4\u30e1\u30fc\u30b8\u306b\u3064\u3044\u3066\u3001\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306e\u5024\u306f\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\n \n \n \n from\n \n \n from\n \n \n \n \'/\' and \'@\' are not allowed.\n \u300c/\u300d\u3068\u300c@\u300d\u306f\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n -- No rbd pools available --\n -- \u4f7f\u7528\u53ef\u80fd\u306arbd\u30d7\u30fc\u30eb\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n -- Select a pool --\n -- \u30d7\u30fc\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Use a dedicated data pool\n \u5c02\u7528\u306e\u30c7\u30fc\u30bf\u30d7\u30fc\u30eb\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044\n \n \n Data pool\n \u30c7\u30fc\u30bf\u30d7\u30fc\u30eb\n \n \n Dedicated pool that stores the object-data of the RBD.\n RBD\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30c7\u30fc\u30bf\u3092\u4fdd\u7ba1\u3059\u308b\u305f\u3081\u306e\u5c02\u7528\u30d7\u30fc\u30eb\n \n \n e.g., 10GiB\n \u4f8b: 10GiB\n \n \n You have to increase the size.\n \u30b5\u30a4\u30ba\u3092\u5927\u304d\u304f\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Advanced\n \u8a73\u7d30\n \n \n Striping\n \u30b9\u30c8\u30e9\u30a4\u30d4\u30f3\u30b0\n \n \n Stripe unit\n \u30b9\u30c8\u30e9\u30a4\u30d7\u5358\u4f4d\n \n \n -- Select stripe unit --\n -- \u30b9\u30c8\u30e9\u30a4\u30d7\u5358\u4f4d\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n This field is required because stripe count is defined!\n \u30b9\u30c8\u30e9\u30a4\u30d7\u6570\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u306f\u5fc5\u9808\u3067\u3059\u3002\n \n \n Stripe unit is greater than object size.\n \u30b9\u30c8\u30e9\u30a4\u30d7\u5358\u4f4d\u304c\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b5\u30a4\u30ba\u3088\u308a\u5927\u304d\u3044\u3067\u3059\u3002\n \n \n Stripe count\n \u30b9\u30c8\u30e9\u30a4\u30d7\u6570\n \n \n This field is required because stripe unit is defined!\n \u30b9\u30c8\u30e9\u30a4\u30d7\u5358\u4f4d\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u306f\u5fc5\u9808\u3067\u3059\u3002\n \n \n Stripe count must be greater than 0.\n \u30b9\u30c8\u30e9\u30a4\u30d7\u6570\u306f0\u3088\u308a\u5927\u304d\u3044\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n \n RBD Snapshot\n \n \n RBD\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\n \n \n \n {VAR_SELECT, select, true {Rename} other {Create} }\n {VAR_SELECT, select, true {Rename} other {Create} }\n \n \n \n Snapshot\n \n \n \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\n \n \n \n PROTECTED\n \u4fdd\u8b77\u6e08\u307f\n \n \n UNPROTECTED\n \u672a\u4fdd\u8b77\n \n \n You are about to rollback\n \u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307e\u3059\n \n \n Purge Trash\n \u3054\u307f\u7bb1\u3092\u7a7a\u306b\u3059\u308b\n \n \n To purge, select one or All images and click\n \u7a7a\u306b\u3059\u308b\u306b\u306f\u30011\u3064\u307e\u305f\u306f\u3059\u3079\u3066\u306e\u30a4\u30e1\u30fc\u30b8\u3092\u9078\u629e\u3057\u3066\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\n \n \n Pool:\n \u30d7\u30fc\u30eb:\n \n \n Pool name...\n \u30d7\u30fc\u30eb\u540d...\n \n \n All\n \u3059\u3079\u3066\n \n \n Restore Image\n \u30a4\u30e1\u30fc\u30b8\u306e\u5fa9\u5143\n \n \n To restore\n \u5fa9\u5143\u3059\u308b\u306b\u306f\n \n \n type the image\'s new name and click\n \u30a4\u30e1\u30fc\u30b8\u306e\u65b0\u3057\u3044\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\n \n \n New Name\n \u65b0\u3057\u3044\u540d\u524d\n \n \n Expired at\n \u5931\u52b9\u65e5\n \n \n Protected until\n \u4fdd\u8b77\u306e\u7d42\u4e86\u65e5\n \n \n This image is protected until \n .\n \n \u3053\u306e\u30a4\u30e1\u30fc\u30b8\u306f\n \u307e\u3067\u4fdd\u8b77\u3055\u308c\u307e\u3059\u3002\n \n \n \n Trash\n \u3054\u307f\u7bb1\n \n \n iSCSI Topology\n iSCSI\u30c8\u30dd\u30ed\u30b8\n \n \n Configure\n Configure\n \n \n Changing these parameters from their default values is usually not necessary.\n \u901a\u5e38\u306f\u3053\u308c\u3089\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u30c7\u30d5\u30a9\u30eb\u30c8\u5024\u304b\u3089\u5909\u66f4\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n Identifier\n Identifier\n \n \n lun\n lun\n \n \n wwn\n wwn\n \n \n Settings\n \u8a2d\u5b9a\n \n \n Backstore\n \u30d0\u30c3\u30af\u30b9\u30c8\u30a2\n \n \n Confirm\n \u78ba\u8a8d\n \n \n Advanced Settings\n \u8a73\u7d30\u8a2d\u5b9a\n \n \n Target IQN\n \u30bf\u30fc\u30b2\u30c3\u30c8IQN\n \n \n IQN has wrong pattern.\n IQN\u306e\u30d1\u30bf\u30fc\u30f3\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n An IQN has the following notation \'iqn.$year-$month.$reversedAddress:$definedName\'\n IQN\u306f\u300ciqn.$year-$month.$reversedAddress:$definedName\u300d\u3068\u3044\u3046\u5f62\u5f0f\u3067\u8868\u8a18\u3055\u308c\u307e\u3059\u3002\n \n \n For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \u4f8b: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309\n \n \n More information\n \u8a73\u7d30\u60c5\u5831\n \n \n This target has modified advanced settings.\n \u3053\u306e\u30bf\u30fc\u30b2\u30c3\u30c8\u306e\u8a73\u7d30\u8a2d\u5b9a\u306f\u5909\u66f4\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n Portals\n \u30dd\u30fc\u30bf\u30eb\n \n \n At least \n gateways are required.\n \n \u5c11\u306a\u304f\u3068\u3082\n \u53f0\u306e\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u304c\u5fc5\u8981\u3067\u3059\u3002\n \n \n \n Add portal\n \u30dd\u30fc\u30bf\u30eb\u306e\u8ffd\u52a0\n \n \n Backstore: \n .\xa0\n \n Backstore: \n .\xa0\n \n \n \n This image has modified settings.\n \u3053\u306e\u30a4\u30e1\u30fc\u30b8\u306e\u8a2d\u5b9a\u306f\u5909\u66f4\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n Duplicated LUN numbers.\n Duplicated LUN numbers.\n \n \n Duplicated WWN.\n Duplicated WWN.\n \n \n Add image\n \u30a4\u30e1\u30fc\u30b8\u306e\u8ffd\u52a0\n \n \n ACL authentication\n ACL\u8a8d\u8a3c\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiators\n \u30a4\u30cb\u30b7\u30a8\u30fc\u30bf\n \n \n Initiator\n \u30a4\u30cb\u30b7\u30a8\u30fc\u30bf\n \n \n Client IQN\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8IQN\n \n \n Initiator IQN needs to be unique.\n \u30a4\u30cb\u30b7\u30a8\u30fc\u30bfIQN\u306f\u4e00\u610f\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Usernames must have a length of 8 to 64 characters and\n can only contain letters, \'.\', \'@\', \'-\', \'_\' or \':\'.\n \u30e6\u30fc\u30b6\u540d\u306f8\uff5e64\u6587\u5b57\u306e\u9577\u3055\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u3001\n\u82f1\u5b57\u3001\u300c.\u300d\u3001\u300c@\u300d\u3001\u300c-\u300d\u3001\u300c_\u300d\u3001\u307e\u305f\u306f\u300c:\u300d\u306e\u307f\u3067\u69cb\u6210\u3055\u308c\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters\n and can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n Passwords must have a length of 12 to 16 characters and\n can only contain letters, \'@\', \'-\', \'_\' or \'/\'.\n \n \n Initiator belongs to a group. Images will be configure in the group.\n \u30a4\u30cb\u30b7\u30a8\u30fc\u30bf\u306f\u3044\u305a\u308c\u304b\u306e\u30b0\u30eb\u30fc\u30d7\u306b\u5c5e\u3057\u307e\u3059\u3002\u30a4\u30e1\u30fc\u30b8\u306f\u305d\u306e\u30b0\u30eb\u30fc\u30d7\u5185\u3067\u8a2d\u5b9a\u3055\u308c\u307e\u3059\u3002\n \n \n No items added.\n \u30a2\u30a4\u30c6\u30e0\u304c\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\n \n \n Add initiator\n \u30a4\u30cb\u30b7\u30a8\u30fc\u30bf\u306e\u8ffd\u52a0\n \n \n Groups\n \u30b0\u30eb\u30fc\u30d7\n \n \n Group\n \u30b0\u30eb\u30fc\u30d7\n \n \n Add group\n \u30b0\u30eb\u30fc\u30d7\u306e\u8ffd\u52a0\n \n \n [object Object]\n [object Object]\n \n \n RBD Configuration\n RBD\u8a2d\u5b9a\n \n \n Remove the local configuration value. The parent configuration value will be inherited and used instead.\n \u30ed\u30fc\u30ab\u30eb\u8a2d\u5b9a\u5024\u3092\u524a\u9664\u3057\u307e\u3059\u3002\u89aa\u8a2d\u5b9a\u5024\u304c\u7d99\u627f\u3055\u308c\u3066\u4ee3\u308f\u308a\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002\n \n \n The mininum value is 0\n \u6700\u5c0f\u5024\u306f0\u3067\u3059\n \n \n Issues\n \u554f\u984c\n \n \n Syncing\n \u540c\u671f\u4e2d\n \n \n Ready\n \u6e96\u5099\u5b8c\u4e86\n \n \n Edit pool mirror mode\n \u30d7\u30fc\u30eb\u306e\u30df\u30e9\u30fc\u30e2\u30fc\u30c9\u306e\u7de8\u96c6\n \n \n To edit the mirror mode for pool\xa0\n \n \n , select a new mode from the list and click\xa0\n Update\n .\n \n \u30d7\u30fc\u30eb\n \n \n \u306e\u30df\u30e9\u30fc\u30e2\u30fc\u30c9\u3092\u7de8\u96c6\u3059\u308b\u306b\u306f\u3001\n\u30ea\u30b9\u30c8\u304b\u3089\u65b0\u3057\u3044\u30e2\u30fc\u30c9\u3092\u9078\u629e\u3057\u3066\u3001\n \uff3b\u66f4\u65b0\uff3d\n \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002\n \n \n \n Mode\n \u30e2\u30fc\u30c9\n \n \n Peer clusters must be removed prior to disabling mirror.\n \u30df\u30e9\u30fc\u3092\u7121\u52b9\u306b\u3059\u308b\u524d\u306b\u3001\u30d4\u30a2\u30af\u30e9\u30b9\u30bf\u3092\u524a\u9664\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n \n \n pool mirror peer\n \n \n \n\u30d7\u30fc\u30eb\u306e\u30df\u30e9\u30fc\u30d4\u30a2\n \n \n \n {VAR_SELECT, select, edit {Edit} other {Add} }\n {VAR_SELECT, select, edit {Edit} other {Add} }\n \n \n \n the pool\n mirror peer attributes for pool \n \n \n and click \n Submit\n .\n \n \n \u30d7\u30fc\u30eb\n \n \n \n\u306e\u30d7\u30fc\u30eb\u30df\u30e9\u30fc\u30d4\u30a2\u5c5e\u6027\u3001\u304a\u3088\u3073\n \uff3b\u9001\u4fe1\uff3d\n \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002\n \n \n \n Cluster Name\n \u30af\u30e9\u30b9\u30bf\u540d\n \n \n The cluster name is not valid.\n \u3053\u306e\u30af\u30e9\u30b9\u30bf\u540d\u306f\u7121\u52b9\u3067\u3059\u3002\n \n \n CephX ID\n CephX ID\n \n \n CephX ID...\n CephX ID...\n \n \n The CephX ID is not valid.\n \u3053\u306eCephX ID\u306f\u7121\u52b9\u3067\u3059\u3002\n \n \n Monitor Addresses\n \u30e2\u30cb\u30bf\u30fc\u30a2\u30c9\u30ec\u30b9\n \n \n Comma-delimited addresses...\n \u30ab\u30f3\u30de\u533a\u5207\u308a\u30a2\u30c9\u30ec\u30b9...\n \n \n The monitory address is not valid.\n \u3053\u306e\u8b66\u544a\u30a2\u30c9\u30ec\u30b9\u306f\u7121\u52b9\u3067\u3059\u3002\n \n \n CephX Key\n CephX\u30ad\u30fc\n \n \n Base64-encoded key...\n Base64\u30a8\u30f3\u30b3\u30fc\u30c9\u5316\u6e08\u307f\u30ad\u30fc...\n \n \n CephX key must be base64 encoded.\n CephX\u30ad\u30fc\u306fbase64\u3067\u30a8\u30f3\u30b3\u30fc\u30c9\u3055\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Pools List\n \u30d7\u30fc\u30eb\u30ea\u30b9\u30c8\n \n \n The name can only consist of alphanumeric characters, dashes and underscores.\n \u540d\u524d\u306f\u82f1\u6570\u5b57\u3001\u30c0\u30c3\u30b7\u30e5\u3001\u304a\u3088\u3073\u4e0b\u7dda\u306e\u307f\u3067\u69cb\u6210\u3055\u308c\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n The chosen erasure code profile name is already in use.\n \u9078\u629e\u3055\u308c\u305f\u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u540d\u306f\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n Plugin\n \u30d7\u30e9\u30b0\u30a4\u30f3\n \n \n Data chunks (k)\n \u30c7\u30fc\u30bf\u30c1\u30e3\u30f3\u30af(k)\n \n \n Must be equal to or greater than 2.\n 2\u4ee5\u4e0a\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Coding chunks (m)\n \u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u30c1\u30e3\u30f3\u30af(m)\n \n \n Must be equal to or greater than 1.\n 1\u4ee5\u4e0a\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Durability estimator (c)\n \u8010\u4e45\u6027\u63a8\u5b9a\u5b50(c)\n \n \n Locality (l)\n \u5730\u57df(l)\n \n \n Crush failure domain\n Crush\u969c\u5bb3\u30c9\u30e1\u30a4\u30f3\n \n \n Crush Locality\n Crush\u5730\u57df\n \n \n None\n \u306a\u3057\n \n \n Technique\n \u6280\u6cd5\n \n \n Packetsize\n \u30d1\u30b1\u30c3\u30c8\u30b5\u30a4\u30ba\n \n \n Crush root\n Crush\u30eb\u30fc\u30c8\n \n \n Crush device class\n Crush\u30c7\u30d0\u30a4\u30b9\u30af\u30e9\u30b9\n \n \n any\n \u4efb\u610f\n \n \n Directory\n \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\n \n \n The chosen Ceph pool name is already in use.\n \u9078\u629e\u3055\u308c\u305fCeph\u30d7\u30fc\u30eb\u540d\u306f\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n Pool type\n \u30d7\u30fc\u30eb\u30bf\u30a4\u30d7\n \n \n -- Select a pool type --\n -- \u30d7\u30fc\u30eb\u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Placement groups\n \u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\n \n \n At least one placement group is needed!\n \u5c11\u306a\u304f\u3068\u30821\u3064\u306e\u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u304c\u5fc5\u8981\u3067\u3059\u3002\n \n \n Your cluster can\'t handle this many PGs. Please recalculate the PG amount needed.\n \u3054\u4f7f\u7528\u306e\u30af\u30e9\u30b9\u30bf\u306f\u3053\u308c\u3060\u3051\u591a\u6570\u306e\u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u3092\u51e6\u7406\u3067\u304d\u307e\u305b\u3093\u3002\u5fc5\u8981\u306a\u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u306e\u6570\u3092\u518d\u8a08\u7b97\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n Calculation help\n \u8a08\u7b97\u306e\u30d8\u30eb\u30d7\n \n \n The current PGs settings were calculated for you, you\n should make sure the values suit your needs before submit.\n \u73fe\u5728\u306e\u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u8a2d\u5b9a\u306f\u81ea\u52d5\u7684\u306b\u8a08\u7b97\u3055\u308c\u305f\u305f\u3081\u3001\n\u9001\u4fe1\u524d\u306b\u3001\u3053\u308c\u3089\u306e\u5024\u304c\u30cb\u30fc\u30ba\u306b\u5408\u3063\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n Crush ruleset\n Crush\u30eb\u30fc\u30eb\u30bb\u30c3\u30c8\n \n \n -- Select a crush rule --\n -- Crush\u30eb\u30fc\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Crush rule\n Crush\u30eb\u30fc\u30eb\n \n \n Crush steps\n Crush\u30b9\u30c6\u30c3\u30d7\n \n \n The rule can\'t be used in the current cluster as it has\n to few OSDs to meet the minimum required OSD by this rule.\n \u73fe\u5728\u306e\u30af\u30e9\u30b9\u30bf\u5185\u306eOSD\u6570\u306f\u3053\u306e\u30eb\u30fc\u30eb\u3067\u8981\u6c42\u3055\u308c\u308b\u6700\u5c0fOSD\u6570\u3092\u4e0b\u56de\u3063\u3066\u3044\u308b\u305f\u3081\u3001\n\u3053\u306e\u30eb\u30fc\u30eb\u3092\u73fe\u5728\u306e\u30af\u30e9\u30b9\u30bf\u3067\u4f7f\u7528\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n Replicated size\n \u8907\u88fd\u3055\u308c\u305f\u30b5\u30a4\u30ba\n \n \n Minimum: \n \n \n \u6700\u5c0f: \n \n \n \n \n Maximum: \n \n \n \u6700\u5927: \n \n \n \n \n The size specified is out of range. A value from\n to \n is valid.\n \n \u6307\u5b9a\u3055\u308c\u305f\u30b5\u30a4\u30ba\u306f\u7bc4\u56f2\u5916\u3067\u3059\u3002\n\u6709\u52b9\u306a\u5024\u306e\u7bc4\u56f2\u306f\n \uff5e\n \u3067\u3059\u3002\n \n \n \n Erasure code profile\n \u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\n \n \n -- No erasure code profile available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n -- Select an erasure code profile --\n -- \u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n EC Overwrites\n EC\u306e\u4e0a\u66f8\u304d\n \n \n Applications\n \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\n \n \n Compression\n \u5727\u7e2e\n \n \n Algorithm\n \u30a2\u30eb\u30b4\u30ea\u30ba\u30e0\n \n \n -- No erasure compression algorithm available --\n -- \u4f7f\u7528\u53ef\u80fd\u306a\u30a4\u30ec\u30a4\u30b8\u30e3\u5727\u7e2e\u30a2\u30eb\u30b4\u30ea\u30ba\u30e0\u304c\u3042\u308a\u307e\u305b\u3093 --\n \n \n Minimum blob size\n \u6700\u5c0fblob\u30b5\u30a4\u30ba\n \n \n e.g., 128KiB\n \u4f8b: 128KiB\n \n \n Value should be greater than 0\n \u5024\u306f0\u3088\u308a\u5927\u304d\u3044\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\n \n \n Value should be less than the maximum blob size\n Value should be less than the maximum blob size\n \n \n Maximum blob size\n \u6700\u5927blob\u30b5\u30a4\u30ba\n \n \n e.g., 512KiB\n \u4f8b: 512KiB\n \n \n Value should be greater than the minimum blob size\n \u5024\u306f\u6700\u5c0fblob\u30b5\u30a4\u30ba\u3088\u308a\u5927\u304d\u3044\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\n \n \n Ratio\n \u7387\n \n \n Compression ratio\n \u5727\u7e2e\u7387\n \n \n Value should be between 0.0 and 1.0\n \u5024\u306f0.0\uff5e1.0\u306e\u9593\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\n \n \n It\'s not possible to create an RBD pool with \'/\' in the name.\n \u540d\u524d\u306b\u300c/\u300d\u304c\u542b\u307e\u308c\u305fRBD\u30d7\u30fc\u30eb\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n Please change the name or remove \'rbd\' from the applications list.\n \u540d\u524d\u3092\u5909\u66f4\u3059\u308b\u304b\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ea\u30b9\u30c8\u304b\u3089\u300crbd\u300d\u3092\u524a\u9664\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n Cache Tiers Details\n \u30ad\u30e3\u30c3\u30b7\u30e5\u5c64\u306e\u8a73\u7d30\n \n \n Please consult the \n documentation\n \n on how to configure and enable the Object Gateway management functionality.\n \n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u7ba1\u7406\u6a5f\u80fd\u3092\u8a2d\u5b9a\u304a\u3088\u3073\u6709\u52b9\u5316\n\u3059\u308b\u65b9\u6cd5\u306b\u95a2\u3059\u308b\n \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\n \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n \n Daemons List\n \u30c7\u30fc\u30e2\u30f3\u30ea\u30b9\u30c8\n \n \n Performance Counters\n \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u30ab\u30a6\u30f3\u30bf\n \n \n Loading bucket data...\n \u30d0\u30b1\u30c3\u30c8\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n \n \n The bucket data could not be loaded.\n \u30d0\u30b1\u30c3\u30c8\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n \n \n Id\n Id\n \n \n The value is not valid.\n \u3053\u306e\u5024\u306f\u7121\u52b9\u3067\u3059\u3002\n \n \n Owner\n \u6240\u6709\u8005\n \n \n -- Select a user --\n -- \u30e6\u30fc\u30b6\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n ID\n ID\n \n \n Index type\n \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u30bf\u30a4\u30d7\n \n \n Placement rule\n \u914d\u7f6e\u30eb\u30fc\u30eb\n \n \n Marker\n \u30de\u30fc\u30ab\u30fc\n \n \n Maximum marker\n \u6700\u5927\u30de\u30fc\u30ab\u30fc\n \n \n Version\n \u30d0\u30fc\u30b8\u30e7\u30f3\n \n \n Master version\n \u30de\u30b9\u30bf\u30d0\u30fc\u30b8\u30e7\u30f3\n \n \n Modification time\n \u5909\u66f4\u6642\u9593\n \n \n Zonegroup\n \u30be\u30fc\u30f3\u30b0\u30eb\u30fc\u30d7\n \n \n Bucket quota\n \u30d0\u30b1\u30c3\u30c8\u30af\u30a9\u30fc\u30bf\n \n \n Enabled\n \u6709\u52b9\u5316\u6e08\u307f\n \n \n Maximum size\n \u6700\u5927\u30b5\u30a4\u30ba\n \n \n Unlimited\n \u7121\u5236\u9650\n \n \n Maximum objects\n \u6700\u5927\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6570\n \n \n -- Select a username --\n -- \u30e6\u30fc\u30b6\u540d\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Auto-generate key\n \u30ad\u30fc\u306e\u81ea\u52d5\u751f\u6210\n \n \n Access key\n \u30a2\u30af\u30bb\u30b9\u30ad\u30fc\n \n \n Secret key\n \u79d8\u5bc6\u30ad\u30fc\n \n \n Email address\n \u96fb\u5b50\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\n \n \n Suspended\n \u4e2d\u65ad\u6e08\u307f\n \n \n System\n \u30b7\u30b9\u30c6\u30e0\n \n \n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n {VAR_SELECT, select, 0 {No} 1 {Yes} }\n \n \n Maximum buckets\n \u6700\u5927\u30d0\u30b1\u30c3\u30c8\u6570\n \n \n Subusers\n \u30b5\u30d6\u30e6\u30fc\u30b6\n \n \n Capabilities\n \u6a5f\u80fd\n \n \n User quota\n \u30e6\u30fc\u30b6\u30af\u30a9\u30fc\u30bf\n \n \n Show\n \u8868\u793a\n \n \n Keys\n \u30ad\u30fc\n \n \n -- Select a type --\n -- \u30bf\u30a4\u30d7\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Permission\n \u8a31\u53ef\n \n \n -- Select a permission --\n -- \u8a31\u53ef\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Subuser\n \u30b5\u30d6\u30e6\u30fc\u30b6\n \n \n The chosen subuser ID is already in use.\n \u9078\u629e\u3055\u308c\u305f\u30b5\u30d6\u30e6\u30fc\u30b6ID\u306f\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n read, write\n \u8aad\u307f\u53d6\u308a\u3001\u66f8\u304d\u8fbc\u307f\n \n \n full\n \u30d5\u30eb\n \n \n Swift key\n \u30b9\u30a6\u30a3\u30d5\u30c8\u30ad\u30fc\n \n \n Auto-generate secret\n \u79d8\u5bc6\u306e\u81ea\u52d5\u751f\u6210\n \n \n Loading user data...\n \u30e6\u30fc\u30b6\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...\n \n \n The user data could not be loaded.\n \u30e6\u30fc\u30b6\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n \n \n The chosen user ID is already in use.\n \u9078\u629e\u3055\u308c\u305f\u30e6\u30fc\u30b6ID\u306f\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n This is not a valid email address.\n \u3053\u308c\u306f\u6709\u52b9\u306a\u96fb\u5b50\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n The chosen email address is already in use.\n \u9078\u629e\u3055\u308c\u305f\u96fb\u5b50\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n Max. buckets\n \u6700\u5927\u30d0\u30b1\u30c3\u30c8\u6570\n \n \n The entered value must be >= 0.\n 0\u4ee5\u4e0a\u306e\u5024\u3092\u5165\u529b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n S3 key\n S3\u30ad\u30fc\n \n \n There are no subusers.\n \u30b5\u30d6\u30e6\u30fc\u30b6\u304c\u3044\u307e\u305b\u3093\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n S3\n S3\n \n \n There are no keys.\n \u30ad\u30fc\u304c\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n Swift\n \u30b9\u30a6\u30a3\u30d5\u30c8\n \n \n There are no capabilities.\n \u6a5f\u80fd\u304c\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n \n \n \n \n \n \n \n \n \n \n Unlimited size\n \u7121\u5236\u9650\u306e\u30b5\u30a4\u30ba\n \n \n Max. size\n \u6700\u5927\u30b5\u30a4\u30ba\n \n \n Unlimited objects\n \u7121\u5236\u9650\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6570\n \n \n Max. objects\n \u6700\u5927\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6570\n \n \n Current\n \u73fe\u5728\n \n \n Updated discovery authentication\n \u691c\u51fa\u8a8d\u8a3c\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n There are no portals available.\n \u4f7f\u7528\u53ef\u80fd\u306a\u30dd\u30fc\u30bf\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n There are no images available.\n \u4f7f\u7528\u53ef\u80fd\u306a\u30a4\u30e1\u30fc\u30b8\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n There are no images available. Please make sure you add an image to the target.\n \u4f7f\u7528\u53ef\u80fd\u306a\u30a4\u30e1\u30fc\u30b8\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u30bf\u30fc\u30b2\u30c3\u30c8\u306b\u30a4\u30e1\u30fc\u30b8\u3092\u8ffd\u52a0\u3057\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n There are no initiators available. Please make sure you add an initiator to the target.\n \u4f7f\u7528\u53ef\u80fd\u306a\u30a4\u30cb\u30b7\u30a8\u30fc\u30bf\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u30bf\u30fc\u30b2\u30c3\u30c8\u306b\u30a4\u30cb\u30b7\u30a8\u30fc\u30bf\u3092\u8ffd\u52a0\u3057\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n \n \n target\n target\n \n \n Target\n \u30bf\u30fc\u30b2\u30c3\u30c8\n \n \n # Sessions\n # Sessions\n \n \n iSCSI target\n iSCSI target\n \n \n State\n \u72b6\u614b\n \n \n # Targets\n # Targets\n \n \n Read Bytes\n \u8aad\u307f\u53d6\u308a\u30d0\u30a4\u30c8\u6570\n \n \n Write Bytes\n \u66f8\u304d\u8fbc\u307f\u30d0\u30a4\u30c8\u6570\n \n \n Read Ops\n \u8aad\u307f\u53d6\u308a\u64cd\u4f5c\u6570\n \n \n Write Ops\n \u66f8\u304d\u8fbc\u307f\u64cd\u4f5c\u6570\n \n \n A/O Since\n \u6b21\u306e\u65e5\u4ed8\u4ee5\u964d\u306eA/O\n \n \n Instance\n \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\n \n \n Hostname\n \u30db\u30b9\u30c8\u540d\n \n \n Issue\n \u554f\u984c\n \n \n Progress\n \u9032\u6357\n \n \n Disabled\n \u7121\u52b9\u5316\u6e08\u307f\n \n \n Edit Mode\n \u30e2\u30fc\u30c9\u306e\u7de8\u96c6\n \n \n Add Peer\n \u30d4\u30a2\u306e\u8ffd\u52a0\n \n \n Edit Peer\n \u30d4\u30a2\u306e\u7de8\u96c6\n \n \n Delete Peer\n \u30d4\u30a2\u306e\u524a\u9664\n \n \n Leader\n \u30ea\u30fc\u30c0\u30fc\n \n \n # Local\n #\u30ed\u30fc\u30ab\u30eb\n \n \n # Remote\n #\u30ea\u30e2\u30fc\u30c8\n \n \n mirror peer\n \u30df\u30e9\u30fc\u30d4\u30a2\n \n \n Key\n \u30ad\u30fc\n \n \n RBD\n RBD\n \n \n Deep flatten\n \u30c7\u30a3\u30fc\u30d7\u30d5\u30e9\u30c3\u30c8\u5316\n \n \n Layering\n \u968e\u5c64\u5316\n \n \n Exclusive lock\n \u6392\u4ed6\u30ed\u30c3\u30af\n \n \n Object map (requires exclusive-lock)\n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30de\u30c3\u30d7(\u6392\u4ed6\u30ed\u30c3\u30af\u304c\u5fc5\u8981)\n \n \n Journaling (requires exclusive-lock)\n \u30b8\u30e3\u30fc\u30ca\u30ea\u30f3\u30b0(\u6392\u4ed6\u30ed\u30c3\u30af\u304c\u5fc5\u8981)\n \n \n Fast diff (interlocked with object-map)\n Fast diff (interlocked with object-map)\n \n \n RBD snapshot rollback\n RBD\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\n \n \n Rollback\n \u30ed\u30fc\u30eb\u30d0\u30c3\u30af\n \n \n RBD snapshot\n RBD\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\n \n \n Deleted At\n \u524a\u9664\u65e5\u6642\n \n \n id\n id\n \n \n type\n \u30bf\u30a4\u30d7\n \n \n state\n \u72b6\u614b\n \n \n version\n \u30d0\u30fc\u30b8\u30e7\u30f3\n \n \n Host\n \u30db\u30b9\u30c8\n \n \n root\n \u30eb\u30fc\u30c8\n \n \n Rank\n \u30e9\u30f3\u30af\n \n \n Daemon\n \u30c7\u30fc\u30e2\u30f3\n \n \n Activity\n \u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3\n \n \n Dentries\n d\u30a8\u30f3\u30c8\u30ea\n \n \n Inodes\n i\u30ce\u30fc\u30c9\n \n \n Usage\n \u4f7f\u7528\u91cf\n \n \n Standby daemons\n \u30b9\u30bf\u30f3\u30d0\u30a4\u30c7\u30fc\u30e2\u30f3\n \n \n The value can be updated at runtime.\n \u3053\u306e\u5024\u306f\u5b9f\u884c\u6642\u306b\u66f4\u65b0\u3067\u304d\u307e\u3059\u3002\n \n \n Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via \'ceph config\n set ...\'. This option should be configured via ceph.conf or via the\n command line.\n \u30c7\u30fc\u30e2\u30f3/\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u3053\u306e\u5024\u3092\u30e2\u30cb\u30bf\u30fc\u8a2d\u5b9a\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304b\u3089\u53d6\u5f97\u3057\u307e\u305b\u3093\u3002\n\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u300cceph config set ...\u300d\u3092\u901a\u3058\u3066\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u306f\u7981\u6b62\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u3001ceph.conf\u307e\u305f\u306f\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u3092\u901a\u3058\u3066\n\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n Option takes effect only during daemon startup.\n \u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u30c7\u30fc\u30e2\u30f3\u59cb\u52d5\u6642\u306e\u307f\u306b\u6709\u52b9\u306b\u306a\u308a\u307e\u3059\u3002\n \n \n Option only affects cluster creation.\n \u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u30af\u30e9\u30b9\u30bf\u306e\u4f5c\u6210\u306e\u307f\u306b\u9069\u7528\u3055\u308c\u307e\u3059\u3002\n \n \n Option only affects daemon creation.\n \u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u30c7\u30fc\u30e2\u30f3\u306e\u4f5c\u6210\u306e\u307f\u306b\u9069\u7528\u3055\u308c\u307e\u3059\u3002\n \n \n Updated config option \n \n \n \u8a2d\u5b9a\u30aa\u30d7\u30b7\u30e7\u30f3\n \u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n \n Service\n \u30b5\u30fc\u30d3\u30b9\n \n \n Current value\n \u73fe\u884c\u5024\n \n \n Editable\n \u7de8\u96c6\u53ef\u80fd\n \n \n Updated options for module "\n ".\n \n \u30e2\u30b8\u30e5\u30fc\u30eb\u300c\n \u300d\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002\n \n \n \n Enable\n \u6709\u52b9\u5316\n \n \n Disable\n \u7121\u52b9\u5316\n \n \n Reconnecting, please wait ...\n \u518d\u63a5\u7d9a\u3057\u3066\u3044\u307e\u3059\u306e\u3067\u3001\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044...\n \n \n Public Address\n \u30d1\u30d6\u30ea\u30c3\u30af\u30a2\u30c9\u30ec\u30b9\n \n \n Open Sessions\n \u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u958b\u59cb\n \n \n No In\n \u30a4\u30f3\u306a\u3057\n \n \n OSDs that were previously marked out will not be marked back in when they start\n \u4ee5\u524d\u306b\u30a2\u30a6\u30c8\u3068\u3057\u3066\u30de\u30fc\u30af\u3055\u308c\u305fOSD\u306f\u3001\u305d\u308c\u3089\u306e\u59cb\u52d5\u6642\u306b\u30a4\u30f3\u3068\u3057\u3066\u30de\u30fc\u30af\u3055\u308c\u308b\u3053\u3068\u306f\u3042\u308a\u307e\u305b\u3093\n \n \n No Out\n \u30a2\u30a6\u30c8\u306a\u3057\n \n \n OSDs will not automatically be marked out after the configured interval\n OSD\u306f\u3001\u8a2d\u5b9a\u6e08\u307f\u306e\u9593\u9694\u304c\u7d4c\u904e\u3057\u305f\u5f8c\u306b\u81ea\u52d5\u7684\u306b\u30a2\u30a6\u30c8\u3068\u3057\u3066\u30de\u30fc\u30af\u3055\u308c\u307e\u3059\n \n \n No Up\n \u30a2\u30c3\u30d7\u306a\u3057\n \n \n OSDs are not allowed to start\n OSD\u3092\u59cb\u52d5\u3059\u308b\u3053\u3068\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u305b\u3093\n \n \n No Down\n \u30c0\u30a6\u30f3\u306a\u3057\n \n \n OSD failure reports are being ignored, such that the monitors will not mark OSDs down\n OSD\u306e\u969c\u5bb3\u30ec\u30dd\u30fc\u30c8\u306f\u7121\u8996\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001OSD\u306f\u30e2\u30cb\u30bf\u30fc\u306b\u3088\u3063\u3066\u30c0\u30a6\u30f3\u3068\u3057\u3066\u30de\u30fc\u30af\u3055\u308c\u307e\u305b\u3093\n \n \n Pause\n \u4e00\u6642\u505c\u6b62\n \n \n Pauses reads and writes\n \u8aad\u307f\u53d6\u308a\u3068\u66f8\u304d\u8fbc\u307f\u3092\u4e00\u6642\u505c\u6b62\u3057\u307e\u3059\n \n \n No Scrub\n \u30b9\u30af\u30e9\u30d6\u306a\u3057\n \n \n Scrubbing is disabled\n \u30b9\u30af\u30e9\u30d6\u51e6\u7406\u306f\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059\n \n \n No Deep Scrub\n \u30c7\u30a3\u30fc\u30d7\u30b9\u30af\u30e9\u30d6\u306a\u3057\n \n \n Deep Scrubbing is disabled\n \u30c7\u30a3\u30fc\u30d7\u30b9\u30af\u30e9\u30d6\u51e6\u7406\u306f\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059\n \n \n No Backfill\n \u30d0\u30c3\u30af\u30d5\u30a3\u30eb\u306a\u3057\n \n \n Backfilling of PGs is suspended\n \u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u306e\u30d0\u30c3\u30af\u30d5\u30a3\u30eb\u306f\u4e2d\u65ad\u3055\u308c\u3066\u3044\u307e\u3059\n \n \n No Recover\n \u56de\u5fa9\u306a\u3057\n \n \n Recovery of PGs is suspended\n \u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u306e\u56de\u5fa9\u306f\u4e2d\u65ad\u3055\u308c\u3066\u3044\u307e\u3059\n \n \n Bitwise Sort\n \u30d3\u30c3\u30c8\u5358\u4f4d\u306e\u30bd\u30fc\u30c8\n \n \n Use bitwise sort\n \u30d3\u30c3\u30c8\u5358\u4f4d\u306e\u30bd\u30fc\u30c8\u3092\u4f7f\u7528\u3059\u308b\n \n \n Purged Snapdirs\n \u6d88\u53bb\u3055\u308c\u305f\u30b9\u30ca\u30c3\u30d7\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\n \n \n OSDs have converted snapsets\n OSD\u306b\u3088\u3063\u3066\u30b9\u30ca\u30c3\u30d7\u30bb\u30c3\u30c8\u304c\u5909\u63db\u3055\u308c\u307e\u3057\u305f\n \n \n Recovery Deletes\n \u56de\u5fa9\u306e\u524a\u9664\n \n \n Deletes performed during recovery instead of peering\n \u30d4\u30a2\u30ea\u30f3\u30b0\u306e\u4ee3\u308f\u308a\u306b\u56de\u5fa9\u6642\u306b\u524a\u9664\u304c\u5b9f\u884c\u3055\u308c\u307e\u3057\u305f\n \n \n PG Log Hard Limit\n \u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u30ed\u30b0\u306e\u30cf\u30fc\u30c9\u5236\u9650\n \n \n Puts a hard limit on pg log length\n \u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u30ed\u30b0\u9577\u306e\u30cf\u30fc\u30c9\u5236\u9650\u3092\u9069\u7528\u3057\u307e\u3059\n \n \n Updated OSD Flags\n OSD\u30d5\u30e9\u30b0\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n out\n \u30a2\u30a6\u30c8\n \n \n in\n \u30a4\u30f3\n \n \n down\n \u30c0\u30a6\u30f3\n \n \n Mark\n \u30de\u30fc\u30af\n \n \n OSD lost\n \u55aa\u5931\u3057\u305fOSD\n \n \n marked lost\n \u55aa\u5931\u3068\u3057\u3066\u30de\u30fc\u30af\u6e08\u307f\n \n \n Purge\n \u6d88\u53bb\n \n \n OSD\n OSD\n \n \n purged\n \u6d88\u53bb\u6e08\u307f\n \n \n destroy\n \u7834\u68c4\n \n \n destroyed\n \u7834\u68c4\u6e08\u307f\n \n \n Cluster-wide Flags\n Cluster-wide Flags\n \n \n Cluster-wide Recovery Priority\n Cluster-wide Recovery Priority\n \n \n PG scrub\n PG scrub\n \n \n PGs\n \u914d\u7f6e\u30b0\u30eb\u30fc\u30d7\u6570\n \n \n Read bytes\n \u8aad\u307f\u53d6\u308a\u30d0\u30a4\u30c8\u6570\n \n \n Writes bytes\n \u66f8\u304d\u8fbc\u307f\u30d0\u30a4\u30c8\u6570\n \n \n Read ops\n \u8aad\u307f\u53d6\u308a\u64cd\u4f5c\u6570\n \n \n Write ops\n \u66f8\u304d\u8fbc\u307f\u64cd\u4f5c\u6570\n \n \n Mark OSD \n \n \n OSD\n \u3092\u30de\u30fc\u30af\n \n \n \n Mark \n \n \n \n \u3092\u30de\u30fc\u30af\n \n \n \n PG scrub options\n PG scrub options\n \n \n Updated PG scrub options\n Updated PG scrub options\n \n \n Max Backfills\n \u6700\u5927\u30d0\u30c3\u30af\u30d5\u30a3\u30eb\u6570\n \n \n Recovery Max Active\n \u56de\u5fa9\u6700\u5927\u30a2\u30af\u30c6\u30a3\u30d6\n \n \n Recovery Max Single Start\n \u56de\u5fa9\u6700\u5927\u5358\u4e00\u59cb\u52d5\n \n \n Recovery Sleep\n \u56de\u5fa9\u30b9\u30ea\u30fc\u30d7\n \n \n Custom\n \u30ab\u30b9\u30bf\u30e0\n \n \n Updated OSD recovery speed priority "\n "\n \n OSD\u306e\u56de\u5fa9\u901f\u5ea6\u512a\u5148\u5ea6\u300c\n \u300d\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n \n \n was initialized in the following OSD: \n \n \n \n \u306f\u6b21\u306eOSD\u3067\u521d\u671f\u5316\u3055\u308c\u307e\u3057\u305f: \n \n \n \n \n Create silence\n Create silence\n \n \n Job\n \u30b8\u30e7\u30d6\n \n \n Severity\n \u91cd\u5927\u5ea6\n \n \n Started\n \u59cb\u52d5\u6e08\u307f\n \n \n URL\n URL\n \n \n silence\n silence\n \n \n Attribute name\n Attribute name\n \n \n Regular expression\n Regular expression\n \n \n Please add your Prometheus host to the dashboard configuration and refresh the page\n Please add your Prometheus host to the dashboard configuration and refresh the page\n \n \n Created by\n Created by\n \n \n Updated\n \u66f4\u65b0\u6e08\u307f\n \n \n Ends\n Ends\n \n \n Silence\n Silence\n \n \n Used\n \u4f7f\u7528\u6e08\u307f\n \n \n Avail.\n \u4f7f\u7528\u53ef\u80fd\n \n \n Clean\n \u30af\u30ea\u30fc\u30f3\n \n \n Working\n \u52d5\u4f5c\u4e2d\n \n \n Warning\n \u8b66\u544a\n \n \n Unknown\n \u4e0d\u660e\n \n \n Healthy\n Healthy\n \n \n Misplaced\n Misplaced\n \n \n Degraded\n Degraded\n \n \n Unfound\n Unfound\n \n \n replicas\n replicas\n \n \n up\n \u30a2\u30c3\u30d7\n \n \n no filesystems\n \u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u304c\u3042\u308a\u307e\u305b\u3093\n \n \n active\n \u30a2\u30af\u30c6\u30a3\u30d6\n \n \n standby\n \u30b9\u30bf\u30f3\u30d0\u30a4\n \n \n n/a\n \u306a\u3057\n \n \n active daemon\n \u30a2\u30af\u30c6\u30a3\u30d6\u30c7\u30fc\u30e2\u30f3\n \n \n quorum\n \u5b9a\u6570\n \n \n The NFS Ganesha service is not configured.\n NFS Ganesha\u30b5\u30fc\u30d3\u30b9\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\n \n \n Transport\n \u30c8\u30e9\u30f3\u30b9\u30dd\u30fc\u30c8\n \n \n CephFS User\n CephFS\u30e6\u30fc\u30b6\n \n \n CephFS Filesystem\n CephFS\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\n \n \n (inherited from global config)\n (\u30b0\u30ed\u30fc\u30d0\u30eb\u8a2d\u5b9a\u304b\u3089\u7d99\u627f)\n \n \n inherited from global config\n \u30b0\u30ed\u30fc\u30d0\u30eb\u8a2d\u5b9a\u304b\u3089\u7d99\u627f\u3055\u308c\u307e\u3057\u305f\n \n \n -- Select what kind of user id squashing is performed --\n -- \u5b9f\u884c\u3055\u308c\u308b\u30e6\u30fc\u30b6ID\u30b9\u30ab\u30c3\u30b7\u30e5\u64cd\u4f5c\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n There are no daemons available.\n \u4f7f\u7528\u53ef\u80fd\u306a\u30c7\u30fc\u30e2\u30f3\u304c\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n NFS export\n NFS export\n \n \n EC Profile\n EC Profile\n \n \n Cache Mode\n \u30ad\u30e3\u30c3\u30b7\u30e5\u30e2\u30fc\u30c9\n \n \n Min Evict Age\n \u9000\u53bb\u307e\u3067\u306e\u6700\u5c0f\u7d4c\u904e\u6642\u9593\n \n \n Min Flush Age\n \u6d88\u53bb\u307e\u3067\u306e\u6700\u5c0f\u7d4c\u904e\u6642\u9593\n \n \n Target Max Bytes\n \u30bf\u30fc\u30b2\u30c3\u30c8\u306e\u6700\u5927\u30d0\u30a4\u30c8\u6570\n \n \n Target Max Objects\n \u30bf\u30fc\u30b2\u30c3\u30c8\u306e\u6700\u5927\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u6570\n \n \n No applications added\n \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306f\u8ffd\u52a0\u3055\u308c\u3066\u3044\u307e\u305b\u3093\n \n \n Applications limit reached\n \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u6570\u306e\u4e0a\u9650\u306b\u9054\u3057\u307e\u3057\u305f\n \n \n A pool can only have up to four applications definitions.\n 1\u3064\u306e\u30d7\u30fc\u30eb\u306f\u6700\u5927\u30674\u3064\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5b9a\u7fa9\u3057\u304b\u4fdd\u6709\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n Allowed characters \'_a-zA-Z0-9\'\n \u4f7f\u7528\u53ef\u80fd\u306a\u6587\u5b57\u300c_a-zA-Z0-9\u300d\n \n \n Maximum length is 128 characters\n \u6700\u5927\u9577\u306f128\u6587\u5b57\u3067\u3059\n \n \n Filter or add applications\n \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\u307e\u305f\u306f\u8ffd\u52a0\n \n \n Add application\n \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8ffd\u52a0\n \n \n pool\n pool\n \n \n erasure code profile\n \u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\n \n \n Replica Size\n \u30ec\u30d7\u30ea\u30ab\u30b5\u30a4\u30ba\n \n \n Last Change\n \u6700\u5f8c\u306e\u5909\u66f4\n \n \n Erasure Coded Profile\n \u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u5316\u6e08\u307f\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\n \n \n Crush Ruleset\n Crush\u30eb\u30fc\u30eb\u30bb\u30c3\u30c8\n \n \n Write bytes\n \u66f8\u304d\u8fbc\u307f\u30d0\u30a4\u30c8\u6570\n \n \n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n Pool deletion is disabled by the mon_allow_pool_delete configuration setting.\n \n \n bucket\n \u30d0\u30b1\u30c3\u30c8\n \n \n Updated Object Gateway bucket "\n "\n \n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30d0\u30b1\u30c3\u30c8\u300c\n \u300d\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n \n Created Object Gateway bucket "\n "\n \n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30d0\u30b1\u30c3\u30c8\u300c\n \u300d\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\n \n \n \n buckets\n \u30d0\u30b1\u30c3\u30c8\u6570\n \n \n capability\n capability\n \n \n user\n \u30e6\u30fc\u30b6\n \n \n subuser\n subuser\n \n \n S3 Key\n S3 Key\n \n \n Updated Object Gateway user "\n "\n \n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30e6\u30fc\u30b6\u300c\n \u300d\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n \n Created Object Gateway user "\n "\n \n \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u30e6\u30fc\u30b6\u300c\n \u300d\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\n \n \n \n users\n \u30e6\u30fc\u30b6\u6570\n \n \n Swift Key\n Swift Key\n \n \n Scope\n \u7bc4\u56f2\n \n \n Read\n \u8aad\u307f\u53d6\u308a\n \n \n Create\n \u4f5c\u6210\n \n \n role\n role\n \n \n Created role \'\n \'\n \n \u5f79\u5272\u300c\n \u300d\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\n \n \n \n Updated role \'\n \'\n \n \u5f79\u5272\u300c\n \u300d\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n \n System Role\n \u30b7\u30b9\u30c6\u30e0\u5f79\u5272\n \n \n Deleted role \'\n \'\n \n \u5f79\u5272\u300c\n \u300d\u3092\u524a\u9664\u3057\u307e\u3057\u305f\n \n \n \n Created user "\n "\n \n \u30e6\u30fc\u30b6\u300c\n \u300d\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\n \n \n \n Update user\n \u30e6\u30fc\u30b6\u306e\u66f4\u65b0\n \n \n Continue\n \u7d9a\u884c\n \n \n You were automatically logged out because your roles have been changed.\n \u3053\u306e\u30e6\u30fc\u30b6\u306e\u5f79\u5272\u304c\u5909\u66f4\u3055\u308c\u305f\u305f\u3081\u3001\u3053\u306e\u30e6\u30fc\u30b6\u306f\u81ea\u52d5\u7684\u306b\u30ed\u30b0\u30a2\u30a6\u30c8\u3055\u308c\u307e\u3057\u305f\u3002\n \n \n Updated user "\n "\n \n \u30e6\u30fc\u30b6\u300c\n \u300d\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f\n \n \n \n Deleted user "\n "\n \n \u30e6\u30fc\u30b6\u300c\n \u300d\u3092\u524a\u9664\u3057\u307e\u3057\u305f\n \n \n \n Failed to delete user "\n "\n \n \u30e6\u30fc\u30b6\u300c\n \u300d\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\n \n \n \n You are currently logged in as "\n ".\n \n \u73fe\u5728\u3053\u306e\u30e6\u30fc\u30b6\u306f\u300c\n \u300d\u3068\u3057\u3066\u30ed\u30b0\u30a4\u30f3\u3057\u3066\u3044\u307e\u3059\u3002\n \n \n \n Each object is split in data-chunks parts, each stored on a different OSD.\n \u5404\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u8907\u6570\u306e\u30c7\u30fc\u30bf\u30c1\u30e3\u30f3\u30af\u30d1\u30fc\u30c8\u306b\u5206\u5272\u3055\u308c\u3066\u304a\u308a\u3001\u305d\u308c\u305e\u308c\u306e\u30d1\u30fc\u30c8\u306f\u7570\u306a\u308bOSD\u306b\u4fdd\u7ba1\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n Compute coding chunks for each object and store them on different OSDs.\n The number of coding chunks is also the number of OSDs that can be down without losing data.\n \u5404\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u30c1\u30e3\u30f3\u30af\u3092\u8a08\u7b97\u3057\u3066\u3001\u3053\u308c\u3089\u306e\u30c1\u30e3\u30f3\u30af\u3092\u5225\u3005\u306eOSD\u306b\u4fdd\u7ba1\u3057\u307e\u3059\u3002\n\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u30c1\u30e3\u30f3\u30af\u306e\u6570\u306f\u3001\u30c7\u30fc\u30bf\u3092\u5931\u3046\u3053\u3068\u306a\u304f\u30c0\u30a6\u30f3\u72b6\u614b\u306b\u306a\u308b\u3053\u3068\u304c\u3067\u304d\u308bOSD\u306e\u6570\u3067\u3082\u3042\u308a\u307e\u3059\u3002\n \n \n The jerasure plugin is the most generic and flexible plugin,\n it is also the default for Ceph erasure coded pools.\n jerasure\u30d7\u30e9\u30b0\u30a4\u30f3\u306f\u6700\u3082\u6c4e\u7528\u7684\u3067\u67d4\u8edf\u6027\u306e\u9ad8\u3044\u30d7\u30e9\u30b0\u30a4\u30f3\u3067\u3059\u3002\n\u3053\u306e\u30d7\u30e9\u30b0\u30a4\u30f3\u306f\u3001Ceph\u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u5316\u6e08\u307f\u30d7\u30fc\u30eb\u7528\u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u3082\u3042\u308a\u307e\u3059\u3002\n \n \n The more flexible technique is reed_sol_van : it is enough to set k\n and m. The cauchy_good technique can be faster but you need to chose the packetsize\n carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents\n in the sense that they can only be configured with m=2.\n \u3055\u3089\u306b\u67d4\u8edf\u6027\u306e\u9ad8\u3044\u6280\u6cd5\u306freed_sol_van\u3067\u3059\u3002k\u3068m\u3092\n\u8a2d\u5b9a\u3059\u308b\u3060\u3051\u3067\u5341\u5206\u3067\u3059\u3002\ncauchy_good\u6280\u6cd5\u306f\u3088\u308a\u9ad8\u901f\u3068\u306a\u308a\u5f97\u307e\u3059\u304c\u3001\u30d1\u30b1\u30c3\u30c8\u30b5\u30a4\u30ba\u3092\u614e\u91cd\u306b\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\nreed_sol_r6_op\u3001liberation\u3001blaum_roth\u3001liber8tion\u306f\u3059\u3079\u3066\u3001\nm=2\u3092\u4f7f\u7528\u3057\u305f\u8a2d\u5b9a\u306e\u307f\u304c\u53ef\u80fd\u3068\u3044\u3046\u610f\u5473\u3067RAID6\u3068\u540c\u7b49\u3067\u3059\u3002\n \n \n The encoding will be done on packets of bytes size at a time.\n Chosing the right packet size is difficult.\n The jerasure documentation contains extensive information on this topic.\n \u30a8\u30f3\u30b3\u30fc\u30c9\u306f\u30d0\u30a4\u30c8\u30b5\u30a4\u30ba\u306e\u30d1\u30b1\u30c3\u30c8\u7fa4\u306b\u5bfe\u3057\u3066\u540c\u6642\u306b\u5b9f\u884c\u3055\u308c\u307e\u3059\u3002\n\u9069\u5207\u306a\u30d1\u30b1\u30c3\u30c8\u30b5\u30a4\u30ba\u3092\u9078\u629e\u3059\u308b\u3053\u3068\u306f\u56f0\u96e3\u3067\u3059\u3002\njerasure\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306b\u306f\u3053\u306e\u30c8\u30d4\u30c3\u30af\u306b\u95a2\u3059\u308b\u8a73\u7d30\u306a\u60c5\u5831\u304c\u8a18\u8f09\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n With the jerasure plugin, when an erasure coded object is stored on\n multiple OSDs, recovering from the loss of one OSD requires reading from all the others.\n For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading\n from the eleven others to repair.\n\n The lrc erasure code plugin creates local parity chunks to be able to recover using\n less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create\n an additional parity chunk for every four OSDs. When a single OSD is lost, it can be\n recovered with only four OSDs instead of eleven.\n jerasure\u30d7\u30e9\u30b0\u30a4\u30f3\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001\u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u5316\u6e08\u307f\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304c\u8907\u6570\u306eOSD\u306b\u4fdd\u7ba1\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f\u3001\n1\u3064\u306eOSD\u306e\u55aa\u5931\u304b\u3089\u56de\u5fa9\u3059\u308b\u306b\u306f\u3001\u4ed6\u306e\u3059\u3079\u3066\u306eOSD\u304b\u3089\u306e\u8aad\u307f\u53d6\u308a\u304c\u5fc5\u8981\u306b\u306a\u308a\u307e\u3059\u3002\n\u305f\u3068\u3048\u3070\u3001k=8\u304a\u3088\u3073m=4\u3092\u4f7f\u7528\u3057\u3066jerasure\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f\u30011\u3064\u306eOSD\u304c\u5931\u308f\u308c\u305f\u5834\u5408\u3001\n\u4fee\u5fa9\u306e\u305f\u3081\u306b\u306f\u4ed6\u306e11\u500b\u306eOSD\u304b\u3089\u306e\u8aad\u307f\u53d6\u308a\u304c\u5fc5\u8981\u306b\u306a\u308a\u307e\u3059\u3002\n\nlrc\u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30e9\u30b0\u30a4\u30f3\u306f\u3001\u3053\u308c\u3088\u308a\u5c11\u306a\u3044OSD\u3092\u4f7f\u7528\u3057\u305f\u56de\u5fa9\u3092\u53ef\u80fd\u306b\u3059\u308b\u305f\u3081\u306b\u3001\n\u30ed\u30fc\u30ab\u30eb\u30d1\u30ea\u30c6\u30a3\u30c1\u30e3\u30f3\u30af\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002\u305f\u3068\u3048\u3070\u3001lrc\u304ck=8\u3001m=4\u3001\u304a\u3088\u3073l=4\u3092\u4f7f\u7528\u3057\u3066\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f\u3001\nlrc\u306f\u30014\u3064\u306eOSD\u3054\u3068\u306b1\u3064\u306e\u8ffd\u52a0\u30d1\u30ea\u30c6\u30a3\u30c1\u30e3\u30f3\u30af\u3092\u4f5c\u6210\u3057\u307e\u3059\u30021\u3064\u306eOSD\u304c\u5931\u308f\u308c\u305f\u5834\u5408\u306f\u3001\n11\u500b\u306e\u4ee3\u308f\u308a\u306b4\u3064\u306eOSD\u306e\u307f\u3092\u4f7f\u7528\u3057\u3066\u305d\u306eOSD\u3092\u56de\u5fa9\u3067\u304d\u307e\u3059\u3002\n \n \n Group the coding and data chunks into sets of size locality. For instance,\n for k=4 and m=2, when locality=3 two groups of three are created. Each set can\n be recovered without reading chunks from another set.\n \u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u30c1\u30e3\u30f3\u30af\u3068\u30c7\u30fc\u30bf\u30c1\u30e3\u30f3\u30af\u3092\u30b5\u30a4\u30ba\u5730\u57df\u306e\u8907\u6570\u30bb\u30c3\u30c8\u306b\u30b0\u30eb\u30fc\u30d7\u5206\u3051\u3057\u307e\u3059\u3002\n\u305f\u3068\u3048\u3070\u3001k=4\u304a\u3088\u3073m=2\u306e\u5834\u5408\u306b\u3001\uff3b\u5730\u57df\uff3d=3\u306e\u5834\u5408\u306f\u30013\u3064\u306e\u30c1\u30e3\u30f3\u30af\u304b\u3089\u306a\u308b\u30b0\u30eb\u30fc\u30d7\u304c2\u3064\u4f5c\u6210\u3055\u308c\u307e\u3059\u3002\n\u5404\u30bb\u30c3\u30c8\u306f\u3001\u5225\u306e\u30bb\u30c3\u30c8\u304b\u3089\u30c1\u30e3\u30f3\u30af\u3092\u8aad\u307f\u53d6\u308b\u3053\u3068\u306a\u304f\u56de\u5fa9\u3067\u304d\u307e\u3059\u3002\n \n \n The type of the crush bucket in which each set of chunks defined\n by l will be stored. For instance, if it is set to rack, each group of l chunks will be\n placed in a different rack. It is used to create a CRUSH rule step such as step choose\n rack. If it is not set, no such grouping is done.\n 1\u306b\u3088\u3063\u3066\u5b9a\u7fa9\u3055\u308c\u305f\u30c1\u30e3\u30f3\u30af\u306e\u5404\u30bb\u30c3\u30c8\u304c\u4fdd\u7ba1\u3055\u308c\u308bCrush\u30d0\u30b1\u30c3\u30c8\u306e\u30bf\u30a4\u30d7\u3002\n\u305f\u3068\u3048\u3070\u3001\u3053\u306e\u30d0\u30b1\u30c3\u30c8\u30bf\u30a4\u30d7\u304c\u30e9\u30c3\u30af\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f\u30011\u306e\u30c1\u30e3\u30f3\u30af\u306e\u5404\u30b0\u30eb\u30fc\u30d7\u306f\u7570\u306a\u308b\u30e9\u30c3\u30af\u306b\u914d\u7f6e\u3055\u308c\u307e\u3059\u3002\n\u3053\u306e\u30d0\u30b1\u30c3\u30c8\u30bf\u30a4\u30d7\u3092\u4f7f\u7528\u3057\u3066\u3001\u300c\u30e9\u30c3\u30af\u306e\u9078\u629e\u300d\u30b9\u30c6\u30c3\u30d7\u306a\u3069\u306eCRUSH\u30eb\u30fc\u30eb\u30b9\u30c6\u30c3\u30d7\u304c\u4f5c\u6210\u3055\u308c\u307e\u3059\u3002\n\u3053\u306e\u30d0\u30b1\u30c3\u30c8\u30bf\u30a4\u30d7\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f\u3001\u3053\u306e\u3088\u3046\u306a\u30b0\u30eb\u30fc\u30d7\u5206\u3051\u306f\u884c\u308f\u308c\u307e\u305b\u3093\u3002\n \n \n The isa plugin encapsulates the ISA library. It only runs on Intel processors.\n isa\u30d7\u30e9\u30b0\u30a4\u30f3\u306fISA\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30ab\u30d7\u30bb\u30eb\u5316\u3057\u307e\u3059\u3002\u3053\u306e\u30d7\u30e9\u30b0\u30a4\u30f3\u306fIntel\u30d7\u30ed\u30bb\u30c3\u30b5\u4e0a\u306e\u307f\u3067\u52d5\u4f5c\u3057\u307e\u3059\u3002\n \n \n The ISA plugin comes in two Reed Solomon forms.\n If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy.\n ISA\u30d7\u30e9\u30b0\u30a4\u30f3\u306f2\u3064\u306e\u30ea\u30fc\u30c9\u30bd\u30ed\u30e2\u30f3\u5f62\u5f0f\u3067\u63d0\u4f9b\u3055\u308c\u3066\u3044\u307e\u3059\u3002reed_sol_van\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f\u3001Vandermonde\u3067\u3042\u308a\u3001cauchy\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f\u3001Cauchy\u3067\u3059\u3002\n \n \n The shec plugin encapsulates the multiple SHEC library.\n It allows ceph to recover data more efficiently than Reed Solomon codes.\n shec\u30d7\u30e9\u30b0\u30a4\u30f3\u306f\u8907\u6570\u306eSHEC\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30ab\u30d7\u30bb\u30eb\u5316\u3057\u307e\u3059\u3002\n\u3053\u306e\u30d7\u30e9\u30b0\u30a4\u30f3\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001ceph\u306f\u30ea\u30fc\u30c9\u30bd\u30ed\u30e2\u30f3\u30b3\u30fc\u30c9\u3088\u308a\u52b9\u7387\u7684\u306b\u30c7\u30fc\u30bf\u3092\u56de\u5fa9\u3067\u304d\u307e\u3059\u3002\n \n \n The number of parity chunks each of which includes each data chunk in its\n calculation range. The number is used as a durability estimator. For instance, if c=2,\n 2 OSDs can be down without losing data.\n \u305d\u308c\u305e\u308c\u304c\u5404\u30c7\u30fc\u30bf\u30c1\u30e3\u30f3\u30af\u3092\u5404\u81ea\u306e\u8a08\u7b97\u7bc4\u56f2\u5185\u306b\u542b\u3093\u3067\u3044\u308b\u30d1\u30ea\u30c6\u30a3\u30c1\u30e3\u30f3\u30af\u306e\u6570\u3002\n\u3053\u306e\u6570\u306f\u3001\u8010\u4e45\u6027\u63a8\u5b9a\u5b50\u3068\u3057\u3066\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002\n\u305f\u3068\u3048\u3070\u3001c=2\u306e\u5834\u5408\u306f\u3001\u30c7\u30fc\u30bf\u3092\u5931\u3046\u3053\u3068\u306a\u304f2\u3064\u306eOSD\u304c\u30c0\u30a6\u30f3\u72b6\u614b\u306b\u306a\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\n \n \n The name of the crush bucket used for the first step of the CRUSH rule.\n For instance step take default.\n CRUSH\u30eb\u30fc\u30eb\u306e\u6700\u521d\u306e\u30b9\u30c6\u30c3\u30d7(\u300c\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u4f7f\u7528\u300d\u30b9\u30c6\u30c3\u30d7\u306a\u3069)\u7528\u306b\n\u4f7f\u7528\u3055\u308c\u308bCrush\u30d0\u30b1\u30c3\u30c8\u306e\u540d\u524d\u3002\n \n \n Ensure that no two chunks are in a bucket with the same failure\n domain. For instance, if the failure domain is host no two chunks will be stored on the same\n host. It is used to create a CRUSH rule step such as step chooseleaf host.\n \u540c\u3058\u969c\u5bb3\u30c9\u30e1\u30a4\u30f3\u306e\u5358\u4e00\u30d0\u30b1\u30c3\u30c8\u5185\u306b2\u3064\u306e\u30c1\u30e3\u30f3\u30af\u304c\u914d\u7f6e\u3055\u308c\u308b\u3053\u3068\u3092\u9632\u6b62\u3057\u307e\u3059\u3002\n\u305f\u3068\u3048\u3070\u3001\u969c\u5bb3\u30c9\u30e1\u30a4\u30f3\u304c\u30db\u30b9\u30c8\u3067\u3042\u308b\u5834\u5408\u306f\u30012\u3064\u306e\u30c1\u30e3\u30f3\u30af\u304c\u540c\u3058\u30db\u30b9\u30c8\u306b\u4fdd\u7ba1\u3055\u308c\u308b\u3053\u3068\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n\u3053\u308c\u3092\u4f7f\u7528\u3057\u3066\u3001\u300c\u30ea\u30fc\u30d5\u30db\u30b9\u30c8\u306e\u9078\u629e\u300d\u30b9\u30c6\u30c3\u30d7\u306a\u3069\u306eCRUSH\u30eb\u30fc\u30eb\u30b9\u30c6\u30c3\u30d7\u304c\u4f5c\u6210\u3055\u308c\u307e\u3059\u3002\n \n \n Restrict placement to devices of a specific class\n (e.g., ssd or hdd), using the crush device class names in the CRUSH map.\n CRUSH\u30de\u30c3\u30d7\u5185\u3067Crush\u30c7\u30d0\u30a4\u30b9\u30af\u30e9\u30b9\u540d\u3092\u4f7f\u7528\u3057\u3066\u3001\u914d\u7f6e\u5148\u3092\u7279\u5b9a\u30af\u30e9\u30b9(ssd\u3084hdd\u306a\u3069)\u306e\u30c7\u30d0\u30a4\u30b9\u306e\u307f\u306b\u5236\u9650\u3057\u307e\u3059\u3002\n \n \n Set the directory name from which the erasure code plugin is loaded.\n \u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u8aad\u307f\u8fbc\u307f\u5143\u3068\u306a\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u540d\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002\n \n \n Allows all operations\n \u3059\u3079\u3066\u306e\u64cd\u4f5c\u3092\u8a31\u53ef\u3057\u307e\u3059\n \n \n Allows only operations that do not modify the server\n \u30b5\u30fc\u30d0\u306b\u5909\u66f4\u3092\u52a0\u3048\u306a\u3044\u64cd\u4f5c\u306e\u307f\u3092\u8a31\u53ef\u3057\u307e\u3059\n \n \n Does not allow read or write operations, but allows any other operation\n \u8aad\u307f\u53d6\u308a/\u66f8\u304d\u8fbc\u307f\u64cd\u4f5c\u3092\u8a31\u53ef\u3057\u307e\u305b\u3093\u304c\u3001\u4ed6\u306e\u3059\u3079\u3066\u306e\u64cd\u4f5c\u3092\u8a31\u53ef\u3057\u307e\u3059\n \n \n Does not allow read, write, or any operation that modifies file attributes or directory content\n \u8aad\u307f\u53d6\u308a/\u66f8\u304d\u8fbc\u307f\u64cd\u4f5c\u3001\u304a\u3088\u3073\u30d5\u30a1\u30a4\u30eb\u5c5e\u6027\u3084\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u5185\u5bb9\u3092\u5909\u66f4\u3059\u308b\u3069\u306e\u64cd\u4f5c\u3082\u8a31\u53ef\u3057\u307e\u305b\u3093\n \n \n Allows no access at all\n \u30a2\u30af\u30bb\u30b9\u3092\u4e00\u5207\u8a31\u53ef\u3057\u307e\u305b\u3093\n \n \n -- Select the priority --\n -- \u512a\u5148\u5ea6\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044 --\n \n \n Low\n \u4f4e\n \n \n High\n \u9ad8\n \n \n Last 5 minutes\n \u76f4\u524d\u306e5\u5206\u9593\n \n \n Last 15 minutes\n \u76f4\u524d\u306e15\u5206\u9593\n \n \n Last 30 minutes\n \u76f4\u524d\u306e30\u5206\u9593\n \n \n Last 1 hour (Default)\n \u76f4\u524d\u306e1\u6642\u9593(\u30c7\u30d5\u30a9\u30eb\u30c8)\n \n \n Last 3 hours\n \u76f4\u524d\u306e3\u6642\u9593\n \n \n Last 6 hours\n \u76f4\u524d\u306e6\u6642\u9593\n \n \n Last 12 hours\n \u76f4\u524d\u306e12\u6642\u9593\n \n \n Last 24 hours\n \u76f4\u524d\u306e24\u6642\u9593\n \n \n Yesterday\n \u6628\u65e5\n \n \n Today\n \u672c\u65e5\n \n \n Today so far\n \u672c\u65e5\u306e\u73fe\u6642\u70b9\u307e\u3067\n \n \n Day before yesterday\n \u4e00\u6628\u65e5\n \n \n Last 2 days\n \u904e\u53bb2\u65e5\u9593\n \n \n This day last week\n \u5148\u9031\u306e\u540c\u3058\u66dc\u65e5\n \n \n Previous week\n \u524d\u9031\n \n \n This week\n \u4eca\u9031\n \n \n This week so far\n \u4eca\u9031\u306e\u73fe\u6642\u70b9\u307e\u3067\n \n \n Last 7 days\n \u904e\u53bb7\u65e5\u9593\n \n \n Previous month\n \u524d\u6708\n \n \n This month\n \u4eca\u6708\n \n \n This month so far\n \u4eca\u6708\u306e\u73fe\u6642\u70b9\u307e\u3067\n \n \n Last 30 days\n \u904e\u53bb30\u65e5\u9593\n \n \n Last 90 days\n \u904e\u53bb90\u65e5\u9593\n \n \n Last 6 months\n \u904e\u53bb6\u30ab\u6708\n \n \n Last 1 year\n \u904e\u53bb1\u5e74\u9593\n \n \n Previous year\n \u524d\u5e74\n \n \n This year\n \u4eca\u5e74\n \n \n This year so far\n \u4eca\u5e74\u306e\u73fe\u6642\u70b9\u307e\u3067\n \n \n Last 2 years\n \u904e\u53bb2\u5e74\u9593\n \n \n Last 5 years\n \u904e\u53bb5\u5e74\u9593\n \n \n Information\n \u60c5\u5831\n \n \n No items selected.\n \u30a2\u30a4\u30c6\u30e0\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\n \n \n Deselect item to select again\n \u30a2\u30a4\u30c6\u30e0\u3092\u9078\u629e\u89e3\u9664\u3057\u3066\u518d\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\n \n \n Selection limit reached\n \u9078\u629e\u306e\u4e0a\u9650\u306b\u9054\u3057\u307e\u3057\u305f\n \n \n Filter tags\n \u30bf\u30b0\u306e\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\n \n \n Add badge\n \u30d0\u30c3\u30b8\u306e\u8ffd\u52a0\n \n \n There are no items available.\n \u4f7f\u7528\u53ef\u80fd\u306a\u30a2\u30a4\u30c6\u30e0\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n \n \n Add\n \u8ffd\u52a0\n \n \n Remove\n Remove\n \n \n Clone\n \u8907\u88fd\n \n \n Copy\n \u30b3\u30d4\u30fc\n \n \n Deep Scrub\n \u30c7\u30a3\u30fc\u30d7\u30b9\u30af\u30e9\u30d6\n \n \n Destroy\n \u7834\u68c4\n \n \n Flatten\n \u30d5\u30e9\u30c3\u30c8\u5316\n \n \n Mark Down\n \u30c0\u30a6\u30f3\u3068\u3057\u3066\u30de\u30fc\u30af\n \n \n Mark In\n \u30a4\u30f3\u3068\u3057\u3066\u30de\u30fc\u30af\n \n \n Mark Lost\n \u55aa\u5931\u3068\u3057\u3066\u30de\u30fc\u30af\n \n \n Mark Out\n \u30a2\u30a6\u30c8\u3068\u3057\u3066\u30de\u30fc\u30af\n \n \n Protect\n \u4fdd\u8b77\n \n \n Rename\n \u540d\u524d\u306e\u5909\u66f4\n \n \n Restore\n \u5fa9\u5143\n \n \n Move to Trash\n \u3054\u307f\u7bb1\u306b\u79fb\u52d5\u3059\u308b\n \n \n Unprotect\n \u4fdd\u8b77\u89e3\u9664\n \n \n Recreate\n Recreate\n \n \n Expire\n Expire\n \n \n Deleted\n \u524a\u9664\u6e08\u307f\n \n \n Added\n Added\n \n \n Removed\n Removed\n \n \n Edited\n Edited\n \n \n Canceled\n Canceled\n \n \n Cloned\n \u8907\u88fd\u6e08\u307f\n \n \n Copied\n \u30b3\u30d4\u30fc\u6e08\u307f\n \n \n Showed\n Showed\n \n \n Moved to Trash\n Moved to Trash\n \n \n Unprotected\n Unprotected\n \n \n Recreated\n Recreated\n \n \n Expired\n Expired\n \n \n Yes\n \u306f\u3044\n \n \n No\n \u3044\u3044\u3048\n \n \n Your matcher seems to match no currently defined rule or active alert.\n Your matcher seems to match no currently defined rule or active alert.\n \n \n no active alerts\n no active alerts\n \n \n 1 active alert\n 1 active alert\n \n \n \n active alerts\n \n \n active alerts\n \n \n \n Matches 1 rule\n Matches 1 rule\n \n \n Matches \n rules\n \n Matches \n rules\n \n \n \n \n with \n .\n \n \n with \n .\n \n \n \n Quality of Service\n \u30b5\u30fc\u30d3\u30b9\u54c1\u8cea\n \n \n BPS Limit\n BPS\u5236\u9650\n \n \n The desired limit of IO bytes per second.\n \u5e0c\u671b\u3059\u308b\u79d2\u3042\u305f\u308a\u5165\u51fa\u529b\u30d0\u30a4\u30c8\u6570\u306e\u4e0a\u9650\u3002\n \n \n IOPS Limit\n IOPS\u5236\u9650\n \n \n The desired limit of IO operations per second.\n \u5e0c\u671b\u3059\u308b\u79d2\u3042\u305f\u308a\u5165\u51fa\u529b\u64cd\u4f5c\u6570\u306e\u4e0a\u9650\u3002\n \n \n Read BPS Limit\n \u8aad\u307f\u53d6\u308aBPS\u5236\u9650\n \n \n The desired limit of read bytes per second.\n \u5e0c\u671b\u3059\u308b\u79d2\u3042\u305f\u308a\u8aad\u307f\u53d6\u308a\u30d0\u30a4\u30c8\u6570\u306e\u4e0a\u9650\u3002\n \n \n Read IOPS Limit\n \u8aad\u307f\u53d6\u308aIOPS\u5236\u9650\n \n \n The desired limit of read operations per second.\n \u5e0c\u671b\u3059\u308b\u79d2\u3042\u305f\u308a\u8aad\u307f\u53d6\u308a\u64cd\u4f5c\u6570\u306e\u4e0a\u9650\u3002\n \n \n Write BPS Limit\n \u66f8\u304d\u8fbc\u307fBPS\u5236\u9650\n \n \n The desired limit of write bytes per second.\n \u5e0c\u671b\u3059\u308b\u79d2\u3042\u305f\u308a\u66f8\u304d\u8fbc\u307f\u30d0\u30a4\u30c8\u6570\u306e\u4e0a\u9650\u3002\n \n \n Write IOPS Limit\n \u66f8\u304d\u8fbc\u307fIOPS\u5236\u9650\n \n \n The desired limit of write operations per second.\n \u5e0c\u671b\u3059\u308b\u79d2\u3042\u305f\u308a\u66f8\u304d\u8fbc\u307f\u64cd\u4f5c\u6570\u306e\u4e0a\u9650\u3002\n \n \n BPS Burst\n BPS\u30d0\u30fc\u30b9\u30c8\n \n \n The desired burst limit of IO bytes.\n \u5e0c\u671b\u3059\u308b\u5165\u51fa\u529b\u30d0\u30a4\u30c8\u6570\u306e\u30d0\u30fc\u30b9\u30c8\u4e0a\u9650\u3002\n \n \n IOPS Burst\n IOPS\u30d0\u30fc\u30b9\u30c8\n \n \n The desired burst limit of IO operations.\n \u5e0c\u671b\u3059\u308b\u5165\u51fa\u529b\u64cd\u4f5c\u6570\u306e\u30d0\u30fc\u30b9\u30c8\u4e0a\u9650\u3002\n \n \n Read BPS Burst\n \u8aad\u307f\u53d6\u308aBPS\u30d0\u30fc\u30b9\u30c8\n \n \n The desired burst limit of read bytes.\n \u5e0c\u671b\u3059\u308b\u8aad\u307f\u53d6\u308a\u30d0\u30a4\u30c8\u6570\u306e\u30d0\u30fc\u30b9\u30c8\u4e0a\u9650\u3002\n \n \n Read IOPS Burst\n \u8aad\u307f\u53d6\u308aIOPS\u30d0\u30fc\u30b9\u30c8\n \n \n The desired burst limit of read operations.\n \u5e0c\u671b\u3059\u308b\u8aad\u307f\u53d6\u308a\u64cd\u4f5c\u6570\u306e\u30d0\u30fc\u30b9\u30c8\u4e0a\u9650\u3002\n \n \n Write BPS Burst\n \u66f8\u304d\u8fbc\u307fBPS\u30d0\u30fc\u30b9\u30c8\n \n \n The desired burst limit of write bytes.\n \u5e0c\u671b\u3059\u308b\u66f8\u304d\u8fbc\u307f\u30d0\u30a4\u30c8\u6570\u306e\u30d0\u30fc\u30b9\u30c8\u4e0a\u9650\u3002\n \n \n Write IOPS Burst\n \u66f8\u304d\u8fbc\u307fIOPS\u30d0\u30fc\u30b9\u30c8\n \n \n The desired burst limit of write operations.\n \u5e0c\u671b\u3059\u308b\u66f8\u304d\u8fbc\u307f\u64cd\u4f5c\u6570\u306e\u30d0\u30fc\u30b9\u30c8\u4e0a\u9650\u3002\n \n \n Failed to \n \n \n \n \n \n \u3092\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\n \n \n \n Executing\n \u5b9f\u884c\u4e2d\n \n \n execute\n \u5b9f\u884c\n \n \n Executed\n \u5b9f\u884c\u6e08\u307f\n \n \n unknown task\n \u4e0d\u660e\u306a\u30bf\u30b9\u30af\n \n \n Creating\n \u4f5c\u6210\u4e2d\n \n \n create\n \u4f5c\u6210\n \n \n Updating\n \u66f4\u65b0\u4e2d\n \n \n update\n \u66f4\u65b0\n \n \n Deleting\n \u524a\u9664\u4e2d\n \n \n delete\n \u524a\u9664\n \n \n RBD \'\n \'\n \n RBD\u300c\n \u300d\n \n \n \n RBD snapshot \'\n \'\n \n RBD\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u300c\n \u300d\n \n \n \n mirror mode for pool \'\n \'\n \n \u30d7\u30fc\u30eb\u300c\n \u300d\u306e\u30df\u30e9\u30fc\u30e2\u30fc\u30c9\n \n \n \n mirror peer for pool \'\n \'\n \n \u30d7\u30fc\u30eb\u300c\n \u300d\u306e\u30df\u30e9\u30fc\u30d4\u30a2\n \n \n \n all dashboards\n all dashboards\n \n \n Name is already used by \n .\n \n \u3053\u306e\u540d\u524d\u306f\n \u306b\u3088\u3063\u3066\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n \n Name is already used by \n .\n \n \u3053\u306e\u540d\u524d\u306f\n \u306b\u3088\u3063\u3066\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n \n Name is already used by \n .\n \n \u3053\u306e\u540d\u524d\u306f\n \u306b\u3088\u3063\u3066\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n \n \n contains snapshots.\n \n \n \u306b\u306f\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n \n Cloning\n \u8907\u88fd\u4e2d\n \n \n clone\n \u8907\u88fd\n \n \n Snapshot of \n must be protected.\n \n \n \u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306f\u4fdd\u8b77\u3055\u308c\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n \n \n \n Copying\n \u30b3\u30d4\u30fc\u4e2d\n \n \n copy\n \u30b3\u30d4\u30fc\n \n \n Flattening\n \u30d5\u30e9\u30c3\u30c8\u5316\u4e2d\n \n \n flatten\n \u30d5\u30e9\u30c3\u30c8\u5316\n \n \n Flattened\n \u30d5\u30e9\u30c3\u30c8\u5316\u6e08\u307f\n \n \n Name is already used by \n .\n \n \u3053\u306e\u540d\u524d\u306f\n \u306b\u3088\u3063\u3066\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n \n Cannot unprotect \n because it contains child images.\n \n \n \u306f\u5b50\u30a4\u30e1\u30fc\u30b8\u3092\u542b\u3093\u3067\u3044\u308b\u305f\u3081\u4fdd\u8b77\u89e3\u9664\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n \n Cannot delete \n because it\'s protected.\n \n \n \u306f\u4fdd\u8b77\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n \n Rolling back\n \u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u4e2d\n \n \n rollback\n \u30ed\u30fc\u30eb\u30d0\u30c3\u30af\n \n \n Rolled back\n \u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u6e08\u307f\n \n \n Moving\n \u79fb\u52d5\u4e2d\n \n \n move\n \u79fb\u52d5\n \n \n Moved\n \u79fb\u52d5\u6e08\u307f\n \n \n image \'\n \' to trash\n \n \u30a4\u30e1\u30fc\u30b8\u300c\n \u300d\u3092\u3054\u307f\u7bb1\u306b\n \n \n \n Could not find image.\n \u30a4\u30e1\u30fc\u30b8\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n \n \n Restoring\n \u5fa9\u5143\u4e2d\n \n \n restore\n \u5fa9\u5143\n \n \n Restored\n \u5fa9\u5143\u6e08\u307f\n \n \n image \'\n \' into \'\n \'\n \n \u30a4\u30e1\u30fc\u30b8\u300c\n \u300d\u3092\u300c\n \u300d\u306b\n \n \n \n Image name \'\n \' is already in use.\n \n \u30a4\u30e1\u30fc\u30b8\u540d\u300c\n \u300d\u306f\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002\n \n \n \n image \'\n \'\n \n \u30a4\u30e1\u30fc\u30b8\u300c\n \u300d\n \n \n \n Purging\n \u6d88\u53bb\u4e2d\n \n \n purge\n \u6d88\u53bb\n \n \n Purged\n \u6d88\u53bb\u6e08\u307f\n \n \n all pools\n \u3059\u3079\u3066\u306e\u30d7\u30fc\u30eb\n \n \n images from \n \n \n \n \u304b\u3089\u306e\u30a4\u30e1\u30fc\u30b8\n \n \n \n Cannot disable mirroring because it contains a peer.\n \u30d4\u30a2\u3092\u542b\u3093\u3067\u3044\u308b\u305f\u3081\u30df\u30e9\u30fc\u30ea\u30f3\u30b0\u3092\u7121\u52b9\u5316\u3067\u304d\u307e\u305b\u3093\u3002\n \n \n pool \'\n \'\n \n \u30d7\u30fc\u30eb\u300c\n \u300d\n \n \n \n erasure code profile \'\n \'\n \n \u30a4\u30ec\u30a4\u30b8\u30e3\u30b3\u30fc\u30c9\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u300c\n \u300d\n \n \n \n target \'\n \'\n \n \u30bf\u30fc\u30b2\u30c3\u30c8\u300c\n \u300d\n \n \n \n NFS \n \n \n NFS \n \n \n \n \n \n'},wbK0:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("dEwP");function r(){for(var t=[],e=0;e>>0,a=0;a0)for(n=0;n=0?n?"+":"":"-")+Math.pow(10,Math.max(0,e-a.length)).toString().substr(1)+a}var z=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,G=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Y={},V={};function H(t,e,n,a){var r=a;"string"==typeof a&&(r=function(){return this[a]()}),t&&(V[t]=r),e&&(V[e[0]]=function(){return F(r.apply(this,arguments),e[1],e[2])}),n&&(V[n]=function(){return this.localeData().ordinal(r.apply(this,arguments),t)})}function B(t,e){return t.isValid()?(e=U(e,t.localeData()),Y[e]=Y[e]||function(t){var e,n,a,r=t.match(z);for(e=0,n=r.length;e=0&&G.test(t);)t=t.replace(G,a),G.lastIndex=0,n-=1;return t}var W=/\d/,K=/\d\d/,$=/\d{3}/,Z=/\d{4}/,X=/[+-]?\d{6}/,J=/\d\d?/,Q=/\d\d\d\d?/,tt=/\d\d\d\d\d\d?/,et=/\d{1,3}/,nt=/\d{1,4}/,at=/[+-]?\d{1,6}/,rt=/\d+/,it=/[+-]?\d+/,st=/Z|[+-]\d\d:?\d\d/gi,ot=/Z|[+-]\d\d(?::?\d\d)?/gi,ut=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ct={};function lt(t,e,n){ct[t]=R(e)?e:function(t,a){return t&&n?n:e}}function dt(t,e){return d(ct,t)?ct[t](e._strict,e._locale):new RegExp(ft(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,a,r){return e||n||a||r})))}function ft(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var pt={};function ht(t,e){var n,a=e;for("string"==typeof t&&(t=[t]),u(e)&&(a=function(t,n){n[e]=w(t)}),n=0;n68?1900:2e3)};var kt,Nt=Rt("FullYear",!0);function Rt(t,e){return function(n){return null!=n?(Dt(this,t,n),r.updateOffset(this,e),this):At(this,t)}}function At(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function Dt(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&Ct(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),Et(n,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](n))}function Et(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=(e%12+12)%12;return t+=(e-n)/12,1===n?Ct(t)?29:28:31-n%7%2}kt=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e=0){var n=Array.prototype.slice.call(arguments);n[0]=t+400,e=new Date(Date.UTC.apply(null,n)),isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t)}else e=new Date(Date.UTC.apply(null,arguments));return e}function Vt(t,e,n){var a=7+e-n;return-(7+Yt(t,0,a).getUTCDay()-e)%7+a-1}function Ht(t,e,n,a,r){var i,s,o=1+7*(e-1)+(7+n-a)%7+Vt(t,a,r);return o<=0?s=It(i=t-1)+o:o>It(t)?(i=t+1,s=o-It(t)):(i=t,s=o),{year:i,dayOfYear:s}}function Bt(t,e,n){var a,r,i=Vt(t.year(),e,n),s=Math.floor((t.dayOfYear()-i-1)/7)+1;return s<1?a=s+Ut(r=t.year()-1,e,n):s>Ut(t.year(),e,n)?(a=s-Ut(t.year(),e,n),r=t.year()+1):(r=t.year(),a=s),{week:a,year:r}}function Ut(t,e,n){var a=Vt(t,e,n),r=Vt(t+1,e,n);return(It(t)-a+r)/7}function Wt(t,e){return t.slice(e,7).concat(t.slice(0,e))}H("w",["ww",2],"wo","week"),H("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),j("week",5),j("isoWeek",5),lt("w",J),lt("ww",J,K),lt("W",J),lt("WW",J,K),gt(["w","ww","W","WW"],function(t,e,n,a){e[a.substr(0,1)]=w(t)}),H("d",0,"do","day"),H("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),H("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),H("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),H("e",0,0,"weekday"),H("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),j("day",11),j("weekday",11),j("isoWeekday",11),lt("d",J),lt("e",J),lt("E",J),lt("dd",function(t,e){return e.weekdaysMinRegex(t)}),lt("ddd",function(t,e){return e.weekdaysShortRegex(t)}),lt("dddd",function(t,e){return e.weekdaysRegex(t)}),gt(["dd","ddd","dddd"],function(t,e,n,a){var r=n._locale.weekdaysParse(t,a,n._strict);null!=r?e.d=r:h(n).invalidWeekday=t}),gt(["d","e","E"],function(t,e,n,a){e[a]=w(t)});var Kt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),$t="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Zt="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Xt=ut,Jt=ut,Qt=ut;function te(){function t(t,e){return e.length-t.length}var e,n,a,r,i,s=[],o=[],u=[],c=[];for(e=0;e<7;e++)n=p([2e3,1]).day(e),a=this.weekdaysMin(n,""),r=this.weekdaysShort(n,""),i=this.weekdays(n,""),s.push(a),o.push(r),u.push(i),c.push(a),c.push(r),c.push(i);for(s.sort(t),o.sort(t),u.sort(t),c.sort(t),e=0;e<7;e++)o[e]=ft(o[e]),u[e]=ft(u[e]),c[e]=ft(c[e]);this._weekdaysRegex=new RegExp("^("+c.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+s.join("|")+")","i")}function ee(){return this.hours()%12||12}function ne(t,e){H(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function ae(t,e){return e._meridiemParse}H("H",["HH",2],0,"hour"),H("h",["hh",2],0,ee),H("k",["kk",2],0,function(){return this.hours()||24}),H("hmm",0,0,function(){return""+ee.apply(this)+F(this.minutes(),2)}),H("hmmss",0,0,function(){return""+ee.apply(this)+F(this.minutes(),2)+F(this.seconds(),2)}),H("Hmm",0,0,function(){return""+this.hours()+F(this.minutes(),2)}),H("Hmmss",0,0,function(){return""+this.hours()+F(this.minutes(),2)+F(this.seconds(),2)}),ne("a",!0),ne("A",!1),L("hour","h"),j("hour",13),lt("a",ae),lt("A",ae),lt("H",J),lt("h",J),lt("k",J),lt("HH",J,K),lt("hh",J,K),lt("kk",J,K),lt("hmm",Q),lt("hmmss",tt),lt("Hmm",Q),lt("Hmmss",tt),ht(["H","HH"],_t),ht(["k","kk"],function(t,e,n){var a=w(t);e[_t]=24===a?0:a}),ht(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),ht(["h","hh"],function(t,e,n){e[_t]=w(t),h(n).bigHour=!0}),ht("hmm",function(t,e,n){var a=t.length-2;e[_t]=w(t.substr(0,a)),e[xt]=w(t.substr(a)),h(n).bigHour=!0}),ht("hmmss",function(t,e,n){var a=t.length-4,r=t.length-2;e[_t]=w(t.substr(0,a)),e[xt]=w(t.substr(a,2)),e[Tt]=w(t.substr(r)),h(n).bigHour=!0}),ht("Hmm",function(t,e,n){var a=t.length-2;e[_t]=w(t.substr(0,a)),e[xt]=w(t.substr(a))}),ht("Hmmss",function(t,e,n){var a=t.length-4,r=t.length-2;e[_t]=w(t.substr(0,a)),e[xt]=w(t.substr(a,2)),e[Tt]=w(t.substr(r))});var re,ie=Rt("Hours",!0),se={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Pt,monthsShort:Mt,week:{dow:0,doy:6},weekdays:Kt,weekdaysMin:Zt,weekdaysShort:$t,meridiemParse:/[ap]\.?m?\.?/i},oe={},ue={};function ce(t){return t?t.toLowerCase().replace("_","-"):t}function le(e){var a=null;if(!oe[e]&&void 0!==t&&t&&t.exports)try{a=re._abbr,n("RnhZ")("./"+e),de(a)}catch(r){}return oe[e]}function de(t,e){var n;return t&&((n=o(e)?pe(t):fe(t,e))?re=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),re._abbr}function fe(t,e){if(null!==e){var n,a=se;if(e.abbr=t,null!=oe[t])N("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),a=oe[t]._config;else if(null!=e.parentLocale)if(null!=oe[e.parentLocale])a=oe[e.parentLocale]._config;else{if(null==(n=le(e.parentLocale)))return ue[e.parentLocale]||(ue[e.parentLocale]=[]),ue[e.parentLocale].push({name:t,config:e}),null;a=n._config}return oe[t]=new D(A(a,e)),ue[t]&&ue[t].forEach(function(t){fe(t.name,t.config)}),de(t),oe[t]}return delete oe[t],null}function pe(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return re;if(!i(t)){if(e=le(t))return e;t=[t]}return function(t){for(var e,n,a,r,i=0;i0;){if(a=le(r.slice(0,e).join("-")))return a;if(n&&n.length>=e&&S(r,n,!0)>=e-1)break;e--}i++}return re}(t)}function he(t){var e,n=t._a;return n&&-2===h(t).overflow&&(e=n[yt]<0||n[yt]>11?yt:n[vt]<1||n[vt]>Et(n[mt],n[yt])?vt:n[_t]<0||n[_t]>24||24===n[_t]&&(0!==n[xt]||0!==n[Tt]||0!==n[wt])?_t:n[xt]<0||n[xt]>59?xt:n[Tt]<0||n[Tt]>59?Tt:n[wt]<0||n[wt]>999?wt:-1,h(t)._overflowDayOfYear&&(evt)&&(e=vt),h(t)._overflowWeeks&&-1===e&&(e=St),h(t)._overflowWeekday&&-1===e&&(e=Ot),h(t).overflow=e),t}function ge(t,e,n){return null!=t?t:null!=e?e:n}function be(t){var e,n,a,i,s,o=[];if(!t._d){for(a=function(t){var e=new Date(r.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}(t),t._w&&null==t._a[vt]&&null==t._a[yt]&&function(t){var e,n,a,r,i,s,o,u;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)i=1,s=4,n=ge(e.GG,t._a[mt],Bt(Ae(),1,4).year),a=ge(e.W,1),((r=ge(e.E,1))<1||r>7)&&(u=!0);else{i=t._locale._week.dow,s=t._locale._week.doy;var c=Bt(Ae(),i,s);n=ge(e.gg,t._a[mt],c.year),a=ge(e.w,c.week),null!=e.d?((r=e.d)<0||r>6)&&(u=!0):null!=e.e?(r=e.e+i,(e.e<0||e.e>6)&&(u=!0)):r=i}a<1||a>Ut(n,i,s)?h(t)._overflowWeeks=!0:null!=u?h(t)._overflowWeekday=!0:(o=Ht(n,a,r,i,s),t._a[mt]=o.year,t._dayOfYear=o.dayOfYear)}(t),null!=t._dayOfYear&&(s=ge(t._a[mt],a[mt]),(t._dayOfYear>It(s)||0===t._dayOfYear)&&(h(t)._overflowDayOfYear=!0),n=Yt(s,0,t._dayOfYear),t._a[yt]=n.getUTCMonth(),t._a[vt]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=o[e]=a[e];for(;e<7;e++)t._a[e]=o[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[_t]&&0===t._a[xt]&&0===t._a[Tt]&&0===t._a[wt]&&(t._nextDay=!0,t._a[_t]=0),t._d=(t._useUTC?Yt:function(t,e,n,a,r,i,s){var o;return t<100&&t>=0?(o=new Date(t+400,e,n,a,r,i,s),isFinite(o.getFullYear())&&o.setFullYear(t)):o=new Date(t,e,n,a,r,i,s),o}).apply(null,o),i=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[_t]=24),t._w&&void 0!==t._w.d&&t._w.d!==i&&(h(t).weekdayMismatch=!0)}}var me=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ye=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ve=/Z|[+-]\d\d(?::?\d\d)?/,_e=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],xe=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Te=/^\/?Date\((\-?\d+)/i;function we(t){var e,n,a,r,i,s,o=t._i,u=me.exec(o)||ye.exec(o);if(u){for(h(t).iso=!0,e=0,n=_e.length;e0&&h(t).unusedInput.push(s),o=o.slice(o.indexOf(n)+n.length),c+=n.length),V[i]?(n?h(t).empty=!1:h(t).unusedTokens.push(i),bt(i,n,t)):t._strict&&!n&&h(t).unusedTokens.push(i);h(t).charsLeftOver=u-c,o.length>0&&h(t).unusedInput.push(o),t._a[_t]<=12&&!0===h(t).bigHour&&t._a[_t]>0&&(h(t).bigHour=void 0),h(t).parsedDateParts=t._a.slice(0),h(t).meridiem=t._meridiem,t._a[_t]=(l=t._locale,d=t._a[_t],null==(f=t._meridiem)?d:null!=l.meridiemHour?l.meridiemHour(d,f):null!=l.isPM?((p=l.isPM(f))&&d<12&&(d+=12),p||12!==d||(d=0),d):d),be(t),he(t)}else Ce(t);else we(t);var l,d,f,p}function Ne(t){var e=t._i,n=t._f;return t._locale=t._locale||pe(t._l),null===e||void 0===n&&""===e?b({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),x(e)?new _(he(e)):(c(e)?t._d=e:i(n)?function(t){var e,n,a,r,i;if(0===t._f.length)return h(t).invalidFormat=!0,void(t._d=new Date(NaN));for(r=0;rthis?this:t:b()});function Le(t,e){var n,a;if(1===e.length&&i(e[0])&&(e=e[0]),!e.length)return Ae();for(n=e[0],a=1;a=0?new Date(t+400,e,n)-rn:new Date(t,e,n).valueOf()}function un(t,e,n){return t<100&&t>=0?Date.UTC(t+400,e,n)-rn:Date.UTC(t,e,n)}function cn(t,e){H(0,[t,t.length],0,e)}function ln(t,e,n,a,r){var i;return null==t?Bt(this,a,r).year:(e>(i=Ut(t,a,r))&&(e=i),(function(t,e,n,a,r){var i=Ht(t,e,n,a,r),s=Yt(i.year,0,i.dayOfYear);return this.year(s.getUTCFullYear()),this.month(s.getUTCMonth()),this.date(s.getUTCDate()),this}).call(this,t,e,n,a,r))}H(0,["gg",2],0,function(){return this.weekYear()%100}),H(0,["GG",2],0,function(){return this.isoWeekYear()%100}),cn("gggg","weekYear"),cn("ggggg","weekYear"),cn("GGGG","isoWeekYear"),cn("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),j("weekYear",1),j("isoWeekYear",1),lt("G",it),lt("g",it),lt("GG",J,K),lt("gg",J,K),lt("GGGG",nt,Z),lt("gggg",nt,Z),lt("GGGGG",at,X),lt("ggggg",at,X),gt(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,a){e[a.substr(0,2)]=w(t)}),gt(["gg","GG"],function(t,e,n,a){e[a]=r.parseTwoDigitYear(t)}),H("Q",0,"Qo","quarter"),L("quarter","Q"),j("quarter",7),lt("Q",W),ht("Q",function(t,e){e[yt]=3*(w(t)-1)}),H("D",["DD",2],"Do","date"),L("date","D"),j("date",9),lt("D",J),lt("DD",J,K),lt("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),ht(["D","DD"],vt),ht("Do",function(t,e){e[vt]=w(t.match(J)[0])});var dn=Rt("Date",!0);H("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),j("dayOfYear",4),lt("DDD",et),lt("DDDD",$),ht(["DDD","DDDD"],function(t,e,n){n._dayOfYear=w(t)}),H("m",["mm",2],0,"minute"),L("minute","m"),j("minute",14),lt("m",J),lt("mm",J,K),ht(["m","mm"],xt);var fn=Rt("Minutes",!1);H("s",["ss",2],0,"second"),L("second","s"),j("second",15),lt("s",J),lt("ss",J,K),ht(["s","ss"],Tt);var pn,hn=Rt("Seconds",!1);for(H("S",0,0,function(){return~~(this.millisecond()/100)}),H(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),H(0,["SSS",3],0,"millisecond"),H(0,["SSSS",4],0,function(){return 10*this.millisecond()}),H(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),H(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),H(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),H(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),H(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),L("millisecond","ms"),j("millisecond",16),lt("S",et,W),lt("SS",et,K),lt("SSS",et,$),pn="SSSS";pn.length<=9;pn+="S")lt(pn,rt);function gn(t,e){e[wt]=w(1e3*("0."+t))}for(pn="S";pn.length<=9;pn+="S")ht(pn,gn);var bn=Rt("Milliseconds",!1);H("z",0,0,"zoneAbbr"),H("zz",0,0,"zoneName");var mn=_.prototype;function yn(t){return t}mn.add=Je,mn.calendar=function(t,e){var n=t||Ae(),a=Ye(n,this).startOf("day"),i=r.calendarFormat(this,a)||"sameElse",s=e&&(R(e[i])?e[i].call(this,n):e[i]);return this.format(s||this.localeData().calendar(i,this,Ae(n)))},mn.clone=function(){return new _(this)},mn.diff=function(t,e,n){var a,r,i;if(!this.isValid())return NaN;if(!(a=Ye(t,this)).isValid())return NaN;switch(r=6e4*(a.utcOffset()-this.utcOffset()),e=P(e)){case"year":i=tn(this,a)/12;break;case"month":i=tn(this,a);break;case"quarter":i=tn(this,a)/3;break;case"second":i=(this-a)/1e3;break;case"minute":i=(this-a)/6e4;break;case"hour":i=(this-a)/36e5;break;case"day":i=(this-a-r)/864e5;break;case"week":i=(this-a-r)/6048e5;break;default:i=this-a}return n?i:T(i)},mn.endOf=function(t){var e;if(void 0===(t=P(t))||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?un:on;switch(t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf(),e+=36e5-sn(e+(this._isUTC?0:6e4*this.utcOffset()),36e5)-1;break;case"minute":e=this._d.valueOf(),e+=6e4-sn(e,6e4)-1;break;case"second":e=this._d.valueOf(),e+=1e3-sn(e,1e3)-1}return this._d.setTime(e),r.updateOffset(this,!0),this},mn.format=function(t){t||(t=this.isUtc()?r.defaultFormatUtc:r.defaultFormat);var e=B(this,t);return this.localeData().postformat(e)},mn.from=function(t,e){return this.isValid()&&(x(t)&&t.isValid()||Ae(t).isValid())?We({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},mn.fromNow=function(t){return this.from(Ae(),t)},mn.to=function(t,e){return this.isValid()&&(x(t)&&t.isValid()||Ae(t).isValid())?We({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},mn.toNow=function(t){return this.to(Ae(),t)},mn.get=function(t){return R(this[t=P(t)])?this[t]():this},mn.invalidAt=function(){return h(this).overflow},mn.isAfter=function(t,e){var n=x(t)?t:Ae(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=P(e)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()9999?B(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):R(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",B(n,"Z")):B(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},mn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',a=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY";return this.format(n+a+"-MM-DD[T]HH:mm:ss.SSS"+e+'[")]')},mn.toJSON=function(){return this.isValid()?this.toISOString():null},mn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},mn.unix=function(){return Math.floor(this.valueOf()/1e3)},mn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},mn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},mn.year=Nt,mn.isLeapYear=function(){return Ct(this.year())},mn.weekYear=function(t){return ln.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},mn.isoWeekYear=function(t){return ln.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},mn.quarter=mn.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},mn.month=jt,mn.daysInMonth=function(){return Et(this.year(),this.month())},mn.week=mn.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},mn.isoWeek=mn.isoWeeks=function(t){var e=Bt(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},mn.weeksInYear=function(){var t=this.localeData()._week;return Ut(this.year(),t.dow,t.doy)},mn.isoWeeksInYear=function(){return Ut(this.year(),1,4)},mn.date=dn,mn.day=mn.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=function(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}(t,this.localeData()),this.add(t-e,"d")):e},mn.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},mn.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=function(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7},mn.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},mn.hour=mn.hours=ie,mn.minute=mn.minutes=fn,mn.second=mn.seconds=hn,mn.millisecond=mn.milliseconds=bn,mn.utcOffset=function(t,e,n){var a,i=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=Ge(ot,t)))return this}else Math.abs(t)<16&&!n&&(t*=60);return!this._isUTC&&e&&(a=Ve(this)),this._offset=t,this._isUTC=!0,null!=a&&this.add(a,"m"),i!==t&&(!e||this._changeInProgress?Xe(this,We(t-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,r.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?i:Ve(this)},mn.utc=function(t){return this.utcOffset(0,t)},mn.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ve(this),"m")),this},mn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=Ge(st,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},mn.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Ae(t).utcOffset():0,(this.utcOffset()-t)%60==0)},mn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},mn.isLocal=function(){return!!this.isValid()&&!this._isUTC},mn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},mn.isUtc=He,mn.isUTC=He,mn.zoneAbbr=function(){return this._isUTC?"UTC":""},mn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},mn.dates=I("dates accessor is deprecated. Use date instead.",dn),mn.months=I("months accessor is deprecated. Use month instead",jt),mn.years=I("years accessor is deprecated. Use year instead",Nt),mn.zone=I("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}),mn.isDSTShifted=I("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var t={};if(y(t,this),(t=Ne(t))._a){var e=t._isUTC?p(t._a):Ae(t._a);this._isDSTShifted=this.isValid()&&S(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var vn=D.prototype;function _n(t,e,n,a){var r=pe(),i=p().set(a,e);return r[n](i,t)}function xn(t,e,n){if(u(t)&&(e=t,t=void 0),t=t||"",null!=e)return _n(t,e,n,"month");var a,r=[];for(a=0;a<12;a++)r[a]=_n(t,a,n,"month");return r}function Tn(t,e,n,a){"boolean"==typeof t?(u(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,u(e)&&(n=e,e=void 0),e=e||"");var r,i=pe(),s=t?i._week.dow:0;if(null!=n)return _n(e,(n+s)%7,a,"day");var o=[];for(r=0;r<7;r++)o[r]=_n(e,(r+s)%7,a,"day");return o}vn.calendar=function(t,e,n){var a=this._calendar[t]||this._calendar.sameElse;return R(a)?a.call(e,n):a},vn.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])},vn.invalidDate=function(){return this._invalidDate},vn.ordinal=function(t){return this._ordinal.replace("%d",t)},vn.preparse=yn,vn.postformat=yn,vn.relativeTime=function(t,e,n,a){var r=this._relativeTime[n];return R(r)?r(t,e,n,a):r.replace(/%d/i,t)},vn.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return R(n)?n(e):n.replace(/%s/i,e)},vn.set=function(t){var e,n;for(n in t)R(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},vn.months=function(t,e){return t?i(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||Lt).test(e)?"format":"standalone"][t.month()]:i(this._months)?this._months:this._months.standalone},vn.monthsShort=function(t,e){return t?i(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[Lt.test(e)?"format":"standalone"][t.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},vn.monthsParse=function(t,e,n){var a,r,i;if(this._monthsParseExact)return(function(t,e,n){var a,r,i,s=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],a=0;a<12;++a)i=p([2e3,a]),this._shortMonthsParse[a]=this.monthsShort(i,"").toLocaleLowerCase(),this._longMonthsParse[a]=this.months(i,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(r=kt.call(this._shortMonthsParse,s))?r:null:-1!==(r=kt.call(this._longMonthsParse,s))?r:null:"MMM"===e?-1!==(r=kt.call(this._shortMonthsParse,s))?r:-1!==(r=kt.call(this._longMonthsParse,s))?r:null:-1!==(r=kt.call(this._longMonthsParse,s))?r:-1!==(r=kt.call(this._shortMonthsParse,s))?r:null}).call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),a=0;a<12;a++){if(r=p([2e3,a]),n&&!this._longMonthsParse[a]&&(this._longMonthsParse[a]=new RegExp("^"+this.months(r,"").replace(".","")+"$","i"),this._shortMonthsParse[a]=new RegExp("^"+this.monthsShort(r,"").replace(".","")+"$","i")),n||this._monthsParse[a]||(i="^"+this.months(r,"")+"|^"+this.monthsShort(r,""),this._monthsParse[a]=new RegExp(i.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[a].test(t))return a;if(n&&"MMM"===e&&this._shortMonthsParse[a].test(t))return a;if(!n&&this._monthsParse[a].test(t))return a}},vn.monthsRegex=function(t){return this._monthsParseExact?(d(this,"_monthsRegex")||Gt.call(this),t?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=zt),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},vn.monthsShortRegex=function(t){return this._monthsParseExact?(d(this,"_monthsRegex")||Gt.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=Ft),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},vn.week=function(t){return Bt(t,this._week.dow,this._week.doy).week},vn.firstDayOfYear=function(){return this._week.doy},vn.firstDayOfWeek=function(){return this._week.dow},vn.weekdays=function(t,e){var n=i(this._weekdays)?this._weekdays:this._weekdays[t&&!0!==t&&this._weekdays.isFormat.test(e)?"format":"standalone"];return!0===t?Wt(n,this._week.dow):t?n[t.day()]:n},vn.weekdaysMin=function(t){return!0===t?Wt(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin},vn.weekdaysShort=function(t){return!0===t?Wt(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort},vn.weekdaysParse=function(t,e,n){var a,r,i;if(this._weekdaysParseExact)return(function(t,e,n){var a,r,i,s=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],a=0;a<7;++a)i=p([2e3,1]).day(a),this._minWeekdaysParse[a]=this.weekdaysMin(i,"").toLocaleLowerCase(),this._shortWeekdaysParse[a]=this.weekdaysShort(i,"").toLocaleLowerCase(),this._weekdaysParse[a]=this.weekdays(i,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(r=kt.call(this._weekdaysParse,s))?r:null:"ddd"===e?-1!==(r=kt.call(this._shortWeekdaysParse,s))?r:null:-1!==(r=kt.call(this._minWeekdaysParse,s))?r:null:"dddd"===e?-1!==(r=kt.call(this._weekdaysParse,s))?r:-1!==(r=kt.call(this._shortWeekdaysParse,s))?r:-1!==(r=kt.call(this._minWeekdaysParse,s))?r:null:"ddd"===e?-1!==(r=kt.call(this._shortWeekdaysParse,s))?r:-1!==(r=kt.call(this._weekdaysParse,s))?r:-1!==(r=kt.call(this._minWeekdaysParse,s))?r:null:-1!==(r=kt.call(this._minWeekdaysParse,s))?r:-1!==(r=kt.call(this._weekdaysParse,s))?r:-1!==(r=kt.call(this._shortWeekdaysParse,s))?r:null}).call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),a=0;a<7;a++){if(r=p([2e3,1]).day(a),n&&!this._fullWeekdaysParse[a]&&(this._fullWeekdaysParse[a]=new RegExp("^"+this.weekdays(r,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[a]=new RegExp("^"+this.weekdaysShort(r,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[a]=new RegExp("^"+this.weekdaysMin(r,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[a]||(i="^"+this.weekdays(r,"")+"|^"+this.weekdaysShort(r,"")+"|^"+this.weekdaysMin(r,""),this._weekdaysParse[a]=new RegExp(i.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[a].test(t))return a;if(n&&"ddd"===e&&this._shortWeekdaysParse[a].test(t))return a;if(n&&"dd"===e&&this._minWeekdaysParse[a].test(t))return a;if(!n&&this._weekdaysParse[a].test(t))return a}},vn.weekdaysRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||te.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=Xt),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},vn.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||te.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Jt),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},vn.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||te.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Qt),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},vn.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},vn.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},de("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===w(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),r.lang=I("moment.lang is deprecated. Use moment.locale instead.",de),r.langData=I("moment.langData is deprecated. Use moment.localeData instead.",pe);var wn=Math.abs;function Sn(t,e,n,a){var r=We(e,n);return t._milliseconds+=a*r._milliseconds,t._days+=a*r._days,t._months+=a*r._months,t._bubble()}function On(t){return t<0?Math.floor(t):Math.ceil(t)}function In(t){return 4800*t/146097}function Cn(t){return 146097*t/4800}function kn(t){return function(){return this.as(t)}}var Nn=kn("ms"),Rn=kn("s"),An=kn("m"),Dn=kn("h"),En=kn("d"),Ln=kn("w"),Pn=kn("M"),Mn=kn("Q"),qn=kn("y");function jn(t){return function(){return this.isValid()?this._data[t]:NaN}}var Fn=jn("milliseconds"),zn=jn("seconds"),Gn=jn("minutes"),Yn=jn("hours"),Vn=jn("days"),Hn=jn("months"),Bn=jn("years"),Un=Math.round,Wn={ss:44,s:45,m:45,h:22,d:26,M:11},Kn=Math.abs;function $n(t){return(t>0)-(t<0)||+t}function Zn(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n=Kn(this._milliseconds)/1e3,a=Kn(this._days),r=Kn(this._months);t=T(n/60),e=T(t/60),n%=60,t%=60;var i=T(r/12),s=r%=12,o=a,u=e,c=t,l=n?n.toFixed(3).replace(/\.?0+$/,""):"",d=this.asSeconds();if(!d)return"P0D";var f=d<0?"-":"",p=$n(this._months)!==$n(d)?"-":"",h=$n(this._days)!==$n(d)?"-":"",g=$n(this._milliseconds)!==$n(d)?"-":"";return f+"P"+(i?p+i+"Y":"")+(s?p+s+"M":"")+(o?h+o+"D":"")+(u||c||l?"T":"")+(u?g+u+"H":"")+(c?g+c+"M":"")+(l?g+l+"S":"")}var Xn=Me.prototype;return Xn.isValid=function(){return this._isValid},Xn.abs=function(){var t=this._data;return this._milliseconds=wn(this._milliseconds),this._days=wn(this._days),this._months=wn(this._months),t.milliseconds=wn(t.milliseconds),t.seconds=wn(t.seconds),t.minutes=wn(t.minutes),t.hours=wn(t.hours),t.months=wn(t.months),t.years=wn(t.years),this},Xn.add=function(t,e){return Sn(this,t,e,1)},Xn.subtract=function(t,e){return Sn(this,t,e,-1)},Xn.as=function(t){if(!this.isValid())return NaN;var e,n,a=this._milliseconds;if("month"===(t=P(t))||"quarter"===t||"year"===t)switch(n=this._months+In(e=this._days+a/864e5),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(Cn(this._months)),t){case"week":return e/7+a/6048e5;case"day":return e+a/864e5;case"hour":return 24*e+a/36e5;case"minute":return 1440*e+a/6e4;case"second":return 86400*e+a/1e3;case"millisecond":return Math.floor(864e5*e)+a;default:throw new Error("Unknown unit "+t)}},Xn.asMilliseconds=Nn,Xn.asSeconds=Rn,Xn.asMinutes=An,Xn.asHours=Dn,Xn.asDays=En,Xn.asWeeks=Ln,Xn.asMonths=Pn,Xn.asQuarters=Mn,Xn.asYears=qn,Xn.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*w(this._months/12):NaN},Xn._bubble=function(){var t,e,n,a,r,i=this._milliseconds,s=this._days,o=this._months,u=this._data;return i>=0&&s>=0&&o>=0||i<=0&&s<=0&&o<=0||(i+=864e5*On(Cn(o)+s),s=0,o=0),u.milliseconds=i%1e3,t=T(i/1e3),u.seconds=t%60,e=T(t/60),u.minutes=e%60,n=T(e/60),u.hours=n%24,s+=T(n/24),o+=r=T(In(s)),s-=On(Cn(r)),a=T(o/12),o%=12,u.days=s,u.months=o,u.years=a,this},Xn.clone=function(){return We(this)},Xn.get=function(t){return t=P(t),this.isValid()?this[t+"s"]():NaN},Xn.milliseconds=Fn,Xn.seconds=zn,Xn.minutes=Gn,Xn.hours=Yn,Xn.days=Vn,Xn.weeks=function(){return T(this.days()/7)},Xn.months=Hn,Xn.years=Bn,Xn.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=function(t,e,n){var a=We(t).abs(),r=Un(a.as("s")),i=Un(a.as("m")),s=Un(a.as("h")),o=Un(a.as("d")),u=Un(a.as("M")),c=Un(a.as("y")),l=r<=Wn.ss&&["s",r]||r0,l[4]=n,(function(t,e,n,a,r){return r.relativeTime(e||1,!!n,t,a)}).apply(null,l)}(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},Xn.toISOString=Zn,Xn.toString=Zn,Xn.toJSON=Zn,Xn.locale=en,Xn.localeData=an,Xn.toIsoString=I("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Zn),Xn.lang=nn,H("X",0,0,"unix"),H("x",0,0,"valueOf"),lt("x",it),lt("X",/[+-]?\d+(\.\d{1,3})?/),ht("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),ht("x",function(t,e,n){n._d=new Date(w(t))}),r.version="2.24.0",e=Ae,r.fn=mn,r.min=function(){return Le("isBefore",[].slice.call(arguments,0))},r.max=function(){return Le("isAfter",[].slice.call(arguments,0))},r.now=function(){return Date.now?Date.now():+new Date},r.utc=p,r.unix=function(t){return Ae(1e3*t)},r.months=function(t,e){return xn(t,e,"months")},r.isDate=c,r.locale=de,r.invalid=b,r.duration=We,r.isMoment=x,r.weekdays=function(t,e,n){return Tn(t,e,n,"weekdays")},r.parseZone=function(){return Ae.apply(null,arguments).parseZone()},r.localeData=pe,r.isDuration=qe,r.monthsShort=function(t,e){return xn(t,e,"monthsShort")},r.weekdaysMin=function(t,e,n){return Tn(t,e,n,"weekdaysMin")},r.defineLocale=fe,r.updateLocale=function(t,e){if(null!=e){var n,a,r=se;null!=(a=le(t))&&(r=a._config),(n=new D(e=A(r,e))).parentLocale=oe[t],oe[t]=n,de(t)}else null!=oe[t]&&(null!=oe[t].parentLocale?oe[t]=oe[t].parentLocale:null!=oe[t]&&delete oe[t]);return oe[t]},r.locales=function(){return C(oe)},r.weekdaysShort=function(t,e,n){return Tn(t,e,n,"weekdaysShort")},r.normalizeUnits=P,r.relativeTimeRounding=function(t){return void 0===t?Un:"function"==typeof t&&(Un=t,!0)},r.relativeTimeThreshold=function(t,e){return void 0!==Wn[t]&&(void 0===e?Wn[t]:(Wn[t]=e,"s"===t&&(Wn.ss=e-1),!0))},r.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},r.prototype=mn,r.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},r}()}).call(this,n("YuTi")(t))},wnGv:function(t,e,n){"use strict";n.d(e,"a",function(){return c});var a=n("CcnG"),r=n("gIcY"),i=n("LvDl"),s=n("QFaf"),o=n("DNAf"),u=n("a96k"),c=function(){function t(t){this.i18n=t,this.data=[],this.options=[],this.messages=new o.a({},this.i18n),this.customBadges=!1,this.customBadgeValidators=[],this.selection=new a.EventEmitter,this.Object=Object,this.filteredOptions=[]}return t.prototype.ngOnInit=function(){this.initFilter(),this.data.length>0&&this.initMissingOptions(),this.options=i.sortBy(this.options,["name"]),this.updateOptions()},t.prototype.initFilter=function(){this.filter=new r.i("",{validators:this.customBadgeValidators}),this.form=new s.a({filter:this.filter}),this.filteredOptions=(this.options||[]).slice()},t.prototype.initMissingOptions=function(){var t=this,e=this.options.map(function(t){return t.name});this.data.filter(function(t){return-1===e.indexOf(t)}).forEach(function(e){return t.addOption(e)}),this.forceOptionsToReflectData()},t.prototype.addOption=function(t){this.options.push(new u.a(!1,t,"")),this.options=i.sortBy(this.options,["name"]),this.triggerSelection(this.options.find(function(e){return e.name===t}))},t.prototype.triggerSelection=function(t){!t||this.selectionLimit&&!t.selected&&this.data.length>=this.selectionLimit||(t.selected=!t.selected,this.updateOptions(),this.selection.emit({option:t}))},t.prototype.updateOptions=function(){var t=this;this.data.splice(0,this.data.length),this.options.forEach(function(e){e.selected&&t.data.push(e.name)}),this.updateFilter()},t.prototype.updateFilter=function(){var t=this;this.filteredOptions=this.options.filter(function(e){return e.name.includes(t.filter.value)})},t.prototype.forceOptionsToReflectData=function(){var t=this;this.options.forEach(function(e){-1!==t.data.indexOf(e.name)&&(e.selected=!0)})},t.prototype.ngOnChanges=function(){this.filter&&this.updateFilter(),this.options&&this.data&&0!==this.data.length&&this.forceOptionsToReflectData()},t.prototype.selectOption=function(){0===this.filteredOptions.length?this.addCustomOption():(this.triggerSelection(this.filteredOptions[0]),this.resetFilter())},t.prototype.addCustomOption=function(){this.isCreatable()&&(this.addOption(this.filter.value),this.resetFilter())},t.prototype.isCreatable=function(){var t=this;return this.customBadges&&this.filter.valid&&this.filter.value.length>0&&this.filteredOptions.every(function(e){return e.name!==t.filter.value})},t.prototype.resetFilter=function(){this.filter.setValue(""),this.updateFilter()},t.prototype.removeItem=function(t){this.triggerSelection(this.options.find(function(e){return e.name===t&&e.selected}))},t}()},x38r:function(t,e,n){"use strict";var a;n.d(e,"a",function(){return a}),function(t){t.bold="bold",t.sparkline="sparkline",t.perSecond="perSecond",t.checkIcon="checkIcon",t.routerLink="routerLink",t.executing="executing",t.classAdding="classAdding",t.map="map"}(a||(a={}))},x6pH:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("he",{months:"\u05d9\u05e0\u05d5\u05d0\u05e8_\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u05d9\u05dc_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8_\u05e1\u05e4\u05d8\u05de\u05d1\u05e8_\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8_\u05e0\u05d5\u05d1\u05de\u05d1\u05e8_\u05d3\u05e6\u05de\u05d1\u05e8".split("_"),monthsShort:"\u05d9\u05e0\u05d5\u05f3_\u05e4\u05d1\u05e8\u05f3_\u05de\u05e8\u05e5_\u05d0\u05e4\u05e8\u05f3_\u05de\u05d0\u05d9_\u05d9\u05d5\u05e0\u05d9_\u05d9\u05d5\u05dc\u05d9_\u05d0\u05d5\u05d2\u05f3_\u05e1\u05e4\u05d8\u05f3_\u05d0\u05d5\u05e7\u05f3_\u05e0\u05d5\u05d1\u05f3_\u05d3\u05e6\u05de\u05f3".split("_"),weekdays:"\u05e8\u05d0\u05e9\u05d5\u05df_\u05e9\u05e0\u05d9_\u05e9\u05dc\u05d9\u05e9\u05d9_\u05e8\u05d1\u05d9\u05e2\u05d9_\u05d7\u05de\u05d9\u05e9\u05d9_\u05e9\u05d9\u05e9\u05d9_\u05e9\u05d1\u05ea".split("_"),weekdaysShort:"\u05d0\u05f3_\u05d1\u05f3_\u05d2\u05f3_\u05d3\u05f3_\u05d4\u05f3_\u05d5\u05f3_\u05e9\u05f3".split("_"),weekdaysMin:"\u05d0_\u05d1_\u05d2_\u05d3_\u05d4_\u05d5_\u05e9".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [\u05d1]MMMM YYYY",LLL:"D [\u05d1]MMMM YYYY HH:mm",LLLL:"dddd, D [\u05d1]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[\u05d4\u05d9\u05d5\u05dd \u05d1\u05be]LT",nextDay:"[\u05de\u05d7\u05e8 \u05d1\u05be]LT",nextWeek:"dddd [\u05d1\u05e9\u05e2\u05d4] LT",lastDay:"[\u05d0\u05ea\u05de\u05d5\u05dc \u05d1\u05be]LT",lastWeek:"[\u05d1\u05d9\u05d5\u05dd] dddd [\u05d4\u05d0\u05d7\u05e8\u05d5\u05df \u05d1\u05e9\u05e2\u05d4] LT",sameElse:"L"},relativeTime:{future:"\u05d1\u05e2\u05d5\u05d3 %s",past:"\u05dc\u05e4\u05e0\u05d9 %s",s:"\u05de\u05e1\u05e4\u05e8 \u05e9\u05e0\u05d9\u05d5\u05ea",ss:"%d \u05e9\u05e0\u05d9\u05d5\u05ea",m:"\u05d3\u05e7\u05d4",mm:"%d \u05d3\u05e7\u05d5\u05ea",h:"\u05e9\u05e2\u05d4",hh:function(t){return 2===t?"\u05e9\u05e2\u05ea\u05d9\u05d9\u05dd":t+" \u05e9\u05e2\u05d5\u05ea"},d:"\u05d9\u05d5\u05dd",dd:function(t){return 2===t?"\u05d9\u05d5\u05de\u05d9\u05d9\u05dd":t+" \u05d9\u05de\u05d9\u05dd"},M:"\u05d7\u05d5\u05d3\u05e9",MM:function(t){return 2===t?"\u05d7\u05d5\u05d3\u05e9\u05d9\u05d9\u05dd":t+" \u05d7\u05d5\u05d3\u05e9\u05d9\u05dd"},y:"\u05e9\u05e0\u05d4",yy:function(t){return 2===t?"\u05e9\u05e0\u05ea\u05d9\u05d9\u05dd":t%10==0&&10!==t?t+" \u05e9\u05e0\u05d4":t+" \u05e9\u05e0\u05d9\u05dd"}},meridiemParse:/\u05d0\u05d7\u05d4"\u05e6|\u05dc\u05e4\u05e0\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8|\u05d1\u05d1\u05d5\u05e7\u05e8|\u05d1\u05e2\u05e8\u05d1/i,isPM:function(t){return/^(\u05d0\u05d7\u05d4"\u05e6|\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd|\u05d1\u05e2\u05e8\u05d1)$/.test(t)},meridiem:function(t,e,n){return t<5?"\u05dc\u05e4\u05e0\u05d5\u05ea \u05d1\u05d5\u05e7\u05e8":t<10?"\u05d1\u05d1\u05d5\u05e7\u05e8":t<12?n?'\u05dc\u05e4\u05e0\u05d4"\u05e6':"\u05dc\u05e4\u05e0\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":t<18?n?'\u05d0\u05d7\u05d4"\u05e6':"\u05d0\u05d7\u05e8\u05d9 \u05d4\u05e6\u05d4\u05e8\u05d9\u05d9\u05dd":"\u05d1\u05e2\u05e8\u05d1"}})}()},x8uC:function(t,e,n){"use strict";var a=n("CDJp"),r=n("K2E3"),i=n("RDha");a._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:i.noop,title:function(t,e){var n="",a=e.labels,r=a?a.length:0;if(t.length>0){var i=t[0];i.xLabel?n=i.xLabel:r>0&&i.index-1?t.split("\n"):t}function l(t){var e=a.global,n=i.valueOrDefault;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:n(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:n(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:n(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:n(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:n(t.titleFontStyle,e.defaultFontStyle),titleFontSize:n(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:n(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:n(t.footerFontStyle,e.defaultFontStyle),footerFontSize:n(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function d(t){return u([],c(t))}(t.exports=r.extend({initialize:function(){this._model=l(this._options),this._lastActive=[]},getTitle:function(){var t=this._options.callbacks,e=t.beforeTitle.apply(this,arguments),n=t.title.apply(this,arguments),a=t.afterTitle.apply(this,arguments),r=[];return r=u(r,c(e)),r=u(r,c(n)),u(r,c(a))},getBeforeBody:function(){return d(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,a=n._options.callbacks,r=[];return i.each(t,function(t){var i={before:[],lines:[],after:[]};u(i.before,c(a.beforeLabel.call(n,t,e))),u(i.lines,a.label.call(n,t,e)),u(i.after,c(a.afterLabel.call(n,t,e))),r.push(i)}),r},getAfterBody:function(){return d(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this._options.callbacks,e=t.beforeFooter.apply(this,arguments),n=t.footer.apply(this,arguments),a=t.afterFooter.apply(this,arguments),r=[];return r=u(r,c(e)),r=u(r,c(n)),u(r,c(a))},update:function(t){var e,n,a,r,o,u,c,d=this,f=d._options,p=d._model,h=d._model=l(f),g=d._active,b=d._data,m={xAlign:p.xAlign,yAlign:p.yAlign},y={x:p.x,y:p.y},v={width:p.width,height:p.height},_={x:p.caretX,y:p.caretY};if(g.length){h.opacity=1;var x=[],T=[];_=s[f.position].call(d,g,d._eventPosition);var w=[];for(e=0,n=g.length;ea.width&&(r=a.width-e.width),r<0&&(r=0)),"top"===u?i+=c:i-="bottom"===u?e.height+c:e.height/2,"center"===u?"left"===o?r+=c:"right"===o&&(r-=c):"left"===o?r-=l:"right"===o&&(r+=l),{x:r,y:i}}(h,v,m=function(t,e){var n,a,r,i,s,o=t._model,u=t._chart,c=t._chart.chartArea,l="center",d="center";o.yu.height-e.height&&(d="bottom");var f=(c.left+c.right)/2,p=(c.top+c.bottom)/2;"center"===d?(n=function(t){return t<=f},a=function(t){return t>f}):(n=function(t){return t<=e.width/2},a=function(t){return t>=u.width-e.width/2}),r=function(t){return t+e.width+o.caretSize+o.caretPadding>u.width},i=function(t){return t-e.width-o.caretSize-o.caretPadding<0},s=function(t){return t<=p?"top":"bottom"},n(o.x)?(l="left",r(o.x)&&(l="center",d=s(o.y))):a(o.x)&&(l="right",i(o.x)&&(l="center",d=s(o.y)));var h=t._options;return{xAlign:h.xAlign?h.xAlign:l,yAlign:h.yAlign?h.yAlign:d}}(this,v),d._chart)}else h.opacity=0;return h.xAlign=m.xAlign,h.yAlign=m.yAlign,h.x=y.x,h.y=y.y,h.width=v.width,h.height=v.height,h.caretX=_.x,h.caretY=_.y,d._model=h,t&&f.custom&&f.custom.call(d,h),d},drawCaret:function(t,e){var n=this._chart.ctx,a=this.getCaretPosition(t,e,this._view);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var a,r,i,s,o,u,c=n.caretSize,l=n.cornerRadius,d=n.xAlign,f=n.yAlign,p=t.x,h=t.y,g=e.width,b=e.height;if("center"===f)o=h+b/2,"left"===d?(r=(a=p)-c,i=a,s=o+c,u=o-c):(r=(a=p+g)+c,i=a,s=o-c,u=o+c);else if("left"===d?(a=(r=p+l+c)-c,i=r+c):"right"===d?(a=(r=p+g-l-c)-c,i=r+c):(a=(r=n.caretX)-c,i=r+c),"top"===f)o=(s=h)-c,u=s;else{o=(s=h+b)+c,u=s;var m=i;i=a,a=m}return{x1:a,x2:r,x3:i,y1:s,y2:o,y3:u}},drawTitle:function(t,e,n,a){var r=e.title;if(r.length){n.textAlign=e._titleAlign,n.textBaseline="top";var s,u,c=e.titleFontSize,l=e.titleSpacing;for(n.fillStyle=o(e.titleFontColor,a),n.font=i.fontString(c,e._titleFontStyle,e._titleFontFamily),s=0,u=r.length;s0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},a={x:e.x,y:e.y},r=Math.abs(e.opacity<.001)?0:e.opacity;this._options.enabled&&(e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length)&&(this.drawBackground(a,e,t,n,r),a.x+=e.xPadding,a.y+=e.yPadding,this.drawTitle(a,e,t,r),this.drawBody(a,e,t,r),this.drawFooter(a,e,t,r))}},handleEvent:function(t){var e,n=this,a=n._options;return n._lastActive=n._lastActive||[],n._active="mouseout"===t.type?[]:n._chart.getElementsAtEventForMode(t,a.mode,a),(e=!i.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(a.enabled||a.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}})).positioners=s},xMyE:function(t,e,n){"use strict";n.d(e,"a",function(){return o});var a=n("mrSG"),r=n("FFOo"),i=n("+umK"),s=n("2Bdj");function o(t,e,n){return function(a){return a.lift(new u(t,e,n))}}var u=function(){function t(t,e,n){this.nextOrObserver=t,this.error=e,this.complete=n}return t.prototype.call=function(t,e){return e.subscribe(new c(t,this.nextOrObserver,this.error,this.complete))},t}(),c=function(t){function e(e,n,a,r){var o=t.call(this,e)||this;return o._tapNext=i.a,o._tapError=i.a,o._tapComplete=i.a,o._tapError=a||i.a,o._tapComplete=r||i.a,Object(s.a)(n)?(o._context=o,o._tapNext=n):n&&(o._context=n,o._tapNext=n.next||i.a,o._tapError=n.error||i.a,o._tapComplete=n.complete||i.a),o}return a.__extends(e,t),e.prototype._next=function(t){try{this._tapNext.call(this._context,t)}catch(e){return void this.destination.error(e)}this.destination.next(t)},e.prototype._error=function(t){try{this._tapError.call(this._context,t)}catch(t){return void this.destination.error(t)}this.destination.error(t)},e.prototype._complete=function(){try{this._tapComplete.call(this._context)}catch(t){return void this.destination.error(t)}return this.destination.complete()},e}(r.a)},xSw7:function(t,e,n){"use strict";var a=n("CcnG"),r=n("Fgil"),i=n("aXbf"),s=n("o4+5"),o=n("Ip0R"),u=n("eajB"),c=n("lqqz"),l=n("NJnL");n("GgAd"),n.d(e,"a",function(){return d}),n.d(e,"b",function(){return p});var d=a["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function f(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,17,"table",[],null,null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,16,"tbody",[],null,null,null,null,null)),(t()(),a["\u0275eld"](2,0,null,null,7,"tr",[],null,null,null,null,null)),(t()(),a["\u0275eld"](3,0,null,null,1,"td",[["class","text-left"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Used:\xa0"])),(t()(),a["\u0275eld"](5,0,null,null,4,"td",[["class","text-right"]],null,null,null,null,null)),(t()(),a["\u0275eld"](6,0,null,null,3,"strong",[],null,null,null,null,null)),(t()(),a["\u0275ted"](7,null,[" ",""])),a["\u0275ppd"](8,1),a["\u0275ppd"](9,1),(t()(),a["\u0275eld"](10,0,null,null,7,"tr",[],null,null,null,null,null)),(t()(),a["\u0275eld"](11,0,null,null,1,"td",[["class","text-left"]],null,null,null,null,null)),(t()(),a["\u0275ted"](-1,null,["Free:\xa0"])),(t()(),a["\u0275eld"](13,0,null,null,4,"td",[["class","'text-right"]],null,null,null,null,null)),(t()(),a["\u0275eld"](14,0,null,null,3,"strong",[],null,null,null,null,null)),(t()(),a["\u0275ted"](15,null,["",""])),a["\u0275ppd"](16,1),a["\u0275ppd"](17,1)],null,function(t,e){var n=e.component,r=a["\u0275unv"](e,7,0,n.isBinary?t(e,8,0,a["\u0275nov"](e.parent,0),n.used):t(e,9,0,a["\u0275nov"](e.parent,1),n.used));t(e,7,0,r);var i=a["\u0275unv"](e,15,0,n.isBinary?t(e,16,0,a["\u0275nov"](e.parent,0),n.total-n.used):t(e,17,0,a["\u0275nov"](e.parent,1),n.total-n.used));t(e,15,0,i)})}function p(t){return a["\u0275vid"](0,[a["\u0275pid"](0,r.a,[i.a]),a["\u0275pid"](0,s.a,[i.a]),a["\u0275pid"](0,o.DecimalPipe,[a.LOCALE_ID]),(t()(),a["\u0275and"](0,[["usageTooltipTpl",2]],null,0,null,f)),(t()(),a["\u0275eld"](4,16777216,null,null,6,"div",[["class","progress oaprogress"],["data-placement","left"]],[[1,"aria-describedby",0]],null,null,null,null)),a["\u0275did"](5,212992,null,0,u.c,[a.ViewContainerRef,c.a,u.a,a.ElementRef,a.Renderer2,l.a],{tooltip:[0,"tooltip"],placement:[1,"placement"]},null),(t()(),a["\u0275eld"](6,0,null,null,3,"div",[["class","progress-bar progress-bar-info"],["role","progressbar"]],[[4,"width",null]],null,null,null,null)),(t()(),a["\u0275eld"](7,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),a["\u0275ted"](8,null,["","%"])),a["\u0275ppd"](9,2),(t()(),a["\u0275eld"](10,0,null,null,0,"div",[["class","progress-bar progress-bar-freespace"],["role","progressbar"]],[[4,"width",null]],null,null,null,null))],function(t,e){t(e,5,0,a["\u0275nov"](e,3),"left")},function(t,e){var n=e.component;t(e,4,0,a["\u0275nov"](e,5).ariaDescribedby),t(e,6,0,n.usedPercentage+"%");var r=a["\u0275unv"](e,8,0,t(e,9,0,a["\u0275nov"](e,2),n.usedPercentage,"1.0-"+n.decimals));t(e,8,0,r),t(e,10,0,n.freePercentage+"%")})}},xTla:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a="function"==typeof Symbol&&Symbol.observable||"@@observable"},xTzq:function(t,e,n){"use strict";n.d(e,"a",function(){return r}),n.d(e,"b",function(){return i});var a=n("LvDl");function r(){for(var t=[],e=0;e=0&&this._children.splice(e,1),this._setFoldingType()}},t.prototype.removeItselfFromParent=function(){this.parent&&this.parent.removeChild(this)},t.prototype.switchFoldingType=function(){!this.isLeaf()&&this.hasChildren()&&(this.disableCollapseOnInit(),this.node._foldingType=this.isNodeExpanded()?i.FoldingType.Collapsed:i.FoldingType.Expanded)},t.prototype.isNodeExpanded=function(){return this.foldingType===i.FoldingType.Expanded},t.prototype.isNodeCollapsed=function(){return this.foldingType===i.FoldingType.Collapsed},t.prototype._setFoldingType=function(){this.node._foldingType=this.childrenShouldBeLoaded()?i.FoldingType.Collapsed:this._children&&!a.isEmpty(this._children)?this.isCollapsedOnInit()?i.FoldingType.Collapsed:i.FoldingType.Expanded:Array.isArray(this._children)?i.FoldingType.Empty:i.FoldingType.Leaf},Object.defineProperty(t.prototype,"foldingType",{get:function(){return this.node._foldingType||this._setFoldingType(),this.node._foldingType},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"foldingCssClass",{get:function(){return this.getCssClassesFromSettings()||this.foldingType.cssClass},enumerable:!0,configurable:!0}),t.prototype.getCssClassesFromSettings=function(){return this.node._foldingType||this._setFoldingType(),a.get(this.node.settings,this.node._foldingType===i.FoldingType.Collapsed?"cssClasses.collapsed":this.node._foldingType===i.FoldingType.Expanded?"cssClasses.expanded":this.node._foldingType===i.FoldingType.Empty?"cssClasses.empty":"cssClasses.leaf",null)},Object.defineProperty(t.prototype,"nodeTemplate",{get:function(){return this.getTemplateFromSettings()},enumerable:!0,configurable:!0}),t.prototype.getTemplateFromSettings=function(){return this.isLeaf()?a.get(this.node.settings,"templates.leaf",""):a.get(this.node.settings,"templates.node","")},Object.defineProperty(t.prototype,"leftMenuTemplate",{get:function(){return this.hasLeftMenu()?a.get(this.node.settings,"templates.leftMenu",""):""},enumerable:!0,configurable:!0}),t.prototype.disableCollapseOnInit=function(){this.node.settings&&(this.node.settings.isCollapsedOnInit=!1)},t.prototype.isCollapsedOnInit=function(){return!!a.get(this.node.settings,"isCollapsedOnInit")},t.prototype.keepNodesInDOM=function(){return a.get(this.node.settings,"keepNodesInDOM")},t.prototype.isNew=function(){return this.node._status===i.TreeStatus.New},Object.defineProperty(t.prototype,"id",{get:function(){return a.get(this.node,"id")},set:function(t){this.node.id=t},enumerable:!0,configurable:!0}),t.prototype.markAsNew=function(){this.node._status=i.TreeStatus.New},t.prototype.isBeingRenamed=function(){return this.node._status===i.TreeStatus.IsBeingRenamed},t.prototype.markAsBeingRenamed=function(){this.node._status=i.TreeStatus.IsBeingRenamed},t.prototype.isModified=function(){return this.node._status===i.TreeStatus.Modified},t.prototype.markAsModified=function(){this.node._status=i.TreeStatus.Modified},t.prototype.toTreeModel=function(){var t=a.defaultsDeep(this.isLeaf()?{}:{children:[]},this.node);return this.children&&this.children.forEach(function(e){t.children.push(e.toTreeModel())}),t},t}()},xbqr:function(t,e,n){"use strict";var a=n("CcnG"),r=n("MdoF"),i=n("lTVp");n("9GXa"),n.d(e,"a",function(){return s}),n.d(e,"b",function(){return o});var s=a["\u0275crt"]({encapsulation:0,styles:[[".warning-panel-alert-icon[_ngcontent-%COMP%]{vertical-align:top;padding-right:15px}.warning-panel-alert-title[_ngcontent-%COMP%]{font-weight:700}"]],data:{}});function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,11,"alert",[["type","warning"]],null,null,null,r.c,r.b)),a["\u0275did"](1,114688,null,0,i.a,[i.b,a.ChangeDetectorRef],{type:[0,"type"]},null),(t()(),a["\u0275eld"](2,0,null,0,9,"table",[],null,null,null,null,null)),(t()(),a["\u0275eld"](3,0,null,null,8,"tbody",[],null,null,null,null,null)),(t()(),a["\u0275eld"](4,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),a["\u0275eld"](5,0,null,null,1,"td",[["class","warning-panel-alert-icon"],["rowspan","2"]],null,null,null,null,null)),(t()(),a["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-3x fa-warning alert-warning"]],null,null,null,null,null)),(t()(),a["\u0275eld"](7,0,null,null,1,"td",[["class","warning-panel-alert-title"]],null,null,null,null,null)),(t()(),a["\u0275ted"](8,null,[" "," "])),(t()(),a["\u0275eld"](9,0,null,null,2,"tr",[],null,null,null,null,null)),(t()(),a["\u0275eld"](10,0,null,null,1,"td",[["class","warning-panel-alert-text"]],null,null,null,null,null)),a["\u0275ncd"](null,0)],function(t,e){t(e,1,0,"warning")},function(t,e){t(e,8,0,e.component.title)})}},xdbM:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata,i=n("CcnG"),s=n("WyAD"),o=function(){function t(t){this.labels=[],this.options={},this.chartClick=new i.EventEmitter,this.chartHover=new i.EventEmitter,this.initFlag=!1,this.element=t}return t.prototype.ngOnInit=function(){this.ctx=this.element.nativeElement.getContext("2d"),this.cvs=this.element.nativeElement,this.initFlag=!0,(this.data||this.datasets)&&this.refresh()},t.prototype.ngOnChanges=function(t){this.initFlag&&(t.hasOwnProperty("data")||t.hasOwnProperty("datasets")?(this.updateChartData(t.data?t.data.currentValue:t.datasets.currentValue),this.chart.update()):this.refresh())},t.prototype.ngOnDestroy=function(){this.chart&&(this.chart.destroy(),this.chart=void 0)},t.prototype.getChartBuilder=function(t){var e=this,n=this.getDatasets(),a=Object.assign({},this.options);return!1===this.legend&&(a.legend={display:!1}),a.hover=a.hover||{},a.hover.onHover||(a.hover.onHover=function(t){t&&!t.length||e.chartHover.emit({active:t})}),a.onClick||(a.onClick=function(t,n){e.chartClick.emit({event:t,active:n})}),new s.Chart(t,{type:this.chartType,data:{labels:this.labels,datasets:n},options:a})},t.prototype.updateChartData=function(t){Array.isArray(t[0].data)?this.chart.data.datasets.forEach(function(e,n){e.data=t[n].data,t[n].label&&(e.label=t[n].label)}):this.chart.data.datasets[0].data=t},t.prototype.getDatasets=function(){var t=this,e=void 0;if((!this.datasets||!this.datasets.length&&this.data&&this.data.length)&&(e=Array.isArray(this.data[0])?this.data.map(function(e,n){return{data:e,label:t.labels[n]||"Label "+n}}):[{data:this.data,label:"Label 0"}]),(this.datasets&&this.datasets.length||e&&e.length)&&(e=(this.datasets||e).map(function(e,n){var a=Object.assign({},e);return t.colors&&t.colors.length?Object.assign(a,t.colors[n]):Object.assign(a,function(t,e,n){return"pie"===t||"doughnut"===t?{backgroundColor:(a=f(n)).map(function(t){return u(t,.6)}),borderColor:a.map(function(){return"#fff"}),pointBackgroundColor:a.map(function(t){return u(t,1)}),pointBorderColor:a.map(function(){return"#fff"}),pointHoverBackgroundColor:a.map(function(t){return u(t,1)}),pointHoverBorderColor:a.map(function(t){return u(t,1)})}:"polarArea"===t?function(t){return{backgroundColor:t.map(function(t){return u(t,.6)}),borderColor:t.map(function(t){return u(t,1)}),hoverBackgroundColor:t.map(function(t){return u(t,.8)}),hoverBorderColor:t.map(function(t){return u(t,1)})}}(f(n)):"line"===t||"radar"===t?function(t){return{backgroundColor:u(t,.4),borderColor:u(t,1),pointBackgroundColor:u(t,1),pointBorderColor:"#fff",pointHoverBackgroundColor:"#fff",pointHoverBorderColor:u(t,.8)}}(d(e)):"bar"===t||"horizontalBar"===t?function(t){return{backgroundColor:u(t,.6),borderColor:u(t,1),hoverBackgroundColor:u(t,.8),hoverBorderColor:u(t,1)}}(d(e)):d(e);var a}(t.chartType,n,a.data.length)),a})),!e)throw new Error("ng-charts configuration error,\n data or datasets field are required to render char "+this.chartType);return e},t.prototype.refresh=function(){this.ngOnDestroy(),this.chart=this.getChartBuilder(this.ctx)},t.defaultColors=[[255,99,132],[54,162,235],[255,206,86],[231,233,237],[75,192,192],[151,187,205],[220,220,220],[247,70,74],[70,191,189],[253,180,92],[148,159,177],[77,83,96]],t}();function u(t,e){return"rgba("+t.concat(e).join(",")+")"}function c(t,e){return Math.floor(Math.random()*(e-t+1))+t}function l(){return[c(0,255),c(0,255),c(0,255)]}function d(t){return o.defaultColors[t]||l()}function f(t){for(var e=new Array(t),n=0;n',providers:[r.TreeService]}]}],t.propDecorators={treeModel:[{type:a.Input,args:["tree"]}],settings:[{type:a.Input}],nodeCreated:[{type:a.Output}],nodeRemoved:[{type:a.Output}],nodeRenamed:[{type:a.Output}],nodeSelected:[{type:a.Output}],nodeUnselected:[{type:a.Output}],nodeMoved:[{type:a.Output}],nodeExpanded:[{type:a.Output}],nodeCollapsed:[{type:a.Output}],loadNextLevel:[{type:a.Output}],nodeChecked:[{type:a.Output}],nodeUnchecked:[{type:a.Output}],menuItemSelected:[{type:a.Output}],rootComponent:[{type:a.ViewChild,args:["rootComponent"]}],template:[{type:a.ContentChild,args:[a.TemplateRef]}]},t}()},xtZt:function(t,e,n){"use strict";n.d(e,"a",function(){return c}),n.d(e,"b",function(){return d}),n.d(e,"c",function(){return f}),n.d(e,"d",function(){return p}),n.d(e,"e",function(){return g}),n.d(e,"f",function(){return l}),n.d(e,"g",function(){return h});var a=n("mrSG"),r=n("CcnG"),i=n("VnD/"),s=n("lqqz"),o=n("rpEJ"),u=n("NJnL"),c=function(){return function(){this.autoClose=!0,this.insideClick=!1}}(),l=function(){return function(){var t=this;this.direction="down",this.isOpenChange=new r.EventEmitter,this.isDisabledChange=new r.EventEmitter,this.toggleClick=new r.EventEmitter,this.dropdownMenu=new Promise(function(e){t.resolveDropdownMenu=e})}}(),d=function(){function t(t,e,n,a){var r=this;this._state=t,this.cd=e,this._renderer=n,this._element=a,this.isOpen=!1,this._subscription=t.isOpenChange.subscribe(function(t){r.isOpen=t;var e=r._element.nativeElement.querySelector(".dropdown-menu");e&&!Object(o.d)()&&(r._renderer.addClass(e,"show"),e.classList.contains("dropdown-menu-right")&&(r._renderer.setStyle(e,"left","auto"),r._renderer.setStyle(e,"right","0")),"up"===r.direction&&(r._renderer.setStyle(e,"top","auto"),r._renderer.setStyle(e,"transform","translateY(-101%)"))),r.cd.markForCheck(),r.cd.detectChanges()})}return Object.defineProperty(t.prototype,"direction",{get:function(){return this._state.direction},enumerable:!0,configurable:!0}),t.prototype._contains=function(t){return this._element.nativeElement.contains(t)},t.prototype.ngOnDestroy=function(){this._subscription.unsubscribe()},t}(),f=function(){function t(t,e,n,a,r,i){this._elementRef=t,this._renderer=e,this._viewContainerRef=n,this._cis=a,this._config=r,this._state=i,this._isInlineOpen=!1,this._subscriptions=[],this._isInited=!1,this._state.autoClose=this._config.autoClose,this._state.insideClick=this._config.insideClick,this._dropdown=this._cis.createLoader(this._elementRef,this._viewContainerRef,this._renderer).provide({provide:l,useValue:this._state}),this.onShown=this._dropdown.onShown,this.onHidden=this._dropdown.onHidden,this.isOpenChange=this._state.isOpenChange}return Object.defineProperty(t.prototype,"autoClose",{get:function(){return this._state.autoClose},set:function(t){this._state.autoClose=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"insideClick",{get:function(){return this._state.insideClick},set:function(t){this._state.insideClick=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isDisabled",{get:function(){return this._isDisabled},set:function(t){this._isDisabled=t,this._state.isDisabledChange.emit(t),t&&this.hide()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isOpen",{get:function(){return this._showInline?this._isInlineOpen:this._dropdown.isShown},set:function(t){t?this.show():this.hide()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isBs4",{get:function(){return!Object(o.d)()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"_showInline",{get:function(){return!this.container},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){var t=this;this._isInited||(this._isInited=!0,this._dropdown.listen({outsideClick:!1,triggers:this.triggers,show:function(){return t.show()}}),this._subscriptions.push(this._state.toggleClick.subscribe(function(e){return t.toggle(e)})),this._subscriptions.push(this._state.isDisabledChange.pipe(Object(i.a)(function(t){return t})).subscribe(function(e){return t.hide()})))},t.prototype.show=function(){var t=this;if(!this.isOpen&&!this.isDisabled)return this._showInline?(this._inlinedMenu||this._state.dropdownMenu.then(function(e){t._dropdown.attachInline(e.viewContainer,e.templateRef),t._inlinedMenu=t._dropdown._inlineViewRef,t.addBs4Polyfills()}).catch(),this.addBs4Polyfills(),this._isInlineOpen=!0,this.onShown.emit(!0),void this._state.isOpenChange.emit(!0)):void this._state.dropdownMenu.then(function(e){var n=t.dropup||void 0!==t.dropup&&t.dropup;t._state.direction=n?"up":"down";var a=t.placement||(n?"top start":"bottom start");t._dropdown.attach(d).to(t.container).position({attachment:a}).show({content:e.templateRef,placement:a}),t._state.isOpenChange.emit(!0)}).catch()},t.prototype.hide=function(){this.isOpen&&(this._showInline?(this.removeShowClass(),this.removeDropupStyles(),this._isInlineOpen=!1,this.onHidden.emit(!0)):this._dropdown.hide(),this._state.isOpenChange.emit(!1))},t.prototype.toggle=function(t){return this.isOpen||!t?this.hide():this.show()},t.prototype._contains=function(t){return this._elementRef.nativeElement.contains(t.target)||this._dropdown.instance&&this._dropdown.instance._contains(t.target)},t.prototype.ngOnDestroy=function(){var t,e;try{for(var n=Object(a.__values)(this._subscriptions),r=n.next();!r.done;r=n.next())r.value.unsubscribe()}catch(i){t={error:i}}finally{try{r&&!r.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}this._dropdown.dispose()},t.prototype.addBs4Polyfills=function(){Object(o.d)()||(this.addShowClass(),this.checkRightAlignment(),this.addDropupStyles())},t.prototype.addShowClass=function(){this._inlinedMenu&&this._inlinedMenu.rootNodes[0]&&this._renderer.addClass(this._inlinedMenu.rootNodes[0],"show")},t.prototype.removeShowClass=function(){this._inlinedMenu&&this._inlinedMenu.rootNodes[0]&&this._renderer.removeClass(this._inlinedMenu.rootNodes[0],"show")},t.prototype.checkRightAlignment=function(){if(this._inlinedMenu&&this._inlinedMenu.rootNodes[0]){var t=this._inlinedMenu.rootNodes[0].classList.contains("dropdown-menu-right");this._renderer.setStyle(this._inlinedMenu.rootNodes[0],"left",t?"auto":"0"),this._renderer.setStyle(this._inlinedMenu.rootNodes[0],"right",t?"0":"auto")}},t.prototype.addDropupStyles=function(){this._inlinedMenu&&this._inlinedMenu.rootNodes[0]&&(this._renderer.setStyle(this._inlinedMenu.rootNodes[0],"top",this.dropup?"auto":"100%"),this._renderer.setStyle(this._inlinedMenu.rootNodes[0],"transform",this.dropup?"translateY(-101%)":"translateY(0)"),this._renderer.setStyle(this._inlinedMenu.rootNodes[0],"bottom","auto"))},t.prototype.removeDropupStyles=function(){this._inlinedMenu&&this._inlinedMenu.rootNodes[0]&&(this._renderer.removeStyle(this._inlinedMenu.rootNodes[0],"top"),this._renderer.removeStyle(this._inlinedMenu.rootNodes[0],"transform"),this._renderer.removeStyle(this._inlinedMenu.rootNodes[0],"bottom"))},t}(),p=function(){return function(t,e,n){t.resolveDropdownMenu({templateRef:n,viewContainer:e})}}(),h=function(){function t(t,e,n,a,r){var i=this;this._changeDetectorRef=t,this._dropdown=e,this._element=n,this._renderer=a,this._state=r,this.isDisabled=null,this._subscriptions=[],this._subscriptions.push(this._state.isOpenChange.subscribe(function(t){i.isOpen=t,t?(i._documentClickListener=i._renderer.listen("document","click",function(t){!i._state.autoClose||2===t.button||i._element.nativeElement.contains(t.target)||i._state.insideClick&&i._dropdown._contains(t)||(i._state.toggleClick.emit(!1),i._changeDetectorRef.detectChanges())}),i._escKeyUpListener=i._renderer.listen(i._element.nativeElement,"keyup.esc",function(){i._state.autoClose&&(i._state.toggleClick.emit(!1),i._changeDetectorRef.detectChanges())})):(i._documentClickListener(),i._escKeyUpListener())})),this._subscriptions.push(this._state.isDisabledChange.subscribe(function(t){return i.isDisabled=t||null}))}return t.prototype.onClick=function(){this.isDisabled||this._state.toggleClick.emit(!0)},t.prototype.ngOnDestroy=function(){var t,e;this._documentClickListener&&this._documentClickListener(),this._escKeyUpListener&&this._escKeyUpListener();try{for(var n=Object(a.__values)(this._subscriptions),r=n.next();!r.done;r=n.next())r.value.unsubscribe()}catch(i){t={error:i}}finally{try{r&&!r.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}},t}(),g=function(){function t(){}return t.forRoot=function(e){return{ngModule:t,providers:[s.a,u.a,l,{provide:c,useValue:e||{autoClose:!0,insideClick:!1}}]}},t}()},y3By:function(t,e,n){"use strict";n.d(e,"a",function(){return r}),n.d(e,"b",function(){return i});var a=n("+umK");function r(){for(var t=[],e=0;e-1?t.splice(a,1):t.push(e),t},e.selectRowsBetween=function(t,e,n,a,r){for(var i=n=n||!i&&s>=a&&s<=n)&&s>=o.start&&s<=o.end&&t.push(e[s])}return t}},y9jh:function(t,e,n){var a;"undefined"!=typeof self&&self,a=function(t,e,n,a,r){return function(t){var e={};function n(a){if(e[a])return e[a].exports;var r=e[a]={i:a,l:!1,exports:{}};return t[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,a){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:a})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s="./src/index.ts")}({"./node_modules/css-loader/index.js!./node_modules/postcss-loader/index.js!./node_modules/sass-loader/lib/loader.js??ref--3-4!./src/components/datatable.component.scss":function(t,e,n){(t.exports=n("./node_modules/css-loader/lib/css-base.js")(!1)).push([t.i,".ngx-datatable {\n display: block;\n overflow: hidden;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n position: relative;\n -webkit-transform: translate3d(0, 0, 0);\n /**\n * Vertical Scrolling Adjustments\n */\n /**\n * Horizontal Scrolling Adjustments\n */\n /**\n * Fixed Header Height Adjustments\n */\n /**\n * Fixed row height adjustments\n */\n /**\n * Shared Styles\n */\n /**\n * Header Styles\n */\n /**\n * Body Styles\n */\n /**\n * Footer Styles\n */ }\n .ngx-datatable [hidden] {\n display: none !important; }\n .ngx-datatable *, .ngx-datatable *:before, .ngx-datatable *:after {\n -webkit-box-sizing: border-box;\n box-sizing: border-box; }\n .ngx-datatable.scroll-vertical .datatable-body {\n overflow-y: auto; }\n .ngx-datatable.scroll-vertical.virtualized .datatable-body .datatable-row-wrapper {\n position: absolute; }\n .ngx-datatable.scroll-horz .datatable-body {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch; }\n .ngx-datatable.fixed-header .datatable-header .datatable-header-inner {\n white-space: nowrap; }\n .ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis; }\n .ngx-datatable.fixed-row .datatable-scroll {\n white-space: nowrap; }\n .ngx-datatable.fixed-row .datatable-scroll .datatable-body-row {\n white-space: nowrap; }\n .ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-cell {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis; }\n .ngx-datatable.fixed-row .datatable-scroll .datatable-body-row .datatable-body-group-cell {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis; }\n .ngx-datatable .datatable-body-row,\n .ngx-datatable .datatable-row-center,\n .ngx-datatable .datatable-header-inner {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n -ms-flex-flow: row;\n -o-flex-flow: row;\n flex-flow: row; }\n .ngx-datatable .datatable-body-cell,\n .ngx-datatable .datatable-header-cell {\n overflow-x: hidden;\n vertical-align: top;\n display: inline-block;\n line-height: 1.625; }\n .ngx-datatable .datatable-body-cell:focus,\n .ngx-datatable .datatable-header-cell:focus {\n outline: none; }\n .ngx-datatable .datatable-row-left,\n .ngx-datatable .datatable-row-right {\n z-index: 9; }\n .ngx-datatable .datatable-row-left,\n .ngx-datatable .datatable-row-center,\n .ngx-datatable .datatable-row-group,\n .ngx-datatable .datatable-row-right {\n position: relative; }\n .ngx-datatable .datatable-header {\n display: block;\n overflow: hidden; }\n .ngx-datatable .datatable-header .datatable-header-inner {\n -webkit-box-align: stretch;\n -ms-flex-align: stretch;\n align-items: stretch;\n -webkit-align-items: stretch; }\n .ngx-datatable .datatable-header .datatable-header-cell {\n position: relative;\n display: inline-block; }\n .ngx-datatable .datatable-header .datatable-header-cell.sortable .datatable-header-cell-wrapper {\n cursor: pointer; }\n .ngx-datatable .datatable-header .datatable-header-cell.longpress .datatable-header-cell-wrapper {\n cursor: move; }\n .ngx-datatable .datatable-header .datatable-header-cell .sort-btn {\n line-height: 100%;\n vertical-align: middle;\n display: inline-block;\n cursor: pointer; }\n .ngx-datatable .datatable-header .datatable-header-cell .resize-handle, .ngx-datatable .datatable-header .datatable-header-cell .resize-handle--not-resizable {\n display: inline-block;\n position: absolute;\n right: 0;\n top: 0;\n bottom: 0;\n width: 5px;\n padding: 0 4px;\n visibility: hidden; }\n .ngx-datatable .datatable-header .datatable-header-cell .resize-handle {\n cursor: ew-resize; }\n .ngx-datatable .datatable-header .datatable-header-cell.resizeable:hover .resize-handle {\n visibility: visible; }\n .ngx-datatable .datatable-header .datatable-header-cell:hover .resize-handle--not-resizable {\n visibility: visible; }\n .ngx-datatable .datatable-header .datatable-header-cell .targetMarker {\n position: absolute;\n top: 0;\n bottom: 0; }\n .ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromLeft {\n right: 0; }\n .ngx-datatable .datatable-header .datatable-header-cell .targetMarker.dragFromRight {\n left: 0; }\n .ngx-datatable .datatable-header .datatable-header-cell .datatable-header-cell-template-wrap {\n height: inherit; }\n .ngx-datatable .datatable-body {\n position: relative;\n z-index: 10;\n display: block; }\n .ngx-datatable .datatable-body .datatable-scroll {\n display: inline-block; }\n .ngx-datatable .datatable-body .datatable-row-detail {\n overflow-y: hidden; }\n .ngx-datatable .datatable-body .datatable-row-wrapper {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column; }\n .ngx-datatable .datatable-body .datatable-body-row {\n outline: none; }\n .ngx-datatable .datatable-body .datatable-body-row > div {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex; }\n .ngx-datatable .datatable-footer {\n display: block;\n width: 100%; }\n .ngx-datatable .datatable-footer .datatable-footer-inner {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n width: 100%; }\n .ngx-datatable .datatable-footer .selected-count .page-count {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 40%;\n flex: 1 1 40%; }\n .ngx-datatable .datatable-footer .selected-count .datatable-pager {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 60%;\n flex: 1 1 60%; }\n .ngx-datatable .datatable-footer .page-count {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 20%;\n flex: 1 1 20%; }\n .ngx-datatable .datatable-footer .datatable-pager {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 80%;\n flex: 1 1 80%;\n text-align: right; }\n .ngx-datatable .datatable-footer .datatable-pager .pager,\n .ngx-datatable .datatable-footer .datatable-pager .pager li {\n padding: 0;\n margin: 0;\n display: inline-block;\n list-style: none; }\n .ngx-datatable .datatable-footer .datatable-pager .pager li, .ngx-datatable .datatable-footer .datatable-pager .pager li a {\n outline: none; }\n .ngx-datatable .datatable-footer .datatable-pager .pager li a {\n cursor: pointer;\n display: inline-block; }\n .ngx-datatable .datatable-footer .datatable-pager .pager li.disabled a {\n cursor: not-allowed; }\n",""])},"./node_modules/css-loader/lib/css-base.js":function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=function(t,e){var n=t[1]||"",a=t[3];if(!a)return n;if(e&&"function"==typeof btoa){var r="/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+" */",i=a.sources.map(function(t){return"/*# sourceURL="+a.sourceRoot+t+" */"});return[n].concat(i).concat([r]).join("\n")}return[n].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+n+"}":n}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var a={},r=0;r=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/utils/index.ts"),o=n("./src/types/index.ts");n("./src/events.ts"),e.DataTableBodyCellComponent=function(){function t(t,e){this.cd=e,this.activate=new i.EventEmitter,this.treeAction=new i.EventEmitter,this.isFocused=!1,this.onCheckboxChangeFn=this.onCheckboxChange.bind(this),this.activateFn=this.activate.emit.bind(this.activate),this.cellContext={onCheckboxChangeFn:this.onCheckboxChangeFn,activateFn:this.activateFn,row:this.row,group:this.group,value:this.value,column:this.column,rowHeight:this.rowHeight,isSelected:this.isSelected,rowIndex:this.rowIndex,treeStatus:this.treeStatus,onTreeAction:this.onTreeAction.bind(this)},this._element=t.nativeElement}return Object.defineProperty(t.prototype,"group",{get:function(){return this._group},set:function(t){this._group=t,this.cellContext.group=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rowHeight",{get:function(){return this._rowHeight},set:function(t){this._rowHeight=t,this.cellContext.rowHeight=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isSelected",{get:function(){return this._isSelected},set:function(t){this._isSelected=t,this.cellContext.isSelected=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"expanded",{get:function(){return this._expanded},set:function(t){this._expanded=t,this.cellContext.expanded=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rowIndex",{get:function(){return this._rowIndex},set:function(t){this._rowIndex=t,this.cellContext.rowIndex=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"column",{get:function(){return this._column},set:function(t){this._column=t,this.cellContext.column=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"row",{get:function(){return this._row},set:function(t){this._row=t,this.cellContext.row=t,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"sorts",{get:function(){return this._sorts},set:function(t){this._sorts=t,this.calcSortDir=this.calcSortDir(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"treeStatus",{get:function(){return this._treeStatus},set:function(t){this._treeStatus="collapsed"!==t&&"expanded"!==t&&"loading"!==t&&"disabled"!==t?"collapsed":t,this.cellContext.treeStatus=this._treeStatus,this.checkValueUpdates(),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columnCssClasses",{get:function(){var t="datatable-body-cell";if(this.column.cellClass)if("string"==typeof this.column.cellClass)t+=" "+this.column.cellClass;else if("function"==typeof this.column.cellClass){var e=this.column.cellClass({row:this.row,group:this.group,column:this.column,value:this.value,rowHeight:this.rowHeight});if("string"==typeof e)t+=e;else if("object"==typeof e)for(var n=0,a=Object.keys(e);n]+(>|$)/g,""):t},t.prototype.onTreeAction=function(){this.treeAction.emit(this.row)},t.prototype.calcLeftMargin=function(t,e){return t.isTreeColumn?e.level*(null!=t.treeLevelIndent?t.treeLevelIndent:50):0},a([i.Input(),r("design:type",Function)],t.prototype,"displayCheck",void 0),a([i.Input(),r("design:type",Object),r("design:paramtypes",[Object])],t.prototype,"group",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"rowHeight",null),a([i.Input(),r("design:type",Boolean),r("design:paramtypes",[Boolean])],t.prototype,"isSelected",null),a([i.Input(),r("design:type",Boolean),r("design:paramtypes",[Boolean])],t.prototype,"expanded",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"rowIndex",null),a([i.Input(),r("design:type",Object),r("design:paramtypes",[Object])],t.prototype,"column",null),a([i.Input(),r("design:type",Object),r("design:paramtypes",[Object])],t.prototype,"row",null),a([i.Input(),r("design:type",Array),r("design:paramtypes",[Array])],t.prototype,"sorts",null),a([i.Input(),r("design:type",String),r("design:paramtypes",[String])],t.prototype,"treeStatus",null),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"activate",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"treeAction",void 0),a([i.ViewChild("cellTemplate",{read:i.ViewContainerRef}),r("design:type",i.ViewContainerRef)],t.prototype,"cellTemplate",void 0),a([i.HostBinding("class"),r("design:type",Object),r("design:paramtypes",[])],t.prototype,"columnCssClasses",null),a([i.HostBinding("style.width.px"),r("design:type",Number),r("design:paramtypes",[])],t.prototype,"width",null),a([i.HostBinding("style.minWidth.px"),r("design:type",Number),r("design:paramtypes",[])],t.prototype,"minWidth",null),a([i.HostBinding("style.maxWidth.px"),r("design:type",Number),r("design:paramtypes",[])],t.prototype,"maxWidth",null),a([i.HostBinding("style.height"),r("design:type",Object),r("design:paramtypes",[])],t.prototype,"height",null),a([i.HostListener("focus"),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",void 0)],t.prototype,"onFocus",null),a([i.HostListener("blur"),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",void 0)],t.prototype,"onBlur",null),a([i.HostListener("click",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onClick",null),a([i.HostListener("dblclick",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onDblClick",null),a([i.HostListener("keydown",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onKeyDown",null),a([i.Component({selector:"datatable-body-cell",changeDetection:i.ChangeDetectionStrategy.OnPush,template:'\n
\n \n \n \n \n \n \n \n \n\n \n \n \n \n
\n '}),r("design:paramtypes",[i.ElementRef,i.ChangeDetectorRef])],t)}()},"./src/components/body/body-group-header-template.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.DatatableGroupHeaderTemplateDirective=function(){return a([i.Directive({selector:"[ngx-datatable-group-header-template]"}),r("design:paramtypes",[i.TemplateRef])],function(t){this.template=t})}()},"./src/components/body/body-group-header.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/components/body/body-group-header-template.directive.ts");e.DatatableGroupHeaderDirective=function(){function t(){this.rowHeight=0,this.toggle=new i.EventEmitter}return t.prototype.toggleExpandGroup=function(t){this.toggle.emit({type:"group",value:t})},t.prototype.expandAllGroups=function(){this.toggle.emit({type:"all",value:!0})},t.prototype.collapseAllGroups=function(){this.toggle.emit({type:"all",value:!1})},a([i.Input(),r("design:type",Object)],t.prototype,"rowHeight",void 0),a([i.Input(),i.ContentChild(s.DatatableGroupHeaderTemplateDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"template",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"toggle",void 0),a([i.Directive({selector:"ngx-datatable-group-header"})],t)}()},"./src/components/body/body-row-wrapper.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");n("./src/events.ts"),e.DataTableRowWrapperComponent=function(){function t(t,e){this.cd=t,this.differs=e,this.rowContextmenu=new i.EventEmitter(!1),this.groupContext={group:this.row,expanded:this.expanded,rowIndex:this.rowIndex},this.rowContext={row:this.row,expanded:this.expanded,rowIndex:this.rowIndex},this._expanded=!1,this.rowDiffer=e.find({}).create()}return Object.defineProperty(t.prototype,"rowIndex",{get:function(){return this._rowIndex},set:function(t){this._rowIndex=t,this.rowContext.rowIndex=t,this.groupContext.rowIndex=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"expanded",{get:function(){return this._expanded},set:function(t){this._expanded=t,this.groupContext.expanded=t,this.rowContext.expanded=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),t.prototype.ngDoCheck=function(){this.rowDiffer.diff(this.row)&&(this.rowContext.row=this.row,this.groupContext.group=this.row,this.cd.markForCheck())},t.prototype.onContextmenu=function(t){this.rowContextmenu.emit({event:t,row:this.row})},t.prototype.getGroupHeaderStyle=function(){var t={};return t.transform="translate3d("+this.offsetX+"px, 0px, 0px)",t["backface-visibility"]="hidden",t.width=this.innerWidth,t},a([i.Input(),r("design:type",Number)],t.prototype,"innerWidth",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"rowDetail",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"groupHeader",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"offsetX",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"detailRowHeight",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"row",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"groupedRows",void 0),a([i.Output(),r("design:type",Object)],t.prototype,"rowContextmenu",void 0),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"rowIndex",null),a([i.Input(),r("design:type",Boolean),r("design:paramtypes",[Boolean])],t.prototype,"expanded",null),a([i.HostListener("contextmenu",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onContextmenu",null),a([i.Component({selector:"datatable-row-wrapper",changeDetection:i.ChangeDetectionStrategy.OnPush,template:'\n
\n \n \n
\n \n \n \n \n \n \n ',host:{class:"datatable-row-wrapper"}}),r("design:paramtypes",[i.ChangeDetectorRef,i.KeyValueDiffers])],t)}()},"./src/components/body/body-row.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)},i=this&&this.__param||function(t,e){return function(n,a){e(n,a,t)}};Object.defineProperty(e,"__esModule",{value:!0});var s=n("@angular/core"),o=n("./src/utils/index.ts"),u=n("./src/services/index.ts");n("./src/events.ts"),e.DataTableBodyRowComponent=function(){function t(t,e,n,a){this.differs=t,this.scrollbarHelper=e,this.cd=n,this.treeStatus="collapsed",this.activate=new s.EventEmitter,this.treeAction=new s.EventEmitter,this._groupStyles={left:{},center:{},right:{}},this._element=a.nativeElement,this._rowDiffer=t.find({}).create()}return Object.defineProperty(t.prototype,"columns",{get:function(){return this._columns},set:function(t){this._columns=t,this.recalculateColumns(t),this.buildStylesByGroup()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"innerWidth",{get:function(){return this._innerWidth},set:function(t){if(this._columns){var e=o.columnsByPin(this._columns);this._columnGroupWidths=o.columnGroupWidths(e,e)}this._innerWidth=t,this.recalculateColumns(),this.buildStylesByGroup()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"offsetX",{get:function(){return this._offsetX},set:function(t){this._offsetX=t,this.buildStylesByGroup()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"cssClass",{get:function(){var t="datatable-body-row";if(this.isSelected&&(t+=" active"),this.rowIndex%2!=0&&(t+=" datatable-row-odd"),this.rowIndex%2==0&&(t+=" datatable-row-even"),this.rowClass){var e=this.rowClass(this.row);if("string"==typeof e)t+=" "+e;else if("object"==typeof e)for(var n=0,a=Object.keys(e);n\n \n \n \n '}),i(1,s.SkipSelf()),r("design:paramtypes",[s.KeyValueDiffers,u.ScrollbarHelper,s.ChangeDetectorRef,s.ElementRef])],t)}()},"./src/components/body/body.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/utils/index.ts"),o=(n("./src/types/index.ts"),n("./src/components/body/scroller.component.ts"));e.DataTableBodyComponent=function(){function t(t){var e=this;this.cd=t,this.selected=[],this.scroll=new i.EventEmitter,this.page=new i.EventEmitter,this.activate=new i.EventEmitter,this.select=new i.EventEmitter,this.detailToggle=new i.EventEmitter,this.rowContextmenu=new i.EventEmitter(!1),this.treeAction=new i.EventEmitter,this.rowHeightsCache=new s.RowHeightCache,this.temp=[],this.offsetY=0,this.indexes={},this.rowIndexes=new Map,this.rowExpansions=new Map,this.getDetailRowHeight=function(t,n){if(!e.rowDetail)return 0;var a=e.rowDetail.rowHeight;return"function"==typeof a?a(t,n):a},this.rowTrackingFn=(function(t,e){var n=this.getRowIndex(e);return this.trackByProp?n+"-"+this.trackByProp:n}).bind(this)}return Object.defineProperty(t.prototype,"pageSize",{get:function(){return this._pageSize},set:function(t){this._pageSize=t,this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rows",{get:function(){return this._rows},set:function(t){this._rows=t,this.rowExpansions.clear(),this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columns",{get:function(){return this._columns},set:function(t){this._columns=t;var e=s.columnsByPin(t);this.columnGroupWidths=s.columnGroupWidths(e,t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"offset",{get:function(){return this._offset},set:function(t){this._offset=t,this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rowCount",{get:function(){return this._rowCount},set:function(t){this._rowCount=t,this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bodyWidth",{get:function(){return this.scrollbarH?this.innerWidth+"px":"100%"},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bodyHeight",{get:function(){return this._bodyHeight},set:function(t){this._bodyHeight=this.scrollbarV?t+"px":"auto",this.recalcLayout()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"selectEnabled",{get:function(){return!!this.selectionType},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scrollHeight",{get:function(){if(this.scrollbarV&&this.virtualization&&this.rowCount)return this.rowHeightsCache.query(this.rowCount-1)},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){var t=this;this.rowDetail&&(this.listener=this.rowDetail.toggle.subscribe(function(e){var n=e.type,a=e.value;"row"===n&&t.toggleRowExpansion(a),"all"===n&&t.toggleAllRows(a),t.updateIndexes(),t.updateRows(),t.cd.markForCheck()})),this.groupHeader&&(this.listener=this.groupHeader.toggle.subscribe(function(e){var n=e.type,a=e.value;"group"===n&&t.toggleRowExpansion(a),"all"===n&&t.toggleAllRows(a),t.updateIndexes(),t.updateRows(),t.cd.markForCheck()}))},t.prototype.ngOnDestroy=function(){this.rowDetail&&this.listener.unsubscribe(),this.groupHeader&&this.listener.unsubscribe()},t.prototype.updateOffsetY=function(t){this.scroller&&(this.scrollbarV&&this.virtualization&&t?t=this.rowHeightsCache.query(this.pageSize*t-1):this.scrollbarV&&!this.virtualization&&(t=0),this.scroller.setOffset(t||0))},t.prototype.onBodyScroll=function(t){var e=t.scrollYPos,n=t.scrollXPos;this.offsetY===e&&this.offsetX===n||this.scroll.emit({offsetY:e,offsetX:n}),this.offsetY=e,this.offsetX=n,this.updateIndexes(),this.updatePage(t.direction),this.updateRows()},t.prototype.updatePage=function(t){var e=this.indexes.first/this.pageSize;"up"===t?e=Math.ceil(e):"down"===t&&(e=Math.floor(e)),void 0===t||isNaN(e)||this.page.emit({offset:e})},t.prototype.updateRows=function(){var t=this.indexes,e=t.last,n=t.first,a=0,r=[];if(this.rowIndexes.clear(),this.groupedRows)for(;n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',changeDetection:i.ChangeDetectionStrategy.OnPush,host:{class:"datatable-body"}}),r("design:paramtypes",[i.ChangeDetectorRef])],t)}()},"./src/components/body/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/components/body/body.component.ts")),a(n("./src/components/body/body-cell.component.ts")),a(n("./src/components/body/body-row.component.ts")),a(n("./src/components/body/progress-bar.component.ts")),a(n("./src/components/body/scroller.component.ts")),a(n("./src/components/body/body-row-wrapper.component.ts")),a(n("./src/components/body/selection.component.ts")),a(n("./src/components/body/body-group-header.directive.ts")),a(n("./src/components/body/body-group-header-template.directive.ts")),a(n("./src/components/body/summary/index.ts"))},"./src/components/body/progress-bar.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s};Object.defineProperty(e,"__esModule",{value:!0});var r=n("@angular/core");e.ProgressBarComponent=function(){return a([r.Component({selector:"datatable-progress",template:'\n
\n
\n
\n
\n
\n ',changeDetection:r.ChangeDetectionStrategy.OnPush})],function(){})}()},"./src/components/body/scroller.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.ScrollerComponent=function(){function t(t,e,n){this.ngZone=t,this.renderer=n,this.scrollbarV=!1,this.scrollbarH=!1,this.scroll=new i.EventEmitter,this.scrollYPos=0,this.scrollXPos=0,this.prevScrollYPos=0,this.prevScrollXPos=0,this.element=e.nativeElement}return t.prototype.ngOnInit=function(){if(this.scrollbarV||this.scrollbarH){var t=this.renderer;this.parentElement=t.parentNode(t.parentNode(this.element)),this.parentElement.addEventListener("scroll",this.onScrolled.bind(this))}},t.prototype.ngOnDestroy=function(){(this.scrollbarV||this.scrollbarH)&&this.parentElement.removeEventListener("scroll",this.onScrolled.bind(this))},t.prototype.setOffset=function(t){this.parentElement&&(this.parentElement.scrollTop=t)},t.prototype.onScrolled=function(t){var e=this,n=t.currentTarget;requestAnimationFrame(function(){e.scrollYPos=n.scrollTop,e.scrollXPos=n.scrollLeft,e.updateOffset()})},t.prototype.updateOffset=function(){var t;this.scrollYPosthis.prevScrollYPos&&(t="up"),this.scroll.emit({direction:t,scrollYPos:this.scrollYPos,scrollXPos:this.scrollXPos}),this.prevScrollYPos=this.scrollYPos,this.prevScrollXPos=this.scrollXPos},a([i.Input(),r("design:type",Boolean)],t.prototype,"scrollbarV",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"scrollbarH",void 0),a([i.HostBinding("style.height.px"),i.Input(),r("design:type",Number)],t.prototype,"scrollHeight",void 0),a([i.HostBinding("style.width.px"),i.Input(),r("design:type",Number)],t.prototype,"scrollWidth",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"scroll",void 0),a([i.Component({selector:"datatable-scroller",template:"\n \n ",host:{class:"datatable-scroll"},changeDetection:i.ChangeDetectionStrategy.OnPush}),r("design:paramtypes",[i.NgZone,i.ElementRef,i.Renderer2])],t)}()},"./src/components/body/selection.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/utils/index.ts"),o=n("./src/types/index.ts");e.DataTableSelectionComponent=function(){function t(){this.activate=new i.EventEmitter,this.select=new i.EventEmitter}return t.prototype.selectRow=function(t,e,n){var a;if(this.selectEnabled){var r=this.selectionType===o.SelectionType.checkbox,i=this.selectionType===o.SelectionType.multiClick,u=[];u=this.selectionType===o.SelectionType.multi||r||i?t.shiftKey?s.selectRowsBetween([],this.rows,e,this.prevIndex,this.getRowSelectedIdx.bind(this)):s.selectRows(t.ctrlKey||t.metaKey||i||r?this.selected.slice():[],n,this.getRowSelectedIdx.bind(this)):s.selectRows([],n,this.getRowSelectedIdx.bind(this)),"function"==typeof this.selectCheck&&(u=u.filter(this.selectCheck.bind(this))),this.selected.splice(0,this.selected.length),(a=this.selected).push.apply(a,u),this.prevIndex=e,this.select.emit({selected:u})}},t.prototype.onActivate=function(t,e){var n=t.type,a=t.event,r=t.row,i=this.selectionType===o.SelectionType.checkbox;!i&&("click"===n||"dblclick"===n)||i&&"checkbox"===n?this.selectRow(a,e,r):"keydown"===n&&(a.keyCode===s.Keys.return?this.selectRow(a,e,r):this.onKeyboardFocus(t)),this.activate.emit(t)},t.prototype.onKeyboardFocus=function(t){var e=t.event.keyCode;if(e===s.Keys.up||e===s.Keys.down||e===s.Keys.right||e===s.Keys.left){var n=this.selectionType===o.SelectionType.cell;t.cellElement&&n?n&&this.focusCell(t.cellElement,t.rowElement,e,t.cellIndex):this.focusRow(t.rowElement,e)}},t.prototype.focusRow=function(t,e){var n=this.getPrevNextRow(t,e);n&&n.focus()},t.prototype.getPrevNextRow=function(t,e){var n=t.parentElement;if(n){var a=void 0;if(e===s.Keys.up?a=n.previousElementSibling:e===s.Keys.down&&(a=n.nextElementSibling),a&&a.children.length)return a.children[0]}},t.prototype.focusCell=function(t,e,n,a){var r;if(n===s.Keys.left)r=t.previousElementSibling;else if(n===s.Keys.right)r=t.nextElementSibling;else if(n===s.Keys.up||n===s.Keys.down){var i=this.getPrevNextRow(e,n);if(i){var o=i.getElementsByClassName("datatable-body-cell");o.length&&(r=o[a])}}r&&r.focus()},t.prototype.getRowSelected=function(t){return this.getRowSelectedIdx(t,this.selected)>-1},t.prototype.getRowSelectedIdx=function(t,e){var n=this;if(!e||!e.length)return-1;var a=this.rowIdentity(t);return e.findIndex(function(t){return n.rowIdentity(t)===a})},a([i.Input(),r("design:type",Array)],t.prototype,"rows",void 0),a([i.Input(),r("design:type",Array)],t.prototype,"selected",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"selectEnabled",void 0),a([i.Input(),r("design:type",String)],t.prototype,"selectionType",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"rowIdentity",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"selectCheck",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"activate",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"select",void 0),a([i.Component({selector:"datatable-selection",template:"\n \n ",changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},"./src/components/body/summary/index.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}(n("./src/components/body/summary/summary-row.component.ts"))},"./src/components/body/summary/summary-row.component.ts":function(t,e,n){"use strict";var a=this&&this.__assign||function(){return(a=Object.assign||function(t){for(var e,n=1,a=arguments.length;n=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var s=n("@angular/core");function o(t){var e=t.filter(function(t){return!!t});return e.length?e.some(function(t){return"number"!=typeof t})?null:e.reduce(function(t,e){return t+e}):null}function u(t){return null}e.DataTableSummaryRowComponent=function(){function t(){this.summaryRow={}}return t.prototype.ngOnChanges=function(){this.columns&&this.rows&&(this.updateInternalColumns(),this.updateValues())},t.prototype.updateInternalColumns=function(){this._internalColumns=this.columns.map(function(t){return a({},t,{cellTemplate:t.summaryTemplate})})},t.prototype.updateValues=function(){var t=this;this.summaryRow={},this.columns.filter(function(t){return!t.summaryTemplate}).forEach(function(e){var n=t.rows.map(function(t){return t[e.prop]}),a=t.getSummaryFunction(e);t.summaryRow[e.prop]=e.pipe?e.pipe.transform(a(n)):a(n)})},t.prototype.getSummaryFunction=function(t){return void 0===t.summaryFunc?o:null===t.summaryFunc?u:t.summaryFunc},r([s.Input(),i("design:type",Array)],t.prototype,"rows",void 0),r([s.Input(),i("design:type",Array)],t.prototype,"columns",void 0),r([s.Input(),i("design:type",Number)],t.prototype,"rowHeight",void 0),r([s.Input(),i("design:type",Number)],t.prototype,"offsetX",void 0),r([s.Input(),i("design:type",Number)],t.prototype,"innerWidth",void 0),r([s.Component({selector:"datatable-summary-row",template:'\n \n \n ',host:{class:"datatable-summary-row"}})],t)}()},"./src/components/columns/column-cell.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.DataTableColumnCellDirective=function(){return a([i.Directive({selector:"[ngx-datatable-cell-template]"}),r("design:paramtypes",[i.TemplateRef])],function(t){this.template=t})}()},"./src/components/columns/column-header.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.DataTableColumnHeaderDirective=function(){return a([i.Directive({selector:"[ngx-datatable-header-template]"}),r("design:paramtypes",[i.TemplateRef])],function(t){this.template=t})}()},"./src/components/columns/column.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/components/columns/column-header.directive.ts"),o=n("./src/components/columns/column-cell.directive.ts"),u=n("./src/components/columns/tree.directive.ts"),c=n("./src/services/column-changes.service.ts");e.DataTableColumnDirective=function(){function t(t){this.columnChangesService=t,this.isFirstChange=!0}return t.prototype.ngOnChanges=function(){this.isFirstChange?this.isFirstChange=!1:this.columnChangesService.onInputChange()},a([i.Input(),r("design:type",String)],t.prototype,"name",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"prop",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"frozenLeft",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"frozenRight",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"flexGrow",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"resizeable",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"comparator",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"pipe",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"sortable",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"draggable",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"canAutoResize",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"minWidth",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"width",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"maxWidth",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"checkboxable",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"headerCheckboxable",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"headerClass",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"cellClass",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"isTreeColumn",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"treeLevelIndent",void 0),a([i.Input(),r("design:type",Function)],t.prototype,"summaryFunc",void 0),a([i.Input(),r("design:type",i.TemplateRef)],t.prototype,"summaryTemplate",void 0),a([i.Input(),i.ContentChild(o.DataTableColumnCellDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"cellTemplate",void 0),a([i.Input(),i.ContentChild(s.DataTableColumnHeaderDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"headerTemplate",void 0),a([i.Input(),i.ContentChild(u.DataTableColumnCellTreeToggle,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"treeToggleTemplate",void 0),a([i.Directive({selector:"ngx-datatable-column"}),r("design:paramtypes",[c.ColumnChangesService])],t)}()},"./src/components/columns/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/components/columns/column.directive.ts")),a(n("./src/components/columns/column-header.directive.ts")),a(n("./src/components/columns/column-cell.directive.ts")),a(n("./src/components/columns/tree.directive.ts"))},"./src/components/columns/tree.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.DataTableColumnCellTreeToggle=function(){return a([i.Directive({selector:"[ngx-datatable-tree-toggle]"}),r("design:paramtypes",[i.TemplateRef])],function(t){this.template=t})}()},"./src/components/datatable.component.scss":function(t,e,n){var a=n("./node_modules/css-loader/index.js!./node_modules/postcss-loader/index.js!./node_modules/sass-loader/lib/loader.js??ref--3-4!./src/components/datatable.component.scss");t.exports="string"==typeof a?a:a.toString()},"./src/components/datatable.component.ts":function(t,e,n){"use strict";var a=this&&this.__assign||function(){return(a=Object.assign||function(t){for(var e,n=1,a=arguments.length;n=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)},s=this&&this.__param||function(t,e){return function(n,a){e(n,a,t)}};Object.defineProperty(e,"__esModule",{value:!0});var o=n("@angular/core"),u=n("./src/utils/index.ts"),c=n("./src/services/index.ts"),l=n("./src/types/index.ts"),d=n("./src/components/body/index.ts"),f=n("./src/components/body/body-group-header.directive.ts"),p=n("./src/components/columns/index.ts"),h=n("./src/components/row-detail/index.ts"),g=n("./src/components/footer/index.ts"),b=n("./src/components/header/index.ts"),m=n("rxjs");e.DatatableComponent=function(){function t(t,e,n,a,r,i){this.scrollbarHelper=t,this.dimensionsHelper=e,this.cd=n,this.columnChangesService=i,this.selected=[],this.scrollbarV=!1,this.scrollbarH=!1,this.rowHeight=30,this.columnMode=l.ColumnMode.standard,this.headerHeight=30,this.footerHeight=0,this.externalPaging=!1,this.externalSorting=!1,this.loadingIndicator=!1,this.reorderable=!0,this.swapColumns=!0,this.sortType=l.SortType.single,this.sorts=[],this.cssClasses={sortAscending:"datatable-icon-up",sortDescending:"datatable-icon-down",pagerLeftArrow:"datatable-icon-left",pagerRightArrow:"datatable-icon-right",pagerPrevious:"datatable-icon-prev",pagerNext:"datatable-icon-skip"},this.messages={emptyMessage:"No data to display",totalMessage:"total",selectedMessage:"selected"},this.rowIdentity=function(t){return t},this.groupExpansionDefault=!1,this.selectAllRowsOnPage=!1,this.virtualization=!0,this.summaryRow=!1,this.summaryHeight=30,this.summaryPosition="top",this.scroll=new o.EventEmitter,this.activate=new o.EventEmitter,this.select=new o.EventEmitter,this.sort=new o.EventEmitter,this.page=new o.EventEmitter,this.reorder=new o.EventEmitter,this.resize=new o.EventEmitter,this.tableContextmenu=new o.EventEmitter(!1),this.treeAction=new o.EventEmitter,this.rowCount=0,this._offsetX=new m.BehaviorSubject(0),this._count=0,this._offset=0,this._subscriptions=[],this.element=a.nativeElement,this.rowDiffer=r.find({}).create()}return Object.defineProperty(t.prototype,"rows",{get:function(){return this._rows},set:function(t){this._rows=t,t&&(this._internalRows=t.slice()),this.externalSorting||this.sortInternalRows(),this._internalRows=u.groupRowsByParents(this._internalRows,u.optionalGetterForProp(this.treeFromRelation),u.optionalGetterForProp(this.treeToRelation)),this.recalculate(),this._rows&&this._groupRowsBy&&(this.groupedRows=this.groupArrayBy(this._rows,this._groupRowsBy)),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"groupRowsBy",{get:function(){return this._groupRowsBy},set:function(t){t&&(this._groupRowsBy=t,this._rows&&this._groupRowsBy&&(this.groupedRows=this.groupArrayBy(this._rows,this._groupRowsBy)))},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columns",{get:function(){return this._columns},set:function(t){t&&(this._internalColumns=t.slice(),u.setColumnDefaults(this._internalColumns),this.recalculateColumns()),this._columns=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"limit",{get:function(){return this._limit},set:function(t){this._limit=t,this.recalculate()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"count",{get:function(){return this._count},set:function(t){this._count=t,this.recalculate()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"offset",{get:function(){return Math.max(Math.min(this._offset,Math.ceil(this.rowCount/this.pageSize)-1),0)},set:function(t){this._offset=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isFixedHeader",{get:function(){var t=this.headerHeight;return"string"!=typeof t||"auto"!==t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isFixedRow",{get:function(){var t=this.rowHeight;return"string"!=typeof t||"auto"!==t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isVertScroll",{get:function(){return this.scrollbarV},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isVirtualized",{get:function(){return this.virtualization},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isHorScroll",{get:function(){return this.scrollbarH},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isSelectable",{get:function(){return void 0!==this.selectionType},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isCheckboxSelection",{get:function(){return this.selectionType===l.SelectionType.checkbox},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isCellSelection",{get:function(){return this.selectionType===l.SelectionType.cell},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isSingleSelection",{get:function(){return this.selectionType===l.SelectionType.single},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isMultiSelection",{get:function(){return this.selectionType===l.SelectionType.multi},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isMultiClickSelection",{get:function(){return this.selectionType===l.SelectionType.multiClick},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columnTemplates",{get:function(){return this._columnTemplates},set:function(t){this._columnTemplates=t,this.translateColumns(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"allRowsSelected",{get:function(){var t=this.rows&&this.selected&&this.selected.length===this.rows.length;if(this.selectAllRowsOnPage){var e=this.bodyComponent.indexes;t=this.selected.length===e.last-e.first}return this.selected&&this.rows&&0!==this.rows.length&&t},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){this.recalculate()},t.prototype.ngAfterViewInit=function(){var t=this;this.externalSorting||this.sortInternalRows(),"undefined"!=typeof requestAnimationFrame&&requestAnimationFrame(function(){t.recalculate(),t.externalPaging&&t.scrollbarV&&t.page.emit({count:t.count,pageSize:t.pageSize,limit:t.limit,offset:0})})},t.prototype.ngAfterContentInit=function(){var t=this;this.columnTemplates.changes.subscribe(function(e){return t.translateColumns(e)}),this.listenForColumnInputChanges()},t.prototype.translateColumns=function(t){if(t){var e=t.toArray();e.length&&(this._internalColumns=u.translateTemplates(e),u.setColumnDefaults(this._internalColumns),this.recalculateColumns(),this.sortInternalRows(),this.cd.markForCheck())}},t.prototype.groupArrayBy=function(t,e){var n=new Map;return t.forEach(function(t){var a=t[e];n.has(a)?n.get(a).push(t):n.set(a,[t])}),Array.from(n,function(t){return{key:t[0],value:t[1]}})},t.prototype.ngDoCheck=function(){this.rowDiffer.diff(this.rows)&&(this.externalSorting?this._internalRows=this.rows.slice():this.sortInternalRows(),this._internalRows=u.groupRowsByParents(this._internalRows,u.optionalGetterForProp(this.treeFromRelation),u.optionalGetterForProp(this.treeToRelation)),this.recalculatePages(),this.cd.markForCheck())},t.prototype.recalculate=function(){this.recalculateDims(),this.recalculateColumns()},t.prototype.onWindowResize=function(){this.recalculate()},t.prototype.recalculateColumns=function(t,e,n){if(void 0===t&&(t=this._internalColumns),void 0===e&&(e=-1),void 0===n&&(n=this.scrollbarH),t){var a=this._innerWidth;return this.scrollbarV&&(a-=this.scrollbarHelper.width),this.columnMode===l.ColumnMode.force?u.forceFillColumnWidths(t,a,e,n):this.columnMode===l.ColumnMode.flex&&u.adjustColumnWidths(t,a),t}},t.prototype.recalculateDims=function(){var t=this.dimensionsHelper.getDimensions(this.element);if(this._innerWidth=Math.floor(t.width),this.scrollbarV){var e=t.height;this.headerHeight&&(e-=this.headerHeight),this.footerHeight&&(e-=this.footerHeight),this.bodyHeight=e}this.recalculatePages()},t.prototype.recalculatePages=function(){this.pageSize=this.calcPageSize(),this.rowCount=this.calcRowCount()},t.prototype.onBodyPage=function(t){this.externalPaging&&!this.virtualization||(this.offset=t.offset,this.page.emit({count:this.count,pageSize:this.pageSize,limit:this.limit,offset:this.offset}))},t.prototype.onBodyScroll=function(t){this._offsetX.next(t.offsetX),this.scroll.emit(t),this.cd.detectChanges()},t.prototype.onFooterPage=function(t){this.offset=t.page-1,this.bodyComponent.updateOffsetY(this.offset),this.page.emit({count:this.count,pageSize:this.pageSize,limit:this.limit,offset:this.offset}),this.selectAllRowsOnPage&&(this.selected=[],this.select.emit({selected:this.selected}))},t.prototype.calcPageSize=function(t){if(void 0===t&&(t=this.rows),this.scrollbarV&&this.virtualization){var e=Math.ceil(this.bodyHeight/this.rowHeight);return Math.max(e,0)}return void 0!==this.limit?this.limit:t?t.length:0},t.prototype.calcRowCount=function(t){return void 0===t&&(t=this.rows),this.externalPaging?this.count:t?this.groupedRows?this.groupedRows.length:null!=this.treeFromRelation&&null!=this.treeToRelation?this._internalRows.length:t.length:0},t.prototype.onColumnContextmenu=function(t){this.tableContextmenu.emit({event:t.event,type:l.ContextmenuType.header,content:t.column})},t.prototype.onRowContextmenu=function(t){this.tableContextmenu.emit({event:t.event,type:l.ContextmenuType.body,content:t.row})},t.prototype.onColumnResize=function(t){var e=t.column,n=t.newValue;if(void 0!==e){var r,i=this._internalColumns.map(function(t,i){return(t=a({},t)).$$id===e.$$id&&(r=i,t.width=n,t.$$oldWidth=n),t});this.recalculateColumns(i,r),this._internalColumns=i,this.resize.emit({column:e,newValue:n})}},t.prototype.onColumnReorder=function(t){var e=t.column,n=t.newValue,r=t.prevValue,i=this._internalColumns.map(function(t){return a({},t)});if(this.swapColumns){var s=i[n];i[n]=e,i[r]=s}else if(n>r){for(var o=i[r],u=r;un;u--)i[u]=i[u-1];i[n]=o}this._internalColumns=i,this.reorder.emit({column:e,newValue:n,prevValue:r})},t.prototype.onColumnSort=function(t){this.selectAllRowsOnPage&&(this.selected=[],this.select.emit({selected:this.selected})),this.sorts=t.sorts,!1===this.externalSorting&&this.sortInternalRows(),this._internalRows=u.groupRowsByParents(this._internalRows,u.optionalGetterForProp(this.treeFromRelation),u.optionalGetterForProp(this.treeToRelation)),this.offset=0,this.bodyComponent.updateOffsetY(this.offset),this.sort.emit(t)},t.prototype.onHeaderSelect=function(t){var e,n;if(this.selectAllRowsOnPage){var a=this.bodyComponent.indexes.first,r=this.bodyComponent.indexes.last,i=this.selected.length===r-a;this.selected=[],i||(e=this.selected).push.apply(e,this._internalRows.slice(a,r))}else i=this.selected.length===this.rows.length,this.selected=[],i||(n=this.selected).push.apply(n,this.rows);this.select.emit({selected:this.selected})},t.prototype.onBodySelect=function(t){this.select.emit(t)},t.prototype.onTreeAction=function(t){var e=this,n=t.row,a=this._rows.findIndex(function(n){return n[e.treeToRelation]===t.row[e.treeToRelation]});this.treeAction.emit({row:n,rowIndex:a})},t.prototype.ngOnDestroy=function(){this._subscriptions.forEach(function(t){return t.unsubscribe()})},t.prototype.listenForColumnInputChanges=function(){var t=this;this._subscriptions.push(this.columnChangesService.columnInputChanges$.subscribe(function(){t.columnTemplates&&t.columnTemplates.notifyOnChanges()}))},t.prototype.sortInternalRows=function(){this._internalRows=u.sortRows(this._internalRows,this._internalColumns,this.sorts)},r([o.Input(),i("design:type",Object)],t.prototype,"targetMarkerTemplate",void 0),r([o.Input(),i("design:type",Object),i("design:paramtypes",[Object])],t.prototype,"rows",null),r([o.Input(),i("design:type",String),i("design:paramtypes",[String])],t.prototype,"groupRowsBy",null),r([o.Input(),i("design:type",Array)],t.prototype,"groupedRows",void 0),r([o.Input(),i("design:type",Array),i("design:paramtypes",[Array])],t.prototype,"columns",null),r([o.Input(),i("design:type",Array)],t.prototype,"selected",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"scrollbarV",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"scrollbarH",void 0),r([o.Input(),i("design:type",Number)],t.prototype,"rowHeight",void 0),r([o.Input(),i("design:type",String)],t.prototype,"columnMode",void 0),r([o.Input(),i("design:type",Object)],t.prototype,"headerHeight",void 0),r([o.Input(),i("design:type",Number)],t.prototype,"footerHeight",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"externalPaging",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"externalSorting",void 0),r([o.Input(),i("design:type",Number),i("design:paramtypes",[Number])],t.prototype,"limit",null),r([o.Input(),i("design:type",Number),i("design:paramtypes",[Number])],t.prototype,"count",null),r([o.Input(),i("design:type",Number),i("design:paramtypes",[Number])],t.prototype,"offset",null),r([o.Input(),i("design:type",Boolean)],t.prototype,"loadingIndicator",void 0),r([o.Input(),i("design:type",String)],t.prototype,"selectionType",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"reorderable",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"swapColumns",void 0),r([o.Input(),i("design:type",String)],t.prototype,"sortType",void 0),r([o.Input(),i("design:type",Array)],t.prototype,"sorts",void 0),r([o.Input(),i("design:type",Object)],t.prototype,"cssClasses",void 0),r([o.Input(),i("design:type",Object)],t.prototype,"messages",void 0),r([o.Input(),i("design:type",Function)],t.prototype,"rowIdentity",void 0),r([o.Input(),i("design:type",Object)],t.prototype,"rowClass",void 0),r([o.Input(),i("design:type",Object)],t.prototype,"selectCheck",void 0),r([o.Input(),i("design:type",Function)],t.prototype,"displayCheck",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"groupExpansionDefault",void 0),r([o.Input(),i("design:type",String)],t.prototype,"trackByProp",void 0),r([o.Input(),i("design:type",Object)],t.prototype,"selectAllRowsOnPage",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"virtualization",void 0),r([o.Input(),i("design:type",String)],t.prototype,"treeFromRelation",void 0),r([o.Input(),i("design:type",String)],t.prototype,"treeToRelation",void 0),r([o.Input(),i("design:type",Boolean)],t.prototype,"summaryRow",void 0),r([o.Input(),i("design:type",Number)],t.prototype,"summaryHeight",void 0),r([o.Input(),i("design:type",String)],t.prototype,"summaryPosition",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"scroll",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"activate",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"select",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"sort",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"page",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"reorder",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"resize",void 0),r([o.Output(),i("design:type",Object)],t.prototype,"tableContextmenu",void 0),r([o.Output(),i("design:type",o.EventEmitter)],t.prototype,"treeAction",void 0),r([o.HostBinding("class.fixed-header"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isFixedHeader",null),r([o.HostBinding("class.fixed-row"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isFixedRow",null),r([o.HostBinding("class.scroll-vertical"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isVertScroll",null),r([o.HostBinding("class.virtualized"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isVirtualized",null),r([o.HostBinding("class.scroll-horz"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isHorScroll",null),r([o.HostBinding("class.selectable"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isSelectable",null),r([o.HostBinding("class.checkbox-selection"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isCheckboxSelection",null),r([o.HostBinding("class.cell-selection"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isCellSelection",null),r([o.HostBinding("class.single-selection"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isSingleSelection",null),r([o.HostBinding("class.multi-selection"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isMultiSelection",null),r([o.HostBinding("class.multi-click-selection"),i("design:type",Boolean),i("design:paramtypes",[])],t.prototype,"isMultiClickSelection",null),r([o.ContentChildren(p.DataTableColumnDirective),i("design:type",o.QueryList),i("design:paramtypes",[o.QueryList])],t.prototype,"columnTemplates",null),r([o.ContentChild(h.DatatableRowDetailDirective),i("design:type",h.DatatableRowDetailDirective)],t.prototype,"rowDetail",void 0),r([o.ContentChild(f.DatatableGroupHeaderDirective),i("design:type",f.DatatableGroupHeaderDirective)],t.prototype,"groupHeader",void 0),r([o.ContentChild(g.DatatableFooterDirective),i("design:type",g.DatatableFooterDirective)],t.prototype,"footer",void 0),r([o.ViewChild(d.DataTableBodyComponent),i("design:type",d.DataTableBodyComponent)],t.prototype,"bodyComponent",void 0),r([o.ViewChild(b.DataTableHeaderComponent),i("design:type",b.DataTableHeaderComponent)],t.prototype,"headerComponent",void 0),r([o.HostListener("window:resize"),u.throttleable(5),i("design:type",Function),i("design:paramtypes",[]),i("design:returntype",void 0)],t.prototype,"onWindowResize",null),r([o.Component({selector:"ngx-datatable",template:'\n \n \n \n \n \n \n \n \n ',changeDetection:o.ChangeDetectionStrategy.OnPush,encapsulation:o.ViewEncapsulation.None,styles:[n("./src/components/datatable.component.scss")],host:{class:"ngx-datatable"}}),s(0,o.SkipSelf()),s(1,o.SkipSelf()),i("design:paramtypes",[c.ScrollbarHelper,c.DimensionsHelper,o.ChangeDetectorRef,o.ElementRef,o.KeyValueDiffers,c.ColumnChangesService])],t)}()},"./src/components/footer/footer-template.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.DataTableFooterTemplateDirective=function(){return a([i.Directive({selector:"[ngx-datatable-footer-template]"}),r("design:paramtypes",[i.TemplateRef])],function(t){this.template=t})}()},"./src/components/footer/footer.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/components/footer/footer.directive.ts");e.DataTableFooterComponent=function(){function t(){this.selectedCount=0,this.page=new i.EventEmitter}return Object.defineProperty(t.prototype,"isVisible",{get:function(){return this.rowCount/this.pageSize>1},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"curPage",{get:function(){return this.offset+1},enumerable:!0,configurable:!0}),a([i.Input(),r("design:type",Number)],t.prototype,"footerHeight",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"rowCount",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"pageSize",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"offset",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerLeftArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerRightArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerPreviousIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerNextIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"totalMessage",void 0),a([i.Input(),r("design:type",s.DatatableFooterDirective)],t.prototype,"footerTemplate",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"selectedCount",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"selectedMessage",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"page",void 0),a([i.Component({selector:"datatable-footer",template:'\n \n \n \n
\n \n {{selectedCount?.toLocaleString()}} {{selectedMessage}} / \n \n {{rowCount?.toLocaleString()}} {{totalMessage}}\n
\n \n \n \n ',host:{class:"datatable-footer"},changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},"./src/components/footer/footer.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/components/footer/footer-template.directive.ts");e.DatatableFooterDirective=function(){function t(){}return a([i.Input(),r("design:type",Number)],t.prototype,"footerHeight",void 0),a([i.Input(),r("design:type",String)],t.prototype,"totalMessage",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"selectedMessage",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerLeftArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerRightArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerPreviousIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerNextIcon",void 0),a([i.Input(),i.ContentChild(s.DataTableFooterTemplateDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"template",void 0),a([i.Directive({selector:"ngx-datatable-footer"})],t)}()},"./src/components/footer/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/components/footer/footer.component.ts")),a(n("./src/components/footer/pager.component.ts")),a(n("./src/components/footer/footer.directive.ts")),a(n("./src/components/footer/footer-template.directive.ts"))},"./src/components/footer/pager.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.DataTablePagerComponent=function(){function t(){this.change=new i.EventEmitter,this._count=0,this._page=1,this._size=0}return Object.defineProperty(t.prototype,"size",{get:function(){return this._size},set:function(t){this._size=t,this.pages=this.calcPages()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"count",{get:function(){return this._count},set:function(t){this._count=t,this.pages=this.calcPages()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"page",{get:function(){return this._page},set:function(t){this._page=t,this.pages=this.calcPages()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"totalPages",{get:function(){var t=this.size<1?1:Math.ceil(this.count/this.size);return Math.max(t||0,1)},enumerable:!0,configurable:!0}),t.prototype.canPrevious=function(){return this.page>1},t.prototype.canNext=function(){return this.page0&&t<=this.totalPages&&t!==this.page&&(this.page=t,this.change.emit({page:t}))},t.prototype.calcPages=function(t){var e=[],n=1,a=this.totalPages;t=t||this.page,5this.totalPages&&(n=Math.max(this.totalPages-5+1,1),a=this.totalPages));for(var r=n;r<=a;r++)e.push({number:r,text:r});return e},a([i.Input(),r("design:type",String)],t.prototype,"pagerLeftArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerRightArrowIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerPreviousIcon",void 0),a([i.Input(),r("design:type",String)],t.prototype,"pagerNextIcon",void 0),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"size",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"count",null),a([i.Input(),r("design:type",Number),r("design:paramtypes",[Number])],t.prototype,"page",null),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"change",void 0),a([i.Component({selector:"datatable-pager",template:'\n
    \n
  • \n \n \n \n
  • \n
  • \n \n \n \n
  • \n \n \n {{pg.text}}\n \n \n
  • \n \n \n \n
  • \n
  • \n \n \n \n
  • \n
\n ',host:{class:"datatable-pager"},changeDetection:i.ChangeDetectionStrategy.OnPush})],t)}()},"./src/components/header/header-cell.component.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/types/index.ts"),o=n("./src/utils/index.ts");n("./src/events.ts"),e.DataTableHeaderCellComponent=function(){function t(t){this.cd=t,this.sort=new i.EventEmitter,this.select=new i.EventEmitter,this.columnContextmenu=new i.EventEmitter(!1),this.sortFn=this.onSort.bind(this),this.selectFn=this.select.emit.bind(this.select),this.cellContext={column:this.column,sortDir:this.sortDir,sortFn:this.sortFn,allRowsSelected:this.allRowsSelected,selectFn:this.selectFn}}return Object.defineProperty(t.prototype,"allRowsSelected",{get:function(){return this._allRowsSelected},set:function(t){this._allRowsSelected=t,this.cellContext.allRowsSelected=t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"column",{get:function(){return this._column},set:function(t){this._column=t,this.cellContext.column=t,this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"sorts",{get:function(){return this._sorts},set:function(t){this._sorts=t,this.sortDir=this.calcSortDir(t),this.cellContext.sortDir=this.sortDir,this.sortClass=this.calcSortClass(this.sortDir),this.cd.markForCheck()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columnCssClasses",{get:function(){var t="datatable-header-cell";if(this.column.sortable&&(t+=" sortable"),this.column.resizeable&&(t+=" resizeable"),this.column.headerClass)if("string"==typeof this.column.headerClass)t+=" "+this.column.headerClass;else if("function"==typeof this.column.headerClass){var e=this.column.headerClass({column:this.column});if("string"==typeof e)t+=e;else if("object"==typeof e)for(var n=0,a=Object.keys(e);n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',host:{class:"datatable-header-cell"},changeDetection:i.ChangeDetectionStrategy.OnPush}),r("design:paramtypes",[i.ChangeDetectorRef])],t)}()},"./src/components/header/header.component.ts":function(t,e,n){"use strict";var a=this&&this.__assign||function(){return(a=Object.assign||function(t){for(var e,n=1,a=arguments.length;n=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},i=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var s=n("@angular/core"),o=n("./src/types/index.ts"),u=n("./src/utils/index.ts");e.DataTableHeaderComponent=function(){function t(t){this.cd=t,this.sort=new s.EventEmitter,this.reorder=new s.EventEmitter,this.resize=new s.EventEmitter,this.select=new s.EventEmitter,this.columnContextmenu=new s.EventEmitter(!1),this._styleByGroup={left:{},center:{},right:{}}}return Object.defineProperty(t.prototype,"innerWidth",{get:function(){return this._innerWidth},set:function(t){if(this._innerWidth=t,this._columns){var e=u.columnsByPin(this._columns);this._columnGroupWidths=u.columnGroupWidths(e,this._columns),this.setStylesByGroup()}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"headerHeight",{get:function(){return this._headerHeight},set:function(t){this._headerHeight="auto"!==t?t+"px":t},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"columns",{get:function(){return this._columns},set:function(t){this._columns=t;var e=u.columnsByPin(t);this._columnsByPin=u.columnsByPinArr(t),this._columnGroupWidths=u.columnGroupWidths(e,t),this.setStylesByGroup()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"offsetX",{get:function(){return this._offsetX},set:function(t){this._offsetX=t,this.setStylesByGroup()},enumerable:!0,configurable:!0}),t.prototype.onLongPressStart=function(t){var e=t.event;t.model.dragging=!0,this.dragEventTarget=e},t.prototype.onLongPressEnd=function(t){var e=this,n=t.model;this.dragEventTarget=t.event,setTimeout(function(){var t=e._columns.find(function(t){return t.$$id===n.$$id});t&&(t.dragging=!1)},5)},Object.defineProperty(t.prototype,"headerWidth",{get:function(){return this.scrollbarH?this.innerWidth+"px":"100%"},enumerable:!0,configurable:!0}),t.prototype.trackByGroups=function(t,e){return e.type},t.prototype.columnTrackingFn=function(t,e){return e.$$id},t.prototype.onColumnResized=function(t,e){t<=e.minWidth?t=e.minWidth:t>=e.maxWidth&&(t=e.maxWidth),this.resize.emit({column:e,prevValue:e.width,newValue:t})},t.prototype.onColumnReordered=function(t){var e=t.prevIndex,n=t.newIndex,a=t.model,r=this.getColumn(n);r.isTarget=!1,r.targetMarkerContext=void 0,this.reorder.emit({column:a,prevValue:e,newValue:n})},t.prototype.onTargetChanged=function(t){var e=t.prevIndex,n=t.newIndex,a=t.initialIndex;if(e||0===e){var r=this.getColumn(e);r.isTarget=!1,r.targetMarkerContext=void 0}if(n||0===n){var i=this.getColumn(n);i.isTarget=!0,a!==n&&(i.targetMarkerContext={class:"targetMarker ".concat(a>n?"dragFromRight":"dragFromLeft")})}},t.prototype.getColumn=function(t){var e=this._columnsByPin[0].columns.length;if(t\n \n \n \n \n \n ',host:{class:"datatable-header"},changeDetection:s.ChangeDetectionStrategy.OnPush}),i("design:paramtypes",[s.ChangeDetectorRef])],t)}()},"./src/components/header/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/components/header/header.component.ts")),a(n("./src/components/header/header-cell.component.ts"))},"./src/components/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/components/datatable.component.ts")),a(n("./src/components/header/index.ts")),a(n("./src/components/body/index.ts")),a(n("./src/components/footer/index.ts")),a(n("./src/components/columns/index.ts")),a(n("./src/components/row-detail/index.ts"))},"./src/components/row-detail/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/components/row-detail/row-detail.directive.ts")),a(n("./src/components/row-detail/row-detail-template.directive.ts"))},"./src/components/row-detail/row-detail-template.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.DatatableRowDetailTemplateDirective=function(){return a([i.Directive({selector:"[ngx-datatable-row-detail-template]"}),r("design:paramtypes",[i.TemplateRef])],function(t){this.template=t})}()},"./src/components/row-detail/row-detail.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("./src/components/row-detail/row-detail-template.directive.ts");e.DatatableRowDetailDirective=function(){function t(){this.rowHeight=0,this.toggle=new i.EventEmitter}return t.prototype.toggleExpandRow=function(t){this.toggle.emit({type:"row",value:t})},t.prototype.expandAllRows=function(){this.toggle.emit({type:"all",value:!0})},t.prototype.collapseAllRows=function(){this.toggle.emit({type:"all",value:!1})},a([i.Input(),r("design:type",Object)],t.prototype,"rowHeight",void 0),a([i.Input(),i.ContentChild(s.DatatableRowDetailTemplateDirective,{read:i.TemplateRef}),r("design:type",i.TemplateRef)],t.prototype,"template",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"toggle",void 0),a([i.Directive({selector:"ngx-datatable-row-detail"})],t)}()},"./src/datatable.module.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s};Object.defineProperty(e,"__esModule",{value:!0});var r=n("@angular/core"),i=n("@angular/common"),s=n("./src/components/index.ts"),o=n("./src/directives/index.ts"),u=n("./src/services/index.ts");e.NgxDatatableModule=function(){return a([r.NgModule({imports:[i.CommonModule],providers:[u.ScrollbarHelper,u.DimensionsHelper,u.ColumnChangesService],declarations:[s.DataTableFooterTemplateDirective,o.VisibilityDirective,o.DraggableDirective,o.ResizeableDirective,o.OrderableDirective,o.LongPressDirective,s.ScrollerComponent,s.DatatableComponent,s.DataTableColumnDirective,s.DataTableHeaderComponent,s.DataTableHeaderCellComponent,s.DataTableBodyComponent,s.DataTableFooterComponent,s.DataTablePagerComponent,s.ProgressBarComponent,s.DataTableBodyRowComponent,s.DataTableRowWrapperComponent,s.DatatableRowDetailDirective,s.DatatableGroupHeaderDirective,s.DatatableRowDetailTemplateDirective,s.DataTableBodyCellComponent,s.DataTableSelectionComponent,s.DataTableColumnHeaderDirective,s.DataTableColumnCellDirective,s.DataTableColumnCellTreeToggle,s.DatatableFooterDirective,s.DatatableGroupHeaderTemplateDirective,s.DataTableSummaryRowComponent],exports:[s.DatatableComponent,s.DatatableRowDetailDirective,s.DatatableGroupHeaderDirective,s.DatatableRowDetailTemplateDirective,s.DataTableColumnDirective,s.DataTableColumnHeaderDirective,s.DataTableColumnCellDirective,s.DataTableColumnCellTreeToggle,s.DataTableFooterTemplateDirective,s.DatatableFooterDirective,s.DataTablePagerComponent,s.DatatableGroupHeaderTemplateDirective]})],function(){})}()},"./src/directives/draggable.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("rxjs"),o=n("rxjs/operators");e.DraggableDirective=function(){function t(t){this.dragX=!0,this.dragY=!0,this.dragStart=new i.EventEmitter,this.dragging=new i.EventEmitter,this.dragEnd=new i.EventEmitter,this.isDragging=!1,this.element=t.nativeElement}return t.prototype.ngOnChanges=function(t){t.dragEventTarget&&t.dragEventTarget.currentValue&&this.dragModel.dragging&&this.onMousedown(t.dragEventTarget.currentValue)},t.prototype.ngOnDestroy=function(){this._destroySubscription()},t.prototype.onMouseup=function(t){this.isDragging&&(this.isDragging=!1,this.element.classList.remove("dragging"),this.subscription&&(this._destroySubscription(),this.dragEnd.emit({event:t,element:this.element,model:this.dragModel})))},t.prototype.onMousedown=function(t){var e=this;if(t.target.classList.contains("draggable")&&(this.dragX||this.dragY)){t.preventDefault(),this.isDragging=!0;var n={x:t.clientX,y:t.clientY},a=s.fromEvent(document,"mouseup");this.subscription=a.subscribe(function(t){return e.onMouseup(t)});var r=s.fromEvent(document,"mousemove").pipe(o.takeUntil(a)).subscribe(function(t){return e.move(t,n)});this.subscription.add(r),this.dragStart.emit({event:t,element:this.element,model:this.dragModel})}},t.prototype.move=function(t,e){if(this.isDragging){var n=t.clientY-e.y;this.dragX&&(this.element.style.left=t.clientX-e.x+"px"),this.dragY&&(this.element.style.top=n+"px"),this.element.classList.add("dragging"),this.dragging.emit({event:t,element:this.element,model:this.dragModel})}},t.prototype._destroySubscription=function(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)},a([i.Input(),r("design:type",Object)],t.prototype,"dragEventTarget",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"dragModel",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"dragX",void 0),a([i.Input(),r("design:type",Boolean)],t.prototype,"dragY",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"dragStart",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"dragging",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"dragEnd",void 0),a([i.Directive({selector:"[draggable]"}),r("design:paramtypes",[i.ElementRef])],t)}()},"./src/directives/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/directives/draggable.directive.ts")),a(n("./src/directives/long-press.directive.ts")),a(n("./src/directives/orderable.directive.ts")),a(n("./src/directives/resizeable.directive.ts")),a(n("./src/directives/visibility.directive.ts"))},"./src/directives/long-press.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("rxjs"),o=n("rxjs/operators");n("./src/events.ts"),e.LongPressDirective=function(){function t(){this.pressEnabled=!0,this.duration=500,this.longPressStart=new i.EventEmitter,this.longPressing=new i.EventEmitter,this.longPressEnd=new i.EventEmitter,this.mouseX=0,this.mouseY=0}return Object.defineProperty(t.prototype,"press",{get:function(){return this.pressing},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isLongPress",{get:function(){return this.isLongPressing},enumerable:!0,configurable:!0}),t.prototype.onMouseDown=function(t){var e=this;if(1===t.which&&this.pressEnabled&&!t.target.classList.contains("resize-handle")){this.mouseX=t.clientX,this.mouseY=t.clientY,this.pressing=!0,this.isLongPressing=!1;var n=s.fromEvent(document,"mouseup");this.subscription=n.subscribe(function(t){return e.onMouseup()}),this.timeout=setTimeout(function(){e.isLongPressing=!0,e.longPressStart.emit({event:t,model:e.pressModel}),e.subscription.add(s.fromEvent(document,"mousemove").pipe(o.takeUntil(n)).subscribe(function(t){return e.onMouseMove(t)})),e.loop(t)},this.duration),this.loop(t)}},t.prototype.onMouseMove=function(t){if(this.pressing&&!this.isLongPressing){var e=Math.abs(t.clientX-this.mouseX)>10,n=Math.abs(t.clientY-this.mouseY)>10;(e||n)&&this.endPress()}},t.prototype.loop=function(t){var e=this;this.isLongPressing&&(this.timeout=setTimeout(function(){e.longPressing.emit({event:t,model:e.pressModel}),e.loop(t)},50))},t.prototype.endPress=function(){clearTimeout(this.timeout),this.isLongPressing=!1,this.pressing=!1,this._destroySubscription(),this.longPressEnd.emit({model:this.pressModel})},t.prototype.onMouseup=function(){this.endPress()},t.prototype.ngOnDestroy=function(){this._destroySubscription()},t.prototype._destroySubscription=function(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)},a([i.Input(),r("design:type",Boolean)],t.prototype,"pressEnabled",void 0),a([i.Input(),r("design:type",Object)],t.prototype,"pressModel",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"duration",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"longPressStart",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"longPressing",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"longPressEnd",void 0),a([i.HostBinding("class.press"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"press",null),a([i.HostBinding("class.longpress"),r("design:type",Boolean),r("design:paramtypes",[])],t.prototype,"isLongPress",null),a([i.HostListener("mousedown",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onMouseDown",null),a([i.Directive({selector:"[long-press]"})],t)}()},"./src/directives/orderable.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)},i=this&&this.__param||function(t,e){return function(n,a){e(n,a,t)}};Object.defineProperty(e,"__esModule",{value:!0});var s=n("@angular/core"),o=n("./src/directives/draggable.directive.ts"),u=n("@angular/platform-browser");e.OrderableDirective=function(){function t(t,e){this.document=e,this.reorder=new s.EventEmitter,this.targetChanged=new s.EventEmitter,this.differ=t.find({}).create()}return t.prototype.ngAfterContentInit=function(){this.updateSubscriptions(),this.draggables.changes.subscribe(this.updateSubscriptions.bind(this))},t.prototype.ngOnDestroy=function(){this.draggables.forEach(function(t){t.dragStart.unsubscribe(),t.dragging.unsubscribe(),t.dragEnd.unsubscribe()})},t.prototype.updateSubscriptions=function(){var t=this,e=this.differ.diff(this.createMapDiffs());if(e){var n=function(t){var e=t.previousValue;e&&(e.dragStart.unsubscribe(),e.dragging.unsubscribe(),e.dragEnd.unsubscribe())};e.forEachAddedItem((function(e){var a=e.currentValue;n({previousValue:e.previousValue}),a&&(a.dragStart.subscribe(t.onDragStart.bind(t)),a.dragging.subscribe(t.onDragging.bind(t)),a.dragEnd.subscribe(t.onDragEnd.bind(t)))}).bind(this)),e.forEachRemovedItem(n.bind(this))}},t.prototype.onDragStart=function(){this.positions={};for(var t=0,e=0,n=this.draggables.toArray();e=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core"),s=n("rxjs"),o=(n("./src/events.ts"),n("rxjs/operators"));e.ResizeableDirective=function(){function t(t,e){this.renderer=e,this.resizeEnabled=!0,this.resize=new i.EventEmitter,this.resizing=!1,this.element=t.nativeElement}return t.prototype.ngAfterViewInit=function(){var t=this.renderer,e=t.createElement("span");t.addClass(e,this.resizeEnabled?"resize-handle":"resize-handle--not-resizable"),t.appendChild(this.element,e)},t.prototype.ngOnDestroy=function(){this._destroySubscription()},t.prototype.onMouseup=function(){this.resizing=!1,this.subscription&&!this.subscription.closed&&(this._destroySubscription(),this.resize.emit(this.element.clientWidth))},t.prototype.onMousedown=function(t){var e=this,n=t.target.classList.contains("resize-handle"),a=this.element.clientWidth,r=t.screenX;if(n){t.stopPropagation(),this.resizing=!0;var i=s.fromEvent(document,"mouseup");this.subscription=i.subscribe(function(t){return e.onMouseup()});var u=s.fromEvent(document,"mousemove").pipe(o.takeUntil(i)).subscribe(function(t){return e.move(t,a,r)});this.subscription.add(u)}},t.prototype.move=function(t,e,n){var a=e+(t.screenX-n);(!this.minWidth||a>=this.minWidth)&&(!this.maxWidth||a<=this.maxWidth)&&(this.element.style.width=a+"px")},t.prototype._destroySubscription=function(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=void 0)},a([i.Input(),r("design:type",Boolean)],t.prototype,"resizeEnabled",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"minWidth",void 0),a([i.Input(),r("design:type",Number)],t.prototype,"maxWidth",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"resize",void 0),a([i.HostListener("mousedown",["$event"]),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",void 0)],t.prototype,"onMousedown",null),a([i.Directive({selector:"[resizeable]",host:{"[class.resizeable]":"resizeEnabled"}}),r("design:paramtypes",[i.ElementRef,i.Renderer2])],t)}()},"./src/directives/visibility.directive.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(e,"__esModule",{value:!0});var i=n("@angular/core");e.VisibilityDirective=function(){function t(t,e){this.element=t,this.zone=e,this.isVisible=!1,this.visible=new i.EventEmitter}return t.prototype.ngOnInit=function(){this.runCheck()},t.prototype.ngOnDestroy=function(){clearTimeout(this.timeout)},t.prototype.onVisibilityChange=function(){var t=this;this.zone.run(function(){t.isVisible=!0,t.visible.emit(!0)})},t.prototype.runCheck=function(){var t=this,e=function(){var n=t.element.nativeElement;n.offsetHeight&&n.offsetWidth?(clearTimeout(t.timeout),t.onVisibilityChange()):(clearTimeout(t.timeout),t.zone.runOutsideAngular(function(){t.timeout=setTimeout(function(){return e()},50)}))};this.timeout=setTimeout(function(){return e()})},a([i.HostBinding("class.visible"),r("design:type",Boolean)],t.prototype,"isVisible",void 0),a([i.Output(),r("design:type",i.EventEmitter)],t.prototype,"visible",void 0),a([i.Directive({selector:"[visibilityObserver]"}),r("design:paramtypes",[i.ElementRef,i.NgZone])],t)}()},"./src/events.ts":function(t,e,n){"use strict";(function(t){Object.defineProperty(e,"__esModule",{value:!0}),e.MouseEvent=("undefined"!=typeof window&&window||t).MouseEvent,e.KeyboardEvent=("undefined"!=typeof window&&window||t).KeyboardEvent,e.Event=("undefined"!=typeof window&&window||t).Event}).call(e,n("./node_modules/webpack/buildin/global.js"))},"./src/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/datatable.module.ts")),a(n("./src/types/index.ts")),a(n("./src/components/index.ts")),a(n("./src/services/index.ts"))},"./src/services/column-changes.service.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s};Object.defineProperty(e,"__esModule",{value:!0});var r=n("@angular/core"),i=n("rxjs");e.ColumnChangesService=function(){function t(){this.columnInputChanges=new i.Subject}return Object.defineProperty(t.prototype,"columnInputChanges$",{get:function(){return this.columnInputChanges.asObservable()},enumerable:!0,configurable:!0}),t.prototype.onInputChange=function(){this.columnInputChanges.next()},a([r.Injectable()],t)}()},"./src/services/dimensions-helper.service.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s};Object.defineProperty(e,"__esModule",{value:!0});var r=n("@angular/core");e.DimensionsHelper=function(){function t(){}return t.prototype.getDimensions=function(t){return t.getBoundingClientRect()},a([r.Injectable()],t)}()},"./src/services/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/services/scrollbar-helper.service.ts")),a(n("./src/services/dimensions-helper.service.ts")),a(n("./src/services/column-changes.service.ts"))},"./src/services/scrollbar-helper.service.ts":function(t,e,n){"use strict";var a=this&&this.__decorate||function(t,e,n,a){var r,i=arguments.length,s=i<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,n):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,a);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(s=(i<3?r(s):i>3?r(e,n,s):r(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s},r=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)},i=this&&this.__param||function(t,e){return function(n,a){e(n,a,t)}};Object.defineProperty(e,"__esModule",{value:!0});var s=n("@angular/core"),o=n("@angular/platform-browser");e.ScrollbarHelper=function(){function t(t){this.document=t,this.width=this.getWidth()}return t.prototype.getWidth=function(){var t=this.document.createElement("div");t.style.visibility="hidden",t.style.width="100px",t.style.msOverflowStyle="scrollbar",this.document.body.appendChild(t);var e=t.offsetWidth;t.style.overflow="scroll";var n=this.document.createElement("div");n.style.width="100%",t.appendChild(n);var a=n.offsetWidth;return t.parentNode.removeChild(t),e-a},a([s.Injectable(),i(0,s.Inject(o.DOCUMENT)),r("design:paramtypes",[Object])],t)}()},"./src/types/click.type.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.single="single",t.double="double"}(e.ClickType||(e.ClickType={}))},"./src/types/column-mode.type.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.standard="standard",t.flex="flex",t.force="force"}(e.ColumnMode||(e.ColumnMode={}))},"./src/types/contextmenu.type.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.header="header",t.body="body"}(e.ContextmenuType||(e.ContextmenuType={}))},"./src/types/index.ts":function(t,e,n){"use strict";function a(t){for(var n in t)e.hasOwnProperty(n)||(e[n]=t[n])}Object.defineProperty(e,"__esModule",{value:!0}),a(n("./src/types/column-mode.type.ts")),a(n("./src/types/sort.type.ts")),a(n("./src/types/sort-direction.type.ts")),a(n("./src/types/selection.type.ts")),a(n("./src/types/click.type.ts")),a(n("./src/types/contextmenu.type.ts"))},"./src/types/selection.type.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.single="single",t.multi="multi",t.multiClick="multiClick",t.cell="cell",t.checkbox="checkbox"}(e.SelectionType||(e.SelectionType={}))},"./src/types/sort-direction.type.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.asc="asc",t.desc="desc"}(e.SortDirection||(e.SortDirection={}))},"./src/types/sort.type.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.single="single",t.multi="multi"}(e.SortType||(e.SortType={}))},"./src/utils/camel-case.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.camelCase=function(t){return(t=(t=(t=t.replace(/[^a-zA-Z0-9 ]/g," ")).replace(/([a-z](?=[A-Z]))/g,"$1 ")).replace(/([^a-zA-Z0-9 ])|^[0-9]+/g,"").trim().toLowerCase()).replace(/([ 0-9]+)([a-zA-Z])/g,function(t,e,n){return e.trim()+n.toUpperCase()})},e.deCamelCase=function(t){return t.replace(/([A-Z])/g,function(t){return" "+t}).replace(/^./,function(t){return t.toUpperCase()})}},"./src/utils/column-helper.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("./src/utils/camel-case.ts"),r=n("./src/utils/id.ts"),i=n("./src/utils/column-prop-getters.ts");function s(t){return null==t}e.setColumnDefaults=function(t){if(t)for(var e=!1,n=0,o=t;n=e;for(var g=0,b=o;gm.maxWidth?(m.width=m.maxWidth,h.push(m)):m.width=y}m.width=Math.max(0,m.width)}p=e-(f=s(t)),i(o,h)}while(p>0&&0!==o.length)}},"./src/utils/prefixes.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a,r,i,s,o=n("./src/utils/camel-case.ts"),u={},c="undefined"!=typeof document?document.createElement("div").style:void 0,l=(s=void 0!==(i=null!==(r=void 0!==(a="undefined"!=typeof window?window.getComputedStyle(document.documentElement,""):void 0)?Array.prototype.slice.call(a).join("").match(/-(moz|webkit|ms)-/):null)?r[1]:void 0)?"WebKit|Moz|MS|O".match(new RegExp("("+i+")","i"))[1]:void 0)?{dom:s,lowercase:i,css:"-"+i+"-",js:i[0].toUpperCase()+i.substr(1)}:void 0;e.getVendorPrefixedName=function(t){var e=o.camelCase(t);return u[e]||(void 0!==l&&void 0!==c[l.css+t]?u[e]=l.css+t:void 0!==c[t]&&(u[e]=t)),u[e]}},"./src/utils/row-height-cache.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.RowHeightCache=function(){function t(){this.treeArray=[]}return t.prototype.clearCache=function(){this.treeArray=[]},t.prototype.initCache=function(t){var e=t.rows,n=t.rowHeight,a=t.detailRowHeight,r=t.externalVirtual,i=t.rowCount,s=t.rowIndexes,o=t.rowExpansions,u="function"==typeof n,c="function"==typeof a;if(!u&&isNaN(n))throw new Error("Row Height cache initialization failed. Please ensure that 'rowHeight' is a\n valid number or function value: ("+n+") when 'scrollbarV' is enabled.");if(!c&&isNaN(a))throw new Error("Row Height cache initialization failed. Please ensure that 'detailRowHeight' is a\n valid number or function value: ("+a+") when 'scrollbarV' is enabled.");var l=r?i:e.length;this.treeArray=new Array(l);for(var d=0;d=0;)e+=this.treeArray[t],t=(t&t+1)-1;return e},t.prototype.queryBetween=function(t,e){return this.query(e)-this.query(t-1)},t.prototype.calcRowIndex=function(t){if(!this.treeArray.length)return 0;for(var e=-1,n=this.treeArray.length,a=Math.pow(2,n.toString(2).length-1);0!==a;a>>=1){var r=e+a;r=this.treeArray[r]&&(t-=this.treeArray[r],e=r)}return e+1},t}()},"./src/utils/selection.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.selectRows=function(t,e,n){var a=n(e,t);return a>-1?t.splice(a,1):t.push(e),t},e.selectRowsBetween=function(t,e,n,a,r){for(var i=n=n||!i&&s>=a&&s<=n)&&s>=o.start&&s<=o.end&&t.push(e[s])}return t}},"./src/utils/sort.ts":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n("./src/types/index.ts"),r=n("./src/utils/column-prop-getters.ts");function i(t,e){if(null==t&&(t=0),null==e&&(e=0),t instanceof Date&&e instanceof Date){if(te)return 1}else if(isNaN(parseFloat(t))||!isFinite(t)||isNaN(parseFloat(e))||!isFinite(e)){if(t=String(t),e=String(e),t.toLowerCase()e.toLowerCase())return 1}else{if(parseFloat(t)parseFloat(e))return 1}return 0}e.nextSortDir=function(t,e){return t===a.SortType.single?e===a.SortDirection.asc?a.SortDirection.desc:a.SortDirection.asc:e?e===a.SortDirection.asc?a.SortDirection.desc:void 0:a.SortDirection.asc},e.orderByComparator=i,e.sortRows=function(t,e,n){if(!t)return[];if(!n||!n.length||!e)return t.slice();var s=new Map;t.forEach(function(t,e){return s.set(t,e)});var o=t.slice(),u=e.reduce(function(t,e){return e.comparator&&"function"==typeof e.comparator&&(t[e.prop]=e.comparator),t},{}),c=n.map(function(t){var e=t.prop;return{prop:e,dir:t.dir,valueGetter:r.getterForProp(e),compareFn:u[e]||i}});return o.sort(function(t,e){for(var n=0,r=c;n-1&&(c=l),s.parent=a[c],s.row.level=s.parent.row.level+1,s.parent.children.push(s)}var d=[];return a[0].flatten(function(){d=d.concat([this.row])},!0),d}return t};var r=function(){function t(t){void 0===t&&(t=null),t||(t={level:-1,treeStatus:"expanded"}),this.row=t,this.parent=null,this.children=[]}return t.prototype.flatten=function(t,e){if("expanded"===this.row.treeStatus)for(var n=0,a=this.children.length;n1)this.connection=null;else{var n=this.connection,a=t._connection;this.connection=null,!a||n&&a!==n||a.unsubscribe()}}else this.connection=null},e}(r.a)},yJti:function(t,e,n){"use strict";n.d(e,"a",function(){return a});var a=function(t){return t[t.ValueOk=0]="ValueOk",t[t.ValueStale=1]="ValueStale",t[t.ValueNone=2]="ValueNone",t[t.ValueException=3]="ValueException",t}({})},yPMN:function(t,e,n){"use strict";n("CDJp")._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),t.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},yPMs:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("sq",{months:"Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_N\xebntor_Dhjetor".split("_"),monthsShort:"Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_N\xebn_Dhj".split("_"),weekdays:"E Diel_E H\xebn\xeb_E Mart\xeb_E M\xebrkur\xeb_E Enjte_E Premte_E Shtun\xeb".split("_"),weekdaysShort:"Die_H\xebn_Mar_M\xebr_Enj_Pre_Sht".split("_"),weekdaysMin:"D_H_Ma_M\xeb_E_P_Sh".split("_"),weekdaysParseExact:!0,meridiemParse:/PD|MD/,isPM:function(t){return"M"===t.charAt(0)},meridiem:function(t,e,n){return t<12?"PD":"MD"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Sot n\xeb] LT",nextDay:"[Nes\xebr n\xeb] LT",nextWeek:"dddd [n\xeb] LT",lastDay:"[Dje n\xeb] LT",lastWeek:"dddd [e kaluar n\xeb] LT",sameElse:"L"},relativeTime:{future:"n\xeb %s",past:"%s m\xeb par\xeb",s:"disa sekonda",ss:"%d sekonda",m:"nj\xeb minut\xeb",mm:"%d minuta",h:"nj\xeb or\xeb",hh:"%d or\xeb",d:"nj\xeb dit\xeb",dd:"%d dit\xeb",M:"nj\xeb muaj",MM:"%d muaj",y:"nj\xeb vit",yy:"%d vite"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},ylLw:function(t,e,n){var a=n("mrSG").__decorate,r=n("mrSG").__metadata;Object.defineProperty(e,"__esModule",{value:!0});var i=n("CcnG"),s=n("3MdB");n("ZYjt"),e.OrderableDirective=function(){function t(t,e){this.document=e,this.reorder=new i.EventEmitter,this.targetChanged=new i.EventEmitter,this.differ=t.find({}).create()}return t.prototype.ngAfterContentInit=function(){this.updateSubscriptions(),this.draggables.changes.subscribe(this.updateSubscriptions.bind(this))},t.prototype.ngOnDestroy=function(){this.draggables.forEach(function(t){t.dragStart.unsubscribe(),t.dragging.unsubscribe(),t.dragEnd.unsubscribe()})},t.prototype.updateSubscriptions=function(){var t=this,e=this.differ.diff(this.createMapDiffs());if(e){var n=function(t){var e=t.previousValue;e&&(e.dragStart.unsubscribe(),e.dragging.unsubscribe(),e.dragEnd.unsubscribe())};e.forEachAddedItem((function(e){var a=e.currentValue;n({previousValue:e.previousValue}),a&&(a.dragStart.subscribe(t.onDragStart.bind(t)),a.dragging.subscribe(t.onDragging.bind(t)),a.dragEnd.subscribe(t.onDragEnd.bind(t)))}).bind(this)),e.forEachRemovedItem(n.bind(this))}},t.prototype.onDragStart=function(){this.positions={};for(var t=0,e=0,n=this.draggables.toArray();e11?n?"d'o":"D'O":n?"d'a":"D'A"},calendar:{sameDay:"[oxhi \xe0] LT",nextDay:"[dem\xe0 \xe0] LT",nextWeek:"dddd [\xe0] LT",lastDay:"[ieiri \xe0] LT",lastWeek:"[s\xfcr el] dddd [lasteu \xe0] LT",sameElse:"L"},relativeTime:{future:"osprei %s",past:"ja%s",s:e,ss:e,m:e,mm:e,h:e,hh:e,d:e,dd:e,M:e,MM:e,y:e,yy:e},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}()},z3Vd:function(t,e,n){!function(t){"use strict";var e="pagh_wa\u2019_cha\u2019_wej_loS_vagh_jav_Soch_chorgh_Hut".split("_");function n(t,n,a,r){var i=function(t){var n=Math.floor(t%1e3/100),a=Math.floor(t%100/10),r=t%10,i="";return n>0&&(i+=e[n]+"vatlh"),a>0&&(i+=(""!==i?" ":"")+e[a]+"maH"),r>0&&(i+=(""!==i?" ":"")+e[r]),""===i?"pagh":i}(t);switch(a){case"ss":return i+" lup";case"mm":return i+" tup";case"hh":return i+" rep";case"dd":return i+" jaj";case"MM":return i+" jar";case"yy":return i+" DIS"}}t.defineLocale("tlh",{months:"tera\u2019 jar wa\u2019_tera\u2019 jar cha\u2019_tera\u2019 jar wej_tera\u2019 jar loS_tera\u2019 jar vagh_tera\u2019 jar jav_tera\u2019 jar Soch_tera\u2019 jar chorgh_tera\u2019 jar Hut_tera\u2019 jar wa\u2019maH_tera\u2019 jar wa\u2019maH wa\u2019_tera\u2019 jar wa\u2019maH cha\u2019".split("_"),monthsShort:"jar wa\u2019_jar cha\u2019_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa\u2019maH_jar wa\u2019maH wa\u2019_jar wa\u2019maH cha\u2019".split("_"),monthsParseExact:!0,weekdays:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysShort:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysMin:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[DaHjaj] LT",nextDay:"[wa\u2019leS] LT",nextWeek:"LLL",lastDay:"[wa\u2019Hu\u2019] LT",lastWeek:"LLL",sameElse:"L"},relativeTime:{future:function(t){var e=t;return-1!==t.indexOf("jaj")?e.slice(0,-3)+"leS":-1!==t.indexOf("jar")?e.slice(0,-3)+"waQ":-1!==t.indexOf("DIS")?e.slice(0,-3)+"nem":e+" pIq"},past:function(t){var e=t;return-1!==t.indexOf("jaj")?e.slice(0,-3)+"Hu\u2019":-1!==t.indexOf("jar")?e.slice(0,-3)+"wen":-1!==t.indexOf("DIS")?e.slice(0,-3)+"ben":e+" ret"},s:"puS lup",ss:n,m:"wa\u2019 tup",mm:n,h:"wa\u2019 rep",hh:n,d:"wa\u2019 jaj",dd:n,M:"wa\u2019 jar",MM:n,y:"wa\u2019 DIS",yy:n},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n("wd/R"))},z5nN:function(t,e,n){"use strict";n.d(e,"b",function(){return u}),n.d(e,"a",function(){return f});var a=n("CcnG"),r=n("DQlY"),i=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function s(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,2,"div",[["role","document"]],[[8,"className",0]],null,null,null,null)),(t()(),a["\u0275eld"](1,0,null,null,1,"div",[["class","modal-content"]],null,null,null,null,null)),a["\u0275ncd"](null,0)],null,function(t,e){var n=e.component;t(e,0,0,"modal-dialog"+(n.config.class?" "+n.config.class:""))})}function o(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"modal-container",[["class","modal"],["role","dialog"],["tabindex","-1"]],[[1,"aria-modal",0]],[[null,"click"],["window","keydown.esc"]],function(t,e,n){var r=!0;return"click"===e&&(r=!1!==a["\u0275nov"](t,1).onClick(n)&&r),"window:keydown.esc"===e&&(r=!1!==a["\u0275nov"](t,1).onEsc(n)&&r),r},s,i)),a["\u0275did"](1,245760,null,0,r.d,[r.f,a.ElementRef,a.Renderer2],null,null)],function(t,e){t(e,1,0)},function(t,e){t(e,0,0,!0)})}var u=a["\u0275ccf"]("modal-container",r.d,o,{},{},["*"]),c=a["\u0275crt"]({encapsulation:2,styles:[],data:{}});function l(t){return a["\u0275vid"](0,[],null,null)}function d(t){return a["\u0275vid"](0,[(t()(),a["\u0275eld"](0,0,null,null,1,"bs-modal-backdrop",[["class","modal-backdrop"]],null,null,null,l,c)),a["\u0275did"](1,114688,null,0,r.c,[a.ElementRef,a.Renderer2],null,null)],function(t,e){t(e,1,0)},null)}var f=a["\u0275ccf"]("bs-modal-backdrop",r.c,d,{},{},[])},zAZS:function(t,e,n){"use strict";n.d(e,"a",function(){return i});var a=n("mrSG"),r=n("FFOo");function i(t,e){return function(n){return n.lift(new s(t,e,n))}}var s=function(){function t(t,e,n){this.predicate=t,this.thisArg=e,this.source=n}return t.prototype.call=function(t,e){return e.subscribe(new o(t,this.predicate,this.thisArg,this.source))},t}(),o=function(t){function e(e,n,a,r){var i=t.call(this,e)||this;return i.predicate=n,i.thisArg=a,i.source=r,i.index=0,i.thisArg=a||i,i}return a.__extends(e,t),e.prototype.notifyComplete=function(t){this.destination.next(t),this.destination.complete()},e.prototype._next=function(t){var e=!1;try{e=this.predicate.call(this.thisArg,t,this.index++,this.source)}catch(n){return void this.destination.error(n)}e||this.notifyComplete(!1)},e.prototype._complete=function(){this.notifyComplete(!0)},e}(r.a)},zQHH:function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("15JJ");function r(t,e){return e?Object(a.a)(function(){return t},e):Object(a.a)(function(){return t})}},zUnb:function(t,e,n){"use strict";n.r(e);var a=n("tAZD"),r=n.n(a),i=n("Ip0R"),s=n("CcnG"),o=function(t){t=t||"en-US";try{return n("vOVK")("./messages."+t+".xlf")}catch(e){return[]}},u=function(){return function(){}}(),c=n("eajB"),l=n("aexS"),d=function(){return Object.assign(new c.a,{container:"body"})},f=function(){function t(t,e){this.authStorageService=t,this.router=e,this.title="cd"}return t.prototype.isLoginActive=function(){return"/login"===this.router.url||!this.authStorageService.isLoggedIn()},t.prototype.isDashboardPage=function(){return"/dashboard"===this.router.url},t}(),p=n("mrSG"),h=n("S5bw"),g=function(){function t(){}return t.START="start",t.STOP="stop",t.UPDATE="update",t.RESET="reset",t.UNSUBSCRIBE="unsubscribe",t}(),b="block-ui-main",m=function(){function t(){this.blockUISettings={},this.blockUIInstances={},this.blockUISubject=new h.a,this.blockUIObservable=this.blockUISubject.asObservable(),this.blockUIObservable.subscribe(this.blockUIMiddleware.bind(this))}return t.prototype.getSettings=function(){return this.blockUISettings},t.prototype.updateSettings=function(t){void 0===t&&(t={}),this.blockUISettings=Object(p.__assign)({},this.blockUISettings,t)},t.prototype.decorate=function(t){void 0===t&&(t=b);var e={name:t,isActive:!1,blockCount:0,start:this.dispatch(this.blockUISubject,g.START,t),update:this.dispatch(this.blockUISubject,g.UPDATE,t),stop:this.dispatch(this.blockUISubject,g.STOP,t),reset:this.dispatch(this.blockUISubject,g.RESET,t),unsubscribe:this.dispatch(this.blockUISubject,g.UNSUBSCRIBE,t)};return this.blockUIInstances[t]=this.blockUIInstances[t]||e,e},t.prototype.observe=function(){return this.blockUIObservable},t.prototype.blockUIMiddleware=function(t){var e=t.name,n=null;switch(t.action){case g.START:n=!0;break;case g.STOP:case g.RESET:n=!1}null!==n&&(this.blockUIInstances[e].isActive=n)},t.prototype.dispatch=function(t,e,n){return void 0===n&&(n=b),function(a){t.next({name:n,action:e,message:a})}},t}(),y=function(){function t(t){this.blockUI=t}return t.prototype.ngOnInit=function(){this.name=this.name||b,this.template=this.template||this.blockUI.blockUISettings.template},t}(),v=function(){function t(t,e,n){this.blockUI=t,this.resolver=e,this.changeDetectionRef=n,this.name=b,this.delayStart=0,this.delayStop=0,this.state={startTimeout:null,stopTimeout:null,blockCount:0},this.active=!1}return t.prototype.ngOnInit=function(){this.settings=this.blockUI.getSettings(),this.blockUISubscription=this.subscribeToBlockUI(this.blockUI.observe())},t.prototype.ngAfterViewInit=function(){try{if(!this.templateCmp)return!1;if(this.templateCmp instanceof s.TemplateRef)this.templateOutlet.createEmbeddedView(this.templateCmp);else{var t=this.resolver.resolveComponentFactory(this.templateCmp);this.templateCompRef=this.templateOutlet.createComponent(t),this.updateBlockTemplate(this.message)}}catch(e){console.error("ng-block-ui:",e)}},t.prototype.ngAfterViewChecked=function(){this.changeDetectionRef.detectChanges()},t.prototype.subscribeToBlockUI=function(t){var e=this;return t.subscribe(function(t){return e.onDispatchedEvent(t)})},t.prototype.onDispatchedEvent=function(t){switch(t.action){case g.START:this.onStart(t);break;case g.STOP:this.onStop(t);break;case g.UPDATE:this.onUpdate(t);break;case g.RESET:this.onReset();break;case g.UNSUBSCRIBE:this.onStop(t),this.onUnsubscribe(t.name)}},t.prototype.onStart=function(t){var e=this,n=t.message;if(t.name===this.name){var a=this.delayStart||this.settings.delayStart||0;a?(null===this.state.startTimeout&&(this.state.startTimeout=setTimeout(function(){e.showBlock(n)},a)),this.state.blockCount++):this.showBlock(n),this.updateInstanceBlockCount()}},t.prototype.onStop=function(t){var e=this;if(t.name===this.name){if(this.state.blockCount>1)this.state.blockCount--;else if(this.active){var n=this.delayStop||this.settings.delayStop||0;n?null===this.state.stopTimeout&&(this.state.stopTimeout=setTimeout(function(){e.hideBlock()},n)):this.hideBlock()}else this.clearState();this.updateInstanceBlockCount()}},t.prototype.onReset=function(){this.hideBlock()},t.prototype.onUpdate=function(t){var e=t.message;t.name===this.name&&(this.active=!0,this.message=e||this.defaultMessage||this.settings.message,this.updateBlockTemplate(this.message),this.changeDetectionRef.detectChanges())},t.prototype.showBlock=function(t){this.active=!0,this.message=t||this.defaultMessage||this.settings.message,this.updateBlockTemplate(this.message),this.changeDetectionRef.detectChanges()},t.prototype.hideBlock=function(){this.clearState(),this.active=!1,this.changeDetectionRef.detectChanges()},t.prototype.clearState=function(){null!=this.state.startTimeout&&clearTimeout(this.state.startTimeout),null!=this.state.stopTimeout&&clearTimeout(this.state.stopTimeout),this.state.blockCount=0,this.state.startTimeout=null,this.state.stopTimeout=null,this.updateInstanceBlockCount()},t.prototype.updateBlockTemplate=function(t){this.templateCompRef&&this.templateCompRef instanceof s.ComponentRef&&(this.templateCompRef.instance.message=t)},t.prototype.onUnsubscribe=function(t){this.blockUISubscription&&t===this.name&&this.blockUISubscription.unsubscribe()},t.prototype.updateInstanceBlockCount=function(){this.blockUI.blockUIInstances[this.name]&&(this.blockUI.blockUIInstances[this.name].blockCount=this.state.blockCount)},t.prototype.ngOnDestroy=function(){this.onUnsubscribe(this.name)},t}(),_=function(){function t(t){this.blockUIInstance=t}return t.prototype.start=function(t,e){this.dispatch(t,g.START,e)},t.prototype.stop=function(t){this.dispatch(t,g.STOP)},t.prototype.unsubscribe=function(t){this.dispatch(t,g.UNSUBSCRIBE)},t.prototype.isActive=function(t){void 0===t&&(t=null);var e=t?this.toArray(t):null,n=this.blockUIInstance.blockUIInstances;return Object.keys(n).some(function(t){return e?e.indexOf(n[t].name)>=0&&n[t].isActive:n[t].isActive})},t.prototype.dispatch=function(t,e,n){var a=this;void 0===t&&(t=[]),this.toArray(t).forEach(function(t){return a.blockUIInstance.decorate(t)[e](n)})},t.prototype.toArray=function(t){return void 0===t&&(t=[]),"string"==typeof t?[t]:t},t}(),x=new m,T=new s.InjectionToken("BlockUIModuleSettings");function w(t){return x.updateSettings(t),x}var S=function(){function t(){}return t.forRoot=function(e){return void 0===e&&(e={}),{ngModule:t,providers:[{provide:T,useValue:e},{provide:m,useFactory:w,deps:[T]},_]}},t}(),O=s["\u0275crt"]({encapsulation:2,styles:[],data:{}});function I(t){return s["\u0275vid"](0,[s["\u0275ncd"](null,0),(t()(),s["\u0275eld"](1,0,null,null,1,"block-ui-content",[],null,null,null,L,N)),s["\u0275did"](2,12828672,null,0,v,[m,s.ComponentFactoryResolver,s.ChangeDetectorRef],{name:[0,"name"],delayStart:[1,"delayStart"],delayStop:[2,"delayStop"],defaultMessage:[3,"defaultMessage"],templateCmp:[4,"templateCmp"]},null)],function(t,e){var n=e.component;t(e,2,0,n.name,n.delayStart,n.delayStop,n.message,n.template)},null)}function C(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"block-ui",[],null,null,null,I,O)),s["\u0275did"](1,114688,null,0,y,[m],null,null)],function(t,e){t(e,1,0)},null)}var k=s["\u0275ccf"]("block-ui",y,C,{name:"name",message:"message",delayStart:"delayStart",delayStop:"delayStop",template:"template"},{},["*"]),N=s["\u0275crt"]({encapsulation:2,styles:["\n.block-ui-wrapper {\n display: none;\n position: fixed;\n height: 100%;\n width: 100%;\n top: 0;\n left: 0;\n background: rgba(0, 0, 0, 0.70);\n z-index: 30000;\n cursor: wait;\n}\n\n.block-ui-wrapper.block-ui-wrapper--element {\n position: absolute;\n}\n\n.block-ui-wrapper.active {\n display: block;\n}\n\n.block-ui-wrapper.block-ui-main {\n position: fixed;\n}\n\n.block-ui-spinner,\n.block-ui-template {\n position: absolute;\n top: 40%;\n margin: 0 auto;\n left: 0;\n right: 0;\n transform: translateY(-50%);\n}\n\n.block-ui-spinner > .message {\n font-size: 1.3em;\n text-align: center;\n color: #fff;\n}\n\n.block-ui__element {\n position: relative;\n}\n\n.loader,\n.loader:after {\n border-radius: 50%;\n width: 10em;\n height: 10em;\n}\n.loader {\n margin: 7px auto;\n font-size: 5px;\n position: relative;\n text-indent: -9999em;\n border-top: 1.1em solid rgba(255, 255, 255, 0.2);\n border-right: 1.1em solid rgba(255, 255, 255, 0.2);\n border-bottom: 1.1em solid rgba(255, 255, 255, 0.2);\n border-left: 1.1em solid #ffffff;\n -webkit-transform: translateZ(0);\n -ms-transform: translateZ(0);\n transform: translateZ(0);\n -webkit-animation: load8 1.1s infinite linear;\n animation: load8 1.1s infinite linear;\n}\n\n@-webkit-keyframes load8 {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes load8 {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n"],data:{}});function R(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"div",[["class","message"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "]))],null,function(t,e){var n=e.component;t(e,1,0,n.message||n.defaultMessage)})}function A(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"div",[["class","block-ui-spinner"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,0,"div",[["class","loader"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,R)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,n.message||n.defaultMessage)},null)}function D(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](0,null,null,0))],null,null)}function E(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,[[1,3],["templateOutlet",2]],null,0,null,D)),(t()(),s["\u0275and"](0,null,null,0))],null,null)}function L(t){return s["\u0275vid"](0,[s["\u0275qud"](671088640,1,{templateOutlet:0}),(t()(),s["\u0275eld"](1,0,null,null,6,"div",[],null,null,null,null,null)),s["\u0275did"](2,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](3,{active:0}),(t()(),s["\u0275and"](16777216,null,null,1,null,A)),s["\u0275did"](5,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,E)),s["\u0275did"](7,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=s["\u0275inlineInterpolate"](2,"block-ui-wrapper ",n.name," ",n.className,""),r=t(e,3,0,n.active);t(e,2,0,a,r),t(e,5,0,!n.templateCmp),t(e,7,0,n.templateCmp)},null)}function P(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"block-ui-content",[],null,null,null,L,N)),s["\u0275did"](1,12828672,null,0,v,[m,s.ComponentFactoryResolver,s.ChangeDetectorRef],null,null)],function(t,e){t(e,1,0)},null)}var M=s["\u0275ccf"]("block-ui-content",v,P,{name:"name",delayStart:"delayStart",delayStop:"delayStop",defaultMessage:"message",templateCmp:"template"},{},[]),q=n("SZbH"),j=s["\u0275crt"]({encapsulation:2,styles:[],data:{animation:[{type:7,name:"flyInOut",definitions:[{type:0,name:"inactive",styles:{type:6,styles:{opacity:0},offset:null},options:void 0},{type:0,name:"active",styles:{type:6,styles:{opacity:1},offset:null},options:void 0},{type:0,name:"removed",styles:{type:6,styles:{opacity:0},offset:null},options:void 0},{type:1,expr:"inactive => active",animation:{type:4,styles:null,timings:"{{ easeTime }}ms {{ easing }}"},options:null},{type:1,expr:"active => removed",animation:{type:4,styles:null,timings:"{{ easeTime }}ms {{ easing }}"},options:null}],options:{}}]}});function F(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"button",[["aria-label","Close"],["class","toast-close-button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.remove()&&a),a},null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xd7"]))],null,null)}function z(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["[","]"]))],null,function(t,e){t(e,1,0,e.component.duplicatesCount+1)})}function G(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"div",[],[[8,"className",0],[1,"aria-label",0]],null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "])),(t()(),s["\u0275and"](16777216,null,null,1,null,z)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,3,0,e.component.duplicatesCount)},function(t,e){var n=e.component;t(e,0,0,n.options.titleClass,n.title),t(e,1,0,n.title)})}function Y(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"div",[["aria-live","polite"],["role","alertdialog"]],[[8,"className",0],[8,"innerHTML",1]],null,null,null,null))],null,function(t,e){var n=e.component;t(e,0,0,n.options.messageClass,n.message)})}function V(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"div",[["aria-live","polite"],["role","alertdialog"]],[[8,"className",0],[1,"aria-label",0]],null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "]))],null,function(t,e){var n=e.component;t(e,0,0,n.options.messageClass,n.message),t(e,1,0,n.message)})}function H(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,0,"div",[["class","toast-progress"]],[[4,"width",null]],null,null,null,null))],null,function(t,e){t(e,1,0,e.component.width+"%")})}function B(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,F)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,G)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Y)),s["\u0275did"](5,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,V)),s["\u0275did"](7,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,H)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.options.closeButton),t(e,3,0,n.title),t(e,5,0,n.message&&n.options.enableHtml),t(e,7,0,n.message&&!n.options.enableHtml),t(e,9,0,n.options.progressBar)},null)}function U(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"div",[["toast-component",""]],[[8,"className",0],[40,"@flyInOut",0],[4,"display",null]],[[null,"click"],[null,"mouseenter"],[null,"mouseleave"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,1).tapToast()&&a),"mouseenter"===e&&(a=!1!==s["\u0275nov"](t,1).stickAround()&&a),"mouseleave"===e&&(a=!1!==s["\u0275nov"](t,1).delayedHideToast()&&a),a},B,j)),s["\u0275did"](1,180224,null,0,q.c,[q.j,q.g,s.NgZone],null,null)],null,function(t,e){t(e,0,0,s["\u0275nov"](e,1).toastClasses,s["\u0275nov"](e,1).state,s["\u0275nov"](e,1).displayStyle)})}var W=s["\u0275ccf"]("[toast-component]",q.c,U,{},{},[]),K=n("pMnS"),$=n("pKUh"),Z=n("YAQW"),X=n("OZfm"),J=n("lqqz"),Q=n("NJnL"),tt=n("ZYCi"),et=function(){return function(){this.cardClass=""}}(),nt=s["\u0275crt"]({encapsulation:0,styles:[[".card[_ngcontent-%COMP%]{border:.5px solid #ddd;border-radius:3px;background-color:#fff;box-shadow:0 1px 1px rgba(3,3,3,.175);margin:0 auto 20px;padding:0 20px;width:auto;height:auto;min-height:6vw;position:relative;font-size:12px}@media screen and (min-width:320px){.card[_ngcontent-%COMP%]{font-size:calc(12px + 9 * ((100vw - 320px)/ 1728))}}@media screen and (min-width:2048px){.card[_ngcontent-%COMP%]{font-size:21px}}.card-title[_ngcontent-%COMP%]{margin:1.1vw 0;padding:0}.card-body[_ngcontent-%COMP%]{text-align:center;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%);transform:translate(-50%)}.content-chart[_ngcontent-%COMP%]{margin-top:-.7vw;position:unset;top:unset;left:unset;-webkit-transform:unset;transform:unset}.no-center[_ngcontent-%COMP%]{position:unset;top:unset;left:unset;-webkit-transform:unset;transform:unset}.text-area-size-2[_ngcontent-%COMP%]{margin-right:-50%;-webkit-transform:translate(-50%,-20%);transform:translate(-50%,-20%)}.text-area-size-3[_ngcontent-%COMP%]{margin-right:-50%;-webkit-transform:translate(-50%,-40%);transform:translate(-50%,-40%)}.content-highlight[_ngcontent-%COMP%]{font-weight:700}.card-medium[_ngcontent-%COMP%]{min-height:12vw}.scroll[_ngcontent-%COMP%]{max-height:18vw;overflow-y:auto}.text-monospace[_ngcontent-%COMP%]{font-size:12px;font-family:monospace;text-align:left}@media (max-width:1599px){.card[_ngcontent-%COMP%]{min-height:7.8vw}.card-medium[_ngcontent-%COMP%]{min-height:14.4vw}}@media (max-width:calc(1200px - 1px)){.card-medium[_ngcontent-%COMP%]{min-height:18vw}.content-chart[_ngcontent-%COMP%]{margin-top:-.6vw}}@media (max-width:calc(992px - 1px)){.card[_ngcontent-%COMP%]{min-height:12vw}.content-chart[_ngcontent-%COMP%]{margin-top:-.3vw}}@media (max-width:calc(992px - 1px)) and (min-width:768px){.card-medium[_ngcontent-%COMP%]{min-height:26.4vw}}@media (max-width:599px){.card[_ngcontent-%COMP%]{min-height:18vw}}@media (max-width:319px){.card[_ngcontent-%COMP%]{min-height:24vw}}"]],data:{}});function at(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,1).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](1,671744,null,0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](2,null,["",""]))],function(t,e){t(e,1,0,e.component.link)},function(t,e){var n=e.component;t(e,0,0,s["\u0275nov"](e,1).target,s["\u0275nov"](e,1).href),t(e,2,0,n.cardTitle)})}function rt(t){return s["\u0275vid"](0,[(t()(),s["\u0275ted"](0,null,[" "," "]))],null,function(t,e){t(e,0,0,e.component.cardTitle)})}function it(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,8,"div",[["class","card"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),s["\u0275eld"](2,0,null,null,3,"div",[["class","card-title"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,at)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(t()(),s["\u0275and"](0,[["noLinkTitle",2]],null,0,null,rt)),(t()(),s["\u0275eld"](6,0,null,null,2,"div",[["class","card-body"]],null,null,null,null,null)),s["\u0275did"](7,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275ncd"](null,0)],function(t,e){var n=e.component;t(e,1,0,"card",n.cardClass),t(e,4,0,n.link,s["\u0275nov"](e,5)),t(e,7,0,"card-body",n.contentClass)},null)}var st=function(){return function(){}}(),ot=s["\u0275crt"]({encapsulation:0,styles:[[".info-group-title[_ngcontent-%COMP%]{margin:0 0 .5vw .5vw;padding:0;font-size:21px}"]],data:{}});function ut(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"div",[["class","info-group-title"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" ","\n"])),s["\u0275ncd"](null,0)],null,function(t,e){t(e,1,0,e.component.groupTitle)})}var ct,lt=n("xdbM"),dt=n("WyAD"),ft=n("LvDl"),pt=n("NEZu"),ht=n("Fgil"),gt=n("o4+5");!function(t){t.DEFAULT_RED="#ff7592",t.DEFAULT_BLUE="#1d699d",t.DEFAULT_ORANGE="#ffa500",t.DEFAULT_MAGENTA="#564d65",t.DEFAULT_GREEN="#00bb00"}(ct||(ct={}));var bt=function(){function t(t,e){var n=this;this.dimlessBinary=t,this.dimless=e,this.config={},this.isBytesData=!1,this.showLabelAsTooltip=!1,this.prepareFn=new s.EventEmitter,this.chartConfig={chartType:"pie",dataset:[{label:null,borderWidth:0}],options:{legend:{display:!0,position:"right",labels:{usePointStyle:!0},onClick:function(t,e){n.onLegendClick(t,e)}},animation:{duration:0},tooltips:{enabled:!1},title:{display:!1}}},this.hiddenSlices=[]}return t.prototype.ngOnInit=function(){var t=this;dt.pluginService.register({beforeDraw:function(t){if(t.options.center_text){var e=t.chart.width,n=t.chart.height,a=t.chart.ctx;a.restore();var r=(n/114).toFixed(2);a.font=r+"em sans-serif",a.textBaseline="middle";var i=t.options.center_text,s=Math.round((e-a.measureText(i).width)/2);a.fillText(i,s,n/2),a.save()}}});var e=new pt.a(this.chartCanvasRef,this.chartTooltipRef,function(t,e){return e+t.caretX+"px"},function(t,e){return e+t.caretY-t.height-10+"px"});e.getBody=function(e){return t.getChartTooltipBody(e)},this.chartConfig.options.tooltips.custom=function(t){e.customTooltips(t)},this.chartConfig.colors=[{backgroundColor:[ct.DEFAULT_RED,ct.DEFAULT_BLUE,ct.DEFAULT_ORANGE,ct.DEFAULT_GREEN,ct.DEFAULT_MAGENTA]}],ft.merge(this.chartConfig,this.config),this.prepareFn.emit([this.chartConfig,this.data])},t.prototype.ngOnChanges=function(){this.prepareFn.emit([this.chartConfig,this.data]),this.hideSlices(),this.setChartSliceBorderWidth()},t.prototype.getChartTooltipBody=function(t){var e=t[0].split(": ");return this.showLabelAsTooltip?e[0]:(e[1]=this.isBytesData?this.dimlessBinary.transform(e[1]):this.dimless.transform(e[1]),e.join(": "))},t.prototype.setChartSliceBorderWidth=function(){var t=0;ft.forEach(this.chartConfig.dataset[0].data,function(e){e>0&&(t+=1)}),this.chartConfig.dataset[0].borderWidth=t>1?1:0},t.prototype.onLegendClick=function(t,e){t.stopPropagation(),this.hiddenSlices[e.index]=!e.hidden,this.ngOnChanges()},t.prototype.hideSlices=function(){var t=this;ft.forEach(this.chartConfig.dataset[0].data,function(e,n){t.hiddenSlices[n]&&(t.chartConfig.dataset[0].data[n]=void 0)})},t}(),mt=s["\u0275crt"]({encapsulation:0,styles:[["canvas[_ngcontent-%COMP%]{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.chartjs-tooltip[_ngcontent-%COMP%]{opacity:0;position:absolute;background:rgba(0,0,0,.7);color:#fff;border-radius:3px;-webkit-transition:.1s;transition:all .1s ease;pointer-events:none;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif!important;-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]{-webkit-transform:translate(-10%,0);transform:translate(-10%,0)}.chartjs-tooltip.transform-left[_ngcontent-%COMP%]::after{left:10%}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]{-webkit-transform:translate(-90%,0);transform:translate(-90%,0)}.chartjs-tooltip.transform-right[_ngcontent-%COMP%]::after{left:90%}.chartjs-tooltip[_ngcontent-%COMP%]::after{content:' ';position:absolute;top:100%;left:50%;margin-left:-5px;border-width:5px;border-style:solid;border-color:#000 transparent transparent} .chartjs-tooltip-key{display:inline-block;width:10px;height:10px;margin-right:10px}.chart-container[_ngcontent-%COMP%]{margin:auto;cursor:pointer;overflow:visible;position:unset;width:100%;height:100%}.chart-canvas[_ngcontent-%COMP%]{position:unset;width:100%;height:100%;margin-left:auto;margin-right:auto;max-width:100%;max-height:100%}"]],data:{}});function yt(t){return s["\u0275vid"](0,[s["\u0275qud"](402653184,1,{chartCanvasRef:0}),s["\u0275qud"](402653184,2,{chartTooltipRef:0}),(t()(),s["\u0275eld"](2,0,null,null,4,"div",[["class","chart-container"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,[[1,0],["chartCanvas",1]],null,1,"canvas",[["baseChart",""],["class","chart-canvas"]],null,null,null,null,null)),s["\u0275did"](4,737280,null,0,lt.BaseChartDirective,[s.ElementRef],{datasets:[0,"datasets"],labels:[1,"labels"],options:[2,"options"],chartType:[3,"chartType"],colors:[4,"colors"]},null),(t()(),s["\u0275eld"](5,0,[[2,0],["chartTooltip",1]],null,1,"div",[["class","chartjs-tooltip"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,0,"table",[],null,null,null,null,null))],function(t,e){var n=e.component;t(e,4,0,n.chartConfig.dataset,n.chartConfig.labels,n.chartConfig.options,n.chartConfig.chartType,n.chartConfig.colors)},null)}var vt=function(){function t(){}return t.prototype.transform=function(t){return"HEALTH_OK"===t?{color:"#00bb00"}:"HEALTH_WARN"===t?{color:"#ffa500"}:"HEALTH_ERR"===t?{color:"#ff0000"}:null},t}(),_t=function(){function t(t){this.i18n=t}return t.prototype.transform=function(t){return t?t.monmap.mons.length.toString()+" ("+this.i18n("quorum")+" "+t.quorum.join(", ")+")":""},t}(),xt=n("Jm/i"),Tt=function(){function t(t){this.i18n=t}return t.prototype.transform=function(t){if(!t)return"";var e=0,n=0;ft.each(t.osds,function(t){t.in&&e++,t.up&&n++});var a=[{content:t.osds.length+" "+this.i18n("total"),class:""}];a.push({content:"",class:"card-text-line-break"}),a.push({content:n+" "+this.i18n("up")+", "+e+" "+this.i18n("in"),class:""});var r=t.osds.length-n,i=n-e;if(r>0||i>0){a.push({content:"",class:"card-text-line-break"});var s=r>0?r+" "+this.i18n("down"):"",o=r>0&&i>0?", ":"",u=i>0?i+" "+this.i18n("out"):"";a.push({content:""+s+o+u,class:"card-text-error"})}return a},t}(),wt=function(){function t(t){this.i18n=t}return t.prototype.transform=function(t){if(!t)return"";var e=this.i18n("n/a"),n=ft.isUndefined(t.active_name)?"":this.i18n("active daemon")+": "+t.active_name;n.length>0&&(e="1");var a=t.standbys.map(function(t){return t.name}).join(", "),r=a?this.i18n("standby daemons")+": "+a:"",i=t.standbys.length,s=[{content:e+" "+this.i18n("active"),class:"popover-info",titleText:n}];return s.push({content:"",class:"card-text-line-break",titleText:""}),s.push({content:i+" "+this.i18n("standby"),class:"popover-info",titleText:r}),s},t}(),St=function(){function t(t){this.i18n=t}return t.prototype.transform=function(t){if(!t)return"";var e="",n="",a=0,r=0,i=0;ft.each(t.standbys,function(){a+=1}),t.standbys&&!t.filesystems?(e=a+" "+this.i18n("up"),n=this.i18n("no filesystems")):0===t.filesystems.length?e=this.i18n("no filesystems"):(ft.each(t.filesystems,function(t){ft.each(t.mdsmap.info,function(t){"up:standby-replay"===t.state?i+=1:r+=1})}),e=r+" "+this.i18n("active"),n=a+i+" "+this.i18n("standby"));var s=t.standbys.map(function(t){return t.name}).join(", "),o=s?this.i18n("standby daemons")+": "+s:"",u=t.filesystems?t.filesystems.length:0,c=Object.values(u>0?t.filesystems[0].mdsmap.info:{}).map(function(t){return t.name}).join(", "),l=c?this.i18n("active daemon")+": "+c:"";!r&&u>0&&(l=i+" "+this.i18n("standbyReplay"));var d=[{content:e,class:"popover-info",titleText:l}];return n&&(d.push({content:"",class:"card-text-line-break",titleText:""}),d.push({content:n,class:"popover-info",titleText:o})),d},t}(),Ot=function(){function t(){}return t.prototype.transform=function(t,e){return ft.round(t,e)},t}(),It=n("aXbf"),Ct=n("DtyJ"),kt=n("t/Na"),Nt=n("pL04"),Rt=function(){function t(t){this.http=t}return t.prototype.getFullHealth=function(){return this.http.get("api/health/full")},t.prototype.getMinimalHealth=function(){return this.http.get("api/health/minimal")},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c))},token:t,providedIn:Nt.a}),t}(),At=n("ej+x"),Dt=n("26FU"),Et=n("xXU7"),Lt=function(){function t(){this.intervalDataSource=new Dt.a(null),this.intervalData$=this.intervalDataSource.asObservable();var t=parseInt(sessionStorage.getItem("dashboard_interval"),10)||5e3;this.setRefreshInterval(t)}return t.prototype.setRefreshInterval=function(t){var e=this;this.intervalTime=t,sessionStorage.setItem("dashboard_interval",t.toString()),this.intervalSubscription&&this.intervalSubscription.unsubscribe(),this.intervalSubscription=Object(Et.a)(this.intervalTime).subscribe(function(){return e.intervalDataSource.next(e.intervalTime)})},t.prototype.getRefreshInterval=function(){return this.intervalTime},t.prototype.ngOnDestroy=function(){this.intervalSubscription&&this.intervalSubscription.unsubscribe()},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t},token:t,providedIn:"root"}),t}(),Pt=n("d+Og"),Mt=function(){function t(t,e,n,a,r,i,s,o){this.healthService=t,this.i18n=e,this.authStorageService=n,this.pgCategoryService=a,this.featureToggles=r,this.refreshIntervalService=i,this.dimlessBinary=s,this.dimless=o,this.interval=new Ct.Subscription,this.rawCapacityChartConfig={options:{title:{display:!0,position:"bottom"}}},this.objectsChartConfig={options:{title:{display:!0,position:"bottom"}},colors:[{backgroundColor:[ct.DEFAULT_GREEN,ct.DEFAULT_MAGENTA,ct.DEFAULT_ORANGE,ct.DEFAULT_RED]}]},this.pgStatusChartConfig={colors:[{backgroundColor:[ct.DEFAULT_GREEN,ct.DEFAULT_BLUE,ct.DEFAULT_ORANGE,ct.DEFAULT_RED]}]},this.permissions=this.authStorageService.getPermissions(),this.enabledFeature$=this.featureToggles.get()}return t.prototype.ngOnInit=function(){var t=this;this.getHealth(),this.interval=this.refreshIntervalService.intervalData$.subscribe(function(){t.getHealth()})},t.prototype.ngOnDestroy=function(){this.interval.unsubscribe()},t.prototype.getHealth=function(){var t=this;this.healthService.getMinimalHealth().subscribe(function(e){t.healthData=e})},t.prototype.prepareReadWriteRatio=function(t){var e=[],n=[],a=this.healthData.client_perf.write_op_per_sec+this.healthData.client_perf.read_op_per_sec;e.push(this.i18n("Writes")+" ("+this.calcPercentage(this.healthData.client_perf.write_op_per_sec,a)+"%)"),n.push(this.healthData.client_perf.write_op_per_sec),e.push(this.i18n("Reads")+" ("+this.calcPercentage(this.healthData.client_perf.read_op_per_sec,a)+"%)"),n.push(this.healthData.client_perf.read_op_per_sec),t.dataset[0].data=n,t.labels=e},t.prototype.prepareRawUsage=function(t,e){var n=this.calcPercentage(e.df.stats.total_bytes-e.df.stats.total_used_raw_bytes,e.df.stats.total_bytes),a=this.calcPercentage(e.df.stats.total_used_raw_bytes,e.df.stats.total_bytes);t.dataset[0].data=[e.df.stats.total_used_raw_bytes,e.df.stats.total_avail_bytes],t.labels=[this.dimlessBinary.transform(e.df.stats.total_used_raw_bytes)+" "+this.i18n("Used")+" ("+a+"%)",this.dimlessBinary.transform(e.df.stats.total_bytes-e.df.stats.total_used_raw_bytes)+" "+this.i18n("Avail.")+" ("+n+"%)"],t.options.title.text=this.dimlessBinary.transform(e.df.stats.total_bytes)+" "+this.i18n("total")},t.prototype.preparePgStatus=function(t,e){var n=this,a={},r=0;ft.forEach(e.pg_info.statuses,function(t,e){var i=n.pgCategoryService.getTypeByStates(e);ft.isUndefined(a[i])&&(a[i]=0),a[i]+=t,r+=t}),t.dataset[0].data=this.pgCategoryService.getAllTypes().map(function(t){return a[t]}),t.labels=[this.i18n("Clean")+" ("+this.calcPercentage(a.clean,r)+"%)",this.i18n("Working")+" ("+this.calcPercentage(a.working,r)+"%)",this.i18n("Warning")+" ("+this.calcPercentage(a.warning,r)+"%)",this.i18n("Unknown")+" ("+this.calcPercentage(a.unknown,r)+"%)"]},t.prototype.prepareObjects=function(t,e){var n=e.pg_info.object_stats.num_object_copies,a=n-e.pg_info.object_stats.num_objects_misplaced-e.pg_info.object_stats.num_objects_degraded-e.pg_info.object_stats.num_objects_unfound;t.labels=[this.i18n("Healthy")+" ("+this.calcPercentage(a,n)+"%)",this.i18n("Misplaced")+" ("+this.calcPercentage(e.pg_info.object_stats.num_objects_misplaced,n)+"%)",this.i18n("Degraded")+" ("+this.calcPercentage(e.pg_info.object_stats.num_objects_degraded,n)+"%)",this.i18n("Unfound")+" ("+this.calcPercentage(e.pg_info.object_stats.num_objects_unfound,n)+"%)"],t.dataset[0].data=[a,e.pg_info.object_stats.num_objects_misplaced,e.pg_info.object_stats.num_objects_degraded,e.pg_info.object_stats.num_objects_unfound],t.options.title.text=this.dimless.transform(e.pg_info.object_stats.num_objects)+" "+this.i18n("total")+" ("+this.dimless.transform(n)+" "+this.i18n("replicas")+")",t.options.maintainAspectRatio=window.innerWidth>=375},t.prototype.isClientReadWriteChartShowable=function(){return(this.healthData.client_perf.read_op_per_sec||0)+(this.healthData.client_perf.write_op_per_sec||0)>0},t.prototype.calcPercentage=function(t,e){return ft.isNumber(t)&&ft.isNumber(e)&&0!==e?Math.round(t/e*100):0},t}(),qt=s["\u0275crt"]({encapsulation:0,styles:[["cd-info-card[_ngcontent-%COMP%]{padding:0 .5vw}.cd-container-flex[_ngcontent-%COMP%]{margin:0;padding:0;display:-webkit-box;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;-webkit-box-pack:justify;justify-content:space-between}.cd-col-5[_ngcontent-%COMP%]{width:20%}@media (max-width:1599px){.cd-col-5[_ngcontent-%COMP%]{width:25%}}@media (max-width:calc(1200px - 1px)){.cd-col-5[_ngcontent-%COMP%]{width:33%}}@media (max-width:calc(992px - 1px)){.cd-col-5[_ngcontent-%COMP%]{width:50%}}@media (max-width:calc(768px - 1px)){cd-info-card[_ngcontent-%COMP%]{padding:0}.cd-col-5[_ngcontent-%COMP%]{width:100%}}.info-group[_ngcontent-%COMP%]{margin:0;padding:0} .pg-status-popover-wrapper{position:relative} .pg-status-popover-wrapper .popover{position:absolute;width:116%;max-height:20vh;min-width:unset!important;max-width:unset!important} .pg-status-popover-wrapper .popover .popover-body{max-width:100%;max-height:19vh;font-size:12px}.logs-link[_ngcontent-%COMP%]{text-align:center}.card-text-error[_ngcontent-%COMP%]{display:inline;color:red}.card-text-line-break[_ngcontent-%COMP%]:after{content:'\\A';white-space:pre}.popover-info[_ngcontent-%COMP%]:hover{cursor:pointer}"]],data:{}});function jt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function Ft(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,3,"span",[],null,null,null,null,null)),s["\u0275did"](2,278528,null,0,i.NgStyle,[s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngStyle:[0,"ngStyle"]},null),s["\u0275ppd"](3,1),(t()(),s["\u0275ted"](4,null,["",""])),(t()(),s["\u0275ted"](5,null,[": "," "]))],function(t,e){var n=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent.parent.parent.parent.parent.parent,0),e.context.$implicit.severity));t(e,2,0,n)},function(t,e){t(e,4,0,e.context.$implicit.type),t(e,5,0,e.context.$implicit.summary.message)})}function zt(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,jt)),s["\u0275did"](1,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(t()(),s["\u0275eld"](2,0,null,null,2,"ul",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Ft)),s["\u0275did"](4,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){var n=e.component;t(e,1,0,s["\u0275nov"](e.parent.parent.parent.parent,7)),t(e,4,0,n.healthData.health.checks)},null)}function Gt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,null,null,null,null,null,null,null)),(t()(),s["\u0275and"](0,[["healthChecks",2]],null,0,null,zt)),(t()(),s["\u0275eld"](2,16777216,null,null,4,"div",[["class","info-card-content-clickable"],["container","body"],["containerClass","info-card-popover-cluster-status"],["placement","bottom"],["triggers",""]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).toggle()&&a),a},null,null)),s["\u0275did"](3,278528,null,0,i.NgStyle,[s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngStyle:[0,"ngStyle"]},null),s["\u0275ppd"](4,1),s["\u0275did"](5,212992,[["healthChecksTarget",4]],0,X.c,[X.a,s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,Q.a],{popover:[0,"popover"],placement:[1,"placement"],triggers:[2,"triggers"],container:[3,"container"],containerClass:[4,"containerClass"]},null),(t()(),s["\u0275ted"](6,null,[" "," "])),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){var n=e.component,a=s["\u0275unv"](e,3,0,t(e,4,0,s["\u0275nov"](e.parent.parent.parent.parent,0),n.healthData.health.status));t(e,3,0,a),t(e,5,0,s["\u0275nov"](e,1),"bottom","","body","info-card-popover-cluster-status")},function(t,e){t(e,6,0,e.component.healthData.health.status)})}function Yt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,3,"div",[],null,null,null,null,null)),s["\u0275did"](2,278528,null,0,i.NgStyle,[s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngStyle:[0,"ngStyle"]},null),s["\u0275ppd"](3,1),(t()(),s["\u0275ted"](4,null,[" "," "]))],function(t,e){var n=e.component,a=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent.parent.parent.parent,0),n.healthData.health.status));t(e,2,0,a)},function(t,e){t(e,4,0,e.component.healthData.health.status)})}function Vt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"cd-info-card",[["cardTitle","Cluster Status"],["class","col-sm-6 col-md-4 col-lg-3"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],contentClass:[1,"contentClass"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Gt)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Yt)),s["\u0275did"](5,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"Cluster Status",(null==n.healthData.health?null:null==n.healthData.health.checks?null:n.healthData.health.checks.length)>0?"content-highlight text-area-size-2":"content-highlight"),t(e,3,0,(null==n.healthData.health?null:null==n.healthData.health.checks?null:n.healthData.health.checks.length)>0),t(e,5,0,!(null!=n.healthData.health&&null!=n.healthData.health.checks&&n.healthData.health.checks.length))},null)}function Ht(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardTitle","Monitors"],["class","col-sm-6 col-md-4 col-lg-3"],["contentClass","content-highlight"],["link","/monitor"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],link:[1,"link"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," "])),s["\u0275ppd"](3,1)],function(t,e){t(e,1,0,"Monitors","/monitor","content-highlight")},function(t,e){var n=e.component,a=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent.parent.parent,1),n.healthData.mon_status));t(e,2,0,a)})}function Bt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngClass:[0,"ngClass"]},null),(t()(),s["\u0275ted"](2,null,[" "," "]))],function(t,e){t(e,1,0,e.context.$implicit.class)},function(t,e){t(e,2,0,e.context.$implicit.content)})}function Ut(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardTitle","OSDs"],["class","col-sm-6 col-md-4 col-lg-3"],["link","/osd"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],link:[1,"link"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Bt)),s["\u0275did"](3,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,1,0,"OSDs","/osd",(5==e.context.ngIf.length?"text-area-size-3":"text-area-size-2")+" content-highlight"),t(e,3,0,e.context.ngIf)},null)}function Wt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[],[[8,"title",0]],null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngClass:[0,"ngClass"]},null),(t()(),s["\u0275ted"](2,null,[" "," "]))],function(t,e){t(e,1,0,e.context.$implicit.class)},function(t,e){t(e,0,0,null!=e.context.$implicit.titleText?e.context.$implicit.titleText:""),t(e,2,0,e.context.$implicit.content)})}function Kt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"cd-info-card",[["cardTitle","Manager Daemons"],["class","col-sm-6 col-md-4 col-lg-3"],["contentClass","content-highlight text-area-size-2"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],contentClass:[1,"contentClass"]},null),(t()(),s["\u0275and"](16777216,null,0,2,null,Wt)),s["\u0275did"](3,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),s["\u0275ppd"](4,1)],function(t,e){var n=e.component;t(e,1,0,"Manager Daemons","content-highlight text-area-size-2");var a=s["\u0275unv"](e,3,0,t(e,4,0,s["\u0275nov"](e.parent.parent.parent,3),n.healthData.mgr_map));t(e,3,0,a)},null)}function $t(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-info-card",[["cardTitle","Hosts"],["class","col-sm-6 col-md-4 col-lg-3"],["contentClass","content-medium content-highlight"],["link","/hosts"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],link:[1,"link"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," total "]))],function(t,e){t(e,1,0,"Hosts","/hosts","content-medium content-highlight")},function(t,e){t(e,2,0,e.component.healthData.hosts)})}function Zt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-info-card",[["cardTitle","Object Gateways"],["class","col-sm-6 col-md-4 col-lg-3"],["contentClass","content-medium content-highlight"],["link","/rgw/daemon"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],link:[1,"link"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," total "]))],function(t,e){t(e,1,0,"Object Gateways","/rgw/daemon","content-medium content-highlight")},function(t,e){t(e,2,0,e.component.healthData.rgw)})}function Xt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[],[[8,"title",0]],null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngClass:[0,"ngClass"]},null),(t()(),s["\u0275ted"](2,null,[" "," "]))],function(t,e){t(e,1,0,e.context.$implicit.class)},function(t,e){t(e,0,0,null!=e.context.$implicit.titleText?e.context.$implicit.titleText:""),t(e,2,0,e.context.$implicit.content)})}function Jt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardTitle","Metadata Servers"],["class","col-sm-6 col-md-4 col-lg-3"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],contentClass:[1,"contentClass"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Xt)),s["\u0275did"](3,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,1,0,"Metadata Servers",(e.context.ngIf.length>1?"text-area-size-2":"")+" content-highlight"),t(e,3,0,e.context.ngIf)},null)}function Qt(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-info-card",[["cardTitle","iSCSI Gateways"],["class","col-sm-6 col-md-4 col-lg-3"],["contentClass","content-medium content-highlight"],["link","/block/iscsi"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],link:[1,"link"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," total "]))],function(t,e){t(e,1,0,"iSCSI Gateways","/block/iscsi","content-medium content-highlight")},function(t,e){t(e,2,0,e.component.healthData.iscsi_daemons)})}function te(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,19,"cd-info-group",[["class","row info-group"],["groupTitle","Status"]],null,null,null,ut,ot)),s["\u0275did"](1,49152,null,0,st,[],{groupTitle:[0,"groupTitle"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Vt)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Ht)),s["\u0275did"](5,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,2,null,Ut)),s["\u0275did"](7,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),s["\u0275ppd"](8,1),(t()(),s["\u0275and"](16777216,null,0,1,null,Kt)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,$t)),s["\u0275did"](12,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Zt)),s["\u0275did"](14,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,2,null,Jt)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),s["\u0275ppd"](17,1),(t()(),s["\u0275and"](16777216,null,0,1,null,Qt)),s["\u0275did"](19,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"Status"),t(e,3,0,null==n.healthData.health?null:n.healthData.health.status),t(e,5,0,n.healthData.mon_status);var a=s["\u0275unv"](e,7,0,t(e,8,0,s["\u0275nov"](e.parent.parent,2),n.healthData.osd_map));t(e,7,0,a),t(e,10,0,n.healthData.mgr_map),t(e,12,0,null!=n.healthData.hosts),t(e,14,0,e.parent.context.ngIf.rgw&&null!=n.healthData.rgw);var r=s["\u0275unv"](e,16,0,t(e,17,0,s["\u0275nov"](e.parent.parent,4),e.parent.context.ngIf.cephfs&&n.healthData.fs_map));t(e,16,0,r),t(e,19,0,e.parent.context.ngIf.iscsi&&null!=n.healthData.iscsi_daemons)},null)}function ee(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Client IOPS"],["class","cd-col-5"],["contentClass","content-medium content-highlight"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," "])),s["\u0275ppd"](3,2)],function(t,e){t(e,1,0,"Client IOPS","card-medium","content-medium content-highlight")},function(t,e){var n=e.component,a=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent.parent.parent,5),n.healthData.client_perf.read_op_per_sec+n.healthData.client_perf.write_op_per_sec,1));t(e,2,0,a)})}function ne(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Client Throughput"],["class","cd-col-5"],["contentClass","content-medium content-highlight"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," "])),s["\u0275ppd"](3,1)],function(t,e){t(e,1,0,"Client Throughput","card-medium","content-medium content-highlight")},function(t,e){var n=e.component,a=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent.parent.parent,6),n.healthData.client_perf.read_bytes_sec+n.healthData.client_perf.write_bytes_sec))+"/s";t(e,2,0,a)})}function ae(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-health-pie",[],null,[[null,"prepareFn"]],function(t,e,n){var a=!0;return"prepareFn"===e&&(a=!1!==t.component.prepareReadWriteRatio(n[0],n[1])&&a),a},yt,mt)),s["\u0275did"](1,638976,null,0,bt,[ht.a,gt.a],{data:[0,"data"]},{prepareFn:"prepareFn"})],function(t,e){t(e,1,0,e.component.healthData)},null)}function re(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[" N/A "]))],null,null)}function ie(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Client Read/Write"],["class","cd-col-5"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,ae)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,re)),s["\u0275did"](5,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"Client Read/Write","card-medium",n.isClientReadWriteChartShowable()?"content-chart":"content-medium content-highlight"),t(e,3,0,n.isClientReadWriteChartShowable()),t(e,5,0,!n.isClientReadWriteChartShowable())},null)}function se(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Recovery Throughput"],["class","cd-col-5"],["contentClass","content-medium content-highlight"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," "])),s["\u0275ppd"](3,1)],function(t,e){t(e,1,0,"Recovery Throughput","card-medium","content-medium content-highlight")},function(t,e){var n=e.component,a=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent.parent.parent,6),n.healthData.client_perf.recovering_bytes_per_sec))+"/s";t(e,2,0,a)})}function oe(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Scrub"],["class","cd-col-5"],["contentClass","content-medium content-highlight"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," "]))],function(t,e){t(e,1,0,"Scrub","card-medium","content-medium content-highlight")},function(t,e){t(e,2,0,e.component.healthData.scrub_status)})}function ue(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,12,"cd-info-group",[["class","row info-group"],["groupTitle","Performance"]],null,null,null,ut,ot)),s["\u0275did"](1,49152,null,0,st,[],{groupTitle:[0,"groupTitle"]},null),(t()(),s["\u0275eld"](2,0,null,0,10,"div",[["class","cd-container-flex"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,ee)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ne)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ie)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,se)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,oe)),s["\u0275did"](12,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"Performance"),t(e,4,0,n.healthData.client_perf),t(e,6,0,n.healthData.client_perf),t(e,8,0,n.healthData.client_perf),t(e,10,0,n.healthData.client_perf),t(e,12,0,n.healthData.scrub_status)},null)}function ce(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Pools"],["class","cd-col-5"],["contentClass","content-medium content-highlight"],["link","/pool"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],link:[1,"link"],cardClass:[2,"cardClass"],contentClass:[3,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," "]))],function(t,e){t(e,1,0,"Pools","/pool","card-medium","content-medium content-highlight")},function(t,e){t(e,2,0,e.component.healthData.pools.length)})}function le(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Raw Capacity"],["class","cd-col-5"],["contentClass","content-chart"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275eld"](2,0,null,0,1,"cd-health-pie",[],null,[[null,"prepareFn"]],function(t,e,n){var a=!0;return"prepareFn"===e&&(a=!1!==t.component.prepareRawUsage(n[0],n[1])&&a),a},yt,mt)),s["\u0275did"](3,638976,null,0,bt,[ht.a,gt.a],{data:[0,"data"],config:[1,"config"],showLabelAsTooltip:[2,"showLabelAsTooltip"]},{prepareFn:"prepareFn"})],function(t,e){var n=e.component;t(e,1,0,"Raw Capacity","card-medium","content-chart"),t(e,3,0,n.healthData,n.rawCapacityChartConfig,!0)},null)}function de(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardClass","card-medium"],["cardTitle","Objects"],["class","cd-col-5"],["contentClass","content-chart"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275eld"](2,0,null,0,1,"cd-health-pie",[],null,[[null,"prepareFn"]],function(t,e,n){var a=!0;return"prepareFn"===e&&(a=!1!==t.component.prepareObjects(n[0],n[1])&&a),a},yt,mt)),s["\u0275did"](3,638976,null,0,bt,[ht.a,gt.a],{data:[0,"data"],config:[1,"config"]},{prepareFn:"prepareFn"})],function(t,e){var n=e.component;t(e,1,0,"Objects","card-medium","content-chart"),t(e,3,0,n.healthData,n.objectsChartConfig)},null)}function fe(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-info-card",[["cardClass","card-medium"],["cardTitle","PGs per OSD"],["class","cd-col-5"],["contentClass","content-medium content-highlight"]],null,null,null,it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275ted"](2,0,[" "," "])),s["\u0275ppd"](3,1)],function(t,e){t(e,1,0,"PGs per OSD","card-medium","content-medium content-highlight")},function(t,e){var n=e.component,a=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent.parent.parent,7),n.healthData.pg_info.pgs_per_osd));t(e,2,0,a)})}function pe(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function he(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"li",[],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" ",": "," "]))],null,function(t,e){t(e,1,0,e.context.$implicit.key,e.context.$implicit.value)})}function ge(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,pe)),s["\u0275did"](1,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(t()(),s["\u0275eld"](2,0,null,null,3,"ul",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,2,null,he)),s["\u0275did"](4,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),s["\u0275pid"](0,i.KeyValuePipe,[s.KeyValueDiffers])],function(t,e){var n=e.component;t(e,1,0,s["\u0275nov"](e.parent.parent.parent,7)),t(e,4,0,s["\u0275unv"](e,4,0,s["\u0275nov"](e,5).transform(n.healthData.pg_info.statuses)))},null)}function be(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,7,"cd-info-card",[["cardClass","card-medium"],["cardTitle","PG Status"],["class","cd-col-5"],["contentClass","content-chart"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).toggle()&&a),a},it,nt)),s["\u0275did"](1,49152,null,0,et,[],{cardTitle:[0,"cardTitle"],cardClass:[1,"cardClass"],contentClass:[2,"contentClass"]},null),(t()(),s["\u0275and"](0,[["pgStatus",2]],0,0,null,ge)),(t()(),s["\u0275eld"](3,0,null,0,4,"div",[["class","pg-status-popover-wrapper"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,16777216,null,null,3,"div",[["placement","bottom"],["triggers",""]],null,null,null,null,null)),s["\u0275did"](5,212992,[["pgStatusTarget",4]],0,X.c,[X.a,s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,Q.a],{popover:[0,"popover"],placement:[1,"placement"],triggers:[2,"triggers"]},null),(t()(),s["\u0275eld"](6,0,null,null,1,"cd-health-pie",[],null,[[null,"prepareFn"]],function(t,e,n){var a=!0;return"prepareFn"===e&&(a=!1!==t.component.preparePgStatus(n[0],n[1])&&a),a},yt,mt)),s["\u0275did"](7,638976,null,0,bt,[ht.a,gt.a],{data:[0,"data"],config:[1,"config"]},{prepareFn:"prepareFn"})],function(t,e){var n=e.component;t(e,1,0,"PG Status","card-medium","content-chart"),t(e,5,0,s["\u0275nov"](e,2),"bottom",""),t(e,7,0,n.healthData,n.pgStatusChartConfig)},null)}function me(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,12,"cd-info-group",[["class","row info-group"],["groupTitle","Capacity"]],null,null,null,ut,ot)),s["\u0275did"](1,49152,null,0,st,[],{groupTitle:[0,"groupTitle"]},null),(t()(),s["\u0275eld"](2,0,null,0,10,"div",[["class","cd-container-flex"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,ce)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,le)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,de)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,fe)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,be)),s["\u0275did"](12,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"Capacity"),t(e,4,0,n.healthData.pools),t(e,6,0,n.healthData.df),t(e,8,0,null!=(null==n.healthData.pg_info?null:null==n.healthData.pg_info.object_stats?null:n.healthData.pg_info.object_stats.num_objects)),t(e,10,0,n.healthData.pg_info),t(e,12,0,n.healthData.pg_info)},null)}function ye(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,7,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,6,"p",[["class","logs-link"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"i",[["class","fa fa-info-circle"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[" See "])),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["routerLink","/logs"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,null,0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Logs"])),(t()(),s["\u0275ted"](-1,null,[" for more details."]))],function(t,e){t(e,5,0,"/logs")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function ve(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,ye)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.component.permissions.log.read)},null)}function _e(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,7,"div",[["class","container-fluid"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,te)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ue)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,me)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,[["logsLink",2]],null,0,null,ve))],function(t,e){var n=e.component;t(e,2,0,(null==n.healthData.health?null:n.healthData.health.status)||n.healthData.mon_status||n.healthData.osd_map||n.healthData.mgr_map||null!=n.healthData.hosts||null!=n.healthData.rgw||n.healthData.fs_map||null!=n.healthData.iscsi_daemons),t(e,4,0,n.healthData.client_perf||n.healthData.scrub_status),t(e,6,0,n.healthData.pools||n.healthData.df||n.healthData.pg_info)},null)}function xe(t){return s["\u0275vid"](0,[s["\u0275pid"](0,vt,[]),s["\u0275pid"](0,_t,[xt.a]),s["\u0275pid"](0,Tt,[xt.a]),s["\u0275pid"](0,wt,[xt.a]),s["\u0275pid"](0,St,[xt.a]),s["\u0275pid"](0,Ot,[]),s["\u0275pid"](0,ht.a,[It.a]),s["\u0275pid"](0,gt.a,[It.a]),(t()(),s["\u0275and"](16777216,null,null,2,null,_e)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),s["\u0275pid"](131072,i.AsyncPipe,[s.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,9,0,s["\u0275unv"](e,9,0,s["\u0275nov"](e,10).transform(n.healthData&&n.enabledFeature$)))},null)}var Te=n("gIcY"),we=n("ANnk"),Se=n("f/UV"),Oe=function(){function t(t){this.refreshIntervalService=t,this.intervalList={"5 s":5e3,"10 s":1e4,"15 s":15e3,"30 s":3e4,"1 min":6e4,"3 min":18e4,"5 min":3e5},this.intervalKeys=Object.keys(this.intervalList)}return t.prototype.ngOnInit=function(){this.selectedInterval=this.refreshIntervalService.getRefreshInterval()||5e3},t.prototype.changeRefreshInterval=function(t){this.refreshIntervalService.setRefreshInterval(t)},t}(),Ie=s["\u0275crt"]({encapsulation:0,styles:[[".refresh-selector[_ngcontent-%COMP%]{padding:0;float:right;margin-right:60px}.refresh-selector[_ngcontent-%COMP%] *[_ngcontent-%COMP%]{padding:0;box-sizing:border-box}.refresh-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{padding:10px 10px 0 0;text-align:right;margin:0}@media (min-width:500px) and (max-width:767px){.refresh-selector[_ngcontent-%COMP%]{width:24vw}}@media (min-width:1200px){.refresh-selector[_ngcontent-%COMP%]{width:12vw}}@media (min-width:1400px){.refresh-selector[_ngcontent-%COMP%]{width:10vw}}"]],data:{}});function Ce(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){var n=e.component;t(e,1,0,n.intervalList[e.context.$implicit]),t(e,2,0,n.intervalList[e.context.$implicit])},function(t,e){t(e,3,0,e.context.$implicit)})}function ke(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,14,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,13,"div",[["class","col-xs-5 col-sm-2 refresh-selector"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,2,"label",[["class","control-label col-xs-5 col-sm-5"],["for","refreshInterval"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Refresh"])),(t()(),s["\u0275eld"](5,0,null,null,9,"div",[["class","col-xs-7 col-sm-7"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,8,"select",[["class","form-control"],["id","refreshInterval"],["name","refreshInterval"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"ngModelChange"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,7).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,7).onTouched()&&a),"change"===e&&(a=!1!==r.changeRefreshInterval(n.target.value)&&a),"ngModelChange"===e&&(a=!1!==(r.selectedInterval=n)&&a),a},null,null)),s["\u0275did"](7,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](9,671744,null,0,Te.u,[[8,null],[8,null],[8,null],[6,Te.p]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](11,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](12,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ce)),s["\u0275did"](14,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){var n=e.component;t(e,9,0,"refreshInterval",n.selectedInterval),t(e,14,0,n.intervalKeys)},function(t,e){t(e,6,0,s["\u0275nov"](e,11).ngClassUntouched,s["\u0275nov"](e,11).ngClassTouched,s["\u0275nov"](e,11).ngClassPristine,s["\u0275nov"](e,11).ngClassDirty,s["\u0275nov"](e,11).ngClassValid,s["\u0275nov"](e,11).ngClassInvalid,s["\u0275nov"](e,11).ngClassPending)})}var Ne=function(){function t(){this.hasGrafana=!1}return t.prototype.ngOnInit=function(){},t}(),Re=s["\u0275crt"]({encapsulation:0,styles:[["div[_ngcontent-%COMP%]{padding-top:20px}"]],data:{}});function Ae(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,7,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](1,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](2,0,null,0,3,"tab",[["heading","Health"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](3,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](4,0,null,null,1,"cd-health",[],null,null,null,xe,qt)),s["\u0275did"](5,245760,null,0,Mt,[Rt,xt.a,l.a,Pt.a,At.a,Lt,ht.a,gt.a],null,null),(t()(),s["\u0275eld"](6,0,null,0,1,"tab",[["heading","Statistics"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](7,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null)],function(t,e){t(e,3,0,"Health"),t(e,5,0),t(e,7,0,"Statistics")},function(t,e){t(e,0,0,s["\u0275nov"](e,1).clazz),t(e,2,0,s["\u0275nov"](e,3).id,s["\u0275nov"](e,3).active,s["\u0275nov"](e,3).addClass),t(e,6,0,s["\u0275nov"](e,7).id,s["\u0275nov"](e,7).active,s["\u0275nov"](e,7).addClass)})}function De(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-health",[],null,null,null,xe,qt)),s["\u0275did"](1,245760,null,0,Mt,[Rt,xt.a,l.a,Pt.a,At.a,Lt,ht.a,gt.a],null,null)],function(t,e){t(e,1,0)},null)}function Ee(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"cd-refresh-selector",[],null,null,null,ke,Ie)),s["\u0275did"](2,114688,null,0,Oe,[Lt],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ae)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,De)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0),t(e,4,0,n.hasGrafana),t(e,6,0,!n.hasGrafana)},null)}function Le(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-dashboard",[],null,null,null,Ee,Re)),s["\u0275did"](1,114688,null,0,Ne,[],null,null)],function(t,e){t(e,1,0)},null)}var Pe=s["\u0275ccf"]("cd-dashboard",Ne,Le,{},{},[]),Me=n("a278"),qe=n("insk"),je=n("mSOc"),Fe=n("ZYjt"),ze=n("20UP"),Ge=n("+0ag"),Ye=n("25BL"),Ve=n("uIqm"),He=n("vCyI"),Be=function(){function t(t){this.authStorageService=t,this.grafanaPermission=this.authStorageService.getPermissions().grafana}return t.prototype.ngOnChanges=function(){this.selection.hasSelection&&(this.host=this.selection.first())},t}(),Ue=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function We(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](1,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](2,0,null,0,3,"tab",[["heading","Performance Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](3,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](4,0,null,null,1,"cd-grafana",[["grafanaStyle","three"],["uid","rtOg0AiWz"]],null,null,null,Me.b,Me.a)),s["\u0275did"](5,638976,null,0,qe.a,[je.a,Fe.DomSanitizer,ze.a,Ge.a,xt.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(t,e){var n=e.component;t(e,3,0,"Performance Details"),t(e,5,0,"host-details?var-ceph_hosts="+n.host.hostname,"three","rtOg0AiWz")},function(t,e){t(e,0,0,s["\u0275nov"](e,1).clazz),t(e,2,0,s["\u0275nov"](e,3).id,s["\u0275nov"](e,3).active,s["\u0275nov"](e,3).addClass)})}function Ke(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,We)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.selection.hasSingleSelection&&n.grafanaPermission.read)},null)}var $e=function(){function t(t){this.http=t}return t.prototype.list=function(){return this.http.get("api/host").toPromise().then(function(t){return t})},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c))},token:t,providedIn:Nt.a}),t}(),Ze=n("85J/"),Xe=function(){function t(t,e,n,a){this.authStorageService=t,this.hostService=e,this.cephShortVersionPipe=n,this.i18n=a,this.columns=[],this.hosts=[],this.isLoadingHosts=!1,this.cdParams={fromLink:"/hosts"},this.selection=new He.a,this.permissions=this.authStorageService.getPermissions()}return t.prototype.ngOnInit=function(){this.columns=[{name:this.i18n("Hostname"),prop:"hostname",flexGrow:1},{name:this.i18n("Services"),prop:"services",flexGrow:3,cellTemplate:this.servicesTpl},{name:this.i18n("Version"),prop:"ceph_version",flexGrow:1,pipe:this.cephShortVersionPipe}]},t.prototype.updateSelection=function(t){this.selection=t},t.prototype.getHosts=function(t){var e=this;if(!this.isLoadingHosts){var n={mds:"cephfs",mon:"monitor",osd:"osd",rgw:"rgw","rbd-mirror":"rbdMirroring",mgr:"manager","tcmu-runner":"iscsi"};this.isLoadingHosts=!0,this.hostService.list().then(function(t){t.map(function(t){return t.services.map(function(t){t.cdLink="/perf_counters/"+t.type+"/"+encodeURIComponent(t.id);var a=e.permissions[n[t.type]];return t.canRead=!!a&&a.read,t}),t}),e.hosts=t,e.isLoadingHosts=!1}).catch(function(){e.isLoadingHosts=!1,t.error()})}},t}(),Je=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Qe(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,1).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](1,671744,null,0,tt.o,[tt.l,tt.a,i.LocationStrategy],{queryParams:[0,"queryParams"],routerLink:[1,"routerLink"]},null),s["\u0275pad"](2,1),(t()(),s["\u0275ted"](3,null,["","."," "]))],function(t,e){var n=e.component.cdParams,a=t(e,2,0,e.parent.context.$implicit.cdLink);t(e,1,0,n,a)},function(t,e){t(e,0,0,s["\u0275nov"](e,1).target,s["\u0275nov"](e,1).href),t(e,3,0,e.parent.context.$implicit.type,e.parent.context.$implicit.id)})}function tn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" ","."," "]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit.type,e.parent.context.$implicit.id)})}function en(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"span",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Qe)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,tn)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275ted"](5,null,[" "," "]))],function(t,e){t(e,2,0,e.context.$implicit.canRead),t(e,4,0,!e.context.$implicit.canRead)},function(t,e){t(e,5,0,e.context.last?"":", ")})}function nn(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,en)),s["\u0275did"](1,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.context.value)},null)}function an(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"tab",[["heading","Overall Performance"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](1,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","two"],["uid","y0KGL0iZz"]],null,null,null,Me.b,Me.a)),s["\u0275did"](3,638976,null,0,qe.a,[je.a,Fe.DomSanitizer,ze.a,Ge.a,xt.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(t,e){t(e,1,0,"Overall Performance"),t(e,3,0,"host-overview?","two","y0KGL0iZz")},function(t,e){t(e,0,0,s["\u0275nov"](e,1).id,s["\u0275nov"](e,1).active,s["\u0275nov"](e,1).addClass)})}function rn(t){return s["\u0275vid"](0,[s["\u0275qud"](402653184,1,{servicesTpl:0}),(t()(),s["\u0275eld"](1,0,null,null,10,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](2,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](3,0,null,0,6,"tab",[["heading","Hosts List"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](4,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](5,0,null,null,4,"cd-table",[["columnMode","flex"],["selectionType","single"]],null,[[null,"fetchData"],[null,"updateSelection"]],function(t,e,n){var a=!0,r=t.component;return"fetchData"===e&&(a=!1!==r.getHosts(n)&&a),"updateSelection"===e&&(a=!1!==r.updateSelection(n)&&a),a},Ye.b,Ye.a)),s["\u0275did"](6,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],selectionType:[3,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(t()(),s["\u0275and"](0,[[1,2],["servicesTpl",2]],null,0,null,nn)),(t()(),s["\u0275eld"](8,0,null,2,1,"cd-host-details",[["cdTableDetail",""]],null,null,null,Ke,Ue)),s["\u0275did"](9,573440,null,0,Be,[l.a],{selection:[0,"selection"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,an)),s["\u0275did"](11,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,4,0,"Hosts List"),t(e,6,0,n.hosts,n.columns,"flex","single"),t(e,9,0,n.selection),t(e,11,0,n.permissions.grafana.read)},function(t,e){t(e,1,0,s["\u0275nov"](e,2).clazz),t(e,3,0,s["\u0275nov"](e,4).id,s["\u0275nov"](e,4).active,s["\u0275nov"](e,4).addClass)})}function sn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-hosts",[],null,null,null,rn,Je)),s["\u0275did"](1,114688,null,0,Xe,[l.a,$e,Ze.a,xt.a],null,null)],function(t,e){t(e,1,0)},null)}var on=s["\u0275ccf"]("cd-hosts",Xe,sn,{},{},[]),un=function(){function t(t){this.http=t}return t.prototype.getMonitor=function(){return this.http.get("api/monitor")},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c))},token:t,providedIn:Nt.a}),t}(),cn=n("x38r"),ln=function(){function t(t,e){this.monitorService=t,this.i18n=e,this.inQuorum={columns:[{prop:"name",name:this.i18n("Name"),cellTransformation:cn.a.routerLink},{prop:"rank",name:this.i18n("Rank")},{prop:"public_addr",name:this.i18n("Public Address")},{prop:"cdOpenSessions",name:this.i18n("Open Sessions"),cellTransformation:cn.a.sparkline,comparator:function(t,e){var n=ft.last(t),a=ft.last(e);return n&&a&&n!==a?n>a?1:-1:0}}],data:[]},this.notInQuorum={columns:[{prop:"name",name:this.i18n("Name"),cellTransformation:cn.a.routerLink},{prop:"rank",name:this.i18n("Rank")},{prop:"public_addr",name:this.i18n("Public Address")}],data:[]}}return t.prototype.refresh=function(){var t=this;this.monitorService.getMonitor().subscribe(function(e){e.in_quorum.map(function(t){return t.cdOpenSessions=t.stats.num_sessions.map(function(t){return t[1]}),t.cdLink="/perf_counters/mon/"+t.name,t.cdParams={fromLink:"/monitor"},t}),e.out_quorum.map(function(t){return t.cdLink="/perf_counters/mon/"+t.name,t.cdParams={fromLink:"/monitor"},t}),t.inQuorum.data=e.in_quorum.slice(),t.notInQuorum.data=e.out_quorum.slice(),t.mon_status=e.mon_status})},t}(),dn=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function fn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,36,"table",[["class","table table-striped"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,35,"tbody",[],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Cluster ID"])),(t()(),s["\u0275eld"](5,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](6,null,["",""])),(t()(),s["\u0275eld"](7,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["monmap modified"])),(t()(),s["\u0275eld"](10,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](11,null,["",""])),(t()(),s["\u0275eld"](12,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["monmap epoch"])),(t()(),s["\u0275eld"](15,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](16,null,["",""])),(t()(),s["\u0275eld"](17,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](18,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["quorum con"])),(t()(),s["\u0275eld"](20,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](21,null,["",""])),(t()(),s["\u0275eld"](22,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](23,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["quorum mon"])),(t()(),s["\u0275eld"](25,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](26,null,["",""])),(t()(),s["\u0275eld"](27,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](28,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["required con"])),(t()(),s["\u0275eld"](30,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](31,null,["",""])),(t()(),s["\u0275eld"](32,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](33,0,null,null,1,"td",[["class","bold"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["required mon"])),(t()(),s["\u0275eld"](35,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](36,null,["",""]))],null,function(t,e){var n=e.component;t(e,6,0,n.mon_status.monmap.fsid),t(e,11,0,n.mon_status.monmap.modified),t(e,16,0,n.mon_status.monmap.epoch),t(e,21,0,n.mon_status.features.quorum_con),t(e,26,0,n.mon_status.features.quorum_mon),t(e,31,0,n.mon_status.features.required_con),t(e,36,0,n.mon_status.features.required_mon)})}function pn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,15,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,5,"div",[["class","col-md-4"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,4,"fieldset",[],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,1,"legend",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Status"])),(t()(),s["\u0275and"](16777216,null,null,1,null,fn)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](7,0,null,null,8,"div",[["class","col-md-8"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,1,"legend",[["class","in-quorum"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["In Quorum"])),(t()(),s["\u0275eld"](10,0,null,null,1,"cd-table",[],null,null,null,Ye.b,Ye.a)),s["\u0275did"](11,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"]},null),(t()(),s["\u0275eld"](12,0,null,null,1,"legend",[["class","in-quorum"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Not In Quorum"])),(t()(),s["\u0275eld"](14,0,null,null,1,"cd-table",[],null,[[null,"fetchData"]],function(t,e,n){var a=!0;return"fetchData"===e&&(a=!1!==t.component.refresh()&&a),a},Ye.b,Ye.a)),s["\u0275did"](15,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"]},{fetchData:"fetchData"})],function(t,e){var n=e.component;t(e,6,0,n.mon_status),t(e,11,0,n.inQuorum.data,n.inQuorum.columns),t(e,15,0,n.notInQuorum.data,n.notInQuorum.columns)},null)}function hn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-monitor",[],null,null,null,pn,dn)),s["\u0275did"](1,49152,null,0,ln,[un,xt.a],null,null)],null,null)}var gn=s["\u0275ccf"]("cd-monitor",ln,hn,{},{},[]),bn=n("xtZt"),mn=n("xSw7"),yn=n("GgAd"),vn=n("xbqr"),_n=n("9GXa"),xn=n("NUGo"),Tn=n("S7zO"),wn=n("sLuX"),Sn=n("FSuO"),On=n("a0VL"),In=n("j8L6"),Cn=n("b5OY"),kn=n("pxLl"),Nn=function(){function t(){this.last={}}return t.prototype.ngOnChanges=function(){this.render()},t.prototype.hexdigits=function(t){var e=Math.floor(255*t).toString(16);return 1===e.length?"0"+e:e},t.prototype.hexcolor=function(t,e,n){return"#"+this.hexdigits(t)+this.hexdigits(e)+this.hexdigits(n)},t.prototype.render=function(){var t=this;if(this.histogram){var e=0;ft.each(this.histogram.values,function(n,a){ft.each(n,function(n,r){e=Math.max(e,t.last&&t.last[a]&&t.last[a][r]?n-t.last[a][r]:n)})}),this.valuesStyle=this.histogram.values.map(function(n,a){return n.map(function(n,r){var i=e?(t.last&&t.last[a]&&t.last[a][r]?n-t.last[a][r]:n)/e:0;return{backgroundColor:t.hexcolor(1-i,i,0)}})}),this.last=this.histogram.values}},t}(),Rn=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function An(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[["style","width: 10px; height: 10px;"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgStyle,[s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngStyle:[0,"ngStyle"]},null)],function(t,e){t(e,1,0,e.context.$implicit)},null)}function Dn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"tr",[["style","height: 10px;"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,An)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.context.$implicit)},null)}function En(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"table",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,2,"tbody",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Dn)),s["\u0275did"](3,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,3,0,e.component.valuesStyle)},null)}var Ln=function(){function t(t,e){this.http=t,this.i18n=e,this.path="api/osd",this.osdRecvSpeedModalPriorities={KNOWN_PRIORITIES:[{name:null,text:this.i18n("-- Select the priority --"),values:{osd_max_backfills:null,osd_recovery_max_active:null,osd_recovery_max_single_start:null,osd_recovery_sleep:null}},{name:"low",text:this.i18n("Low"),values:{osd_max_backfills:1,osd_recovery_max_active:1,osd_recovery_max_single_start:1,osd_recovery_sleep:.5}},{name:"default",text:this.i18n("Default"),values:{osd_max_backfills:1,osd_recovery_max_active:3,osd_recovery_max_single_start:1,osd_recovery_sleep:0}},{name:"high",text:this.i18n("High"),values:{osd_max_backfills:4,osd_recovery_max_active:4,osd_recovery_max_single_start:4,osd_recovery_sleep:0}}]}}return t.prototype.getList=function(){return this.http.get(""+this.path)},t.prototype.getDetails=function(t){return this.http.get(this.path+"/"+t)},t.prototype.scrub=function(t,e){return this.http.post(this.path+"/"+t+"/scrub?deep="+e,null)},t.prototype.getFlags=function(){return this.http.get(this.path+"/flags")},t.prototype.updateFlags=function(t){return this.http.put(this.path+"/flags",{flags:t})},t.prototype.markOut=function(t){return this.http.post(this.path+"/"+t+"/mark_out",null)},t.prototype.markIn=function(t){return this.http.post(this.path+"/"+t+"/mark_in",null)},t.prototype.markDown=function(t){return this.http.post(this.path+"/"+t+"/mark_down",null)},t.prototype.reweight=function(t,e){return this.http.post(this.path+"/"+t+"/reweight",{weight:e})},t.prototype.markLost=function(t){return this.http.post(this.path+"/"+t+"/mark_lost",null)},t.prototype.purge=function(t){return this.http.post(this.path+"/"+t+"/purge",null)},t.prototype.destroy=function(t){return this.http.post(this.path+"/"+t+"/destroy",null)},t.prototype.safeToDestroy=function(t){return this.http.get(this.path+"/"+t+"/safe_to_destroy")},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c),s.inject(xt.a))},token:t,providedIn:Nt.a}),t}(),Pn=function(){function t(t,e){this.osdService=t,this.authStorageService=e,this.grafanaPermission=this.authStorageService.getPermissions().grafana}return t.prototype.ngOnChanges=function(){this.osd={loaded:!1},this.selection.hasSelection&&(this.osd=this.selection.first(),this.refresh())},t.prototype.refresh=function(){var t=this;this.osdService.getDetails(this.osd.id).subscribe(function(e){t.osd.details=e,t.osd.histogram_failed="",ft.isObject(e.histogram)||(t.osd.histogram_failed=e.histogram,t.osd.details.histogram=void 0),t.osd.loaded=!0})},t}(),Mn=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function qn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-table-key-value",[],null,null,null,wn.b,wn.a)),s["\u0275did"](1,638976,null,0,Sn.a,[On.a],{data:[0,"data"]},null)],function(t,e){t(e,1,0,e.component.osd.details.osd_map)},null)}function jn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-table-key-value",[],null,[[null,"fetchData"]],function(t,e,n){var a=!0;return"fetchData"===e&&(a=!1!==t.component.refresh()&&a),a},wn.b,wn.a)),s["\u0275did"](1,638976,null,0,Sn.a,[On.a],{data:[0,"data"]},{fetchData:"fetchData"})],function(t,e){t(e,1,0,e.component.osd.details.osd_metadata)},null)}function Fn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-warning-panel",[],null,null,null,vn.b,vn.a)),s["\u0275did"](1,49152,null,0,_n.a,[],null,null),(t()(),s["\u0275ted"](-1,0,["Metadata not available"]))],null,null)}function zn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-table-performance-counter",[["serviceType","osd"]],null,null,null,In.b,In.a)),s["\u0275did"](1,114688,null,0,Cn.a,[kn.a,xt.a],{serviceType:[0,"serviceType"],serviceId:[1,"serviceId"]},null)],function(t,e){t(e,1,0,"osd",e.component.osd.id)},null)}function Gn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-warning-panel",[],null,null,null,vn.b,vn.a)),s["\u0275did"](1,49152,null,0,_n.a,[],null,null),(t()(),s["\u0275ted"](2,0,["Histogram not available: ",""]))],null,function(t,e){t(e,2,0,e.component.osd.histogram_failed)})}function Yn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,10,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,4,"div",[["class","col-md-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"h4",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Writes"])),(t()(),s["\u0275eld"](4,0,null,null,1,"cd-osd-performance-histogram",[],null,null,null,En,Rn)),s["\u0275did"](5,573440,null,0,Nn,[],{histogram:[0,"histogram"]},null),(t()(),s["\u0275eld"](6,0,null,null,4,"div",[["class","col-md-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,1,"h4",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Reads"])),(t()(),s["\u0275eld"](9,0,null,null,1,"cd-osd-performance-histogram",[],null,null,null,En,Rn)),s["\u0275did"](10,573440,null,0,Nn,[],{histogram:[0,"histogram"]},null)],function(t,e){var n=e.component;t(e,5,0,n.osd.details.histogram.osd.op_w_latency_in_bytes_histogram),t(e,10,0,n.osd.details.histogram.osd.op_r_latency_out_bytes_histogram)},null)}function Vn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"tab",[["heading","Performance Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](1,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","GrafanaStyles.two"],["uid","CrAHE0iZz"]],null,null,null,Me.b,Me.a)),s["\u0275did"](3,638976,null,0,qe.a,[je.a,Fe.DomSanitizer,ze.a,Ge.a,xt.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(t,e){var n=e.component;t(e,1,0,"Performance Details"),t(e,3,0,"osd-device-details?var-osd=osd."+n.osd.id,"GrafanaStyles.two","CrAHE0iZz")},function(t,e){t(e,0,0,s["\u0275nov"](e,1).id,s["\u0275nov"](e,1).active,s["\u0275nov"](e,1).addClass)})}function Hn(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,22,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](1,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](2,0,null,0,3,"tab",[["heading","Attributes (OSD map)"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](3,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,qn)),s["\u0275did"](5,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](6,0,null,0,4,"tab",[["heading","Metadata"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](7,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,jn)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(t()(),s["\u0275and"](0,[["noMetaData",2]],null,0,null,Fn)),(t()(),s["\u0275eld"](11,0,null,0,3,"tab",[["heading","Performance counter"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](12,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,zn)),s["\u0275did"](14,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](15,0,null,0,5,"tab",[["heading","Histogram"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](16,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Gn)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Yn)),s["\u0275did"](20,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,Vn)),s["\u0275did"](22,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,"Attributes (OSD map)"),t(e,5,0,n.osd.loaded),t(e,7,0,"Metadata"),t(e,9,0,n.osd.loaded&&n.osd.details.osd_metadata,s["\u0275nov"](e,10)),t(e,12,0,"Performance counter"),t(e,14,0,n.osd.loaded),t(e,16,0,"Histogram"),t(e,18,0,n.osd.loaded&&n.osd.histogram_failed),t(e,20,0,n.osd.loaded&&n.osd.details.histogram),t(e,22,0,n.grafanaPermission.read)},function(t,e){t(e,0,0,s["\u0275nov"](e,1).clazz),t(e,2,0,s["\u0275nov"](e,3).id,s["\u0275nov"](e,3).active,s["\u0275nov"](e,3).addClass),t(e,6,0,s["\u0275nov"](e,7).id,s["\u0275nov"](e,7).active,s["\u0275nov"](e,7).addClass),t(e,11,0,s["\u0275nov"](e,12).id,s["\u0275nov"](e,12).active,s["\u0275nov"](e,12).addClass),t(e,15,0,s["\u0275nov"](e,16).id,s["\u0275nov"](e,16).active,s["\u0275nov"](e,16).addClass)})}function Bn(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Hn)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,1,0,e.component.selection.hasSingleSelection)},null)}function Un(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-osd-details",[],null,null,null,Bn,Mn)),s["\u0275did"](1,573440,null,0,Pn,[Ln,l.a],null,null)],null,null)}var Wn=s["\u0275ccf"]("cd-osd-details",Pn,Un,{selection:"selection"},{},[]),Kn=n("OLbh"),$n=n("0+/T"),Zn=n("sne2"),Xn=n("mtw6"),Jn=n("9nlD"),Qn=function(){function t(t,e,n,a,r){this.bsModalRef=t,this.authStorageService=e,this.osdService=n,this.notificationService=a,this.i18n=r,this.osdFlagsForm=new Te.k({}),this.allFlags={noin:{code:"noin",name:this.i18n("No In"),value:!1,description:this.i18n("OSDs that were previously marked out will not be marked back in when they start")},noout:{code:"noout",name:this.i18n("No Out"),value:!1,description:this.i18n("OSDs will not automatically be marked out after the configured interval")},noup:{code:"noup",name:this.i18n("No Up"),value:!1,description:this.i18n("OSDs are not allowed to start")},nodown:{code:"nodown",name:this.i18n("No Down"),value:!1,description:this.i18n("OSD failure reports are being ignored, such that the monitors will not mark OSDs down")},pause:{code:"pause",name:this.i18n("Pause"),value:!1,description:this.i18n("Pauses reads and writes")},noscrub:{code:"noscrub",name:this.i18n("No Scrub"),value:!1,description:this.i18n("Scrubbing is disabled")},"nodeep-scrub":{code:"nodeep-scrub",name:this.i18n("No Deep Scrub"),value:!1,description:this.i18n("Deep Scrubbing is disabled")},nobackfill:{code:"nobackfill",name:this.i18n("No Backfill"),value:!1,description:this.i18n("Backfilling of PGs is suspended")},norebalance:{code:"norebalance",name:this.i18n("No Rebalance"),value:!1,description:this.i18n("OSD will choose not to backfill unless PG is also degraded")},norecover:{code:"norecover",name:this.i18n("No Recover"),value:!1,description:this.i18n("Recovery of PGs is suspended")},sortbitwise:{code:"sortbitwise",name:this.i18n("Bitwise Sort"),value:!1,description:this.i18n("Use bitwise sort"),disabled:!0},purged_snapdirs:{code:"purged_snapdirs",name:this.i18n("Purged Snapdirs"),value:!1,description:this.i18n("OSDs have converted snapsets"),disabled:!0},recovery_deletes:{code:"recovery_deletes",name:this.i18n("Recovery Deletes"),value:!1,description:this.i18n("Deletes performed during recovery instead of peering"),disabled:!0},pglog_hardlimit:{code:"pglog_hardlimit",name:this.i18n("PG Log Hard Limit"),value:!1,description:this.i18n("Puts a hard limit on pg log length"),disabled:!0}},this.unknownFlags=[],this.permissions=this.authStorageService.getPermissions()}return t.prototype.ngOnInit=function(){var t=this;this.osdService.getFlags().subscribe(function(e){e.forEach(function(e){t.allFlags[e]?t.allFlags[e].value=!0:t.unknownFlags.push(e)}),t.flags=ft.toArray(t.allFlags)})},t.prototype.submitAction=function(){var t=this,e=this.flags.filter(function(t){return t.value}).map(function(t){return t.code}).concat(this.unknownFlags);this.osdService.updateFlags(e).subscribe(function(){t.notificationService.show(Xn.a.success,t.i18n("Updated OSD Flags")),t.bsModalRef.hide()},function(){t.bsModalRef.hide()})},t}(),ta=n("VNr4"),ea=n("MuvH"),na=n("QFaf"),aa=n("1Ni5"),ra=function(){function t(){}return t.getType=function(t){var e=ft.find(this.knownTypes,function(e){return e.name===t});if(void 0!==e)return e;throw new Error('Found unknown type "'+t+'" for config option.')},t.getTypeValidators=function(e){var n=t.getType(e.type);if("bool"!==n.name&&"str"!==n.name){var a={validators:[],patternHelpText:n.patternHelpText};return n.isNumberType?(e.max&&""!==e.max&&(a.max=e.max,a.validators.push(Te.A.max(e.max))),e.min&&""!==e.min?(a.min=e.min,a.validators.push(Te.A.min(e.min))):"defaultMin"in n&&(a.min=n.defaultMin,a.validators.push(Te.A.min(n.defaultMin))),a.validators.push("float"===e.type?aa.a.decimalNumber():aa.a.number(n.allowsNegative))):"addr"===e.type?a.validators=[aa.a.ip()]:"uuid"===e.type&&(a.validators=[aa.a.uuid()]),a}},t.getTypeStep=function(t,e){if(["uint","int","size","secs"].includes(t))return 1;if("float"===t){if(null!==e&&-1!==e.toString().indexOf(".")){var n=e.toString().split(".");return Math.pow(10,-n[1].length)}return.1}},t.knownTypes=[{name:"uint",inputType:"number",humanReadable:"Unsigned integer value",defaultMin:0,patternHelpText:"The entered value needs to be an unsigned number.",isNumberType:!0,allowsNegative:!1},{name:"int",inputType:"number",humanReadable:"Integer value",patternHelpText:"The entered value needs to be a number.",isNumberType:!0,allowsNegative:!0},{name:"size",inputType:"number",humanReadable:"Unsigned integer value (>=16bit)",defaultMin:0,patternHelpText:"The entered value needs to be a unsigned number.",isNumberType:!0,allowsNegative:!1},{name:"secs",inputType:"number",humanReadable:"Number of seconds",defaultMin:1,patternHelpText:"The entered value needs to be a number >= 1.",isNumberType:!0,allowsNegative:!1},{name:"float",inputType:"number",humanReadable:"Double value",patternHelpText:"The entered value needs to be a number or decimal.",isNumberType:!0,allowsNegative:!0},{name:"str",inputType:"text",humanReadable:"Text",isNumberType:!1},{name:"addr",inputType:"text",humanReadable:"IPv4 or IPv6 address",patternHelpText:"The entered value needs to be a valid IP address.",isNumberType:!1},{name:"uuid",inputType:"text",humanReadable:"UUID",patternHelpText:"The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8",isNumberType:!1},{name:"bool",inputType:"checkbox",humanReadable:"Boolean value",isNumberType:!1}],t}(),ia=function(){function t(t){this.configService=t,this.optionNames=[],this.optionsForm=new na.a({}),this.optionsFormDir=new Te.t([],[]),this.optionsFormGroupName="",this.optionsFormShowReset=!0,this.options=[],this.optionsFormGroup=new na.a({})}return t.optionNameToText=function(t){var e=["mon","mgr","osd","mds","client"];return t.split("_").filter(function(t,n){return 0!==n||!e.includes(t)}).map(function(t){return t.charAt(0).toUpperCase()+t.substring(1)}).join(" ")},t.prototype.ngOnInit=function(){this.createForm(),this.loadStoredData()},t.prototype.createForm=function(){var t=this;this.optionsForm.addControl(this.optionsFormGroupName,this.optionsFormGroup),this.optionNames.forEach(function(e){t.optionsFormGroup.addControl(e,new Te.i(null))})},t.prototype.getStep=function(t,e){return ra.getTypeStep(t,e)},t.prototype.loadStoredData=function(){var e=this;this.configService.filter(this.optionNames).subscribe(function(n){e.options=n.map(function(n){var a=e.optionsForm.get(n.name),r=ra.getTypeValidators(n);return n.additionalTypeInfo=ra.getType(n.type),n.text=t.optionNameToText(n.name),n.value=ft.find(n.value,function(t){return"osd"===t.section}),n.value&&a.setValue("bool"===n.additionalTypeInfo.name?"true"===n.value.value:n.value.value),r&&(n.patternHelpText=r.patternHelpText,"max"in r&&""!==r.max&&(n.maxValue=r.max),"min"in r&&""!==r.min&&(n.minValue=r.min),a.setValidators(r.validators)),n})})},t.prototype.saveValues=function(){var t=this,e={};return this.optionNames.forEach(function(n){var a=t.optionsForm.getValue(n);null!==a&&""!==a&&(e[n]={section:"osd",value:a})}),this.configService.bulkCreate({options:e})},t.prototype.resetValue=function(t){var e=this;this.configService.delete(t,"osd").subscribe(function(){e.optionsForm.get(t).reset()})},t}(),sa=function(){function t(){}return t.basicOptions=["osd_scrub_during_recovery","osd_scrub_begin_hour","osd_scrub_end_hour","osd_scrub_begin_week_day","osd_scrub_end_week_day","osd_scrub_min_interval","osd_scrub_max_interval","osd_deep_scrub_interval","osd_scrub_auto_repair","osd_max_scrubs","osd_scrub_priority","osd_scrub_sleep"],t.advancedOptions=["osd_scrub_auto_repair_num_errors","osd_debug_deep_scrub_sleep","osd_deep_scrub_keys","osd_deep_scrub_large_omap_object_key_threshold","osd_deep_scrub_large_omap_object_value_sum_threshold","osd_deep_scrub_randomize_ratio","osd_deep_scrub_stride","osd_deep_scrub_update_digest_min_age","osd_op_queue_mclock_scrub_lim","osd_op_queue_mclock_scrub_res","osd_op_queue_mclock_scrub_wgt","osd_requested_scrub_priority","osd_scrub_backoff_ratio","osd_scrub_chunk_max","osd_scrub_chunk_min","osd_scrub_cost","osd_scrub_interval_randomize_ratio","osd_scrub_invalid_stats","osd_scrub_load_threshold","osd_scrub_max_preemptions"],t}(),oa=function(){function t(t,e,n,a,r){this.bsModalRef=t,this.authStorageService=e,this.notificationService=n,this.i18n=a,this.actionLabels=r,this.basicOptions=sa.basicOptions,this.advancedOptions=sa.advancedOptions,this.advancedEnabled=!1,this.osdPgScrubForm=new na.a({}),this.resource=this.i18n("PG scrub options"),this.action=this.actionLabels.EDIT,this.permissions=this.authStorageService.getPermissions()}return t.prototype.submitAction=function(){var t=this,e=[this.basicOptionsValues.saveValues()];this.advancedOptionsValues&&e.push(this.advancedOptionsValues.saveValues()),Object(ta.a)(e).subscribe(function(){t.notificationService.show(Xn.a.success,t.i18n("Updated PG scrub options")),t.bsModalRef.hide()},function(){t.bsModalRef.hide()})},t}(),ua=function(){function t(t,e,n,a,r,i){var s=this;this.bsModalRef=t,this.authStorageService=e,this.configService=n,this.notificationService=a,this.i18n=r,this.osdService=i,this.priorities=[],this.priorityAttrs={},this.permissions=this.authStorageService.getPermissions(),this.priorities=this.osdService.osdRecvSpeedModalPriorities.KNOWN_PRIORITIES,this.osdRecvSpeedForm=new na.a({priority:new Te.i(null,{validators:[Te.A.required]}),customizePriority:new Te.i(!1)}),this.priorityAttrs={osd_max_backfills:{text:this.i18n("Max Backfills"),desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0},osd_recovery_max_active:{text:this.i18n("Recovery Max Active"),desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0},osd_recovery_max_single_start:{text:this.i18n("Recovery Max Single Start"),desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0},osd_recovery_sleep:{text:this.i18n("Recovery Sleep"),desc:"",patternHelpText:"",maxValue:void 0,minValue:void 0}},Object.keys(this.priorityAttrs).forEach(function(t){s.osdRecvSpeedForm.addControl(t,new Te.i(null,{validators:[Te.A.required]}))})}return t.prototype.ngOnInit=function(){var t=this;this.configService.filter(Object.keys(this.priorityAttrs)).subscribe(function(e){var n=t.getCurrentValues(e);t.detectPriority(n.values,function(e){t.setPriority(e)}),t.setDescription(n.configOptions),t.setValidators(n.configOptions)})},t.prototype.detectPriority=function(t,e){var n=ft.find(this.priorities,function(e){return ft.isEqual(e.values,t)});return this.osdRecvSpeedForm.controls.customizePriority.setValue(!1),n?e(n):4===Object.entries(t).length?(this.osdRecvSpeedForm.controls.customizePriority.setValue(!0),e(Object({name:"custom",text:this.i18n("Custom"),values:t}))):e(this.priorities[0])},t.prototype.getCurrentValues=function(t){var e={values:{},configOptions:[]};return t.forEach(function(t){e.configOptions.push(t),"value"in t?t.value.forEach(function(n){"osd"===n.section&&(e.values[t.name]=Number(n.value))}):"default"in t&&null!==t.default&&(e.values[t.name]=Number(t.default))}),e},t.prototype.setDescription=function(t){var e=this;t.forEach(function(t){""!==t.desc&&(e.priorityAttrs[t.name].desc=t.desc)})},t.prototype.setPriority=function(t){var e=this,n=ft.find(this.priorities,function(t){return"custom"===t.name});"custom"===t.name?n||this.priorities.push(t):n&&this.priorities.splice(this.priorities.indexOf(n),1),this.osdRecvSpeedForm.controls.priority.setValue(t.name),Object.entries(t.values).forEach(function(t){e.osdRecvSpeedForm.controls[t[0]].setValue(t[1])})},t.prototype.setValidators=function(t){var e=this;t.forEach(function(t){var n=ra.getTypeValidators(t);n?(n.validators.push(Te.A.required),"max"in n&&""!==n.max&&(e.priorityAttrs[t.name].maxValue=n.max),"min"in n&&""!==n.min&&(e.priorityAttrs[t.name].minValue=n.min),e.priorityAttrs[t.name].patternHelpText=n.patternHelpText,e.osdRecvSpeedForm.controls[t.name].setValidators(n.validators)):e.osdRecvSpeedForm.controls[t.name].setValidators(Te.A.required)})},t.prototype.onCustomizePriorityChange=function(){var t=this,e={};if(Object.keys(this.priorityAttrs).forEach(function(n){e[n]=t.osdRecvSpeedForm.getValue(n)}),this.osdRecvSpeedForm.getValue("customizePriority")){var n={name:"custom",text:this.i18n("Custom"),values:e};this.setPriority(n)}else this.detectPriority(e,function(e){t.setPriority(e)})},t.prototype.onPriorityChange=function(t){var e=ft.find(this.priorities,function(e){return e.name===t})||this.priorities[0];this.osdRecvSpeedForm.get("customizePriority").setValue(!1),this.setPriority(e)},t.prototype.submitAction=function(){var t=this,e={};Object.keys(this.priorityAttrs).forEach(function(n){e[n]={section:"osd",value:t.osdRecvSpeedForm.getValue(n)}}),this.configService.bulkCreate({options:e}).subscribe(function(){t.notificationService.show(Xn.a.success,t.i18n('Updated OSD recovery speed priority "{{value}}"',{value:t.osdRecvSpeedForm.getValue("priority")})),t.bsModalRef.hide()},function(){t.bsModalRef.hide()})},t}(),ca=n("2EZI"),la=function(){function t(t,e,n){this.bsModalRef=t,this.osdService=e,this.fb=n,this.currentWeight=1}return Object.defineProperty(t.prototype,"weight",{get:function(){return this.reweightForm.get("weight")},enumerable:!0,configurable:!0}),t.prototype.ngOnInit=function(){this.reweightForm=this.fb.group({weight:this.fb.control(this.currentWeight,[Te.A.required,Te.A.max(1),Te.A.min(0)])})},t.prototype.reweight=function(){var t=this;this.osdService.reweight(this.osdId,this.reweightForm.value.weight).subscribe(function(){return t.bsModalRef.hide()})},t}(),da=function(){function t(t,e,n,a){this.bsModalRef=t,this.osdService=e,this.notificationService=n,this.i18n=a,this.selected=[]}return t.prototype.ngOnInit=function(){this.scrubForm=new Te.k({})},t.prototype.scrub=function(){var t=this,e=this.selected[0].id;this.osdService.scrub(e,this.deep).subscribe(function(){t.notificationService.show(Xn.a.success,t.i18n("{{operation}} was initialized in the following OSD: {{id}}",{operation:t.deep?"Deep scrub":"Scrub",id:e})),t.bsModalRef.hide()},function(){t.bsModalRef.hide()})},t}(),fa=function(){function t(t,e,n,a,r,i){var s=this;this.authStorageService=t,this.osdService=e,this.dimlessBinaryPipe=n,this.modalService=a,this.i18n=r,this.actionLabels=i,this.osds=[],this.selection=new He.a,this.permissions=this.authStorageService.getPermissions(),this.tableActions=[{name:this.actionLabels.SCRUB,permission:"update",icon:"fa-stethoscope",click:function(){return s.scrubAction(!1)},disable:function(){return!s.hasOsdSelected}},{name:this.actionLabels.DEEP_SCRUB,permission:"update",icon:"fa-cog",click:function(){return s.scrubAction(!0)},disable:function(){return!s.hasOsdSelected}},{name:this.actionLabels.REWEIGHT,permission:"update",click:function(){return s.reweight()},disable:function(){return!s.hasOsdSelected},icon:"fa-balance-scale"},{name:this.actionLabels.MARK_OUT,permission:"update",click:function(){return s.showConfirmationModal(s.i18n("out"),s.osdService.markOut)},disable:function(){return s.isNotSelectedOrInState("out")},icon:"fa-arrow-left"},{name:this.actionLabels.MARK_IN,permission:"update",click:function(){return s.showConfirmationModal(s.i18n("in"),s.osdService.markIn)},disable:function(){return s.isNotSelectedOrInState("in")},icon:"fa-arrow-right"},{name:this.actionLabels.MARK_DOWN,permission:"update",click:function(){return s.showConfirmationModal(s.i18n("down"),s.osdService.markDown)},disable:function(){return s.isNotSelectedOrInState("down")},icon:"fa-arrow-down"},{name:this.actionLabels.MARK_LOST,permission:"delete",click:function(){return s.showCriticalConfirmationModal(s.i18n("Mark"),s.i18n("OSD lost"),s.i18n("marked lost"),s.osdService.markLost)},disable:function(){return s.isNotSelectedOrInState("up")},icon:"fa-unlink"},{name:this.actionLabels.PURGE,permission:"delete",click:function(){return s.showCriticalConfirmationModal(s.i18n("Purge"),s.i18n("OSD"),s.i18n("purged"),s.osdService.purge)},disable:function(){return s.isNotSelectedOrInState("up")},icon:"fa-eraser"},{name:this.actionLabels.DESTROY,permission:"delete",click:function(){return s.showCriticalConfirmationModal(s.i18n("destroy"),s.i18n("OSD"),s.i18n("destroyed"),s.osdService.destroy)},disable:function(){return s.isNotSelectedOrInState("up")},icon:"fa-remove"}],this.advancedTableActions=[{name:this.i18n("Cluster-wide Flags"),icon:"fa-flag",click:function(){return s.configureFlagsAction()},permission:this.permissions.osd.read},{name:this.i18n("Cluster-wide Recovery Priority"),icon:"fa-cog",click:function(){return s.configureQosParamsAction()},permission:this.permissions.configOpt.read},{name:this.i18n("PG scrub"),icon:"fa-stethoscope",click:function(){return s.configurePgScrubAction()},permission:this.permissions.configOpt.read}]}return t.collectStates=function(t){return[t.in?"in":"out",t.up?"up":"down"]},t.prototype.ngOnInit=function(){this.columns=[{prop:"host.name",name:this.i18n("Host")},{prop:"id",name:this.i18n("ID"),cellTransformation:cn.a.bold},{prop:"collectedStates",name:this.i18n("Status"),cellTemplate:this.statusColor},{prop:"stats.numpg",name:this.i18n("PGs")},{prop:"stats.stat_bytes",name:this.i18n("Size"),pipe:this.dimlessBinaryPipe},{prop:"stats.usage",name:this.i18n("Usage"),cellTemplate:this.osdUsageTpl},{prop:"stats_history.out_bytes",name:this.i18n("Read bytes"),cellTransformation:cn.a.sparkline},{prop:"stats_history.in_bytes",name:this.i18n("Write bytes"),cellTransformation:cn.a.sparkline},{prop:"stats.op_r",name:this.i18n("Read ops"),cellTransformation:cn.a.perSecond},{prop:"stats.op_w",name:this.i18n("Write ops"),cellTransformation:cn.a.perSecond}],this.removeActionsWithNoPermissions()},Object.defineProperty(t.prototype,"hasOsdSelected",{get:function(){if(this.selection.hasSelection){var t=this.selection.first().id;return!!this.osds.filter(function(e){return e.id===t}).pop()}return!1},enumerable:!0,configurable:!0}),t.prototype.updateSelection=function(t){this.selection=t},t.prototype.isNotSelectedOrInState=function(t){if(!this.hasOsdSelected)return!0;var e=this.selection.first().id,n=this.osds.filter(function(t){return t.id===e}).pop();if(!n)return!0;switch(t){case"in":return 1===n.in;case"out":return 1!==n.in;case"down":return 1!==n.up;case"up":return 1===n.up}},t.prototype.getOsdList=function(){var e=this;this.osdService.getList().subscribe(function(n){e.osds=n.map(function(e){return e.collectedStates=t.collectStates(e),e.stats_history.out_bytes=e.stats_history.op_out_bytes.map(function(t){return t[1]}),e.stats_history.in_bytes=e.stats_history.op_in_bytes.map(function(t){return t[1]}),e.stats.usage=e.stats.stat_bytes_used/e.stats.stat_bytes,e.cdIsBinary=!0,e})})},t.prototype.scrubAction=function(t){this.hasOsdSelected&&(this.bsModalRef=this.modalService.show(da,{initialState:{selected:this.tableComponent.selection.selected,deep:t}}))},t.prototype.configureFlagsAction=function(){this.bsModalRef=this.modalService.show(Qn,{})},t.prototype.showConfirmationModal=function(t,e){var n=this;this.bsModalRef=this.modalService.show(Kn.a,{initialState:{titleText:this.i18n("Mark OSD {{markAction}}",{markAction:t}),buttonText:this.i18n("Mark {{markAction}}",{markAction:t}),bodyTpl:this.markOsdConfirmationTpl,bodyContext:{markActionDescription:t},onSubmit:function(){e.call(n.osdService,n.selection.first().id).subscribe(function(){return n.bsModalRef.hide()})}}})},t.prototype.reweight=function(){var t=this,e=this.osds.filter(function(e){return e.id===t.selection.first().id}).pop();this.modalService.show(la,{initialState:{currentWeight:e.weight,osdId:e.id}})},t.prototype.showCriticalConfirmationModal=function(t,e,n,a){var r=this;this.osdService.safeToDestroy(this.selection.first().id).subscribe(function(i){var s=r.modalService.show($n.a,{initialState:{actionDescription:t,itemDescription:e,bodyTemplate:r.criticalConfirmationTpl,bodyContext:{result:i,actionDescription:n},submitAction:function(){a.call(r.osdService,r.selection.first().id).subscribe(function(){return s.hide()})}}})})},t.prototype.configureQosParamsAction=function(){this.bsModalRef=this.modalService.show(ua,{})},t.prototype.configurePgScrubAction=function(){this.bsModalRef=this.modalService.show(oa,{class:"modal-lg"})},t.prototype.removeActionsWithNoPermissions=function(){this.advancedTableActions=this.permissions?this.advancedTableActions.filter(function(t){return t.permission}):[]},t}(),pa=n("DQlY"),ha=s["\u0275crt"]({encapsulation:0,styles:[[".caret.caret-black[_ngcontent-%COMP%]{color:#000}"]],data:{}});function ga(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"button",[["class","btn btn-sm btn-default dropdown-toggle dropdown-toggle-split"],["dropdownToggle",""],["type","button"]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,1).onClick()&&a),a},null,null)),s["\u0275did"](1,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275eld"](2,0,null,null,0,"span",[["class","caret caret-black"]],null,null,null,null,null))],null,function(t,e){t(e,0,0,!0,s["\u0275nov"](e,1).isDisabled,s["\u0275nov"](e,1).isOpen)})}function ba(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,4,"li",[["role","menuitem"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,3,"a",[["class","dropdown-item"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.context.$implicit.click()&&a),a},null,null)),(t()(),s["\u0275eld"](3,0,null,null,0,"i",[["aria-hidden","true"]],[[8,"className",0]],null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](5,null,["",""]))],null,function(t,e){t(e,3,0,s["\u0275inlineInterpolate"](1,"fa fa-fw ",e.context.$implicit.icon,"")),t(e,5,0,e.context.$implicit.name)})}function ma(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"ul",[["class","dropdown-menu"],["role","menu"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,2,null,ba)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),s["\u0275pid"](0,i.SlicePipe,[])],function(t,e){var n=e.component;t(e,2,0,s["\u0275unv"](e,2,0,s["\u0275nov"](e,3).transform(n.advancedTableActions,1)))},null)}function ya(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,16777216,null,null,10,"div",[["class","btn-group"],["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](2,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),(t()(),s["\u0275eld"](3,0,null,null,3,"button",[["class","btn btn-sm btn-default btn-label tc_configureCluster"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.advancedTableActions[0].click()&&a),a},null,null)),(t()(),s["\u0275eld"](4,0,null,null,0,"i",[],[[8,"className",0]],null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](6,null,["",""])),(t()(),s["\u0275and"](16777216,null,null,1,null,ga)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ma)),s["\u0275did"](10,16384,null,0,bn.d,[bn.f,s.ViewContainerRef,s.TemplateRef],null,null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,2,0),t(e,8,0,n.advancedTableActions.length>1)},function(t,e){var n=e.component;t(e,0,0,s["\u0275nov"](e,2).dropup,s["\u0275nov"](e,2).isOpen,s["\u0275nov"](e,2).isOpen&&s["\u0275nov"](e,2).isBs4),t(e,4,0,s["\u0275inlineInterpolate"](1,"fa fa-fw ",n.advancedTableActions[0].icon,"")),t(e,6,0,n.advancedTableActions[0].name)})}function va(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0"]))],null,null)}function _a(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,8,"span",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,5,"span",[["class","label"]],null,null,null,null,null)),s["\u0275did"](2,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pad"](3,2),s["\u0275pad"](4,2),s["\u0275pod"](5,{"label-success":0,"label-danger":1}),(t()(),s["\u0275ted"](6,null,["",""])),(t()(),s["\u0275and"](16777216,null,null,1,null,va)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=t(e,5,0,t(e,3,0,"in","up").includes(e.context.$implicit),t(e,4,0,"down","out").includes(e.context.$implicit));t(e,2,0,"label",n),t(e,8,0,!e.context.last)},function(t,e){t(e,6,0,e.context.$implicit)})}function xa(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,_a)),s["\u0275did"](1,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.context.value)},null)}function Ta(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-usage-bar",[],null,null,null,mn.b,mn.a)),s["\u0275did"](1,573440,null,0,yn.a,[],{total:[0,"total"],used:[1,"used"]},null)],function(t,e){t(e,1,0,e.context.row.stats.stat_bytes,e.context.row.stats.stat_bytes_used)},null)}function wa(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"tab",[["heading","Overall Performance"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](1,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","three"],["uid","lo02I1Aiz"]],null,null,null,Me.b,Me.a)),s["\u0275did"](3,638976,null,0,qe.a,[je.a,Fe.DomSanitizer,ze.a,Ge.a,xt.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(t,e){t(e,1,0,"Overall Performance"),t(e,3,0,"osd-overview?","three","lo02I1Aiz")},function(t,e){t(e,0,0,s["\u0275nov"](e,1).id,s["\u0275nov"](e,1).active,s["\u0275nov"](e,1).addClass)})}function Sa(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,["OSD ",""])),(t()(),s["\u0275ted"](-1,null,[" will be marked "])),(t()(),s["\u0275eld"](4,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](5,null,["",""])),(t()(),s["\u0275ted"](-1,null,[" if you proceed."]))],null,function(t,e){t(e,2,0,e.component.selection.first().id),t(e,5,0,e.context.markActionDescription)})}function Oa(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"div",[["class","danger"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,2,"cd-warning-panel",[],null,null,null,vn.b,vn.a)),s["\u0275did"](2,49152,null,0,_n.a,[],null,null),(t()(),s["\u0275ted"](-1,0,["The OSD is not safe to destroy!"]))],null,null)}function Ia(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Oa)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](2,0,null,null,6,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](4,null,["OSD ",""])),(t()(),s["\u0275ted"](-1,null,[" will be "])),(t()(),s["\u0275eld"](6,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](7,null,["",""])),(t()(),s["\u0275ted"](-1,null,[" if you proceed."]))],function(t,e){t(e,1,0,!e.context.result.is_safe_to_destroy)},function(t,e){t(e,4,0,e.component.selection.first().id),t(e,7,0,e.context.actionDescription)})}function Ca(t){return s["\u0275vid"](0,[s["\u0275qud"](402653184,1,{statusColor:0}),s["\u0275qud"](402653184,2,{osdUsageTpl:0}),s["\u0275qud"](402653184,3,{markOsdConfirmationTpl:0}),s["\u0275qud"](402653184,4,{criticalConfirmationTpl:0}),s["\u0275qud"](402653184,5,{tableComponent:0}),s["\u0275qud"](402653184,6,{reweightBodyTpl:0}),s["\u0275qud"](402653184,7,{safeToDestroyBodyTpl:0}),(t()(),s["\u0275eld"](7,0,null,null,16,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](8,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](9,0,null,0,12,"tab",[["heading","OSDs List"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](10,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](11,0,null,null,8,"cd-table",[["selectionType","single"]],null,[[null,"fetchData"],[null,"updateSelection"]],function(t,e,n){var a=!0,r=t.component;return"fetchData"===e&&(a=!1!==r.getOsdList()&&a),"updateSelection"===e&&(a=!1!==r.updateSelection(n)&&a),a},Ye.b,Ye.a)),s["\u0275did"](12,2867200,[[5,4]],0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],selectionType:[2,"selectionType"],updateSelectionOnRefresh:[3,"updateSelectionOnRefresh"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(t()(),s["\u0275eld"](13,0,null,0,4,"div",[["class","table-actions btn-toolbar"]],null,null,null,null,null)),(t()(),s["\u0275eld"](14,0,null,null,1,"cd-table-actions",[["class","btn-group"]],null,null,null,xn.b,xn.a)),s["\u0275did"](15,114688,null,0,Tn.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ya)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](18,0,null,2,1,"cd-osd-details",[["cdTableDetail",""]],null,null,null,Bn,Mn)),s["\u0275did"](19,573440,null,0,Pn,[Ln,l.a],{selection:[0,"selection"]},null),(t()(),s["\u0275and"](0,[[1,2],["statusColor",2]],null,0,null,xa)),(t()(),s["\u0275and"](0,[[2,2],["osdUsageTpl",2]],null,0,null,Ta)),(t()(),s["\u0275and"](16777216,null,0,1,null,wa)),s["\u0275did"](23,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,[[3,2],["markOsdConfirmationTpl",2]],null,0,null,Sa)),(t()(),s["\u0275and"](0,[[4,2],["criticalConfirmationTpl",2]],null,0,null,Ia))],function(t,e){var n=e.component;t(e,10,0,"OSDs List"),t(e,12,0,n.osds,n.columns,"single","never"),t(e,15,0,n.permissions.osd,n.selection,n.tableActions),t(e,17,0,n.advancedTableActions.length>0),t(e,19,0,n.selection),t(e,23,0,n.permissions.grafana.read)},function(t,e){t(e,7,0,s["\u0275nov"](e,8).clazz),t(e,9,0,s["\u0275nov"](e,10).id,s["\u0275nov"](e,10).active,s["\u0275nov"](e,10).addClass)})}function ka(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-osd-list",[],null,null,null,Ca,ha)),s["\u0275did"](1,114688,null,0,fa,[l.a,Ln,ht.a,pa.b,xt.a,Zn.b],null,null)],function(t,e){t(e,1,0)},null)}var Na=s["\u0275ccf"]("cd-osd-list",fa,ka,{},{},[]),Ra=function(){function t(){}return t.prototype.transform=function(t,e){return t.filter(function(t){var n=!0;return e.forEach(function(e){if(e.value)return(n=n&&e.applyFilter(t,e.value))?void 0:n}),n})},t}(),Aa=n("iExv"),Da=function(){function t(t){this.i18n=t,this.flags={runtime:this.i18n("The value can be updated at runtime."),no_mon_update:this.i18n("Daemons/clients do not pull this value from the\n monitor config database. We disallow setting this option via 'ceph config\n set ...'. This option should be configured via ceph.conf or via the\n command line."),startup:this.i18n("Option takes effect only during daemon startup."),cluster_create:this.i18n("Option only affects cluster creation."),create:this.i18n("Option only affects daemon creation.")}}return t.prototype.ngOnChanges=function(){this.selection.hasSelection&&(this.selectedItem=this.selection.first(),this.selectedItem.services=ft.split(this.selectedItem.services,","))},t}(),Ea=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function La(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" ",": ","",""])),(t()(),s["\u0275eld"](2,0,null,null,0,"br",[],null,null,null,null,null))],null,function(t,e){t(e,1,0,e.context.$implicit.section,e.context.$implicit.value,e.context.last?"":",")})}function Pa(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"span",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,3,"span",[],[[8,"title",0]],null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,2,"span",[["class","badge badge-pill badge-primary margin-right-sm"]],null,null,null,null,null)),(t()(),s["\u0275ted"](3,null,["",""])),s["\u0275ppd"](4,1)],null,function(t,e){t(e,1,0,s["\u0275inlineInterpolate"](1,"",e.component.flags[e.context.$implicit],""));var n=s["\u0275unv"](e,3,0,t(e,4,0,s["\u0275nov"](e.parent.parent,0),e.context.$implicit));t(e,3,0,n)})}function Ma(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[["class","badge badge-pill badge-primary margin-right-sm"]],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,2,0,e.context.$implicit)})}function qa(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,94,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](1,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](2,0,null,0,92,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](3,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](4,0,null,null,90,"table",[["class","table table-striped table-bordered"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,89,"tbody",[],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Name"])),(t()(),s["\u0275eld"](9,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](10,null,["",""])),(t()(),s["\u0275eld"](11,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Description"])),(t()(),s["\u0275eld"](14,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](15,null,["",""])),(t()(),s["\u0275eld"](16,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](17,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Long description"])),(t()(),s["\u0275eld"](19,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](20,null,["",""])),(t()(),s["\u0275eld"](21,0,null,null,5,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](22,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Current values"])),(t()(),s["\u0275eld"](24,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,La)),s["\u0275did"](26,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](27,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](28,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Default"])),(t()(),s["\u0275eld"](30,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](31,null,["",""])),(t()(),s["\u0275eld"](32,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](33,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Daemon default"])),(t()(),s["\u0275eld"](35,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](36,null,["",""])),(t()(),s["\u0275eld"](37,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](38,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Type"])),(t()(),s["\u0275eld"](40,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](41,null,["",""])),(t()(),s["\u0275eld"](42,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](43,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Min"])),(t()(),s["\u0275eld"](45,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](46,null,["",""])),(t()(),s["\u0275eld"](47,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](48,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Max"])),(t()(),s["\u0275eld"](50,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](51,null,["",""])),(t()(),s["\u0275eld"](52,0,null,null,5,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](53,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Flags"])),(t()(),s["\u0275eld"](55,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Pa)),s["\u0275did"](57,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](58,0,null,null,5,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](59,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Services"])),(t()(),s["\u0275eld"](61,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Ma)),s["\u0275did"](63,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](64,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](65,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Source"])),(t()(),s["\u0275eld"](67,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](68,null,["",""])),(t()(),s["\u0275eld"](69,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](70,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Level"])),(t()(),s["\u0275eld"](72,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](73,null,["",""])),(t()(),s["\u0275eld"](74,0,null,null,5,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](75,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Can be updated at runtime (editable)"])),(t()(),s["\u0275eld"](77,0,null,null,2,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](78,null,["",""])),s["\u0275ppd"](79,1),(t()(),s["\u0275eld"](80,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](81,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Tags"])),(t()(),s["\u0275eld"](83,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](84,null,["",""])),(t()(),s["\u0275eld"](85,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](86,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Enum values"])),(t()(),s["\u0275eld"](88,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](89,null,["",""])),(t()(),s["\u0275eld"](90,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](91,0,null,null,1,"td",[["class","bold col-sm-1"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["See also"])),(t()(),s["\u0275eld"](93,0,null,null,1,"td",[["class","col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](94,null,["",""]))],function(t,e){var n=e.component;t(e,3,0,"Details"),t(e,26,0,n.selectedItem.value),t(e,57,0,n.selectedItem.flags),t(e,63,0,n.selectedItem.services)},function(t,e){var n=e.component;t(e,0,0,s["\u0275nov"](e,1).clazz),t(e,2,0,s["\u0275nov"](e,3).id,s["\u0275nov"](e,3).active,s["\u0275nov"](e,3).addClass),t(e,10,0,n.selectedItem.name),t(e,15,0,n.selectedItem.desc),t(e,20,0,n.selectedItem.long_desc),t(e,31,0,n.selectedItem.default),t(e,36,0,n.selectedItem.daemon_default),t(e,41,0,n.selectedItem.type),t(e,46,0,n.selectedItem.min),t(e,51,0,n.selectedItem.max),t(e,68,0,n.selectedItem.source),t(e,73,0,n.selectedItem.level);var a=s["\u0275unv"](e,78,0,t(e,79,0,s["\u0275nov"](e.parent,1),n.selectedItem.can_update_at_runtime));t(e,78,0,a),t(e,84,0,n.selectedItem.tags),t(e,89,0,n.selectedItem.enum_values),t(e,94,0,n.selectedItem.see_also)})}function ja(t){return s["\u0275vid"](0,[s["\u0275pid"](0,i.UpperCasePipe,[]),s["\u0275pid"](0,Aa.a,[xt.a]),(t()(),s["\u0275and"](16777216,null,null,1,null,qa)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,null==n.selection?null:n.selection.hasSingleSelection)},null)}var Fa=function(){function t(t,e,n,a){var r=this;this.authStorageService=t,this.configurationService=e,this.i18n=n,this.actionLabels=a,this.data=[],this.selection=new He.a,this.filters=[{label:this.i18n("Level"),prop:"level",initValue:"basic",value:"basic",options:["basic","advanced","dev"],applyFilter:function(t,e){var n=function(t){return t[t.basic=0]="basic",t[t.advanced=1]="advanced",t[t.dev=2]="dev",t}({});return n[t.level]<=n[e]}},{label:this.i18n("Service"),prop:"services",initValue:"any",value:"any",options:["any","mon","mgr","osd","mds","common","mds_client","rgw"],applyFilter:function(t,e){return"any"===e||t.services.includes(e)}},{label:this.i18n("Source"),prop:"source",initValue:"any",value:"any",options:["any","mon"],applyFilter:function(t,e){return"any"===e||!!t.hasOwnProperty("source")&&t.source.includes(e)}}],this.permission=this.authStorageService.getPermissions().configOpt,this.tableActions=[{permission:"update",icon:"fa-pencil",routerLink:function(){return"/configuration/edit/"+(r.selection.first()&&""+encodeURIComponent(r.selection.first().name))},name:this.actionLabels.EDIT,disable:function(){return!r.isEditable(r.selection)}}]}return t.prototype.ngOnInit=function(){this.columns=[{canAutoResize:!0,prop:"name",name:this.i18n("Name")},{prop:"desc",name:this.i18n("Description"),cellClass:"wrap"},{prop:"value",name:this.i18n("Current value"),cellClass:"wrap",cellTemplate:this.confValTpl},{prop:"default",name:this.i18n("Default"),cellClass:"wrap"},{prop:"can_update_at_runtime",name:this.i18n("Editable"),cellTransformation:cn.a.checkIcon,flexGrow:.4,cellClass:"text-center"}]},t.prototype.updateSelection=function(t){this.selection=t},t.prototype.getConfigurationList=function(t){var e=this;this.configurationService.getConfigData().subscribe(function(t){e.data=t},function(){t.error()})},t.prototype.updateFilter=function(){this.data=this.data.slice()},t.prototype.resetFilter=function(){this.filters.forEach(function(t){t.value=t.initValue}),this.data=this.data.slice()},t.prototype.isEditable=function(t){return 1===t.selected.length&&t.selected[0].can_update_at_runtime},t}(),za=s["\u0275crt"]({encapsulation:0,styles:[[".filter[_ngcontent-%COMP%]{padding-right:8px} datatable-body-cell.wrap{word-break:break-all}"]],data:{}});function Ga(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],null,null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],null,null),(t()(),s["\u0275ted"](3,null,["",""]))],null,function(t,e){t(e,3,0,e.context.$implicit)})}function Ya(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,11,"div",[["class","form-group filter"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"label",[],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,["",": "])),(t()(),s["\u0275eld"](3,0,null,null,8,"select",[["class","form-control input-sm"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,5).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,5).onTouched()&&a),"ngModelChange"===e&&(a=!1!==(t.context.$implicit.value=n)&&a),"ngModelChange"===e&&(a=!1!==r.updateFilter()&&a),a},null,null)),s["\u0275did"](4,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](5,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](7,671744,null,0,Te.u,[[8,null],[8,null],[8,null],[6,Te.p]],{model:[0,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](9,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ga)),s["\u0275did"](11,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,7,0,e.context.$implicit.value),t(e,11,0,e.context.$implicit.options)},function(t,e){t(e,2,0,e.context.$implicit.label),t(e,3,0,s["\u0275nov"](e,9).ngClassUntouched,s["\u0275nov"](e,9).ngClassTouched,s["\u0275nov"](e,9).ngClassPristine,s["\u0275nov"](e,9).ngClassDirty,s["\u0275nov"](e,9).ngClassValid,s["\u0275nov"](e,9).ngClassInvalid,s["\u0275nov"](e,9).ngClassPending)})}function Va(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" ",": ","",""])),(t()(),s["\u0275eld"](2,0,null,null,0,"br",[],null,null,null,null,null))],null,function(t,e){t(e,1,0,e.context.$implicit.section,e.context.$implicit.value,e.context.last?"":",")})}function Ha(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Va)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.parent.context.value)},null)}function Ba(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Ha)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.context.value)},null)}function Ua(t){return s["\u0275vid"](0,[s["\u0275pid"](0,Ra,[]),s["\u0275qud"](402653184,1,{confValTpl:0}),s["\u0275qud"](402653184,2,{confFlagTpl:0}),(t()(),s["\u0275eld"](3,0,null,null,12,"cd-table",[["selectionType","single"]],null,[[null,"fetchData"],[null,"updateSelection"]],function(t,e,n){var a=!0,r=t.component;return"fetchData"===e&&(a=!1!==r.getConfigurationList(n)&&a),"updateSelection"===e&&(a=!1!==r.updateSelection(n)&&a),a},Ye.b,Ye.a)),s["\u0275did"](4,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],selectionType:[2,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),s["\u0275ppd"](5,2),(t()(),s["\u0275eld"](6,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,xn.b,xn.a)),s["\u0275did"](7,114688,null,0,Tn.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(t()(),s["\u0275eld"](8,0,null,1,5,"div",[["class","table-filters"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Ya)),s["\u0275did"](10,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](11,0,null,null,2,"a",[["class","fa-stack"],["title","Reset filters"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.resetFilter()&&a),a},null,null)),(t()(),s["\u0275eld"](12,0,null,null,0,"i",[["class","fa fa-filter fa-stack-2x"]],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,0,"i",[["class","fa fa-times fa-stack-1x"],["style","margin-left: 8px; margin-top: 5px;"]],null,null,null,null,null)),(t()(),s["\u0275eld"](14,0,null,2,1,"cd-configuration-details",[["cdTableDetail",""]],null,null,null,ja,Ea)),s["\u0275did"](15,573440,null,0,Da,[xt.a],{selection:[0,"selection"]},null),(t()(),s["\u0275and"](0,[[1,2],["confValTpl",2]],null,0,null,Ba))],function(t,e){var n=e.component,a=s["\u0275unv"](e,4,0,t(e,5,0,s["\u0275nov"](e,0),n.data,n.filters));t(e,4,0,a,n.columns,"single"),t(e,7,0,n.permission,n.selection,n.tableActions),t(e,10,0,n.filters),t(e,15,0,n.selection)},null)}function Wa(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-configuration",[],null,null,null,Ua,za)),s["\u0275did"](1,114688,null,0,Fa,[l.a,ea.a,xt.a,Zn.b],null,null)],function(t,e){t(e,1,0)},null)}var Ka=s["\u0275ccf"]("cd-configuration",Fa,Wa,{},{},[]),$a=n("gp3X"),Za=n("sb0X"),Xa=n("KVJa"),Ja=n("Z21x"),Qa=function(){return function(){this.value=[]}}(),tr=function(){function t(t,e,n,a,r){this.route=t,this.router=e,this.configService=n,this.notificationService=a,this.i18n=r,this.availSections=["global","mon","mgr","osd","mds","client"],this.createForm()}return t.prototype.createForm=function(){var t={name:new Te.i({value:null}),desc:new Te.i({value:null}),long_desc:new Te.i({value:null}),values:new Te.k({}),default:new Te.i({value:null}),daemon_default:new Te.i({value:null}),services:new Te.i([])};this.availSections.forEach(function(e){t.values.addControl(e,new Te.i(null))}),this.configForm=new na.a(t)},t.prototype.ngOnInit=function(){var t=this;this.route.params.subscribe(function(e){t.configService.get(e.name).subscribe(function(e){t.setResponse(e)})})},t.prototype.getValidators=function(t){var e=ra.getTypeValidators(t);if(e)return this.patternHelpText=e.patternHelpText,"max"in e&&""!==e.max&&(this.maxValue=e.max),"min"in e&&""!==e.min&&(this.minValue=e.min),e.validators},t.prototype.getStep=function(t,e){return ra.getTypeStep(t,e)},t.prototype.setResponse=function(t){var e=this;this.response=t;var n=this.getValidators(t);this.configForm.get("name").setValue(t.name),this.configForm.get("desc").setValue(t.desc),this.configForm.get("long_desc").setValue(t.long_desc),this.configForm.get("default").setValue(t.default),this.configForm.get("daemon_default").setValue(t.daemon_default),this.configForm.get("services").setValue(t.services),this.response.value&&this.response.value.forEach(function(t){var n;n="true"===t.value||"false"!==t.value&&t.value,e.configForm.get("values").get(t.section).setValue(n)}),this.availSections.forEach(function(t){e.configForm.get("values").get(t).setValidators(n)});var a=ra.getType(t.type);this.type=a.name,this.inputType=a.inputType,this.humanReadableType=a.humanReadable},t.prototype.createRequest=function(){var t=this,e=[];if(this.availSections.forEach(function(n){var a=t.configForm.getValue(n);null!==a&&""!==a&&e.push({section:n,value:a})}),!ft.isEqual(this.response.value,e)){var n=new Qa;return n.name=this.configForm.getValue("name"),n.value=e,n}return null},t.prototype.submit=function(){var t=this,e=this.createRequest();e&&this.configService.create(e).subscribe(function(){t.notificationService.show(Xn.a.success,t.i18n("Updated config option {{name}}",{name:e.name})),t.router.navigate(["/configuration"])},function(){t.configForm.setErrors({cdSubmitButton:!0})}),this.router.navigate(["/configuration"])},t}(),er=s["\u0275crt"]({encapsulation:0,styles:[[".form-component-badge[_ngcontent-%COMP%]{height:34px;display:block}.form-component-badge[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{margin-top:7px}.resize-vertical[_ngcontent-%COMP%]{resize:vertical}"]],data:{}});function nr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Description"])),(t()(),s["\u0275eld"](3,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,6,"textarea",[["class","form-control resize-vertical"],["formControlName","desc"],["id","desc"],["readonly",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,5)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,5).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,5)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,5)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](5,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](7,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](9,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275ted"](-1,null,[" "]))],function(t,e){t(e,7,0,"desc")},function(t,e){t(e,4,0,s["\u0275nov"](e,9).ngClassUntouched,s["\u0275nov"](e,9).ngClassTouched,s["\u0275nov"](e,9).ngClassPristine,s["\u0275nov"](e,9).ngClassDirty,s["\u0275nov"](e,9).ngClassValid,s["\u0275nov"](e,9).ngClassInvalid,s["\u0275nov"](e,9).ngClassPending)})}function ar(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Long description"])),(t()(),s["\u0275eld"](3,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,6,"textarea",[["class","form-control resize-vertical"],["formControlName","long_desc"],["id","long_desc"],["readonly",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,5)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,5).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,5)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,5)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](5,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](7,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](9,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275ted"](-1,null,[" "]))],function(t,e){t(e,7,0,"long_desc")},function(t,e){t(e,4,0,s["\u0275nov"](e,9).ngClassUntouched,s["\u0275nov"](e,9).ngClassTouched,s["\u0275nov"](e,9).ngClassPristine,s["\u0275nov"](e,9).ngClassDirty,s["\u0275nov"](e,9).ngClassValid,s["\u0275nov"](e,9).ngClassInvalid,s["\u0275nov"](e,9).ngClassPending)})}function rr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Default"])),(t()(),s["\u0275eld"](3,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,6,"input",[["class","form-control"],["formControlName","default"],["id","default"],["readonly",""],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,6)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,6).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,6)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,6)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](5,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](6,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](8,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](10,16384,null,0,Te.r,[[4,Te.q]],null,null)],function(t,e){t(e,8,0,"default")},function(t,e){t(e,4,0,s["\u0275nov"](e,10).ngClassUntouched,s["\u0275nov"](e,10).ngClassTouched,s["\u0275nov"](e,10).ngClassPristine,s["\u0275nov"](e,10).ngClassDirty,s["\u0275nov"](e,10).ngClassValid,s["\u0275nov"](e,10).ngClassInvalid,s["\u0275nov"](e,10).ngClassPending)})}function ir(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Daemon default"])),(t()(),s["\u0275eld"](3,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,6,"input",[["class","form-control"],["formControlName","daemon_default"],["id","daemon_default"],["readonly",""],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,6)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,6).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,6)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,6)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](5,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](6,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](8,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](10,16384,null,0,Te.r,[[4,Te.q]],null,null)],function(t,e){t(e,8,0,"daemon_default")},function(t,e){t(e,4,0,s["\u0275nov"](e,10).ngClassUntouched,s["\u0275nov"](e,10).ngClassTouched,s["\u0275nov"](e,10).ngClassPristine,s["\u0275nov"](e,10).ngClassDirty,s["\u0275nov"](e,10).ngClassValid,s["\u0275nov"](e,10).ngClassInvalid,s["\u0275nov"](e,10).ngClassPending)})}function sr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[["class","form-component-badge"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[["class","badge badge-pill badge-primary"]],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,2,0,e.context.$implicit)})}function or(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Services"])),(t()(),s["\u0275eld"](3,0,null,null,2,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,sr)),s["\u0275did"](5,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,5,0,e.component.configForm.getValue("services"))},null)}function ur(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"label",[["class","control-label col-sm-3"]],[[8,"htmlFor",0]],null,null,null,null)),(t()(),s["\u0275ted"](2,null,[""," "])),(t()(),s["\u0275eld"](3,0,null,null,19,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,18,"select",[["class","form-control custom-select"],["id","pool"],["name","pool"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,6).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,6).onTouched()&&a),a},null,null)),s["\u0275did"](5,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](6,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](8,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](10,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275eld"](11,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](12,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{ngValue:[0,"ngValue"]},null),s["\u0275did"](13,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(t()(),s["\u0275ted"](-1,null,["-- Default --"])),(t()(),s["\u0275eld"](15,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](16,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{ngValue:[0,"ngValue"]},null),s["\u0275did"](17,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(t()(),s["\u0275ted"](-1,null,["true"])),(t()(),s["\u0275eld"](19,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](20,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{ngValue:[0,"ngValue"]},null),s["\u0275did"](21,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(t()(),s["\u0275ted"](-1,null,["false"]))],function(t,e){t(e,8,0,e.parent.context.$implicit),t(e,12,0,null),t(e,13,0,null),t(e,16,0,!0),t(e,17,0,!0),t(e,20,0,!1),t(e,21,0,!1)},function(t,e){t(e,1,0,e.parent.context.$implicit),t(e,2,0,e.parent.context.$implicit),t(e,4,0,s["\u0275nov"](e,10).ngClassUntouched,s["\u0275nov"](e,10).ngClassTouched,s["\u0275nov"](e,10).ngClassPristine,s["\u0275nov"](e,10).ngClassDirty,s["\u0275nov"](e,10).ngClassValid,s["\u0275nov"](e,10).ngClassInvalid,s["\u0275nov"](e,10).ngClassPending)})}function cr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "]))],null,function(t,e){t(e,1,0,e.component.patternHelpText)})}function lr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "]))],null,function(t,e){t(e,1,0,e.component.patternHelpText)})}function dr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too high! It must not be greater than ","."]))],null,function(t,e){t(e,1,0,e.component.maxValue)})}function fr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too low! It must not be lower than ","."]))],null,function(t,e){t(e,1,0,e.component.minValue)})}function pr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,1,"label",[["class","control-label col-sm-3"]],[[8,"htmlFor",0]],null,null,null,null)),(t()(),s["\u0275ted"](4,null,[""," "])),(t()(),s["\u0275eld"](5,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,6,"input",[["class","form-control"]],[[8,"type",0],[8,"id",0],[8,"placeholder",0],[8,"step",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,8)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,8).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,8)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,8)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](7,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](8,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](10,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](12,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,cr)),s["\u0275did"](14,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,lr)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,dr)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,fr)),s["\u0275did"](20,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.configForm.showError(e.parent.context.$implicit,s["\u0275nov"](e.parent.parent,3)));t(e,1,0,"form-group",a),t(e,10,0,e.parent.context.$implicit),t(e,14,0,n.configForm.showError(e.parent.context.$implicit,s["\u0275nov"](e.parent.parent,3),"pattern")),t(e,16,0,n.configForm.showError(e.parent.context.$implicit,s["\u0275nov"](e.parent.parent,3),"invalidUuid")),t(e,18,0,n.configForm.showError(e.parent.context.$implicit,s["\u0275nov"](e.parent.parent,3),"max")),t(e,20,0,n.configForm.showError(e.parent.context.$implicit,s["\u0275nov"](e.parent.parent,3),"min"))},function(t,e){var n=e.component;t(e,3,0,e.parent.context.$implicit),t(e,4,0,e.parent.context.$implicit),t(e,6,1,[n.inputType,e.parent.context.$implicit,n.humanReadableType,n.getStep(n.type,n.configForm.getValue(e.parent.context.$implicit)),s["\u0275nov"](e,12).ngClassUntouched,s["\u0275nov"](e,12).ngClassTouched,s["\u0275nov"](e,12).ngClassPristine,s["\u0275nov"](e,12).ngClassDirty,s["\u0275nov"](e,12).ngClassValid,s["\u0275nov"](e,12).ngClassInvalid,s["\u0275nov"](e,12).ngClassPending])})}function hr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,ur)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,pr)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,"bool"===n.type),t(e,4,0,"bool"!==n.type)},null)}function gr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,49,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,48,"form",[["class","form-horizontal"],["name","configForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,3).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,3).onReset()&&a),a},null,null)),s["\u0275did"](2,16384,null,0,Te.D,[],null,null),s["\u0275did"](3,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](5,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](6,0,null,null,43,"div",[["class","panel panel-default"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(t()(),s["\u0275eld"](9,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Edit"])),(t()(),s["\u0275ted"](11,null,[" "," "])),(t()(),s["\u0275eld"](12,0,null,null,29,"div",[["class","panel-body"]],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,10,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](14,0,null,null,1,"label",[["class","control-label col-sm-3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Name"])),(t()(),s["\u0275eld"](16,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](17,0,null,null,6,"input",[["class","form-control"],["formControlName","name"],["id","name"],["readonly",""],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,19)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,19).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](18,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](19,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](21,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](23,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,nr)),s["\u0275did"](25,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ar)),s["\u0275did"](27,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,rr)),s["\u0275did"](29,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ir)),s["\u0275did"](31,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,or)),s["\u0275did"](33,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](34,0,null,null,7,"div",[["class","col-sm-12"],["formGroupName","values"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),s["\u0275did"](35,212992,null,0,Te.m,[[3,Te.d],[8,null],[8,null]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.m]),s["\u0275did"](37,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](38,0,null,null,1,"h2",[["class","page-header"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Values"])),(t()(),s["\u0275and"](16777216,null,null,1,null,hr)),s["\u0275did"](41,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](42,0,null,null,7,"div",[["class","panel-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](43,0,null,null,6,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),s["\u0275eld"](44,0,null,null,3,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.submit()&&a),a},$a.b,$a.a)),s["\u0275did"](45,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(t()(),s["\u0275eld"](46,0,null,0,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Save"])),(t()(),s["\u0275eld"](48,0,null,null,1,"cd-back-button",[],null,null,null,Xa.b,Xa.a)),s["\u0275did"](49,49152,null,0,Ja.a,[i.Location,Zn.b],null,null)],function(t,e){var n=e.component;t(e,3,0,n.configForm),t(e,21,0,"name"),t(e,25,0,n.configForm.getValue("desc")),t(e,27,0,n.configForm.getValue("long_desc")),t(e,29,0,""!==n.configForm.getValue("default")),t(e,31,0,""!==n.configForm.getValue("daemon_default")),t(e,33,0,n.configForm.getValue("services").length>0),t(e,35,0,"values"),t(e,41,0,n.availSections),t(e,45,0,s["\u0275nov"](e,3),"button")},function(t,e){var n=e.component;t(e,1,0,s["\u0275nov"](e,5).ngClassUntouched,s["\u0275nov"](e,5).ngClassTouched,s["\u0275nov"](e,5).ngClassPristine,s["\u0275nov"](e,5).ngClassDirty,s["\u0275nov"](e,5).ngClassValid,s["\u0275nov"](e,5).ngClassInvalid,s["\u0275nov"](e,5).ngClassPending),t(e,11,0,n.configForm.getValue("name")),t(e,17,0,s["\u0275nov"](e,23).ngClassUntouched,s["\u0275nov"](e,23).ngClassTouched,s["\u0275nov"](e,23).ngClassPristine,s["\u0275nov"](e,23).ngClassDirty,s["\u0275nov"](e,23).ngClassValid,s["\u0275nov"](e,23).ngClassInvalid,s["\u0275nov"](e,23).ngClassPending),t(e,34,0,s["\u0275nov"](e,37).ngClassUntouched,s["\u0275nov"](e,37).ngClassTouched,s["\u0275nov"](e,37).ngClassPristine,s["\u0275nov"](e,37).ngClassDirty,s["\u0275nov"](e,37).ngClassValid,s["\u0275nov"](e,37).ngClassInvalid,s["\u0275nov"](e,37).ngClassPending)})}function br(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-configuration-form",[],null,null,null,gr,er)),s["\u0275did"](1,114688,null,0,tr,[tt.a,tt.l,ea.a,Jn.a,xt.a],null,null)],function(t,e){t(e,1,0)},null)}var mr=s["\u0275ccf"]("cd-configuration-form",tr,br,{},{},[]),yr=n("nuQ0"),vr=n("Tff5"),_r=n("urB8"),xr=n("xtUU"),Tr=function(){function t(t){this.healthService=t,this.metadataKeyMap={}}return t.prototype.ngOnInit=function(){var t=this;this.healthService.getFullHealth().subscribe(function(e){t.tree=t._abstractTreeData(e)})},t.prototype._abstractTreeData=function(t){var e=this,n=t.osd_map.tree.nodes||[],a={};if(0===n.length)return{value:"No nodes!",settings:{static:!0}};var r=[];return n.reverse().forEach(function(t){"root"===t.type&&r.push(t.id),a[t.id]=e.generateTreeLeaf(t,a)}),{value:"CRUSH map",children:r.map(function(t){return a[t]})}},t.prototype.generateTreeLeaf=function(t,e){var n=t.id;this.metadataKeyMap[n]=t;var a={static:!0},r=t.name+" ("+t.type+")",i=t.status,s=[];return t.children?(t.children.sort().forEach(function(t){s.push(e[t])}),{value:r,status:i,settings:a,id:n,children:s}):{value:r,status:i,settings:a,id:n}},t.prototype.onNodeSelected=function(t){var e=this.metadataKeyMap[t.node.id],n=e.name,a=e.type,r=p.__rest(e,["name","type","status"]);this.metadata=r,this.metadataTitle=n+" ("+a+")"},t}(),wr=s["\u0275crt"]({encapsulation:0,styles:[["tree-internal .tree li{cursor:pointer} tree-internal .tree .node-value{color:#2b99a8;border-radius:5px} tree-internal .tree .node-selected{background-color:#d9edf7;color:#212121} tree-internal .tree .node-value:hover{color:#212121} tree-internal .tree .node-value:after{height:0}"]],data:{}});function Sr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"span",[["class","label"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pad"](2,2),s["\u0275pad"](3,3),s["\u0275pod"](4,{"label-success":0,"label-danger":1}),(t()(),s["\u0275ted"](5,null,["",""])),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0"])),(t()(),s["\u0275eld"](8,0,null,null,0,"span",[["class","node-name"]],[[8,"innerHTML",1]],null,null,null,null))],function(t,e){var n=t(e,4,0,t(e,2,0,"in","up").includes(e.context.$implicit.status),t(e,3,0,"down","out","destroyed").includes(e.context.$implicit.status));t(e,1,0,"label",n)},function(t,e){t(e,5,0,e.context.$implicit.status),t(e,8,0,e.context.$implicit.value)})}function Or(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"div",[["class","col-sm-6 col-lg-6 metadata"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"legend",[],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,["",""])),(t()(),s["\u0275eld"](3,0,null,null,1,"cd-table-key-value",[],null,null,null,wn.b,wn.a)),s["\u0275did"](4,638976,null,0,Sn.a,[On.a],{data:[0,"data"]},null)],function(t,e){t(e,4,0,e.component.metadata)},function(t,e){t(e,2,0,e.component.metadataTitle)})}function Ir(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,16,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,15,"div",[["class","col-sm-12 col-lg-12"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,14,"div",[["class","panel panel-default"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,3,"div",[["class","panel-heading"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,2,"h3",[["class","panel-title"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["CRUSH map viewer"])),(t()(),s["\u0275eld"](7,0,null,null,9,"div",[["class","panel-body"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,6,"div",[["class","col-sm-6 col-lg-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](9,0,null,null,5,"tree",[],null,[[null,"nodeSelected"]],function(t,e,n){var a=!0;return"nodeSelected"===e&&(a=!1!==t.component.onNodeSelected(n)&&a),a},yr.b,yr.a)),s["\u0275prd"](512,null,vr.TreeService,vr.TreeService,[_r.NodeDraggableService]),s["\u0275did"](11,770048,null,1,xr.TreeComponent,[vr.TreeService],{treeModel:[0,"treeModel"],settings:[1,"settings"]},{nodeSelected:"nodeSelected"}),s["\u0275qud"](335544320,1,{template:0}),s["\u0275pod"](13,{rootIsVisible:0}),(t()(),s["\u0275and"](0,[[1,2]],null,0,null,Sr)),(t()(),s["\u0275and"](16777216,null,null,1,null,Or)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=n.tree,r=t(e,13,0,!1);t(e,11,0,a,r),t(e,16,0,n.metadata)},null)}function Cr(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-crushmap",[],null,null,null,Ir,wr)),s["\u0275did"](1,114688,null,0,Tr,[Rt],null,null)],function(t,e){t(e,1,0)},null)}var kr=s["\u0275ccf"]("cd-crushmap",Tr,Cr,{},{},[]),Nr=n("ARl4"),Rr=n("MwfX"),Ar=function(){function t(){}return t.prototype.writeValue=function(e){return{type:t.WRITE_VALUE,payload:e}},t.prototype.changeHours=function(e){return{type:t.CHANGE_HOURS,payload:e}},t.prototype.changeMinutes=function(e){return{type:t.CHANGE_MINUTES,payload:e}},t.prototype.changeSeconds=function(e){return{type:t.CHANGE_SECONDS,payload:e}},t.prototype.setTime=function(e){return{type:t.SET_TIME_UNIT,payload:e}},t.prototype.updateControls=function(e){return{type:t.UPDATE_CONTROLS,payload:e}},t.WRITE_VALUE="[timepicker] write value from ng model",t.CHANGE_HOURS="[timepicker] change hours",t.CHANGE_MINUTES="[timepicker] change minutes",t.CHANGE_SECONDS="[timepicker] change seconds",t.SET_TIME_UNIT="[timepicker] set time unit",t.UPDATE_CONTROLS="[timepicker] update controls",t}(),Dr=10,Er=24,Lr=12,Pr=60,Mr=60;function qr(t){return!!t&&!(t instanceof Date&&isNaN(t.getHours()))&&("string"!=typeof t||qr(new Date(t)))}function jr(t,e){return!(t.min&&et.max)}function Fr(t){return"number"==typeof t?t:parseInt(t,Dr)}function zr(t,e){void 0===e&&(e=!1);var n=Fr(t);return isNaN(n)||n<0||n>(e?Lr:Er)?NaN:n!==Lr||e?n:0}function Gr(t){var e=Fr(t);return isNaN(e)||e<0||e>Pr?NaN:e}function Yr(t){var e=Fr(t);return isNaN(e)||e<0||e>Mr?NaN:e}function Vr(t){return"string"==typeof t?new Date(t):t}function Hr(t,e){if(!t)return Hr(Ur(new Date,0,0,0),e);var n=t.getHours(),a=t.getMinutes(),r=t.getSeconds();return e.hour&&(n=(n+Fr(e.hour))%Er)<0&&(n+=Er),e.minute&&(a+=Fr(e.minute)),e.seconds&&(r+=Fr(e.seconds)),Ur(t,n,a,r)}function Br(t,e){var n=zr(e.hour),a=Gr(e.minute),r=Yr(e.seconds)||0;return e.isPM&&12!==n&&(n+=Lr),t?isNaN(n)||isNaN(a)?t:Ur(t,n,a,r):isNaN(n)||isNaN(a)?t:Ur(new Date,n,a,r)}function Ur(t,e,n,a){return new Date(t.getFullYear(),t.getMonth(),t.getDate(),e,n,a,t.getMilliseconds())}function Wr(t){var e=t.toString();return e.length>1?e:"0"+e}function Kr(t,e){return!isNaN(zr(t,e))}function $r(t){return!isNaN(Gr(t))}function Zr(t){return!isNaN(Yr(t))}function Xr(t,e,n,a){return void 0===e&&(e="0"),void 0===n&&(n="0"),Kr(t,a)&&$r(e)&&Zr(n)}function Jr(t,e){if(t.readonlyInput||t.disabled)return!1;if(e){if("wheel"===e.source&&!t.mousewheel)return!1;if("key"===e.source&&!t.arrowkeys)return!1}return!0}function Qr(t){return{hourStep:t.hourStep,minuteStep:t.minuteStep,secondsStep:t.secondsStep,readonlyInput:t.readonlyInput,disabled:t.disabled,mousewheel:t.mousewheel,arrowkeys:t.arrowkeys,showSpinners:t.showSpinners,showMeridian:t.showMeridian,showSeconds:t.showSeconds,meridians:t.meridians,min:t.min,max:t.max}}var ti=function(){return function(){this.hourStep=1,this.minuteStep=5,this.secondsStep=10,this.showMeridian=!0,this.meridians=["AM","PM"],this.readonlyInput=!1,this.disabled=!1,this.mousewheel=!0,this.arrowkeys=!0,this.showSpinners=!0,this.showSeconds=!1,this.showMinutes=!0}}(),ei={value:null,config:new ti,controls:{canIncrementHours:!0,canIncrementMinutes:!0,canIncrementSeconds:!0,canDecrementHours:!0,canDecrementMinutes:!0,canDecrementSeconds:!0,canToggleMeridian:!0}};function ni(t,e){switch(void 0===t&&(t=ei),e.type){case Ar.WRITE_VALUE:return Object.assign({},t,{value:e.payload});case Ar.CHANGE_HOURS:if(!Jr(t.config,e.payload)||(s=t.controls,!(i=e.payload).step||i.step>0&&!s.canIncrementHours||i.step<0&&!s.canDecrementHours))return t;var n=Hr(t.value,{hour:e.payload.step});return!t.config.max&&!t.config.min||jr(t.config,n)?Object.assign({},t,{value:n}):t;case Ar.CHANGE_MINUTES:return Jr(t.config,e.payload)&&function(t,e){return!(!t.step||t.step>0&&!e.canIncrementMinutes||t.step<0&&!e.canDecrementMinutes)}(e.payload,t.controls)?(n=Hr(t.value,{minute:e.payload.step}),!t.config.max&&!t.config.min||jr(t.config,n)?Object.assign({},t,{value:n}):t):t;case Ar.CHANGE_SECONDS:return Jr(t.config,e.payload)&&function(t,e){return!(!t.step||t.step>0&&!e.canIncrementSeconds||t.step<0&&!e.canDecrementSeconds)}(e.payload,t.controls)?(n=Hr(t.value,{seconds:e.payload.step}),!t.config.max&&!t.config.min||jr(t.config,n)?Object.assign({},t,{value:n}):t):t;case Ar.SET_TIME_UNIT:return Jr(t.config)?(n=Br(t.value,e.payload),Object.assign({},t,{value:n})):t;case Ar.UPDATE_CONTROLS:var a=function(t,e){var n=e.min,a=e.max,r=e.hourStep,i=e.minuteStep,s=e.secondsStep,o=e.showSeconds,u={canIncrementHours:!0,canIncrementMinutes:!0,canIncrementSeconds:!0,canDecrementHours:!0,canDecrementMinutes:!0,canDecrementSeconds:!0,canToggleMeridian:!0};if(!t)return u;if(a){var c=Hr(t,{hour:r});if(u.canIncrementHours=a>c,!u.canIncrementHours){var l=Hr(t,{minute:i});u.canIncrementMinutes=o?a>l:a>=l}if(!u.canIncrementMinutes){var d=Hr(t,{seconds:s});u.canIncrementSeconds=a>=d}t.getHours()<12&&(u.canToggleMeridian=Hr(t,{hour:12})=12&&(u.canToggleMeridian=Hr(t,{hour:-12})>n)),u}(t.value,e.payload),r={value:t.value,config:e.payload,controls:a};return t.config.showMeridian!==r.config.showMeridian&&t.value&&(r.value=new Date(t.value)),Object.assign({},t,r);default:return t}var i,s}var ai=function(t){function e(){var e=new Dt.a({type:"[mini-ngrx] dispatcher init"}),n=new Rr.a(ei,e,ni);return t.call(this,e,ni,n)||this}return Object(p.__extends)(e,t),e}(Rr.b),ri=function(){function t(t,e,n,a){var r=this;this._cd=e,this._store=n,this._timepickerActions=a,this.isValid=new s.EventEmitter,this.invalidHours=!1,this.invalidMinutes=!1,this.invalidSeconds=!1,this.onChange=Function.prototype,this.onTouched=Function.prototype,Object.assign(this,t),this.timepickerSub=n.select(function(t){return t.value}).subscribe(function(t){r._renderTime(t),r.onChange(t),r._store.dispatch(r._timepickerActions.updateControls(Qr(r)))}),n.select(function(t){return t.controls}).subscribe(function(t){r.isValid.emit(Xr(r.hours,r.minutes,r.seconds,r.isPM())),Object.assign(r,t),e.markForCheck()})}return Object.defineProperty(t.prototype,"isSpinnersVisible",{get:function(){return this.showSpinners&&!this.readonlyInput},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isEditable",{get:function(){return!(this.readonlyInput||this.disabled)},enumerable:!0,configurable:!0}),t.prototype.resetValidation=function(){this.invalidHours=!1,this.invalidMinutes=!1,this.invalidSeconds=!1},t.prototype.isPM=function(){return this.showMeridian&&this.meridian===this.meridians[1]},t.prototype.prevDef=function(t){t.preventDefault()},t.prototype.wheelSign=function(t){return-1*Math.sign(t.deltaY)},t.prototype.ngOnChanges=function(t){this._store.dispatch(this._timepickerActions.updateControls(Qr(this)))},t.prototype.changeHours=function(t,e){void 0===e&&(e=""),this.resetValidation(),this._store.dispatch(this._timepickerActions.changeHours({step:t,source:e}))},t.prototype.changeMinutes=function(t,e){void 0===e&&(e=""),this.resetValidation(),this._store.dispatch(this._timepickerActions.changeMinutes({step:t,source:e}))},t.prototype.changeSeconds=function(t,e){void 0===e&&(e=""),this.resetValidation(),this._store.dispatch(this._timepickerActions.changeSeconds({step:t,source:e}))},t.prototype.updateHours=function(t){if(this.resetValidation(),this.hours=t,!Kr(this.hours,this.isPM())||!this.isValidLimit())return this.invalidHours=!0,this.isValid.emit(!1),void this.onChange(null);this._updateTime()},t.prototype.updateMinutes=function(t){if(this.resetValidation(),this.minutes=t,!$r(this.minutes)||!this.isValidLimit())return this.invalidMinutes=!0,this.isValid.emit(!1),void this.onChange(null);this._updateTime()},t.prototype.updateSeconds=function(t){if(this.resetValidation(),this.seconds=t,!Zr(this.seconds)||!this.isValidLimit())return this.invalidSeconds=!0,this.isValid.emit(!1),void this.onChange(null);this._updateTime()},t.prototype.isValidLimit=function(){return t={hour:this.hours,minute:this.minutes,seconds:this.seconds,isPM:this.isPM()},e=this.max,n=this.min,a=Br(new Date,t),!(e&&a>e||n&&a=12?1:0],0==(n%=12)&&(n=12)),this.hours=Wr(n),this.minutes=Wr(e.getMinutes()),this.seconds=Wr(e.getUTCSeconds())},t}(),ii=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[ti,Ar,ai]}},t}(),si=s["\u0275crt"]({encapsulation:2,styles:["\n .bs-chevron {\n border-style: solid;\n display: block;\n width: 9px;\n height: 9px;\n position: relative;\n border-width: 3px 0px 0 3px;\n }\n\n .bs-chevron-up {\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n top: 2px;\n }\n\n .bs-chevron-down {\n -webkit-transform: rotate(-135deg);\n transform: rotate(-135deg);\n top: -2px;\n }\n\n .bs-timepicker-field {\n width: 50px;\n }\n "],data:{}});function oi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0\xa0\xa0"]))],null,null)}function ui(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"a",[["class","btn btn-link"]],[[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.changeMinutes(r.minuteStep)&&a),a},null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"span",[["class","bs-chevron bs-chevron-up"]],null,null,null,null,null))],null,function(t,e){var n=e.component;t(e,1,0,!n.canIncrementMinutes||!n.isEditable)})}function ci(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0"]))],null,null)}function li(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"a",[["class","btn btn-link"]],[[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.changeSeconds(r.secondsStep)&&a),a},null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"span",[["class","bs-chevron bs-chevron-up"]],null,null,null,null,null))],null,function(t,e){var n=e.component;t(e,1,0,!n.canIncrementSeconds||!n.isEditable)})}function di(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0\xa0\xa0"]))],null,null)}function fi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"td",[],null,null,null,null,null))],null,null)}function pi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0:\xa0"]))],null,null)}function hi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[["class","form-group"]],[[2,"has-error",null]],null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,0,"input",[["class","form-control text-center bs-timepicker-field"],["maxlength","2"],["placeholder","MM"],["type","text"]],[[2,"is-invalid",null],[8,"readOnly",0],[8,"disabled",0],[8,"value",0]],[[null,"wheel"],[null,"keydown.ArrowUp"],[null,"keydown.ArrowDown"],[null,"change"]],function(t,e,n){var a=!0,r=t.component;return"wheel"===e&&(r.prevDef(n),a=!1!==r.changeMinutes(r.minuteStep*r.wheelSign(n),"wheel")&&a),"keydown.ArrowUp"===e&&(a=!1!==r.changeMinutes(r.minuteStep,"key")&&a),"keydown.ArrowDown"===e&&(a=!1!==r.changeMinutes(0-r.minuteStep,"key")&&a),"change"===e&&(a=!1!==r.updateMinutes(n.target.value)&&a),a},null,null))],null,function(t,e){var n=e.component;t(e,0,0,n.invalidMinutes),t(e,1,0,n.invalidMinutes,n.readonlyInput,n.disabled,n.minutes)})}function gi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0:\xa0"]))],null,null)}function bi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[["class","form-group"]],[[2,"has-error",null]],null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,0,"input",[["class","form-control text-center bs-timepicker-field"],["maxlength","2"],["placeholder","SS"],["type","text"]],[[2,"is-invalid",null],[8,"readOnly",0],[8,"disabled",0],[8,"value",0]],[[null,"wheel"],[null,"keydown.ArrowUp"],[null,"keydown.ArrowDown"],[null,"change"]],function(t,e,n){var a=!0,r=t.component;return"wheel"===e&&(r.prevDef(n),a=!1!==r.changeSeconds(r.secondsStep*r.wheelSign(n),"wheel")&&a),"keydown.ArrowUp"===e&&(a=!1!==r.changeSeconds(r.secondsStep,"key")&&a),"keydown.ArrowDown"===e&&(a=!1!==r.changeSeconds(0-r.secondsStep,"key")&&a),"change"===e&&(a=!1!==r.updateSeconds(n.target.value)&&a),a},null,null))],null,function(t,e){var n=e.component;t(e,0,0,n.invalidSeconds),t(e,1,0,n.invalidSeconds,n.readonlyInput,n.disabled,n.seconds)})}function mi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0\xa0\xa0"]))],null,null)}function yi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"button",[["class","btn btn-default text-center"],["type","button"]],[[8,"disabled",0],[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.toggleMeridian()&&a),a},null,null)),(t()(),s["\u0275ted"](2,null,[""," "]))],null,function(t,e){var n=e.component;t(e,1,0,!n.isEditable||!n.canToggleMeridian,!n.isEditable||!n.canToggleMeridian),t(e,2,0,n.meridian)})}function vi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0\xa0\xa0"]))],null,null)}function _i(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"a",[["class","btn btn-link"]],[[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.changeMinutes(0-r.minuteStep)&&a),a},null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"span",[["class","bs-chevron bs-chevron-down"]],null,null,null,null,null))],null,function(t,e){var n=e.component;t(e,1,0,!n.canDecrementMinutes||!n.isEditable)})}function xi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0"]))],null,null)}function Ti(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"a",[["class","btn btn-link"]],[[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.changeSeconds(0-r.secondsStep)&&a),a},null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"span",[["class","bs-chevron bs-chevron-down"]],null,null,null,null,null))],null,function(t,e){var n=e.component;t(e,1,0,!n.canDecrementSeconds||!n.isEditable)})}function wi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"td",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0\xa0\xa0"]))],null,null)}function Si(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"td",[],null,null,null,null,null))],null,null)}function Oi(t){return s["\u0275vid"](2,[(t()(),s["\u0275eld"](0,0,null,null,48,"table",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,47,"tbody",[],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,15,"tr",[["class","text-center"]],[[8,"hidden",0]],null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,"a",[["class","btn btn-link"]],[[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.changeHours(r.hourStep)&&a),a},null,null)),(t()(),s["\u0275eld"](5,0,null,null,0,"span",[["class","bs-chevron bs-chevron-up"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,oi)),s["\u0275did"](7,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ui)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ci)),s["\u0275did"](11,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,li)),s["\u0275did"](13,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,di)),s["\u0275did"](15,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,fi)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](18,0,null,null,14,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,1,"td",[["class","form-group"]],[[2,"has-error",null]],null,null,null,null)),(t()(),s["\u0275eld"](20,0,null,null,0,"input",[["class","form-control text-center bs-timepicker-field"],["maxlength","2"],["placeholder","HH"],["type","text"]],[[2,"is-invalid",null],[8,"readOnly",0],[8,"disabled",0],[8,"value",0]],[[null,"wheel"],[null,"keydown.ArrowUp"],[null,"keydown.ArrowDown"],[null,"change"]],function(t,e,n){var a=!0,r=t.component;return"wheel"===e&&(r.prevDef(n),a=!1!==r.changeHours(r.hourStep*r.wheelSign(n),"wheel")&&a),"keydown.ArrowUp"===e&&(a=!1!==r.changeHours(r.hourStep,"key")&&a),"keydown.ArrowDown"===e&&(a=!1!==r.changeHours(0-r.hourStep,"key")&&a),"change"===e&&(a=!1!==r.updateHours(n.target.value)&&a),a},null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,pi)),s["\u0275did"](22,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,hi)),s["\u0275did"](24,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,gi)),s["\u0275did"](26,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,bi)),s["\u0275did"](28,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,mi)),s["\u0275did"](30,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,yi)),s["\u0275did"](32,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](33,0,null,null,15,"tr",[["class","text-center"]],[[8,"hidden",0]],null,null,null,null)),(t()(),s["\u0275eld"](34,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](35,0,null,null,1,"a",[["class","btn btn-link"]],[[2,"disabled",null]],[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=!1!==r.changeHours(0-r.hourStep)&&a),a},null,null)),(t()(),s["\u0275eld"](36,0,null,null,0,"span",[["class","bs-chevron bs-chevron-down"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,vi)),s["\u0275did"](38,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,_i)),s["\u0275did"](40,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,xi)),s["\u0275did"](42,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ti)),s["\u0275did"](44,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,wi)),s["\u0275did"](46,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Si)),s["\u0275did"](48,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,7,0,n.showMinutes),t(e,9,0,n.showMinutes),t(e,11,0,n.showSeconds),t(e,13,0,n.showSeconds),t(e,15,0,n.showMeridian),t(e,17,0,n.showMeridian),t(e,22,0,n.showMinutes),t(e,24,0,n.showMinutes),t(e,26,0,n.showSeconds),t(e,28,0,n.showSeconds),t(e,30,0,n.showMeridian),t(e,32,0,n.showMeridian),t(e,38,0,n.showMinutes),t(e,40,0,n.showMinutes),t(e,42,0,n.showSeconds),t(e,44,0,n.showSeconds),t(e,46,0,n.showMeridian),t(e,48,0,n.showMeridian)},function(t,e){var n=e.component;t(e,2,0,!n.showSpinners),t(e,4,0,!n.canIncrementHours||!n.isEditable),t(e,19,0,n.invalidHours),t(e,20,0,n.invalidHours,n.readonlyInput,n.disabled,n.hours),t(e,33,0,!n.showSpinners),t(e,35,0,!n.canDecrementHours||!n.isEditable)})}var Ii=n("E2fk"),Ci=function(){function t(t){this.http=t}return t.prototype.getLogs=function(){return this.http.get("api/logs/all")},t.prototype.validateDashboardUrl=function(t){return this.http.get("api/grafana/validation/"+t)},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c))},token:t,providedIn:Nt.a}),t}(),ki=function(){function t(t){this.logsService=t,this.bsConfig={dateInputFormat:"YYYY-MM-DD",containerClass:"theme-default"},this.prioritys=[{name:"Info",value:"[INF]"},{name:"Warning",value:"[WRN]"},{name:"Error",value:"[ERR]"},{name:"All",value:"All"}],this.priority="All",this.search="",this.startTime=new Date,this.endTime=new Date,this.startTime.setHours(0,0),this.endTime.setHours(23,59)}return t.prototype.ngOnInit=function(){var t=this;this.getInfo(),this.interval=window.setInterval(function(){t.getInfo()},5e3)},t.prototype.ngOnDestroy=function(){clearInterval(this.interval)},t.prototype.getInfo=function(){var t=this;this.logsService.getLogs().subscribe(function(e){t.contentData=e,t.filterLogs()})},t.prototype.abstractfilters=function(){var t,e=this.priority,n=this.search.toLowerCase().replace(/,/g,"");if(this.selectedDate){var a=this.selectedDate.getMonth()+1,r=this.selectedDate.getDate();t=this.selectedDate.getFullYear().toString()+"-"+(a<=9?"0"+a:""+a)+"-"+(r<=9?"0"+r:""+r)}else t="";return{priority:e,key:n,yearMonthDay:t,sTime:60*(this.startTime?this.startTime.getHours():0)+(this.startTime?this.startTime.getMinutes():0),eTime:60*(this.endTime?this.endTime.getHours():23)+(this.endTime?this.endTime.getMinutes():59)}},t.prototype.filterExecutor=function(t,e){return t.filter(function(t){var n,a,r=parseInt(t.stamp.slice(11,13),10),i=parseInt(t.stamp.slice(14,16),10);return n=e.yearMonthDay?e.yearMonthDay:t.stamp,a=60*r+i,t.priority===("All"===e.priority?t.priority:e.priority)&&-1!==t.message.toLowerCase().indexOf(e.key)&&-1!==t.stamp.indexOf(n)&&a>=e.sTime&&a<=e.eTime})},t.prototype.filterLogs=function(){var t=this.abstractfilters();this.clog=this.filterExecutor(this.contentData.clog,t),this.audit_log=this.filterExecutor(this.contentData.audit_log,t)},t.prototype.clearSearchKey=function(){this.search="",this.filterLogs()},t.prototype.clearDate=function(){this.selectedDate=null,this.filterLogs()},t}(),Ni=s["\u0275crt"]({encapsulation:0,styles:[["p[_ngcontent-%COMP%]{font-family:monospace;color:#000}.well[_ngcontent-%COMP%] div[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{display:-webkit-box;display:flex}.well[_ngcontent-%COMP%] div[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child{margin-bottom:0}.well[_ngcontent-%COMP%] .timestamp[_ngcontent-%COMP%]{font-weight:700;flex-shrink:0}.well[_ngcontent-%COMP%] .priority[_ngcontent-%COMP%]{margin-left:.5rem}.well[_ngcontent-%COMP%] .message[_ngcontent-%COMP%]{margin-left:1rem}.well[_ngcontent-%COMP%] .err[_ngcontent-%COMP%]{color:#a94442}.well[_ngcontent-%COMP%] .warn[_ngcontent-%COMP%]{color:#ffc200}.well[_ngcontent-%COMP%] .info[_ngcontent-%COMP%]{color:#2b99a8} timepicker table tbody tr td .bs-timepicker-field{width:3.5rem;font-size:1rem;padding:4px 6px} timepicker table tbody tr td .btn{font-size:1rem}.log-filters[_ngcontent-%COMP%]{margin-bottom:5px;padding:0 30px}.log-filters[_ngcontent-%COMP%] *[_ngcontent-%COMP%]{box-sizing:border-box}.log-filters[_ngcontent-%COMP%] .filter-box[_ngcontent-%COMP%]{margin:0;padding:0 15px 5px 0;display:-webkit-box;display:flex;-webkit-box-pack:start;justify-content:flex-start;-webkit-box-align:center;align-items:center}.log-filters[_ngcontent-%COMP%] .filter-box[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{padding-top:5px;padding-right:5px}@media (max-width:991px){.log-filters[_ngcontent-%COMP%] .time-box[_ngcontent-%COMP%]{margin-top:20px}}@media (min-width:1200px){.log-filters[_ngcontent-%COMP%] .cd-col-4[_ngcontent-%COMP%]{width:28vw}.log-filters[_ngcontent-%COMP%] .cd-col-3[_ngcontent-%COMP%]{width:20vw}.log-filters[_ngcontent-%COMP%] .cd-col-2[_ngcontent-%COMP%]{width:16vw}.log-filters[_ngcontent-%COMP%] .cd-col-1[_ngcontent-%COMP%]{width:14vw}}@media (min-width:1400px){.log-filters[_ngcontent-%COMP%] .cd-col-4[_ngcontent-%COMP%]{width:24vw}.log-filters[_ngcontent-%COMP%] .cd-col-3[_ngcontent-%COMP%]{width:18vw}.log-filters[_ngcontent-%COMP%] .cd-col-2[_ngcontent-%COMP%]{width:14vw}.log-filters[_ngcontent-%COMP%] .cd-col-1[_ngcontent-%COMP%]{width:12vw}}@media (min-width:1600px){.log-filters[_ngcontent-%COMP%] .cd-col-4[_ngcontent-%COMP%]{width:22vw}.log-filters[_ngcontent-%COMP%] .cd-col-3[_ngcontent-%COMP%]{width:16vw}.log-filters[_ngcontent-%COMP%] .cd-col-2[_ngcontent-%COMP%]{width:12vw}.log-filters[_ngcontent-%COMP%] .cd-col-1[_ngcontent-%COMP%]{width:10vw}}@media (min-width:1800px){.log-filters[_ngcontent-%COMP%] .cd-col-3[_ngcontent-%COMP%]{width:14vw}.log-filters[_ngcontent-%COMP%] .cd-col-2[_ngcontent-%COMP%]{width:11vw}.log-filters[_ngcontent-%COMP%] .cd-col-1[_ngcontent-%COMP%]{width:9vw}}"]],data:{}});function Ri(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function Ai(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,7,"p",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[["class","timestamp"]],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,["",""])),(t()(),s["\u0275eld"](3,0,null,null,2,"span",[],[[8,"className",0]],null,null,null,null)),s["\u0275ppd"](4,1),(t()(),s["\u0275ted"](5,null,["",""])),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[["class","message"]],null,null,null,null,null)),(t()(),s["\u0275ted"](7,null,["",""]))],null,function(t,e){t(e,2,0,e.context.$implicit.stamp);var n=s["\u0275inlineInterpolate"](1,"priority ",s["\u0275unv"](e,3,0,t(e,4,0,s["\u0275nov"](e.parent.parent.parent,0),e.context.$implicit.priority)),"");t(e,3,0,n),t(e,5,0,e.context.$implicit.priority),t(e,7,0,e.context.$implicit.message)})}function Di(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"div",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Ai)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.component.clog)},null)}function Ei(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["No entries found"]))],null,null)}function Li(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,7,"p",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[["class","timestamp"]],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,["",""])),(t()(),s["\u0275eld"](3,0,null,null,2,"span",[],[[8,"className",0]],null,null,null,null)),s["\u0275ppd"](4,1),(t()(),s["\u0275ted"](5,null,["",""])),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[["class","message"]],null,null,null,null,null)),(t()(),s["\u0275ted"](7,null,["",""]))],null,function(t,e){t(e,2,0,e.context.$implicit.stamp);var n=s["\u0275inlineInterpolate"](1,"priority ",s["\u0275unv"](e,3,0,t(e,4,0,s["\u0275nov"](e.parent.parent.parent,0),e.context.$implicit.priority)),"");t(e,3,0,n),t(e,5,0,e.context.$implicit.priority),t(e,7,0,e.context.$implicit.message)})}function Pi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"div",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Li)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.component.audit_log)},null)}function Mi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["No entries found"]))],null,null)}function qi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,18,"div",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Ri)),s["\u0275did"](2,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(t()(),s["\u0275eld"](3,0,null,null,15,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](4,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](5,0,null,0,6,"tab",[["heading","Cluster Logs"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](6,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](7,0,null,null,4,"div",[["class","well"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Di)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ei)),s["\u0275did"](11,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](12,0,null,0,6,"tab",[["heading","Audit Logs"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](13,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](14,0,null,null,4,"div",[["class","well"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Pi)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Mi)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,s["\u0275nov"](e.parent,3)),t(e,6,0,"Cluster Logs"),t(e,9,0,n.clog),t(e,11,0,0===n.contentData.clog.length),t(e,13,0,"Audit Logs"),t(e,16,0,n.audit_log),t(e,18,0,0===n.contentData.audit_log.length)},function(t,e){t(e,3,0,s["\u0275nov"](e,4).clazz),t(e,5,0,s["\u0275nov"](e,6).id,s["\u0275nov"](e,6).active,s["\u0275nov"](e,6).addClass),t(e,12,0,s["\u0275nov"](e,13).id,s["\u0275nov"](e,13).active,s["\u0275nov"](e,13).addClass)})}function ji(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["class","form-control"]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit.value),t(e,2,0,e.context.$implicit.value)},function(t,e){t(e,3,0,e.context.$implicit.name)})}function Fi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,65,"div",[["class","row log-filters"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,11,"div",[["class","col-xs-4 col-md-2 cd-col-1 filter-box"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"label",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Priority:"])),(t()(),s["\u0275eld"](4,0,null,null,8,"select",[["class","form-control"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,6).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,6).onTouched()&&a),"ngModelChange"===e&&(a=!1!==(r.priority=n)&&a),"ngModelChange"===e&&(a=!1!==r.filterLogs()&&a),a},null,null)),s["\u0275did"](5,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](6,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](8,671744,null,0,Te.u,[[8,null],[8,null],[8,null],[6,Te.p]],{model:[0,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](10,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,ji)),s["\u0275did"](12,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](13,0,null,null,15,"div",[["class","col-xs-4 col-md-3 cd-col-3 filter-box"]],null,null,null,null,null)),(t()(),s["\u0275eld"](14,0,null,null,1,"label",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Keyword:"])),(t()(),s["\u0275eld"](16,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](17,0,null,null,1,"span",[["class","input-group-addon"]],null,null,null,null,null)),(t()(),s["\u0275eld"](18,0,null,null,0,"i",[["class","glyphicon glyphicon-search"]],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,6,"input",[["class","form-control"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"keyup"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0,r=t.component;return"input"===e&&(a=!1!==s["\u0275nov"](t,21)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,21).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,21)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,21)._compositionEnd(n.target.value)&&a),"ngModelChange"===e&&(a=!1!==(r.search=n)&&a),"keyup"===e&&(a=!1!==r.filterLogs()&&a),a},null,null)),s["\u0275did"](20,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](21,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](23,671744,null,0,Te.u,[[8,null],[8,null],[8,null],[6,Te.p]],{model:[0,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](25,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275eld"](26,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(t()(),s["\u0275eld"](27,0,null,null,1,"button",[["class","btn btn-default clear-input tc_clearInputBtn"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.clearSearchKey()&&a),a},null,null)),(t()(),s["\u0275eld"](28,0,null,null,0,"i",[["class","icon-prepend fa fa-remove"]],null,null,null,null,null)),(t()(),s["\u0275eld"](29,0,null,null,16,"div",[["class","col-xs-4 col-md-3 cd-col-2 filter-box"]],null,null,null,null,null)),(t()(),s["\u0275eld"](30,0,null,null,1,"label",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Date:"])),(t()(),s["\u0275eld"](32,0,null,null,13,"div",[["class","input-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](33,16777216,null,null,9,"input",[["bsDatepicker",""],["class","form-control"],["placeholder","Datepicker"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"],[null,"keyup.esc"]],function(t,e,n){var a=!0,r=t.component;return"input"===e&&(a=!1!==s["\u0275nov"](t,35)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,35).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,35)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,35)._compositionEnd(n.target.value)&&a),"change"===e&&(a=!1!==s["\u0275nov"](t,37).onChange(n)&&a),"keyup.esc"===e&&(a=!1!==s["\u0275nov"](t,37).hide()&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,37).onBlur()&&a),"ngModelChange"===e&&(a=!1!==(r.selectedDate=n)&&a),"ngModelChange"===e&&(a=!1!==r.filterLogs()&&a),a},null,null)),s["\u0275did"](34,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](35,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275did"](36,737280,null,0,Nr.c,[Nr.a,s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a],{bsConfig:[0,"bsConfig"]},null),s["\u0275did"](37,16384,null,0,Nr.f,[Nr.c,Nr.j,s.Renderer2,s.ElementRef,s.ChangeDetectorRef],null,null),s["\u0275prd"](1024,null,Te.o,function(t){return[t]},[Nr.f]),s["\u0275prd"](1024,null,Te.p,function(t,e){return[t,e]},[Te.e,Nr.f]),s["\u0275did"](40,671744,null,0,Te.u,[[8,null],[6,Te.o],[8,null],[6,Te.p]],{model:[0,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](42,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275eld"](43,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(t()(),s["\u0275eld"](44,0,null,null,1,"button",[["class","btn btn-default clear-input tc_clearInputBtn"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.clearDate()&&a),a},null,null)),(t()(),s["\u0275eld"](45,0,null,null,0,"i",[["class","icon-prepend fa fa-remove"]],null,null,null,null,null)),(t()(),s["\u0275eld"](46,0,null,null,0,"div",[["class","clearfix visible-xs-block"]],null,null,null,null,null)),(t()(),s["\u0275eld"](47,0,null,null,18,"div",[["class","col-xs-8 col-md-4 cd-col-4 filter-box time-box"]],null,null,null,null,null)),(t()(),s["\u0275eld"](48,0,null,null,1,"label",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Time range:"])),(t()(),s["\u0275eld"](50,0,null,null,6,"timepicker",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"]],function(t,e,n){var a=!0,r=t.component;return"ngModelChange"===e&&(a=!1!==(r.startTime=n)&&a),"ngModelChange"===e&&(a=!1!==r.filterLogs()&&a),a},Oi,si)),s["\u0275prd"](512,null,ai,ai,[]),s["\u0275did"](52,704512,null,0,ri,[ti,s.ChangeDetectorRef,ai,Ar],{minuteStep:[0,"minuteStep"],showSpinners:[1,"showSpinners"],showMeridian:[2,"showMeridian"]},null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[ri]),s["\u0275did"](54,671744,null,0,Te.u,[[8,null],[8,null],[8,null],[6,Te.p]],{model:[0,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](56,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275eld"](57,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xa0\u2014\xa0"])),(t()(),s["\u0275eld"](59,0,null,null,6,"timepicker",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"]],function(t,e,n){var a=!0,r=t.component;return"ngModelChange"===e&&(a=!1!==(r.endTime=n)&&a),"ngModelChange"===e&&(a=!1!==r.filterLogs()&&a),a},Oi,si)),s["\u0275prd"](512,null,ai,ai,[]),s["\u0275did"](61,704512,null,0,ri,[ti,s.ChangeDetectorRef,ai,Ar],{minuteStep:[0,"minuteStep"],showSpinners:[1,"showSpinners"],showMeridian:[2,"showMeridian"]},null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[ri]),s["\u0275did"](63,671744,null,0,Te.u,[[8,null],[8,null],[8,null],[6,Te.p]],{model:[0,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](65,16384,null,0,Te.r,[[4,Te.q]],null,null)],function(t,e){var n=e.component;t(e,8,0,n.priority),t(e,12,0,n.prioritys),t(e,23,0,n.search),t(e,36,0,n.bsConfig),t(e,40,0,n.selectedDate),t(e,52,0,1,n.showSpinners,!1),t(e,54,0,n.startTime),t(e,61,0,1,n.showSpinners,!1),t(e,63,0,n.endTime)},function(t,e){t(e,4,0,s["\u0275nov"](e,10).ngClassUntouched,s["\u0275nov"](e,10).ngClassTouched,s["\u0275nov"](e,10).ngClassPristine,s["\u0275nov"](e,10).ngClassDirty,s["\u0275nov"](e,10).ngClassValid,s["\u0275nov"](e,10).ngClassInvalid,s["\u0275nov"](e,10).ngClassPending),t(e,19,0,s["\u0275nov"](e,25).ngClassUntouched,s["\u0275nov"](e,25).ngClassTouched,s["\u0275nov"](e,25).ngClassPristine,s["\u0275nov"](e,25).ngClassDirty,s["\u0275nov"](e,25).ngClassValid,s["\u0275nov"](e,25).ngClassInvalid,s["\u0275nov"](e,25).ngClassPending),t(e,33,0,s["\u0275nov"](e,42).ngClassUntouched,s["\u0275nov"](e,42).ngClassTouched,s["\u0275nov"](e,42).ngClassPristine,s["\u0275nov"](e,42).ngClassDirty,s["\u0275nov"](e,42).ngClassValid,s["\u0275nov"](e,42).ngClassInvalid,s["\u0275nov"](e,42).ngClassPending),t(e,50,0,s["\u0275nov"](e,56).ngClassUntouched,s["\u0275nov"](e,56).ngClassTouched,s["\u0275nov"](e,56).ngClassPristine,s["\u0275nov"](e,56).ngClassDirty,s["\u0275nov"](e,56).ngClassValid,s["\u0275nov"](e,56).ngClassInvalid,s["\u0275nov"](e,56).ngClassPending),t(e,59,0,s["\u0275nov"](e,65).ngClassUntouched,s["\u0275nov"](e,65).ngClassTouched,s["\u0275nov"](e,65).ngClassPristine,s["\u0275nov"](e,65).ngClassDirty,s["\u0275nov"](e,65).ngClassValid,s["\u0275nov"](e,65).ngClassInvalid,s["\u0275nov"](e,65).ngClassPending)})}function zi(t){return s["\u0275vid"](0,[s["\u0275pid"](0,Ii.a,[]),(t()(),s["\u0275and"](16777216,null,null,1,null,qi)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,[["logFiltersTpl",2]],null,0,null,Fi))],function(t,e){t(e,2,0,e.component.contentData)},null)}function Gi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-logs",[],null,null,null,zi,Ni)),s["\u0275did"](1,245760,null,0,ki,[Ci],null,null)],function(t,e){t(e,1,0)},null)}var Yi,Vi=s["\u0275ccf"]("cd-logs",ki,Gi,{},{},[]),Hi=n("EgGo");!function(t){t.add="fa fa-plus",t.addCircle="fa fa-plus-circle",t.minusCircle="fa fa-minus-circle",t.edit="fa fa-pencil",t.destroy="fa fa-times",t.destroyCircle="fa fa-times-circle",t.exchange="fa fa-exchange",t.copy="fa fa-copy",t.clipboard="fa fa-clipboard",t.flatten="fa-chain-broken",t.trash="fa fa-trash-o",t.lock="fa fa-lock",t.unlock="fa fa-unlock",t.clone="fa fa-clone",t.undo="fa fa-undo",t.search="fa fa-search",t.start="fa fa-play",t.stop="fa fa-stop",t.analyse="fa fa-stethoscope",t.deepCheck="fa fa-cog",t.reweight="fa-balance-scale",t.left="fa fa-arrow-left",t.right="fa fa-arrow-right",t.down="fa fa-arrow-down",t.erase="fa fa-eraser",t.user="fa fa-user",t.share="fa fa-share-alt",t.key="fa fa-key-modern",t.warning="fa fa-exclamation-triangle",t.info="fa fa-info",t.infoCircle="fa fa-info-circle",t.questionCircle="fa fa-question-circle-o",t.check="fa fa-check",t.show="fa fa-eye",t.paragraph="fa fa-paragraph",t.terminal="fa fa-terminal",t.magic="fa fa-magic",t.hourglass="fa fa-hourglass-o",t.filledHourglass="fa fa-hourglass",t.table="fa fa-table",t.spinner="fa spinner",t.refresh="fa fa-refresh",t.bullseye="fa fa-bullseye",t.disk="fa fa-hdd-o",t.server="fa fa-server",t.filter="fa fa-filter",t.lineChart="fa fa-line-chart",t.signOut="fa fa-sign-out",t.health="fa fa-heartbeat",t.circle="fa fa-circle",t.bell="fa fa-bell",t.tag="fa fa-tag",t.leftArrow="fa fa-angle-left",t.rightArrow="fa fa-angle-right",t.leftArrowDouble="fa fa-angle-double-left",t.rightArrowDouble="fa fa-angle-double-right",t.flag="fa fa-flag",t.width="fa fa-fw",t.large="fa fa-lg",t.large2x="fa fa-2x",t.large3x="fa fa-3x",t.stack="fa fa-stack",t.stack1x="fa fa-stack-1x",t.stack2x="fa fa-stack-2x",t.pulse="fa fa-pulse",t.spin="fa fa-spin",t.inverse="fa fa-inverse"}(Yi||(Yi={}));var Bi=n("67Y/"),Ui=function(){function t(t,e){this.http=t,this.settingsService=e,this.baseURL="api/prometheus",this.settingsKey={alertmanager:"api/settings/alertmanager-api-host",prometheus:"api/settings/prometheus-api-host"}}return t.prototype.ifAlertmanagerConfigured=function(t,e){this.settingsService.ifSettingConfigured(this.settingsKey.alertmanager,t,e)},t.prototype.disableAlertmanagerConfig=function(){this.settingsService.disableSetting(this.settingsKey.alertmanager)},t.prototype.ifPrometheusConfigured=function(t,e){this.settingsService.ifSettingConfigured(this.settingsKey.prometheus,t,e)},t.prototype.disablePrometheusConfig=function(){this.settingsService.disableSetting(this.settingsKey.prometheus)},t.prototype.getAlerts=function(t){return void 0===t&&(t={}),this.http.get(this.baseURL,{params:t})},t.prototype.getSilences=function(t){return void 0===t&&(t={}),this.http.get(this.baseURL+"/silences",{params:t})},t.prototype.getRules=function(t){void 0===t&&(t="all");var e,n=this.http.get(this.baseURL+"/rules");switch(t){case"alerting":case"rewrites":e=t,n=n.pipe(Object(Bi.a)(function(t){return t.groups=t.groups.map(function(t){return t.rules=t.rules.filter(function(t){return t.type===e}),t}),t}))}return n},t.prototype.setSilence=function(t){return this.http.post(this.baseURL+"/silence",t,{observe:"response"})},t.prototype.expireSilence=function(t){return this.http.delete(this.baseURL+"/silence/"+t,{observe:"response"})},t.prototype.getNotifications=function(t){return this.http.get(this.baseURL+"/notifications?from="+(t&&t.id?t.id:"last"))},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c),s.inject(ze.a))},token:t,providedIn:Nt.a}),t}(),Wi=n("G1I9"),Ki=function(){function t(t){this.notificationService=t}return t.prototype.sendNotifications=function(t){var e=this;t.forEach(function(t){return e.notificationService.show(t)})},t.prototype.convertToCustomAlerts=function(t){var e=this;return ft.uniqWith(t.map(function(t){return{status:ft.isObject(t.status)?t.status.state:e.getPrometheusNotificationStatus(t),name:t.labels.alertname,url:t.generatorURL,summary:t.annotations.summary,fingerprint:ft.isObject(t.status)&&t.fingerprint}}),ft.isEqual)},t.prototype.getPrometheusNotificationStatus=function(t){var e=t.status;return"firing"===e?"active":e},t.prototype.convertAlertToNotification=function(t){return new Wi.b(this.formatType(t.status),t.name+" ("+t.status+")",this.appendSourceLink(t,t.summary),void 0,"Prometheus")},t.prototype.formatType=function(t){return Xn.a[ft.findKey({error:["firing","active"],info:["suppressed","unprocessed"],success:["resolved"]},function(e){return e.includes(t)})]},t.prototype.appendSourceLink=function(t,e){return e+' '},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(Jn.a))},token:t,providedIn:"root"}),t}(),$i=function(){function t(t,e){this.alertFormatter=t,this.prometheusService=e,this.canAlertsBeNotified=!1,this.alerts=[],this.rules=[]}return t.prototype.getAlerts=function(){var t=this;this.prometheusService.ifAlertmanagerConfigured(function(){t.prometheusService.getAlerts().subscribe(function(e){return t.handleAlerts(e)},function(e){[404,504].includes(e.status)&&t.prometheusService.disableAlertmanagerConfig()})})},t.prototype.getRules=function(){var t=this;this.prometheusService.ifPrometheusConfigured(function(){t.prometheusService.getRules("alerting").subscribe(function(e){t.rules=e.groups.reduce(function(t,e){return t.concat(e.rules.map(function(t){return t.group=e.name,t}))},[])})})},t.prototype.refresh=function(){this.getAlerts(),this.getRules()},t.prototype.handleAlerts=function(t){this.canAlertsBeNotified&&this.notifyOnAlertChanges(t,this.alerts),this.alerts=t,this.canAlertsBeNotified=!0},t.prototype.notifyOnAlertChanges=function(t,e){var n=this,a=this.getChangedAlerts(this.alertFormatter.convertToCustomAlerts(t),this.alertFormatter.convertToCustomAlerts(e)).map(function(t){return n.alertFormatter.convertAlertToNotification(t)});this.alertFormatter.sendNotifications(a)},t.prototype.getChangedAlerts=function(t,e){return ft.differenceWith(t,e,ft.isEqual).concat(this.getVanishedAlerts(t,e))},t.prototype.getVanishedAlerts=function(t,e){return ft.differenceWith(e,t,function(t,e){return t.fingerprint===e.fingerprint}).map(function(t){return t.status="resolved",t})},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(Ki),s.inject(Ui))},token:t,providedIn:"root"}),t}(),Zi=new Hi.a("silence"),Xi=function(){function t(t,e,n,a,r){var i=this;this.authStorageService=t,this.prometheusAlertService=e,this.urlBuilder=n,this.i18n=a,this.cdDatePipe=r,this.selection=new He.a,this.icons=Yi,this.customCss={"label label-danger":"active","label label-warning":"unprocessed","label label-info":"suppressed"},this.permission=this.authStorageService.getPermissions().prometheus,this.tableActions=[{permission:"create",canBePrimary:function(t){return t.hasSingleSelection},disable:function(t){return!t.hasSingleSelection||t.first().cdExecuting},icon:Yi.add,routerLink:function(){return"/monitoring"+i.urlBuilder.getCreateFrom(i.selection.first().fingerprint)},name:this.i18n("Create Silence")}]}return t.prototype.ngOnInit=function(){this.columns=[{name:this.i18n("Name"),prop:"labels.alertname",flexGrow:2},{name:this.i18n("Job"),prop:"labels.job",flexGrow:2},{name:this.i18n("Severity"),prop:"labels.severity"},{name:this.i18n("State"),prop:"status.state",cellTransformation:cn.a.classAdding},{name:this.i18n("Started"),prop:"startsAt",pipe:this.cdDatePipe},{name:this.i18n("URL"),prop:"generatorURL",sortable:!1,cellTemplate:this.externalLinkTpl}]},t.prototype.updateSelection=function(t){this.selection=t},t}(),Ji=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Qi(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"tabset",[["cdTableDetail",""]],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](1,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](2,0,null,0,3,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](3,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](4,0,null,null,1,"cd-table-key-value",[],null,null,null,wn.b,wn.a)),s["\u0275did"](5,638976,null,0,Sn.a,[On.a],{data:[0,"data"],autoReload:[1,"autoReload"],renderObjects:[2,"renderObjects"],appendParentKey:[3,"appendParentKey"],hideEmpty:[4,"hideEmpty"],customCss:[5,"customCss"]},null)],function(t,e){var n=e.component;t(e,3,0,"Details"),t(e,5,0,n.selection.first(),!1,!0,!1,!0,n.customCss)},function(t,e){t(e,0,0,s["\u0275nov"](e,1).clazz),t(e,2,0,s["\u0275nov"](e,3).id,s["\u0275nov"](e,3).active,s["\u0275nov"](e,3).addClass)})}function ts(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"a",[["target","_blank"]],[[8,"href",4]],null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,0,"i",[["class","fa fa-line-chart"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[" Source"]))],null,function(t,e){t(e,0,0,e.context.value)})}function es(t){return s["\u0275vid"](0,[s["\u0275qud"](402653184,1,{externalLinkTpl:0}),(t()(),s["\u0275eld"](1,0,null,null,5,"cd-table",[["identifier","fingerprint"],["selectionType","single"]],null,[[null,"updateSelection"]],function(t,e,n){var a=!0;return"updateSelection"===e&&(a=!1!==t.component.updateSelection(n)&&a),a},Ye.b,Ye.a)),s["\u0275did"](2,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],identifier:[2,"identifier"],forceIdentifier:[3,"forceIdentifier"],selectionType:[4,"selectionType"],customCss:[5,"customCss"]},{updateSelection:"updateSelection"}),(t()(),s["\u0275eld"](3,0,null,0,1,"cd-table-actions",[["class","table-actions"]],null,null,null,xn.b,xn.a)),s["\u0275did"](4,114688,null,0,Tn.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(t()(),s["\u0275and"](16777216,null,2,1,null,Qi)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,[[1,2],["externalLinkTpl",2]],null,0,null,ts))],function(t,e){var n=e.component;t(e,2,0,n.prometheusAlertService.alerts,n.columns,"fingerprint",!0,"single",n.customCss),t(e,4,0,n.permission,n.selection,n.tableActions),t(e,6,0,n.selection.hasSingleSelection)},null)}var ns=n("TZo1"),as=n("9Kw/"),rs=n("wd/R"),is=function(){function t(){}return t.prototype.transform=function(t,e){return void 0===e&&(e=!1),e?rs(t).fromNow():this._forHumans(t)},t.prototype._forHumans=function(t){for(var e=[[""+Math.floor(t/31536e3),"years"],[""+Math.floor(t%31536e3/86400),"days"],[""+Math.floor(t%86400/3600),"hours"],[""+Math.floor(t%3600/60),"minutes"],[""+Math.floor(t%60),"seconds"]],n="",a=0,r=e.length;a1?n.rules:n.rule,alerts:e?e>1?n.alerts:n.alert:n.noAlerts}):n.noRule},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(xt.a))},token:t,providedIn:"root"}),t}(),Ds=function(){function t(){}return t.prototype.calculateDuration=function(t,e){var n=+t,a=+e,r=this.getDuration(Math.abs(n-a));return n>a?"-"+r:r},t.prototype.getDuration=function(t){var e=new Date(t),n=e.getUTCHours(),a=e.getUTCMinutes(),r=function(t,e){return t?t+e:t};return[r(Math.floor(t/864e5),"d"),r(n,"h"),r(a,"m")].filter(function(t){return t}).join(" ")},t.prototype.calculateDate=function(t,e,n){var a=+t;if(!ft.isNaN(a)){var r=this.getDurationMs(e)*(n?-1:1);return new Date(a+r)}},t.prototype.getDurationMs=function(t){return 6e4*(60*(24*this.getNumbersFromString(t,"d")+this.getNumbersFromString(t,"h"))+this.getNumbersFromString(t,"m"))},t.prototype.getNumbersFromString=function(t,e){var n=t.match(new RegExp("[0-9 ]+"+e,"i"));return n?parseInt(n,10):0},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t},token:t,providedIn:"root"}),t}(),Es=function(){function t(t,e,n){this.formBuilder=t,this.silenceMatcher=e,this.bsModalRef=n,this.submitAction=new s.EventEmitter,this.editMode=!1,this.nameAttributes=["alertname","instance","job","severity"],this.possibleValues=[],this.matcherMatch=void 0,this.createForm(),this.subscribeToChanges()}return t.prototype.createForm=function(){this.form=this.formBuilder.group({name:[null,[Te.A.required]],value:[{value:null,disabled:!0},[Te.A.required]],isRegex:new Te.i(!1)})},t.prototype.subscribeToChanges=function(){var t=this;this.form.get("name").valueChanges.subscribe(function(e){null!==e?(t.setPossibleValues(e),t.form.get("value").enable()):t.form.get("value").disable()}),this.form.get("value").valueChanges.subscribe(function(e){var n=t.form.value;n.value=e,t.matcherMatch=t.silenceMatcher.singleMatch(n,t.rules)})},t.prototype.setPossibleValues=function(t){var e=this;this.possibleValues=ft.sortedUniq(this.rules.map(function(n){return ft.get(n,e.silenceMatcher.getAttributePath(t))}).filter(function(t){return t}))},t.prototype.preFillControls=function(t){this.form.setValue(t)},t.prototype.onSubmit=function(){this.submitAction.emit(this.form.value),this.bsModalRef.hide()},t}(),Ls=function(){function t(t,e,n,a,r,i,s,o,u,c,l,d){this.i18n=t,this.router=e,this.authStorageService=n,this.formBuilder=a,this.prometheusService=r,this.notificationService=i,this.route=s,this.timeDiff=o,this.bsModalService=u,this.silenceMatcher=c,this.actionLabels=l,this.succeededLabels=d,this.icons=Yi,this.bsConfig={dateInputFormat:"YYYY-MM-DDT HH:mm"},this.recreate=!1,this.edit=!1,this.resource=this.i18n("silence"),this.matchers=[],this.matcherMatch=void 0,this.matcherConfig=[{tooltip:this.i18n("Attribute name"),icon:this.icons.paragraph,attribute:"name"},{tooltip:this.i18n("Value"),icon:this.icons.terminal,attribute:"value"},{tooltip:this.i18n("Regular expression"),icon:this.icons.magic,attribute:"isRegex"}],this.init()}return t.prototype.init=function(){this.chooseMode(),this.authenticate(),this.createForm(),this.setupDates(),this.getData()},t.prototype.chooseMode=function(){this.edit=this.router.url.startsWith("/monitoring/silence/edit"),this.recreate=this.router.url.startsWith("/monitoring/silence/recreate"),this.action=this.edit?this.actionLabels.EDIT:this.recreate?this.actionLabels.RECREATE:this.actionLabels.CREATE},t.prototype.authenticate=function(){this.permission=this.authStorageService.getPermissions().prometheus,this.permission.read&&(this.edit?this.permission.update:this.permission.create)||this.router.navigate(["/404"])},t.prototype.createForm=function(){var t=this;this.form=this.formBuilder.group({startsAt:[null,[Te.A.required]],duration:["2h",[Te.A.min(1)]],endsAt:[null,[Te.A.required]],createdBy:[this.authStorageService.getUsername(),[Te.A.required]],comment:[null,[Te.A.required]]},{validators:aa.a.custom("matcherRequired",function(){return 0===t.matchers.length})})},t.prototype.setupDates=function(){var t=new Date;t.setSeconds(0,0),this.form.silentSet("startsAt",t),this.updateDate(),this.subscribeDateChanges()},t.prototype.updateDate=function(t){var e=this.timeDiff.calculateDate(this.form.getValue(t?"endsAt":"startsAt"),this.form.getValue("duration"),t);e&&this.form.silentSet(t?"startsAt":"endsAt",e)},t.prototype.subscribeDateChanges=function(){var t=this;this.form.get("startsAt").valueChanges.subscribe(function(){t.onDateChange()}),this.form.get("duration").valueChanges.subscribe(function(){t.updateDate()}),this.form.get("endsAt").valueChanges.subscribe(function(){t.onDateChange(!0)})},t.prototype.onDateChange=function(t){this.form.getValue("startsAt")0),t(e,6,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"invalidUuid")),t(e,8,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"pattern"))},null)}function Do(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Eo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too high! It must be lower or equal to ","."]))],null,function(t,e){t(e,1,0,e.parent.parent.context.$implicit.value.max)})}function Lo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too low! It must be greater or equal to ","."]))],null,function(t,e){t(e,1,0,e.parent.parent.context.$implicit.value.min)})}function Po(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["The entered value needs to be a number."]))],null,null)}function Mo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,16,"div",[["class","col-sm-7"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,7,"input",[["class","form-control"],["type","number"]],[[8,"id",0],[8,"min",0],[8,"max",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,2)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,2).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,2)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,2)._compositionEnd(n.target.value)&&a),"change"===e&&(a=!1!==s["\u0275nov"](t,3).onChange(n.target.value)&&a),"input"===e&&(a=!1!==s["\u0275nov"](t,3).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,3).onTouched()&&a),a},null,null)),s["\u0275did"](2,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275did"](3,16384,null,0,Te.C,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t,e){return[t,e]},[Te.e,Te.C]),s["\u0275did"](5,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](7,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](8,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Do)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Eo)),s["\u0275did"](12,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Lo)),s["\u0275did"](14,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Po)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,5,0,s["\u0275inlineInterpolate"](1,"",e.parent.context.$implicit.value.name,"")),t(e,10,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"required")),t(e,12,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"max")),t(e,14,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"min")),t(e,16,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"pattern"))},function(t,e){t(e,1,0,s["\u0275inlineInterpolate"](1,"",e.parent.context.$implicit.value.name,""),s["\u0275inlineInterpolate"](1,"",e.parent.context.$implicit.value.min,""),s["\u0275inlineInterpolate"](1,"",e.parent.context.$implicit.value.max,""),s["\u0275nov"](e,7).ngClassUntouched,s["\u0275nov"](e,7).ngClassTouched,s["\u0275nov"](e,7).ngClassPristine,s["\u0275nov"](e,7).ngClassDirty,s["\u0275nov"](e,7).ngClassValid,s["\u0275nov"](e,7).ngClassInvalid,s["\u0275nov"](e,7).ngClassPending)})}function qo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["This field is required."]))],null,null)}function jo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["The entered value needs to be a number or decimal."]))],null,null)}function Fo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,12,"div",[["class","col-sm-7"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,7,"input",[["class","form-control"],["type","number"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,2)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,2).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,2)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,2)._compositionEnd(n.target.value)&&a),"change"===e&&(a=!1!==s["\u0275nov"](t,3).onChange(n.target.value)&&a),"input"===e&&(a=!1!==s["\u0275nov"](t,3).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,3).onTouched()&&a),a},null,null)),s["\u0275did"](2,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275did"](3,16384,null,0,Te.C,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t,e){return[t,e]},[Te.e,Te.C]),s["\u0275did"](5,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](7,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](8,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,qo)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,jo)),s["\u0275did"](12,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,5,0,s["\u0275inlineInterpolate"](1,"",e.parent.context.$implicit.value.name,"")),t(e,10,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"required")),t(e,12,0,n.mgrModuleForm.showError(e.parent.context.$implicit.value.name,s["\u0275nov"](e.parent.parent,3),"pattern"))},function(t,e){t(e,1,0,s["\u0275inlineInterpolate"](1,"",e.parent.context.$implicit.value.name,""),s["\u0275nov"](e,7).ngClassUntouched,s["\u0275nov"](e,7).ngClassTouched,s["\u0275nov"](e,7).ngClassPristine,s["\u0275nov"](e,7).ngClassDirty,s["\u0275nov"](e,7).ngClassValid,s["\u0275nov"](e,7).ngClassInvalid,s["\u0275nov"](e,7).ngClassPending)})}function zo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,3,"label",[["class","control-label col-sm-3"]],[[8,"htmlFor",0]],null,null,null,null)),(t()(),s["\u0275ted"](4,null,[" "," "])),(t()(),s["\u0275and"](16777216,null,null,1,null,So)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Oo)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,2,null,Ao)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),s["\u0275pad"](11,3),(t()(),s["\u0275and"](16777216,null,null,2,null,Mo)),s["\u0275did"](13,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),s["\u0275pad"](14,4),(t()(),s["\u0275and"](16777216,null,null,1,null,Fo)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=t(e,2,0,e.component.mgrModuleForm.showError(e.context.$implicit.value.name,s["\u0275nov"](e.parent,3)));t(e,1,0,"form-group",n),t(e,6,0,e.context.$implicit.value.long_desc||e.context.$implicit.value.desc),t(e,8,0,"bool"===e.context.$implicit.value.type);var a=t(e,11,0,"addr","str","uuid").includes(e.context.$implicit.value.type);t(e,10,0,a);var r=t(e,14,0,"uint","int","size","secs").includes(e.context.$implicit.value.type);t(e,13,0,r),t(e,16,0,"float"===e.context.$implicit.value.type)},function(t,e){t(e,3,0,s["\u0275inlineInterpolate"](1,"",e.context.$implicit.value.name,"")),t(e,4,0,e.context.$implicit.value.name)})}function Go(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,22,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,21,"form",[["class","form-horizontal"],["name","mgrModuleForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,3).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,3).onReset()&&a),a},null,null)),s["\u0275did"](2,16384,null,0,Te.D,[],null,null),s["\u0275did"](3,540672,[["frm",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](5,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](6,0,null,null,16,"div",[["class","panel panel-default"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,2,"div",[["class","panel-heading"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,1,"h3",[["class","panel-title"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Edit Manager module"])),(t()(),s["\u0275eld"](10,0,null,null,3,"div",[["class","panel-body"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,2,null,zo)),s["\u0275did"](12,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),s["\u0275pid"](0,i.KeyValuePipe,[s.KeyValueDiffers]),(t()(),s["\u0275eld"](14,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](15,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),s["\u0275eld"](16,0,null,null,3,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.onSubmit()&&a),a},$a.b,$a.a)),s["\u0275did"](17,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(t()(),s["\u0275eld"](18,0,null,0,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Update"])),(t()(),s["\u0275eld"](20,0,null,null,2,"button",[["class","btn btn-sm btn-default"],["routerLink","/mgr-modules"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,21).onClick()&&a),a},null,null)),s["\u0275did"](21,16384,null,0,tt.m,[tt.l,tt.a,[8,null],s.Renderer2,s.ElementRef],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Back"]))],function(t,e){var n=e.component;t(e,3,0,n.mgrModuleForm),t(e,12,0,s["\u0275unv"](e,12,0,s["\u0275nov"](e,13).transform(n.moduleOptions))),t(e,17,0,n.mgrModuleForm,"button"),t(e,21,0,"/mgr-modules")},function(t,e){t(e,1,0,s["\u0275nov"](e,5).ngClassUntouched,s["\u0275nov"](e,5).ngClassTouched,s["\u0275nov"](e,5).ngClassPristine,s["\u0275nov"](e,5).ngClassDirty,s["\u0275nov"](e,5).ngClassValid,s["\u0275nov"](e,5).ngClassInvalid,s["\u0275nov"](e,5).ngClassPending)})}function Yo(t){return s["\u0275vid"](0,[s["\u0275pid"](0,Rs.a,[]),(t()(),s["\u0275and"](16777216,null,null,1,null,To)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,wo)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Go)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,n.loading&&!n.error),t(e,4,0,n.loading&&n.error),t(e,6,0,!n.loading&&!n.error)},null)}function Vo(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-mgr-module-form",[],null,null,null,Yo,xo)),s["\u0275did"](1,114688,null,0,_o,[tt.a,tt.l,ca.a,ro,Jn.a,xt.a],null,null)],function(t,e){t(e,1,0)},null)}var Ho=s["\u0275ccf"]("cd-mgr-module-form",_o,Vo,{},{},[]),Bo=function(){function t(){this.lhsCounter="mds_mem.ino",this.rhsCounter="mds_server.handle_client_request",this.chart={datasets:[{label:this.lhsCounter,yAxisID:"LHS",data:[],lineTension:.1},{label:this.rhsCounter,yAxisID:"RHS",data:[],lineTension:.1}],options:{title:{text:"",display:!0},responsive:!0,maintainAspectRatio:!1,legend:{position:"top"},scales:{xAxes:[{position:"top",type:"time",time:{displayFormats:{quarter:"MMM YYYY"}},ticks:{maxRotation:0}}],yAxes:[{id:"LHS",type:"linear",position:"left"},{id:"RHS",type:"linear",position:"right"}]},tooltips:{enabled:!1,mode:"index",intersect:!1,position:"nearest",callbacks:{title:function(t,e){var n=0;if(t.length>0){var a=t[0];n=e.datasets[a.datasetIndex].data[a.index].x}return n.toString()}}}},chartType:"line"}}return t.prototype.ngOnInit=function(){ft.isUndefined(this.mdsCounter)||(this.setChartTooltip(),this.updateChart())},t.prototype.ngOnChanges=function(){ft.isUndefined(this.mdsCounter)||this.updateChart()},t.prototype.setChartTooltip=function(){var t=new pt.a(this.chartCanvas,this.chartTooltip,function(t){return t.caretX+"px"},function(t){return t.caretY-t.height-23+"px"});t.getTitle=function(t){return rs(t,"x").format("LTS")},t.checkOffset=!0,ft.merge(this.chart,{options:{title:{text:this.mdsCounter.name},tooltips:{custom:function(e){return t.customTooltips(e)}}}})},t.prototype.updateChart=function(){var t=[{data:this.convertTimeSeries(this.mdsCounter[this.lhsCounter])},{data:this.deltaTimeSeries(this.mdsCounter[this.rhsCounter])}];ft.merge(this.chart,{datasets:t}),this.chart.datasets=this.chart.datasets.slice()},t.prototype.convertTimeSeries=function(t){var e=[];return ft.each(t,function(t){e.push({x:1e3*t[0],y:t[1]})}),e.shift(),e},t.prototype.deltaTimeSeries=function(t){var e,n=t[0],a=[];for(e=1;ei?1:-1}}],data:[]}},t.prototype.refresh=function(){var t=this;this.cephfsService.getCephfs(this.id).subscribe(function(e){t.ranks.data=e.cephfs.ranks,t.pools.data=e.cephfs.pools,t.pools.data.forEach(function(t){t.size=t.used+t.avail}),t.standbys=[{key:t.i18n("Standby daemons"),value:e.standbys.map(function(t){return t.name}).join(", ")}],t.name=e.cephfs.name,t.clientCount=e.cephfs.client_count}),this.cephfsService.getMdsCounters(this.id).subscribe(function(e){ft.each(t.mdsCounters,function(n,a){void 0===e[a]&&delete t.mdsCounters[a]}),ft.each(e,function(e,n){e.name=n,t.mdsCounters[n]=e})})},t.prototype.trackByFn=function(t,e){return e.name},t}(),nu=s["\u0275crt"]({encapsulation:0,styles:[[".progress[_ngcontent-%COMP%]{margin-bottom:0}"]],data:{}});function au(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,2,"div",[["class","col-md-12"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"cd-cephfs-chart",[],null,null,null,Wo,Uo)),s["\u0275did"](3,638976,null,0,Bo,[],{mdsCounter:[0,"mdsCounter"]},null)],function(t,e){t(e,3,0,e.context.$implicit)},null)}function ru(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-cephfs-clients",[],null,null,null,tu,Qo)),s["\u0275did"](1,114688,null,0,Jo,[Zo,xt.a],{id:[0,"id"]},null)],function(t,e){t(e,1,0,e.component.id)},null)}function iu(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"tab",[["heading","Performance Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](1,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](2,0,null,null,1,"cd-grafana",[["grafanaStyle","one"],["uid","tbO9LAiZz"]],null,null,null,Me.b,Me.a)),s["\u0275did"](3,638976,null,0,qe.a,[je.a,Fe.DomSanitizer,ze.a,Ge.a,xt.a],{grafanaPath:[0,"grafanaPath"],grafanaStyle:[1,"grafanaStyle"],uid:[2,"uid"]},null)],function(t,e){var n=e.component;t(e,1,0,"Performance Details"),t(e,3,0,"mds-performance?var-mds_servers=mds."+n.grafanaId,"one","tbO9LAiZz")},function(t,e){t(e,0,0,s["\u0275nov"](e,1).id,s["\u0275nov"](e,1).active,s["\u0275nov"](e,1).addClass)})}function su(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,26,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](1,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](2,0,null,0,18,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](3,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](4,0,null,null,12,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,6,"div",[["class","col-sm-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,1,"legend",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Ranks"])),(t()(),s["\u0275eld"](8,0,null,null,1,"cd-table",[],null,[[null,"fetchData"]],function(t,e,n){var a=!0;return"fetchData"===e&&(a=!1!==t.component.refresh()&&a),a},Ye.b,Ye.a)),s["\u0275did"](9,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],toolHeader:[2,"toolHeader"]},{fetchData:"fetchData"}),(t()(),s["\u0275eld"](10,0,null,null,1,"cd-table-key-value",[],null,null,null,wn.b,wn.a)),s["\u0275did"](11,638976,null,0,Sn.a,[On.a],{data:[0,"data"]},null),(t()(),s["\u0275eld"](12,0,null,null,4,"div",[["class","col-sm-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,1,"legend",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Pools"])),(t()(),s["\u0275eld"](15,0,null,null,1,"cd-table",[],null,null,null,Ye.b,Ye.a)),s["\u0275did"](16,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],toolHeader:[2,"toolHeader"]},null),(t()(),s["\u0275eld"](17,0,null,null,1,"legend",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["MDS performance counters"])),(t()(),s["\u0275and"](16777216,null,null,1,null,au)),s["\u0275did"](20,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(t()(),s["\u0275eld"](21,0,null,0,3,"tab",[],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],[[null,"selectTab"],[null,"deselect"]],function(t,e,n){var a=!0,r=t.component;return"selectTab"===e&&(a=0!=(r.clientsSelect=!0)&&a),"deselect"===e&&(a=0!=(r.clientsSelect=!1)&&a),a},null,null)),s["\u0275did"](22,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},{selectTab:"selectTab",deselect:"deselect"}),(t()(),s["\u0275and"](16777216,null,null,1,null,ru)),s["\u0275did"](24,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,0,1,null,iu)),s["\u0275did"](26,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,"Details"),t(e,9,0,n.ranks.data,n.ranks.columns,!1),t(e,11,0,n.standbys),t(e,16,0,n.pools.data,n.pools.columns,!1),t(e,20,0,n.objectValues(n.mdsCounters),n.trackByFn),t(e,22,0,s["\u0275inlineInterpolate"](1,"Clients: ",n.clientCount,"")),t(e,24,0,n.clientsSelect),t(e,26,0,n.grafanaPermission.read)},function(t,e){t(e,0,0,s["\u0275nov"](e,1).clazz),t(e,2,0,s["\u0275nov"](e,3).id,s["\u0275nov"](e,3).active,s["\u0275nov"](e,3).addClass),t(e,21,0,s["\u0275nov"](e,22).id,s["\u0275nov"](e,22).active,s["\u0275nov"](e,22).addClass)})}function ou(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-usage-bar",[],null,null,null,mn.b,mn.a)),s["\u0275did"](1,573440,null,0,yn.a,[],{total:[0,"total"],used:[1,"used"]},null)],function(t,e){t(e,1,0,e.context.row.size,e.context.row.used)},null)}function uu(t){return s["\u0275vid"](0,[(t()(),s["\u0275ted"](0,null,[" ",": "," /s\n"])),s["\u0275ppd"](1,1)],null,function(t,e){var n="standby-replay"===e.context.row.state?"Evts":"Reqs",a=s["\u0275unv"](e,0,1,t(e,1,0,s["\u0275nov"](e.parent,0),e.context.value));t(e,0,0,n,a)})}function cu(t){return s["\u0275vid"](0,[s["\u0275pid"](0,gt.a,[It.a]),s["\u0275qud"](402653184,1,{poolUsageTpl:0}),s["\u0275qud"](402653184,2,{activityTmpl:0}),(t()(),s["\u0275and"](16777216,null,null,1,null,su)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,[[1,2],["poolUsageTpl",2]],null,0,null,ou)),(t()(),s["\u0275and"](0,[[2,2],["activityTmpl",2]],null,0,null,uu))],function(t,e){t(e,4,0,e.component.selectedItem)},null)}var lu=function(){function t(t,e){this.cephfsService=t,this.i18n=e,this.filesystems=[],this.selection=new He.a}return t.prototype.ngOnInit=function(){this.columns=[{name:this.i18n("Name"),prop:"mdsmap.fs_name",flexGrow:2},{name:this.i18n("Created"),prop:"mdsmap.created",flexGrow:2},{name:this.i18n("Enabled"),prop:"mdsmap.enabled",flexGrow:1}]},t.prototype.loadFilesystems=function(t){var e=this;this.cephfsService.list().subscribe(function(t){e.filesystems=t},function(){t.error()})},t.prototype.updateSelection=function(t){this.selection=t},t}(),du=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function fu(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["identifier","id"],["selectionType","single"]],null,[[null,"fetchData"],[null,"updateSelection"]],function(t,e,n){var a=!0,r=t.component;return"fetchData"===e&&(a=!1!==r.loadFilesystems(n)&&a),"updateSelection"===e&&(a=!1!==r.updateSelection(n)&&a),a},Ye.b,Ye.a)),s["\u0275did"](1,2867200,null,0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],forceIdentifier:[4,"forceIdentifier"],selectionType:[5,"selectionType"]},{fetchData:"fetchData",updateSelection:"updateSelection"}),(t()(),s["\u0275eld"](2,0,null,2,1,"cd-cephfs-detail",[["cdTableDetail",""]],null,null,null,cu,nu)),s["\u0275did"](3,638976,null,0,eu,[l.a,Zo,ht.a,gt.a,xt.a],{selection:[0,"selection"]},null)],function(t,e){var n=e.component;t(e,1,0,n.filesystems,n.columns,"flex","id","true","single"),t(e,3,0,n.selection)},null)}function pu(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-cephfs-list",[],null,null,null,fu,du)),s["\u0275did"](1,114688,null,0,lu,[Zo,xt.a],null,null)],function(t,e){t(e,1,0)},null)}var hu=s["\u0275ccf"]("cd-cephfs-list",lu,pu,{},{},[]),gu=function(){function t(t,e,n,a){this.route=t,this.summaryService=e,this.cephReleaseNamePipe=n,this.i18n=a,this.message=this.i18n("The NFS Ganesha service is not configured.")}return t.prototype.ngOnInit=function(){var t=this,e=this.summaryService.subscribe(function(n){if(n){var a=t.cephReleaseNamePipe.transform(n.version);t.docsUrl="http://docs.ceph.com/docs/"+a+"/mgr/dashboard/#configuring-nfs-ganesha-in-the-dashboard",setTimeout(function(){e.unsubscribe()},0)}});this.routeParamsSubscribe=this.route.params.subscribe(function(e){t.message=e.message})},t.prototype.ngOnDestroy=function(){this.routeParamsSubscribe.unsubscribe()},t}(),bu=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function mu(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,8,"cd-info-panel",[],null,null,null,ns.b,ns.a)),s["\u0275did"](1,49152,null,0,as.a,[xt.a],null,null),(t()(),s["\u0275ted"](2,0,[" ",""])),(t()(),s["\u0275eld"](3,0,null,0,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,0,4,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Please consult the "])),(t()(),s["\u0275eld"](6,0,null,null,1,"a",[["target","_blank"]],[[8,"href",4]],null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["documentation"])),(t()(),s["\u0275ted"](-1,null,[" on how to configure and enable the NFS Ganesha management functionality."]))],null,function(t,e){var n=e.component;t(e,2,0,n.message),t(e,6,0,s["\u0275inlineInterpolate"](1,"",n.docsUrl,""))})}function yu(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-nfs-501",[],null,null,null,mu,bu)),s["\u0275did"](1,245760,null,0,gu,[tt.a,je.a,Ge.a,xt.a],null,null)],function(t,e){t(e,1,0)},null)}var vu=s["\u0275ccf"]("cd-nfs-501",gu,yu,{},{},[]),_u=function(){function t(t){this.i18n=t,this.clients=[],this.clientsColumns=[{name:this.i18n("Addresses"),prop:"addresses",flexGrow:2},{name:this.i18n("Access Type"),prop:"access_type",flexGrow:1},{name:this.i18n("Squash"),prop:"squash",flexGrow:1}]}return t.prototype.ngOnChanges=function(){this.selection.hasSelection&&(this.selectedItem=this.selection.first(),this.clients=this.selectedItem.clients,this.data={},this.data[this.i18n("Cluster")]=this.selectedItem.cluster_id,this.data[this.i18n("Daemons")]=this.selectedItem.daemons,this.data[this.i18n("NFS Protocol")]=this.selectedItem.protocols.map(function(t){return"NFSv"+t}),this.data[this.i18n("Pseudo")]=this.selectedItem.pseudo,this.data[this.i18n("Access Type")]=this.selectedItem.access_type,this.data[this.i18n("Squash")]=this.selectedItem.squash,this.data[this.i18n("Transport")]=this.selectedItem.transports,this.data[this.i18n("Path")]=this.selectedItem.path,"CEPH"===this.selectedItem.fsal.name?(this.data[this.i18n("Storage Backend")]=this.i18n("CephFS"),this.data[this.i18n("CephFS User")]=this.selectedItem.fsal.user_id,this.data[this.i18n("CephFS Filesystem")]=this.selectedItem.fsal.fs_name,this.data[this.i18n("Security Label")]=this.selectedItem.fsal.sec_label_xattr):(this.data[this.i18n("Storage Backend")]=this.i18n("Object Gateway"),this.data[this.i18n("Object Gateway User")]=this.selectedItem.fsal.rgw_user_id))},t}(),xu=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Tu(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,9,"tabset",[],[[2,"tab-container",null]],null,null,$.b,$.a)),s["\u0275did"](1,180224,null,0,Z.d,[Z.e,s.Renderer2,s.ElementRef],null,null),(t()(),s["\u0275eld"](2,0,null,0,3,"tab",[["heading","Details"]],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](3,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](4,0,null,null,1,"cd-table-key-value",[],null,null,null,wn.b,wn.a)),s["\u0275did"](5,638976,null,0,Sn.a,[On.a],{data:[0,"data"]},null),(t()(),s["\u0275eld"](6,0,null,0,3,"tab",[],[[1,"id",0],[2,"active",null],[2,"tab-pane",null]],null,null,null,null)),s["\u0275did"](7,212992,null,0,Z.b,[Z.d,s.ElementRef,s.Renderer2],{heading:[0,"heading"]},null),(t()(),s["\u0275eld"](8,0,null,null,1,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["identifier","addresses"],["selectionType",""]],null,null,null,Ye.b,Ye.a)),s["\u0275did"](9,2867200,[["table",4]],0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],forceIdentifier:[4,"forceIdentifier"],selectionType:[5,"selectionType"]},null)],function(t,e){var n=e.component;t(e,3,0,"Details"),t(e,5,0,n.data),t(e,7,0,s["\u0275inlineInterpolate"](1,"Clients (",n.clients.length,")")),t(e,9,0,n.clients,n.clientsColumns,"flex","addresses","true","")},function(t,e){t(e,0,0,s["\u0275nov"](e,1).clazz),t(e,2,0,s["\u0275nov"](e,3).id,s["\u0275nov"](e,3).active,s["\u0275nov"](e,3).addClass),t(e,6,0,s["\u0275nov"](e,7).id,s["\u0275nov"](e,7).active,s["\u0275nov"](e,7).addClass)})}function wu(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Tu)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,null==n.selection?null:n.selection.hasSingleSelection)},null)}var Su=n("VTlA"),Ou=n("ufoC"),Iu=function(){function t(t,e){this.http=t,this.i18n=e,this.apiPath="api/nfs-ganesha",this.uiApiPath="ui-api/nfs-ganesha",this.nfsAccessType=[{value:"RW",help:this.i18n("Allows all operations")},{value:"RO",help:this.i18n("Allows only operations that do not modify the server")},{value:"MDONLY",help:this.i18n("Does not allow read or write operations, but allows any other operation")},{value:"MDONLY_RO",help:this.i18n("Does not allow read, write, or any operation that modifies file attributes or directory content")},{value:"NONE",help:this.i18n("Allows no access at all")}],this.nfsFsal=[{value:"CEPH",descr:this.i18n("CephFS")},{value:"RGW",descr:this.i18n("Object Gateway")}],this.nfsSquash=["no_root_squash","root_id_squash","root_squash","all_squash"]}return t.prototype.list=function(){return this.http.get(this.apiPath+"/export")},t.prototype.get=function(t,e){return this.http.get(this.apiPath+"/export/"+t+"/"+e)},t.prototype.create=function(t){return this.http.post(this.apiPath+"/export",t,{observe:"response"})},t.prototype.update=function(t,e,n){return this.http.put(this.apiPath+"/export/"+t+"/"+e,n,{observe:"response"})},t.prototype.delete=function(t,e){return this.http.delete(this.apiPath+"/export/"+t+"/"+e,{observe:"response"})},t.prototype.lsDir=function(t){return this.http.get(this.uiApiPath+"/lsdir?root_dir="+t)},t.prototype.buckets=function(t){return this.http.get(this.uiApiPath+"/rgw/buckets?user_id="+t)},t.prototype.clients=function(){return this.http.get(this.uiApiPath+"/cephx/clients")},t.prototype.fsals=function(){return this.http.get(this.uiApiPath+"/fsals")},t.prototype.filesystems=function(){return this.http.get(this.uiApiPath+"/cephfs/filesystems")},t.prototype.daemon=function(){return this.http.get(this.apiPath+"/daemon")},t.prototype.start=function(t){return this.http.put(this.apiPath+"/service/"+t+"/start",null,{observe:"response"})},t.prototype.stop=function(t){return this.http.put(this.apiPath+"/service/"+t+"/stop",null,{observe:"response"})},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c),s.inject(xt.a))},token:t,providedIn:Nt.a}),t}(),Cu=n("kvvV"),ku=n("kn/O"),Nu=function(){function t(t,e,n,a,r,i,s){var o=this;this.authStorageService=t,this.i18n=e,this.modalService=n,this.nfsService=a,this.taskListService=r,this.taskWrapper=i,this.actionLabels=s,this.selection=new He.a,this.isDefaultCluster=!1,this.builders={"nfs/create":function(t){return{path:t.path,cluster_id:t.cluster_id,fsal:t.fsal}}},this.permission=this.authStorageService.getPermissions().nfs,this.tableActions=[{permission:"create",icon:"fa-plus",routerLink:function(){return"/nfs/create"},canBePrimary:function(t){return!t.hasSingleSelection},name:this.actionLabels.CREATE},{permission:"update",icon:"fa-pencil",routerLink:function(){return"/nfs/edit/"+(o.selection.first()&&encodeURI(o.selection.first().cluster_id)+"/"+encodeURI(o.selection.first().export_id))},name:this.actionLabels.EDIT},{permission:"delete",icon:"fa-times",click:function(){return o.deleteNfsModal()},name:this.actionLabels.DELETE}]}return t.prototype.ngOnInit=function(){var t=this;this.columns=[{name:this.i18n("Path"),prop:"path",flexGrow:2,cellTransformation:cn.a.executing},{name:this.i18n("Pseudo"),prop:"pseudo",flexGrow:2},{name:this.i18n("Cluster"),prop:"cluster_id",flexGrow:2},{name:this.i18n("Daemons"),prop:"daemons",flexGrow:2},{name:this.i18n("Storage Backend"),prop:"fsal",flexGrow:2,cellTemplate:this.nfsFsal},{name:this.i18n("Access Type"),prop:"access_type",flexGrow:2}],this.nfsService.daemon().subscribe(function(e){var n=ft(e).map(function(t){return t.cluster_id}).uniq().value();t.isDefaultCluster=1===n.length&&"_default_"===n[0],t.columns[2].isHidden=t.isDefaultCluster,t.table&&t.table.updateColumns(),t.taskListService.init(function(){return t.nfsService.list()},function(e){return t.prepareResponse(e)},function(e){return t.exports=e},function(){return t.onFetchError()},t.taskFilter,t.itemFilter,t.builders)},function(){t.onFetchError()})},t.prototype.ngOnDestroy=function(){this.summaryDataSubscription&&this.summaryDataSubscription.unsubscribe()},t.prototype.prepareResponse=function(t){var e=[];return t.forEach(function(t){t.id=t.cluster_id+":"+t.export_id,t.state="LOADING",e=e.concat(t)}),e},t.prototype.onFetchError=function(){this.table.reset(),this.viewCacheStatus={status:Xo.a.ValueException}},t.prototype.itemFilter=function(t,e){return t.cluster_id===e.metadata.cluster_id&&t.export_id===e.metadata.export_id},t.prototype.taskFilter=function(t){return["nfs/create","nfs/delete","nfs/edit"].includes(t.name)},t.prototype.updateSelection=function(t){this.selection=t},t.prototype.deleteNfsModal=function(){var t=this,e=this.selection.first().cluster_id,n=this.selection.first().export_id;this.modalRef=this.modalService.show($n.a,{initialState:{itemDescription:this.i18n("NFS export"),itemNames:[e+":"+n],submitActionObservable:function(){return t.taskWrapper.wrapTaskAroundCall({task:new Cu.a("nfs/delete",{cluster_id:e,export_id:n}),call:t.nfsService.delete(e,n)})}}})},t}(),Ru=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Au(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["CephFS"]))],null,null)}function Du(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Object Gateway"]))],null,null)}function Eu(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Au)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Du)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,"CEPH"===e.context.value.name),t(e,3,0,"RGW"===e.context.value.name)},null)}function Lu(t){return s["\u0275vid"](0,[s["\u0275qud"](402653184,1,{nfsState:0}),s["\u0275qud"](402653184,2,{nfsFsal:0}),s["\u0275qud"](402653184,3,{table:0}),(t()(),s["\u0275eld"](3,0,null,null,6,"cd-table",[["columnMode","flex"],["forceIdentifier","true"],["identifier","id"],["selectionType","single"]],null,[[null,"updateSelection"]],function(t,e,n){var a=!0;return"updateSelection"===e&&(a=!1!==t.component.updateSelection(n)&&a),a},Ye.b,Ye.a)),s["\u0275did"](4,2867200,[[3,4],["table",4]],0,Ve.a,[s.NgZone,s.ChangeDetectorRef],{data:[0,"data"],columns:[1,"columns"],columnMode:[2,"columnMode"],identifier:[3,"identifier"],forceIdentifier:[4,"forceIdentifier"],selectionType:[5,"selectionType"]},{updateSelection:"updateSelection"}),(t()(),s["\u0275eld"](5,0,null,0,2,"div",[["class","table-actions btn-toolbar"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,1,"cd-table-actions",[["class","btn-group"]],null,null,null,xn.b,xn.a)),s["\u0275did"](7,114688,null,0,Tn.a,[],{permission:[0,"permission"],selection:[1,"selection"],tableActions:[2,"tableActions"]},null),(t()(),s["\u0275eld"](8,0,null,2,1,"cd-nfs-details",[["cdTableDetail",""]],null,null,null,wu,xu)),s["\u0275did"](9,573440,null,0,_u,[xt.a],{selection:[0,"selection"]},null),(t()(),s["\u0275and"](0,[[2,2],["nfsFsal",2]],null,0,null,Eu))],function(t,e){var n=e.component;t(e,4,0,n.exports,n.columns,"flex","id","true","single"),t(e,7,0,n.permission,n.selection,n.tableActions),t(e,9,0,n.selection)},null)}function Pu(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-nfs-list",[],null,null,null,Lu,Ru)),s["\u0275prd"](131584,null,Su.a,Su.a,[Ou.a,je.a]),s["\u0275did"](2,245760,null,0,Nu,[l.a,xt.a,pa.b,Iu,Su.a,ku.a,Zn.b],null,null)],function(t,e){t(e,2,0)},null)}var Mu=s["\u0275ccf"]("cd-nfs-list",Nu,Pu,{},{},[]),qu=n("rpEJ"),ju=n("ihYY"),Fu=n("t9fZ"),zu=n("Gi3i"),Gu=n("15JJ"),Yu=n("psW0"),Vu=n("VnD/"),Hu=n("R+r5"),Bu=n("zrt+"),Uu=n("0/uQ"),Wu={"\xc1":"A","\u0102":"A","\u1eae":"A","\u1eb6":"A","\u1eb0":"A","\u1eb2":"A","\u1eb4":"A","\u01cd":"A","\xc2":"A","\u1ea4":"A","\u1eac":"A","\u1ea6":"A","\u1ea8":"A","\u1eaa":"A","\xc4":"A","\u01de":"A","\u0226":"A","\u01e0":"A","\u1ea0":"A","\u0200":"A","\xc0":"A","\u1ea2":"A","\u0202":"A","\u0100":"A","\u0104":"A","\xc5":"A","\u01fa":"A","\u1e00":"A","\u023a":"A","\xc3":"A","\ua732":"AA","\xc6":"AE","\u01fc":"AE","\u01e2":"AE","\ua734":"AO","\ua736":"AU","\ua738":"AV","\ua73a":"AV","\ua73c":"AY","\u1e02":"B","\u1e04":"B","\u0181":"B","\u1e06":"B","\u0243":"B","\u0182":"B","\u0106":"C","\u010c":"C","\xc7":"C","\u1e08":"C","\u0108":"C","\u010a":"C","\u0187":"C","\u023b":"C","\u010e":"D","\u1e10":"D","\u1e12":"D","\u1e0a":"D","\u1e0c":"D","\u018a":"D","\u1e0e":"D","\u01f2":"D","\u01c5":"D","\u0110":"D","\u018b":"D","\u01f1":"DZ","\u01c4":"DZ","\xc9":"E","\u0114":"E","\u011a":"E","\u0228":"E","\u1e1c":"E","\xca":"E","\u1ebe":"E","\u1ec6":"E","\u1ec0":"E","\u1ec2":"E","\u1ec4":"E","\u1e18":"E","\xcb":"E","\u0116":"E","\u1eb8":"E","\u0204":"E","\xc8":"E","\u1eba":"E","\u0206":"E","\u0112":"E","\u1e16":"E","\u1e14":"E","\u0118":"E","\u0246":"E","\u1ebc":"E","\u1e1a":"E","\ua76a":"ET","\u1e1e":"F","\u0191":"F","\u01f4":"G","\u011e":"G","\u01e6":"G","\u0122":"G","\u011c":"G","\u0120":"G","\u0193":"G","\u1e20":"G","\u01e4":"G","\u1e2a":"H","\u021e":"H","\u1e28":"H","\u0124":"H","\u2c67":"H","\u1e26":"H","\u1e22":"H","\u1e24":"H","\u0126":"H","\xcd":"I","\u012c":"I","\u01cf":"I","\xce":"I","\xcf":"I","\u1e2e":"I","\u0130":"I","\u1eca":"I","\u0208":"I","\xcc":"I","\u1ec8":"I","\u020a":"I","\u012a":"I","\u012e":"I","\u0197":"I","\u0128":"I","\u1e2c":"I","\ua779":"D","\ua77b":"F","\ua77d":"G","\ua782":"R","\ua784":"S","\ua786":"T","\ua76c":"IS","\u0134":"J","\u0248":"J","\u1e30":"K","\u01e8":"K","\u0136":"K","\u2c69":"K","\ua742":"K","\u1e32":"K","\u0198":"K","\u1e34":"K","\ua740":"K","\ua744":"K","\u0139":"L","\u023d":"L","\u013d":"L","\u013b":"L","\u1e3c":"L","\u1e36":"L","\u1e38":"L","\u2c60":"L","\ua748":"L","\u1e3a":"L","\u013f":"L","\u2c62":"L","\u01c8":"L","\u0141":"L","\u01c7":"LJ","\u1e3e":"M","\u1e40":"M","\u1e42":"M","\u2c6e":"M","\u0143":"N","\u0147":"N","\u0145":"N","\u1e4a":"N","\u1e44":"N","\u1e46":"N","\u01f8":"N","\u019d":"N","\u1e48":"N","\u0220":"N","\u01cb":"N","\xd1":"N","\u01ca":"NJ","\xd3":"O","\u014e":"O","\u01d1":"O","\xd4":"O","\u1ed0":"O","\u1ed8":"O","\u1ed2":"O","\u1ed4":"O","\u1ed6":"O","\xd6":"O","\u022a":"O","\u022e":"O","\u0230":"O","\u1ecc":"O","\u0150":"O","\u020c":"O","\xd2":"O","\u1ece":"O","\u01a0":"O","\u1eda":"O","\u1ee2":"O","\u1edc":"O","\u1ede":"O","\u1ee0":"O","\u020e":"O","\ua74a":"O","\ua74c":"O","\u014c":"O","\u1e52":"O","\u1e50":"O","\u019f":"O","\u01ea":"O","\u01ec":"O","\xd8":"O","\u01fe":"O","\xd5":"O","\u1e4c":"O","\u1e4e":"O","\u022c":"O","\u01a2":"OI","\ua74e":"OO","\u0190":"E","\u0186":"O","\u0222":"OU","\u1e54":"P","\u1e56":"P","\ua752":"P","\u01a4":"P","\ua754":"P","\u2c63":"P","\ua750":"P","\ua758":"Q","\ua756":"Q","\u0154":"R","\u0158":"R","\u0156":"R","\u1e58":"R","\u1e5a":"R","\u1e5c":"R","\u0210":"R","\u0212":"R","\u1e5e":"R","\u024c":"R","\u2c64":"R","\ua73e":"C","\u018e":"E","\u015a":"S","\u1e64":"S","\u0160":"S","\u1e66":"S","\u015e":"S","\u015c":"S","\u0218":"S","\u1e60":"S","\u1e62":"S","\u1e68":"S","\u0164":"T","\u0162":"T","\u1e70":"T","\u021a":"T","\u023e":"T","\u1e6a":"T","\u1e6c":"T","\u01ac":"T","\u1e6e":"T","\u01ae":"T","\u0166":"T","\u2c6f":"A","\ua780":"L","\u019c":"M","\u0245":"V","\ua728":"TZ","\xda":"U","\u016c":"U","\u01d3":"U","\xdb":"U","\u1e76":"U","\xdc":"U","\u01d7":"U","\u01d9":"U","\u01db":"U","\u01d5":"U","\u1e72":"U","\u1ee4":"U","\u0170":"U","\u0214":"U","\xd9":"U","\u1ee6":"U","\u01af":"U","\u1ee8":"U","\u1ef0":"U","\u1eea":"U","\u1eec":"U","\u1eee":"U","\u0216":"U","\u016a":"U","\u1e7a":"U","\u0172":"U","\u016e":"U","\u0168":"U","\u1e78":"U","\u1e74":"U","\ua75e":"V","\u1e7e":"V","\u01b2":"V","\u1e7c":"V","\ua760":"VY","\u1e82":"W","\u0174":"W","\u1e84":"W","\u1e86":"W","\u1e88":"W","\u1e80":"W","\u2c72":"W","\u1e8c":"X","\u1e8a":"X","\xdd":"Y","\u0176":"Y","\u0178":"Y","\u1e8e":"Y","\u1ef4":"Y","\u1ef2":"Y","\u01b3":"Y","\u1ef6":"Y","\u1efe":"Y","\u0232":"Y","\u024e":"Y","\u1ef8":"Y","\u0179":"Z","\u017d":"Z","\u1e90":"Z","\u2c6b":"Z","\u017b":"Z","\u1e92":"Z","\u0224":"Z","\u1e94":"Z","\u01b5":"Z","\u0132":"IJ","\u0152":"OE","\u1d00":"A","\u1d01":"AE","\u0299":"B","\u1d03":"B","\u1d04":"C","\u1d05":"D","\u1d07":"E","\ua730":"F","\u0262":"G","\u029b":"G","\u029c":"H","\u026a":"I","\u0281":"R","\u1d0a":"J","\u1d0b":"K","\u029f":"L","\u1d0c":"L","\u1d0d":"M","\u0274":"N","\u1d0f":"O","\u0276":"OE","\u1d10":"O","\u1d15":"OU","\u1d18":"P","\u0280":"R","\u1d0e":"N","\u1d19":"R","\ua731":"S","\u1d1b":"T","\u2c7b":"E","\u1d1a":"R","\u1d1c":"U","\u1d20":"V","\u1d21":"W","\u028f":"Y","\u1d22":"Z","\xe1":"a","\u0103":"a","\u1eaf":"a","\u1eb7":"a","\u1eb1":"a","\u1eb3":"a","\u1eb5":"a","\u01ce":"a","\xe2":"a","\u1ea5":"a","\u1ead":"a","\u1ea7":"a","\u1ea9":"a","\u1eab":"a","\xe4":"a","\u01df":"a","\u0227":"a","\u01e1":"a","\u1ea1":"a","\u0201":"a","\xe0":"a","\u1ea3":"a","\u0203":"a","\u0101":"a","\u0105":"a","\u1d8f":"a","\u1e9a":"a","\xe5":"a","\u01fb":"a","\u1e01":"a","\u2c65":"a","\xe3":"a","\ua733":"aa","\xe6":"ae","\u01fd":"ae","\u01e3":"ae","\ua735":"ao","\ua737":"au","\ua739":"av","\ua73b":"av","\ua73d":"ay","\u1e03":"b","\u1e05":"b","\u0253":"b","\u1e07":"b","\u1d6c":"b","\u1d80":"b","\u0180":"b","\u0183":"b","\u0275":"o","\u0107":"c","\u010d":"c","\xe7":"c","\u1e09":"c","\u0109":"c","\u0255":"c","\u010b":"c","\u0188":"c","\u023c":"c","\u010f":"d","\u1e11":"d","\u1e13":"d","\u0221":"d","\u1e0b":"d","\u1e0d":"d","\u0257":"d","\u1d91":"d","\u1e0f":"d","\u1d6d":"d","\u1d81":"d","\u0111":"d","\u0256":"d","\u018c":"d","\u0131":"i","\u0237":"j","\u025f":"j","\u0284":"j","\u01f3":"dz","\u01c6":"dz","\xe9":"e","\u0115":"e","\u011b":"e","\u0229":"e","\u1e1d":"e","\xea":"e","\u1ebf":"e","\u1ec7":"e","\u1ec1":"e","\u1ec3":"e","\u1ec5":"e","\u1e19":"e","\xeb":"e","\u0117":"e","\u1eb9":"e","\u0205":"e","\xe8":"e","\u1ebb":"e","\u0207":"e","\u0113":"e","\u1e17":"e","\u1e15":"e","\u2c78":"e","\u0119":"e","\u1d92":"e","\u0247":"e","\u1ebd":"e","\u1e1b":"e","\ua76b":"et","\u1e1f":"f","\u0192":"f","\u1d6e":"f","\u1d82":"f","\u01f5":"g","\u011f":"g","\u01e7":"g","\u0123":"g","\u011d":"g","\u0121":"g","\u0260":"g","\u1e21":"g","\u1d83":"g","\u01e5":"g","\u1e2b":"h","\u021f":"h","\u1e29":"h","\u0125":"h","\u2c68":"h","\u1e27":"h","\u1e23":"h","\u1e25":"h","\u0266":"h","\u1e96":"h","\u0127":"h","\u0195":"hv","\xed":"i","\u012d":"i","\u01d0":"i","\xee":"i","\xef":"i","\u1e2f":"i","\u1ecb":"i","\u0209":"i","\xec":"i","\u1ec9":"i","\u020b":"i","\u012b":"i","\u012f":"i","\u1d96":"i","\u0268":"i","\u0129":"i","\u1e2d":"i","\ua77a":"d","\ua77c":"f","\u1d79":"g","\ua783":"r","\ua785":"s","\ua787":"t","\ua76d":"is","\u01f0":"j","\u0135":"j","\u029d":"j","\u0249":"j","\u1e31":"k","\u01e9":"k","\u0137":"k","\u2c6a":"k","\ua743":"k","\u1e33":"k","\u0199":"k","\u1e35":"k","\u1d84":"k","\ua741":"k","\ua745":"k","\u013a":"l","\u019a":"l","\u026c":"l","\u013e":"l","\u013c":"l","\u1e3d":"l","\u0234":"l","\u1e37":"l","\u1e39":"l","\u2c61":"l","\ua749":"l","\u1e3b":"l","\u0140":"l","\u026b":"l","\u1d85":"l","\u026d":"l","\u0142":"l","\u01c9":"lj","\u017f":"s","\u1e9c":"s","\u1e9b":"s","\u1e9d":"s","\u1e3f":"m","\u1e41":"m","\u1e43":"m","\u0271":"m","\u1d6f":"m","\u1d86":"m","\u0144":"n","\u0148":"n","\u0146":"n","\u1e4b":"n","\u0235":"n","\u1e45":"n","\u1e47":"n","\u01f9":"n","\u0272":"n","\u1e49":"n","\u019e":"n","\u1d70":"n","\u1d87":"n","\u0273":"n","\xf1":"n","\u01cc":"nj","\xf3":"o","\u014f":"o","\u01d2":"o","\xf4":"o","\u1ed1":"o","\u1ed9":"o","\u1ed3":"o","\u1ed5":"o","\u1ed7":"o","\xf6":"o","\u022b":"o","\u022f":"o","\u0231":"o","\u1ecd":"o","\u0151":"o","\u020d":"o","\xf2":"o","\u1ecf":"o","\u01a1":"o","\u1edb":"o","\u1ee3":"o","\u1edd":"o","\u1edf":"o","\u1ee1":"o","\u020f":"o","\ua74b":"o","\ua74d":"o","\u2c7a":"o","\u014d":"o","\u1e53":"o","\u1e51":"o","\u01eb":"o","\u01ed":"o","\xf8":"o","\u01ff":"o","\xf5":"o","\u1e4d":"o","\u1e4f":"o","\u022d":"o","\u01a3":"oi","\ua74f":"oo","\u025b":"e","\u1d93":"e","\u0254":"o","\u1d97":"o","\u0223":"ou","\u1e55":"p","\u1e57":"p","\ua753":"p","\u01a5":"p","\u1d71":"p","\u1d88":"p","\ua755":"p","\u1d7d":"p","\ua751":"p","\ua759":"q","\u02a0":"q","\u024b":"q","\ua757":"q","\u0155":"r","\u0159":"r","\u0157":"r","\u1e59":"r","\u1e5b":"r","\u1e5d":"r","\u0211":"r","\u027e":"r","\u1d73":"r","\u0213":"r","\u1e5f":"r","\u027c":"r","\u1d72":"r","\u1d89":"r","\u024d":"r","\u027d":"r","\u2184":"c","\ua73f":"c","\u0258":"e","\u027f":"r","\u015b":"s","\u1e65":"s","\u0161":"s","\u1e67":"s","\u015f":"s","\u015d":"s","\u0219":"s","\u1e61":"s","\u1e63":"s","\u1e69":"s","\u0282":"s","\u1d74":"s","\u1d8a":"s","\u023f":"s","\u0261":"g","\u1d11":"o","\u1d13":"o","\u1d1d":"u","\u0165":"t","\u0163":"t","\u1e71":"t","\u021b":"t","\u0236":"t","\u1e97":"t","\u2c66":"t","\u1e6b":"t","\u1e6d":"t","\u01ad":"t","\u1e6f":"t","\u1d75":"t","\u01ab":"t","\u0288":"t","\u0167":"t","\u1d7a":"th","\u0250":"a","\u1d02":"ae","\u01dd":"e","\u1d77":"g","\u0265":"h","\u02ae":"h","\u02af":"h","\u1d09":"i","\u029e":"k","\ua781":"l","\u026f":"m","\u0270":"m","\u1d14":"oe","\u0279":"r","\u027b":"r","\u027a":"r","\u2c79":"r","\u0287":"t","\u028c":"v","\u028d":"w","\u028e":"y","\ua729":"tz","\xfa":"u","\u016d":"u","\u01d4":"u","\xfb":"u","\u1e77":"u","\xfc":"u","\u01d8":"u","\u01da":"u","\u01dc":"u","\u01d6":"u","\u1e73":"u","\u1ee5":"u","\u0171":"u","\u0215":"u","\xf9":"u","\u1ee7":"u","\u01b0":"u","\u1ee9":"u","\u1ef1":"u","\u1eeb":"u","\u1eed":"u","\u1eef":"u","\u0217":"u","\u016b":"u","\u1e7b":"u","\u0173":"u","\u1d99":"u","\u016f":"u","\u0169":"u","\u1e79":"u","\u1e75":"u","\u1d6b":"ue","\ua778":"um","\u2c74":"v","\ua75f":"v","\u1e7f":"v","\u028b":"v","\u1d8c":"v","\u2c71":"v","\u1e7d":"v","\ua761":"vy","\u1e83":"w","\u0175":"w","\u1e85":"w","\u1e87":"w","\u1e89":"w","\u1e81":"w","\u2c73":"w","\u1e98":"w","\u1e8d":"x","\u1e8b":"x","\u1d8d":"x","\xfd":"y","\u0177":"y","\xff":"y","\u1e8f":"y","\u1ef5":"y","\u1ef3":"y","\u01b4":"y","\u1ef7":"y","\u1eff":"y","\u0233":"y","\u1e99":"y","\u024f":"y","\u1ef9":"y","\u017a":"z","\u017e":"z","\u1e91":"z","\u0291":"z","\u2c6c":"z","\u017c":"z","\u1e93":"z","\u0225":"z","\u1e95":"z","\u1d76":"z","\u1d8e":"z","\u0290":"z","\u01b6":"z","\u0240":"z","\ufb00":"ff","\ufb03":"ffi","\ufb04":"ffl","\ufb01":"fi","\ufb02":"fl","\u0133":"ij","\u0153":"oe","\ufb06":"st","\u2090":"a","\u2091":"e","\u1d62":"i","\u2c7c":"j","\u2092":"o","\u1d63":"r","\u1d64":"u","\u1d65":"v","\u2093":"x"},Ku=function(){function t(t,e,n){void 0===e&&(e=t),void 0===n&&(n=!1),this.item=t,this.value=e,this.header=n}return t.prototype.isHeader=function(){return this.header},t.prototype.toString=function(){return this.value},t}();function $u(t){return t?t.replace(/[^A-Za-z0-9\[\] ]/g,function(t){return Wu[t]||t}):""}function Zu(t,e,n){void 0===e&&(e=" "),void 0===n&&(n="");for(var a,r=t.split(new RegExp("(?:["+n+"])([^"+n+"]+)(?:["+n+"])|([^"+e+"]+)","g")),i=[],s=r.length,o=new RegExp("["+n+"]+","g"),u=0;u=e}}return Object.defineProperty(t.prototype,"isBs4",{get:function(){return!Object(qu.d)()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"active",{get:function(){return this._active},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"matches",{get:function(){return this._matches},set:function(t){var e=this;if(this.positionService.setOptions({modifiers:{flip:{enabled:this.adaptivePosition}},allowedPositions:["top","bottom"]}),this.positionService.event$.pipe(Object(Fu.a)(1)).subscribe(function(){e.positionService.disable(),e.visibility=e.typeaheadScrollable?"hidden":"visible",e.animationState=e.isAnimated?e.isTopPosition?"animated-up":"animated-down":"unanimated"}),this._matches=t,this.needScrollbar=this.typeaheadScrollable&&this.typeaheadOptionsInScrollableView0&&(this._active=this._matches[0],this._active.isHeader()&&this.nextActiveMatch()),this._active&&!this.typeaheadIsFirstItemActive){var n=this._matches.find(function(t){return t.value===e._active.value});if(n)return void this.selectActive(n);this._active=null}},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isTopPosition",{get:function(){return this.element.nativeElement.classList.contains("top")},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"optionsListTemplate",{get:function(){return this.parent?this.parent.optionsListTemplate:void 0},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isAnimated",{get:function(){return!!this.parent&&this.parent.isAnimated},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"adaptivePosition",{get:function(){return!!this.parent&&this.parent.adaptivePosition},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"typeaheadScrollable",{get:function(){return!!this.parent&&this.parent.typeaheadScrollable},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"typeaheadOptionsInScrollableView",{get:function(){return this.parent?this.parent.typeaheadOptionsInScrollableView:5},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"typeaheadIsFirstItemActive",{get:function(){return!this.parent||this.parent.typeaheadIsFirstItemActive},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"itemTemplate",{get:function(){return this.parent?this.parent.typeaheadItemTemplate:void 0},enumerable:!0,configurable:!0}),t.prototype.selectActiveMatch=function(t){this._active&&this.parent.typeaheadSelectFirstItem&&this.selectMatch(this._active),!this.parent.typeaheadSelectFirstItem&&t&&this.selectMatch(this._active)},t.prototype.positionServiceEnable=function(){this.positionService.enable()},t.prototype.prevActiveMatch=function(){var t=this.matches.indexOf(this._active);this._active=this.matches[t-1<0?this.matches.length-1:t-1],this._active.isHeader()&&this.prevActiveMatch(),this.typeaheadScrollable&&this.scrollPrevious(t)},t.prototype.nextActiveMatch=function(){var t=this.matches.indexOf(this._active);this._active=this.matches[t+1>this.matches.length-1?0:t+1],this._active.isHeader()&&this.nextActiveMatch(),this.typeaheadScrollable&&this.scrollNext(t)},t.prototype.selectActive=function(t){this.isFocused=!0,this._active=t},t.prototype.highlight=function(t,e){var n,a,r=t.value,i=(this.parent&&this.parent.typeaheadLatinize?$u(r):r).toLowerCase();if("object"==typeof e)for(var s=e.length,o=0;o=0&&a>0&&(r=r.substring(0,n)+""+r.substring(n,n+a)+""+r.substring(n+a),i=i.substring(0,n)+" "+" ".repeat(a)+" "+i.substring(n+a));else e&&(n=i.indexOf(e),a=e.length,n>=0&&a>0&&(r=r.substring(0,n)+""+r.substring(n,n+a)+""+r.substring(n+a)));return r},t.prototype.focusLost=function(){this.isFocused=!1},t.prototype.isActive=function(t){return this._active===t},t.prototype.selectMatch=function(t,e){var n=this;return void 0===e&&(e=void 0),e&&(e.stopPropagation(),e.preventDefault()),this.parent.changeModel(t),setTimeout(function(){return n.parent.typeaheadOnSelect.emit(t)},0),!1},t.prototype.setScrollableMode=function(){if(this.ulElement||(this.ulElement=this.element),this.liElements.first){var t=qu.b.getStyles(this.ulElement.nativeElement),e=qu.b.getStyles(this.liElements.first.nativeElement),n=parseFloat((t["padding-bottom"]?t["padding-bottom"]:"").replace("px","")),a=parseFloat((t["padding-top"]?t["padding-top"]:"0").replace("px","")),r=parseFloat((e.height?e.height:"0").replace("px",""));this.guiHeight=this.typeaheadOptionsInScrollableView*r+a+n+"px"}this.renderer.setStyle(this.element.nativeElement,"visibility","visible")},t.prototype.scrollPrevious=function(t){if(0!==t){if(this.liElements){var e=this.liElements.toArray()[t-1];e&&!this.isScrolledIntoView(e.nativeElement)&&(this.ulElement.nativeElement.scrollTop=e.nativeElement.offsetTop)}}else this.scrollToBottom()},t.prototype.scrollNext=function(t){if(t+1>this.matches.length-1)this.scrollToTop();else if(this.liElements){var e=this.liElements.toArray()[t+1];e&&!this.isScrolledIntoView(e.nativeElement)&&(this.ulElement.nativeElement.scrollTop=e.nativeElement.offsetTop-Number(this.ulElement.nativeElement.offsetHeight)+Number(e.nativeElement.offsetHeight))}},t.prototype.scrollToBottom=function(){this.ulElement.nativeElement.scrollTop=this.ulElement.nativeElement.scrollHeight},t.prototype.scrollToTop=function(){this.ulElement.nativeElement.scrollTop=0},t}(),Qu=function(){return function(){this.adaptivePosition=!1,this.isAnimated=!1,this.hideResultsOnBlur=!0,this.selectFirstItem=!0,this.isFirstItemActive=!0,this.minLength=1}}(),tc=function(){function t(t,e,n,a,r,i,o){this.changeDetection=n,this.element=a,this.ngControl=r,this.renderer=i,this.typeaheadMinLength=void 0,this.isAnimated=!1,this.typeaheadAsync=void 0,this.typeaheadLatinize=!0,this.typeaheadSingleWords=!0,this.typeaheadWordDelimiters=" ",this.typeaheadPhraseDelimiters="'\"",this.typeaheadScrollable=!1,this.typeaheadOptionsInScrollableView=5,this.typeaheadSelectFirstItem=!0,this.typeaheadIsFirstItemActive=!0,this.typeaheadLoading=new s.EventEmitter,this.typeaheadNoResults=new s.EventEmitter,this.typeaheadOnSelect=new s.EventEmitter,this.typeaheadOnBlur=new s.EventEmitter,this.dropup=!1,this.isActiveItemChanged=!1,this.isTypeaheadOptionsListActive=!1,this.keyUpEventEmitter=new s.EventEmitter,this.placement="bottom-left",this._subscriptions=[],this._typeahead=t.createLoader(a,o,i).provide({provide:Qu,useValue:e}),Object.assign(this,{typeaheadHideResultsOnBlur:e.hideResultsOnBlur,typeaheadSelectFirstItem:e.selectFirstItem,typeaheadIsFirstItemActive:e.isFirstItemActive,typeaheadMinLength:e.minLength,adaptivePosition:e.adaptivePosition,isAnimated:e.isAnimated})}return t.prototype.ngOnInit=function(){this.typeaheadOptionsLimit=this.typeaheadOptionsLimit||20,this.typeaheadMinLength=void 0===this.typeaheadMinLength?1:this.typeaheadMinLength,this.typeaheadWaitMs=this.typeaheadWaitMs||0,void 0!==this.typeaheadAsync||Object(Bu.a)(this.typeahead)||(this.typeaheadAsync=!1),Object(Bu.a)(this.typeahead)&&(this.typeaheadAsync=!0),this.typeaheadAsync?this.asyncActions():this.syncActions()},t.prototype.onInput=function(t){var e=void 0!==t.target.value?t.target.value:void 0!==t.target.textContent?t.target.textContent:t.target.innerText;null!=e&&e.trim().length>=this.typeaheadMinLength?(this.typeaheadLoading.emit(!0),this.keyUpEventEmitter.emit(t.target.value)):(this.typeaheadLoading.emit(!1),this.typeaheadNoResults.emit(!1),this.hide())},t.prototype.onChange=function(t){if(this._container){if(27===t.keyCode||"Escape"===t.key)return void this.hide();if(38===t.keyCode||"ArrowUp"===t.key)return this.isActiveItemChanged=!0,void this._container.prevActiveMatch();if(40===t.keyCode||"ArrowDown"===t.key)return this.isActiveItemChanged=!0,void this._container.nextActiveMatch();if(13===t.keyCode||"Enter"===t.key)return void this._container.selectActiveMatch()}},t.prototype.onFocus=function(){0===this.typeaheadMinLength&&(this.typeaheadLoading.emit(!0),this.keyUpEventEmitter.emit(this.element.nativeElement.value||""))},t.prototype.onBlur=function(){this._container&&!this._container.isFocused&&this.typeaheadOnBlur.emit(this._container.active)},t.prototype.onKeydown=function(t){if(this._container&&(9===t.keyCode||"Tab"===t.key||13===t.keyCode||"Enter"===t.key)){if(t.preventDefault(),this.typeaheadSelectFirstItem)return void this._container.selectActiveMatch();this.typeaheadSelectFirstItem||(this._container.selectActiveMatch(this.isActiveItemChanged),this.isActiveItemChanged=!1,this.hide())}},t.prototype.changeModel=function(t){var e=t.value;this.ngControl.viewToModelUpdate(e),this.ngControl.control.setValue(e),this.changeDetection.markForCheck(),this.hide()},Object.defineProperty(t.prototype,"matches",{get:function(){return this._matches},enumerable:!0,configurable:!0}),t.prototype.show=function(){var t=this;this._typeahead.attach(Ju).to(this.container).position({attachment:(this.dropup?"top":"bottom")+" start"}).show({typeaheadRef:this,placement:this.placement,animation:!1,dropup:this.dropup}),this._outsideClickListener=this.renderer.listen("document","click",function(e){0===t.typeaheadMinLength&&t.element.nativeElement.contains(e.target)||t.typeaheadHideResultsOnBlur&&!t.element.nativeElement.contains(e.target)&&t.onOutsideClick()}),this._container=this._typeahead.instance,this._container.parent=this;var e=(this.typeaheadLatinize?$u(this.ngControl.control.value):this.ngControl.control.value).toString().toLowerCase();this._container.query=this.typeaheadSingleWords?Zu(e,this.typeaheadWordDelimiters,this.typeaheadPhraseDelimiters):e,this._container.matches=this._matches,this.element.nativeElement.focus()},t.prototype.hide=function(){this._typeahead.isShown&&(this._typeahead.hide(),this._outsideClickListener(),this._container=null)},t.prototype.onOutsideClick=function(){this._container&&!this._container.isFocused&&this.hide()},t.prototype.ngOnDestroy=function(){var t,e;try{for(var n=Object(p.__values)(this._subscriptions),a=n.next();!a.done;a=n.next())a.value.unsubscribe()}catch(r){t={error:r}}finally{try{a&&!a.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}this._typeahead.dispose()},t.prototype.asyncActions=function(){var t=this;this._subscriptions.push(this.keyUpEventEmitter.pipe(Object(zu.a)(this.typeaheadWaitMs),Object(Gu.a)(function(){return t.typeahead})).subscribe(function(e){t.finalizeAsyncCall(e)}))},t.prototype.syncActions=function(){var t=this;this._subscriptions.push(this.keyUpEventEmitter.pipe(Object(zu.a)(this.typeaheadWaitMs),Object(Yu.a)(function(e){var n=t.normalizeQuery(e);return Object(Uu.a)(t.typeahead).pipe(Object(Vu.a)(function(e){return e&&t.testMatch(t.normalizeOption(e),n)}),Object(Hu.a)())})).subscribe(function(e){t.finalizeAsyncCall(e)}))},t.prototype.normalizeOption=function(t){var e=Xu(t,this.typeaheadOptionField);return(this.typeaheadLatinize?$u(e):e).toLowerCase()},t.prototype.normalizeQuery=function(t){var e=(this.typeaheadLatinize?$u(t):t).toString().toLowerCase();return this.typeaheadSingleWords?Zu(e,this.typeaheadWordDelimiters,this.typeaheadPhraseDelimiters):e},t.prototype.testMatch=function(t,e){var n;if("object"==typeof e){n=e.length;for(var a=0;a0&&t.indexOf(e[a])<0)return!1;return!0}return t.indexOf(e)>=0},t.prototype.finalizeAsyncCall=function(t){if(this.prepareMatches(t||[]),this.typeaheadLoading.emit(!1),this.typeaheadNoResults.emit(!this.hasMatches()),this.hasMatches())if(this._container){var e=((this.typeaheadLatinize?$u(this.ngControl.control.value):this.ngControl.control.value)||"").toString().toLowerCase();this._container.query=this.typeaheadSingleWords?Zu(e,this.typeaheadWordDelimiters,this.typeaheadPhraseDelimiters):e,this._container.matches=this._matches}else this.show();else this.hide()},t.prototype.prepareMatches=function(t){var e=this,n=t.slice(0,this.typeaheadOptionsLimit);if(this.typeaheadGroupField){var a=[];n.map(function(t){return Xu(t,e.typeaheadGroupField)}).filter(function(t,e,n){return n.indexOf(t)===e}).forEach(function(t){a.push(new Ku(t,t,!0)),a=a.concat(n.filter(function(n){return Xu(n,e.typeaheadGroupField)===t}).map(function(t){return new Ku(t,Xu(t,e.typeaheadOptionField))}))}),this._matches=a}else this._matches=n.map(function(t){return new Ku(t,Xu(t,e.typeaheadOptionField))})},t.prototype.hasMatches=function(){return this._matches.length>0},t}(),ec=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[J.a,Q.a,Qu]}},t}(),nc=n("WiuZ"),ac=n("wnGv"),rc=n("TYzs"),ic=function(){function t(t,e){this.nfsService=t,this.i18n=e,this.nfsSquash=this.nfsService.nfsSquash,this.nfsAccessType=this.nfsService.nfsAccessType}return t.prototype.getNoAccessTypeDescr=function(){return this.form.getValue("access_type")?this.form.getValue("access_type")+" "+this.i18n("(inherited from global config)"):this.i18n("-- Select the access type --")},t.prototype.getAccessTypeHelp=function(t){var e=this,n=this.nfsAccessType.find(function(n){return e.getValue(t,"access_type")===n.value});return ft.isObjectLike(n)?n.help:""},t.prototype.getNoSquashDescr=function(){return this.form.getValue("squash")?this.form.getValue("squash")+" ("+this.i18n("inherited from global config")+")":this.i18n("-- Select what kind of user id squashing is performed --")},t.prototype.addClient=function(){var t=this.form.get("clients"),e=new na.a({addresses:new Te.i("",{validators:[Te.A.required,Te.A.pattern("(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}).([0-9]{1,3})([/](\\d|[1-2]\\d|3[0-2]))?)([ ,]{1,2}(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}).([0-9]{1,3})([/](\\d|[1-2]\\d|3[0-2]))?))*")]}),access_type:new Te.i(""),squash:new Te.i("")});return t.push(e),e},t.prototype.removeClient=function(t){this.form.get("clients").removeAt(t)},t.prototype.showError=function(t,e,n,a){return this.form.controls.clients.controls[t].showError(e,n,a)},t.prototype.getValue=function(t,e){return this.form.get("clients").at(t).getValue(e)},t.prototype.resolveModel=function(t){var e=this;ft.forEach(t,function(t){e.addClient().patchValue(t)})},t.prototype.trackByFn=function(t){return t},t}(),sc=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function oc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[["class","form-control no-border text-muted"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Any client can access"]))],null,null)}function uc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function cc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"span",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Must contain one or more comma-separated values"])),(t()(),s["\u0275eld"](3,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["For example:"])),(t()(),s["\u0275ted"](-1,null,[" 192.168.0.10, 192.168.1.0/8 "]))],null,null)}function lc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit.value),t(e,2,0,e.context.$implicit.value)},function(t,e){t(e,3,0,e.context.$implicit.value)})}function dc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "]))],null,function(t,e){t(e,1,0,e.component.getAccessTypeHelp(e.parent.context.index))})}function fc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit),t(e,2,0,e.context.$implicit)},function(t,e){t(e,3,0,e.context.$implicit)})}function pc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,65,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,64,"div",[["class","panel panel-default"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),s["\u0275did"](2,212992,null,0,Te.m,[[3,Te.d],[8,null],[8,null]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.m]),s["\u0275did"](4,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](5,0,null,null,5,"div",[["class","panel-heading"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,4,"h3",[["class","panel-title"]],null,null,null,null,null)),(t()(),s["\u0275ted"](7,null,[""," "])),s["\u0275ppd"](8,1),(t()(),s["\u0275eld"](9,0,null,null,1,"span",[["class","pull-right clickable"],["tooltip","Remove"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.removeClient(t.context.index)&&a),a},null,null)),(t()(),s["\u0275ted"](-1,null,["\xd7"])),(t()(),s["\u0275eld"](11,0,null,null,54,"div",[["class","panel-body"]],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,17,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](13,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](14,{"has-error":0}),(t()(),s["\u0275eld"](15,0,null,null,1,"label",[["class","col-sm-3 control-label"],["for","addresses"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Addresses"])),(t()(),s["\u0275eld"](17,0,null,null,12,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](18,0,null,null,6,"input",[["class","form-control"],["formControlName","addresses"],["id","addresses"],["name","addresses"],["placeholder","192.168.0.10, 192.168.1.0/8"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,19)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,19).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](19,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](21,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](23,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](24,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](25,0,null,null,4,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,uc)),s["\u0275did"](27,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,cc)),s["\u0275did"](29,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](30,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](31,0,null,null,1,"label",[["class","col-sm-3 control-label"],["for","access_type"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Access Type"])),(t()(),s["\u0275eld"](33,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](34,0,null,null,12,"select",[["class","form-control"],["formControlName","access_type"],["id","access_type"],["name","access_type"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,35).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,35).onTouched()&&a),a},null,null)),s["\u0275did"](35,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](37,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](39,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](40,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](41,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](42,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](43,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](44,null,["",""])),(t()(),s["\u0275and"](16777216,null,null,1,null,lc)),s["\u0275did"](46,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,dc)),s["\u0275did"](48,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](49,0,null,null,16,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](50,0,null,null,1,"label",[["class","col-sm-3 control-label"],["for","squash"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Squash"])),(t()(),s["\u0275eld"](52,0,null,null,13,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](53,0,null,null,12,"select",[["class","form-control"],["formControlName","squash"],["id","squash"],["name","squash"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,54).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,54).onTouched()&&a),a},null,null)),s["\u0275did"](54,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](56,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](58,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](59,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](60,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](61,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](62,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](63,null,["",""])),(t()(),s["\u0275and"](16777216,null,null,1,null,fc)),s["\u0275did"](65,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){var n=e.component;t(e,2,0,e.context.index);var a=t(e,14,0,n.showError(e.context.index,"addresses",s["\u0275nov"](e.parent,5)));t(e,13,0,"form-group",a),t(e,21,0,"addresses"),t(e,27,0,n.showError(e.context.index,"addresses",s["\u0275nov"](e.parent,5),"required")),t(e,29,0,n.showError(e.context.index,"addresses",s["\u0275nov"](e.parent,5),"pattern")),t(e,37,0,"access_type"),t(e,42,0,""),t(e,43,0,""),t(e,46,0,n.nfsAccessType),t(e,48,0,n.getValue(e.context.index,"access_type")),t(e,56,0,"squash"),t(e,61,0,""),t(e,62,0,""),t(e,65,0,n.nfsSquash)},function(t,e){var n=e.component;t(e,1,0,s["\u0275nov"](e,4).ngClassUntouched,s["\u0275nov"](e,4).ngClassTouched,s["\u0275nov"](e,4).ngClassPristine,s["\u0275nov"](e,4).ngClassDirty,s["\u0275nov"](e,4).ngClassValid,s["\u0275nov"](e,4).ngClassInvalid,s["\u0275nov"](e,4).ngClassPending);var a=s["\u0275unv"](e,7,0,t(e,8,0,s["\u0275nov"](e.parent,0),e.context.index+1));t(e,7,0,a),t(e,18,0,s["\u0275nov"](e,23).ngClassUntouched,s["\u0275nov"](e,23).ngClassTouched,s["\u0275nov"](e,23).ngClassPristine,s["\u0275nov"](e,23).ngClassDirty,s["\u0275nov"](e,23).ngClassValid,s["\u0275nov"](e,23).ngClassInvalid,s["\u0275nov"](e,23).ngClassPending),t(e,34,0,s["\u0275nov"](e,39).ngClassUntouched,s["\u0275nov"](e,39).ngClassTouched,s["\u0275nov"](e,39).ngClassPristine,s["\u0275nov"](e,39).ngClassDirty,s["\u0275nov"](e,39).ngClassValid,s["\u0275nov"](e,39).ngClassInvalid,s["\u0275nov"](e,39).ngClassPending),t(e,44,0,n.getNoAccessTypeDescr()),t(e,53,0,s["\u0275nov"](e,58).ngClassUntouched,s["\u0275nov"](e,58).ngClassTouched,s["\u0275nov"](e,58).ngClassPristine,s["\u0275nov"](e,58).ngClassDirty,s["\u0275nov"](e,58).ngClassValid,s["\u0275nov"](e,58).ngClassInvalid,s["\u0275nov"](e,58).ngClassPending),t(e,63,0,n.getNoSquashDescr())})}function hc(t){return s["\u0275vid"](0,[s["\u0275pid"](0,rc.a,[]),(t()(),s["\u0275eld"](1,0,null,null,20,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"label",[["class","col-sm-3 control-label"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Clients"])),(t()(),s["\u0275eld"](4,0,null,null,17,"div",[["class","col-sm-9"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,5).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,5).onReset()&&a),a},null,null)),s["\u0275did"](5,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](7,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,oc)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](10,0,null,null,5,null,null,null,null,null,null,null)),s["\u0275did"](11,212992,null,0,Te.g,[[3,Te.d],[8,null],[8,null]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.g]),s["\u0275did"](13,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,pc)),s["\u0275did"](15,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(t()(),s["\u0275eld"](16,0,null,null,4,"span",[["class","form-control no-border"]],null,null,null,null,null)),(t()(),s["\u0275eld"](17,0,null,null,3,"button",[["class","btn btn-default btn-label pull-right"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.addClient()&&a),a},null,null)),(t()(),s["\u0275eld"](18,0,null,null,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Add clients"])),(t()(),s["\u0275eld"](21,0,null,null,0,"hr",[],null,null,null,null,null))],function(t,e){var n=e.component;t(e,5,0,n.form),t(e,9,0,0===n.form.get("clients").value.length),t(e,11,0,"clients"),t(e,15,0,n.form.get("clients").value,n.trackByFn)},function(t,e){t(e,4,0,s["\u0275nov"](e,7).ngClassUntouched,s["\u0275nov"](e,7).ngClassTouched,s["\u0275nov"](e,7).ngClassPristine,s["\u0275nov"](e,7).ngClassDirty,s["\u0275nov"](e,7).ngClassValid,s["\u0275nov"](e,7).ngClassInvalid,s["\u0275nov"](e,7).ngClassPending)})}var gc=n("F/XL"),bc=n("P8lu"),mc=n("DNAf"),yc=n("a96k"),vc=function(){function t(t,e,n,a,r,i,s,o,u,c,l,d){var f=this;this.authStorageService=t,this.nfsService=e,this.route=n,this.router=a,this.rgwUserService=r,this.formBuilder=i,this.summaryservice=s,this.cephReleaseNamePipe=o,this.taskWrapper=u,this.cdRef=c,this.i18n=l,this.actionLabels=d,this.isEdit=!1,this.cluster_id=null,this.export_id=null,this.isNewDirectory=!1,this.isNewBucket=!1,this.isDefaultCluster=!1,this.allClusters=null,this.allDaemons={},this.allFsals=[],this.allRgwUsers=[],this.allCephxClients=null,this.allFsNames=null,this.defaultAccessType={RGW:"RO"},this.nfsAccessType=this.nfsService.nfsAccessType,this.nfsSquash=this.nfsService.nfsSquash,this.daemonsSelections=[],this.daemonsMessages=new mc.a({noOptions:this.i18n("There are no daemons available.")},this.i18n),this.pathDataSource=ds.a.create(function(t){t.next(f.nfsForm.getValue("path"))}).pipe(Object(Yu.a)(function(t){return f.getPathTypeahead(t)}),Object(Bi.a)(function(t){return t.paths})),this.bucketDataSource=ds.a.create(function(t){t.next(f.nfsForm.getValue("path"))}).pipe(Object(Yu.a)(function(t){return f.getBucketTypeahead(t)})),this.permission=this.authStorageService.getPermissions().pool,this.resource=this.i18n("NFS export"),this.createForm()}return t.prototype.ngOnInit=function(){var t=this,e=[this.nfsService.daemon(),this.nfsService.fsals(),this.nfsService.clients(),this.nfsService.filesystems()];this.router.url.startsWith("/nfs/edit")&&(this.isEdit=!0),this.isEdit?(this.action=this.actionLabels.EDIT,this.route.params.subscribe(function(n){t.cluster_id=decodeURIComponent(n.cluster_id),t.export_id=decodeURIComponent(n.export_id),e.push(t.nfsService.get(t.cluster_id,t.export_id)),t.getData(e)}),this.nfsForm.get("cluster_id").disable()):(this.action=this.actionLabels.CREATE,this.getData(e));var n=this.summaryservice.getCurrentSummary(),a=this.cephReleaseNamePipe.transform(n.version);this.docsUrl="http://docs.ceph.com/docs/"+a+"/radosgw/nfs/"},t.prototype.getData=function(t){var e=this;Object(ta.a)(t).subscribe(function(t){e.resolveDaemons(t[0]),e.resolvefsals(t[1]),e.resolveClients(t[2]),e.resolveFilesystems(t[3]),t[4]&&e.resolveModel(t[4])})},t.prototype.createForm=function(){this.nfsForm=new na.a({cluster_id:new Te.i("",{validators:[Te.A.required]}),daemons:new Te.i([]),fsal:new na.a({name:new Te.i("",{validators:[Te.A.required]}),user_id:new Te.i("",{validators:[aa.a.requiredIf({name:"CEPH"})]}),fs_name:new Te.i("",{validators:[aa.a.requiredIf({name:"CEPH"})]}),rgw_user_id:new Te.i("",{validators:[aa.a.requiredIf({name:"RGW"})]})}),path:new Te.i(""),protocolNfsv3:new Te.i(!0,{validators:[aa.a.requiredIf({protocolNfsv4:!1},function(t){return!t})]}),protocolNfsv4:new Te.i(!0,{validators:[aa.a.requiredIf({protocolNfsv3:!1},function(t){return!t})]}),tag:new Te.i(""),pseudo:new Te.i("",{validators:[aa.a.requiredIf({protocolNfsv4:!0}),Te.A.pattern("^/[^><|&()]*$")]}),access_type:new Te.i("RW",{validators:[Te.A.required]}),squash:new Te.i("",{validators:[Te.A.required]}),transportUDP:new Te.i(!0,{validators:[aa.a.requiredIf({transportTCP:!1},function(t){return!t})]}),transportTCP:new Te.i(!0,{validators:[aa.a.requiredIf({transportUDP:!1},function(t){return!t})]}),clients:this.formBuilder.array([]),security_label:new Te.i(!1),sec_label_xattr:new Te.i("security.selinux",aa.a.requiredIf({security_label:!0,"fsal.name":"CEPH"}))})},t.prototype.resolveModel=function(t){"CEPH"===t.fsal.name&&(t.sec_label_xattr=t.fsal.sec_label_xattr),this.daemonsSelections=ft.map(this.allDaemons[t.cluster_id],function(e){return new yc.a(-1!==t.daemons.indexOf(e),e,"")}),this.daemonsSelections=this.daemonsSelections.slice(),t.protocolNfsv3=-1!==t.protocols.indexOf(3),t.protocolNfsv4=-1!==t.protocols.indexOf(4),delete t.protocols,t.transportTCP=-1!==t.transports.indexOf("TCP"),t.transportUDP=-1!==t.transports.indexOf("UDP"),delete t.transports,t.clients.forEach(function(t){var e="";t.addresses.forEach(function(t){e+=t+", "}),e.length>=2&&(e=e.substring(0,e.length-2)),t.addresses=e}),this.nfsForm.patchValue(t),this.setPathValidation(),this.nfsClients.resolveModel(t.clients)},t.prototype.resolveDaemons=function(t){var e=this;t=ft.sortBy(t,["daemon_id"]),this.allClusters=ft(t).map(function(t){return t.cluster_id}).sortedUniq().value(),ft.forEach(this.allClusters,function(t){e.allDaemons[t]=[]}),ft.forEach(t,function(t){e.allDaemons[t.cluster_id].push(t.daemon_id)});var n=ft.isArray(this.allClusters)&&1===this.allClusters.length;this.isDefaultCluster=n&&"_default_"===this.allClusters[0],n&&(this.nfsForm.patchValue({cluster_id:this.allClusters[0]}),this.onClusterChange())},t.prototype.resolvefsals=function(t){var e=this;t.forEach(function(t){var n=e.nfsService.nfsFsal.find(function(e){return t===e.value});ft.isObjectLike(n)&&(e.allFsals.push(n),"RGW"===n.value&&e.rgwUserService.list().subscribe(function(t){t.forEach(function(t){0===t.suspended&&t.keys.length>0&&e.allRgwUsers.push(t.user_id)})}))}),1===this.allFsals.length&&ft.isUndefined(this.nfsForm.getValue("fsal"))&&this.nfsForm.patchValue({fsal:this.allFsals[0]})},t.prototype.resolveClients=function(t){this.allCephxClients=t},t.prototype.resolveFilesystems=function(t){this.allFsNames=t,1===t.length&&this.nfsForm.patchValue({fsal:{fs_name:t[0].name}})},t.prototype.fsalChangeHandler=function(){this.nfsForm.patchValue({tag:this._generateTag(),pseudo:this._generatePseudo(),access_type:this._updateAccessType()}),this.setPathValidation(),this.cdRef.detectChanges()},t.prototype.accessTypeChangeHandler=function(){var t=this.nfsForm.getValue("name"),e=this.nfsForm.getValue("access_type");this.defaultAccessType[t]=e},t.prototype.setPathValidation=function(){"RGW"===this.nfsForm.getValue("name")?this.nfsForm.get("path").setValidators([Te.A.required,Te.A.pattern("^(/|[^/><|&()#?]+)$")]):this.nfsForm.get("path").setValidators([Te.A.required,Te.A.pattern("^/[^><|&()?]*$")])},t.prototype.rgwUserIdChangeHandler=function(){this.nfsForm.patchValue({pseudo:this._generatePseudo()})},t.prototype.getAccessTypeHelp=function(t){var e=this.nfsAccessType.find(function(e){if(t===e.value)return e});return ft.isObjectLike(e)?e.help:""},t.prototype.getId=function(){return ft.isString(this.nfsForm.getValue("cluster_id"))&&ft.isString(this.nfsForm.getValue("path"))?this.nfsForm.getValue("cluster_id")+":"+this.nfsForm.getValue("path"):""},t.prototype.getPathTypeahead=function(t){return ft.isString(t)&&"/"!==t?this.nfsService.lsDir(t):Object(gc.a)([])},t.prototype.pathChangeHandler=function(){var t=this;this.nfsForm.patchValue({pseudo:this._generatePseudo()});var e=this.nfsForm.getValue("path");this.getPathTypeahead(e).subscribe(function(n){t.isNewDirectory="/"!==e&&-1===n.paths.indexOf(e)})},t.prototype.bucketChangeHandler=function(){var t=this;this.nfsForm.patchValue({tag:this._generateTag(),pseudo:this._generatePseudo()});var e=this.nfsForm.getValue("path");this.getBucketTypeahead(e).subscribe(function(n){t.isNewBucket=""!==e&&-1===n.indexOf(e)})},t.prototype.getBucketTypeahead=function(t){var e=this.nfsForm.getValue("rgw_user_id");return ft.isString(e)&&ft.isString(t)&&"/"!==t&&""!==t?this.nfsService.buckets(e):Object(gc.a)([])},t.prototype._generateTag=function(){var t=this.nfsForm.getValue("tag");return this.nfsForm.get("tag").dirty||(t=void 0,"RGW"===this.nfsForm.getValue("fsal")&&(t=this.nfsForm.getValue("path"))),t},t.prototype._generatePseudo=function(){var t=this.nfsForm.getValue("pseudo");return this.nfsForm.get("pseudo")&&!this.nfsForm.get("pseudo").dirty&&(t=void 0,"CEPH"===this.nfsForm.getValue("fsal")?(t="/cephfs",ft.isString(this.nfsForm.getValue("path"))&&(t+=this.nfsForm.getValue("path"))):"RGW"===this.nfsForm.getValue("fsal")&&ft.isString(this.nfsForm.getValue("rgw_user_id"))&&(t="/"+this.nfsForm.getValue("rgw_user_id"),ft.isString(this.nfsForm.getValue("path"))&&(t+="/"+this.nfsForm.getValue("path")))),t},t.prototype._updateAccessType=function(){var t=this.nfsForm.getValue("name"),e=this.defaultAccessType[t];return e||(e="RW"),e},t.prototype.onClusterChange=function(){var t=this.nfsForm.getValue("cluster_id");this.daemonsSelections=ft.map(this.allDaemons[t],function(t){return new yc.a(!1,t,"")}),this.daemonsSelections=this.daemonsSelections.slice(),this.nfsForm.patchValue({daemons:[]})},t.prototype.removeDaemon=function(t,e){this.daemonsSelections.forEach(function(t){t.name===e&&(t.selected=!1)});var n=this.nfsForm.get("daemons");return n.value.splice(t,1),n.setValue(n.value),!1},t.prototype.onDaemonSelection=function(){this.nfsForm.get("daemons").setValue(this.nfsForm.getValue("daemons"))},t.prototype.submitAction=function(){var t=this,e=this._buildRequest();this.taskWrapper.wrapTaskAroundCall(this.isEdit?{task:new Cu.a("nfs/edit",{cluster_id:this.cluster_id,export_id:this.export_id}),call:this.nfsService.update(this.cluster_id,this.export_id,e)}:{task:new Cu.a("nfs/create",{path:e.path,fsal:e.fsal,cluster_id:e.cluster_id}),call:this.nfsService.create(e)}).subscribe(void 0,function(){return t.nfsForm.setErrors({cdSubmitButton:!0})},function(){return t.router.navigate(["/nfs"])})},t.prototype._buildRequest=function(){var t=ft.cloneDeep(this.nfsForm.value);return(ft.isUndefined(t.tag)||""===t.tag)&&(t.tag=null),this.isEdit&&(t.export_id=this.export_id),"CEPH"===t.fsal.name?delete t.fsal.rgw_user_id:(delete t.fsal.fs_name,delete t.fsal.user_id),t.protocols=[],t.protocolNfsv3?t.protocols.push(3):t.tag=null,delete t.protocolNfsv3,t.protocolNfsv4?t.protocols.push(4):t.pseudo=null,delete t.protocolNfsv4,t.transports=[],t.transportTCP&&t.transports.push("TCP"),delete t.transportTCP,t.transportUDP&&t.transports.push("UDP"),delete t.transportUDP,t.clients.forEach(function(e){e.addresses=ft.isString(e.addresses)?ft(e.addresses).split(/[ ,]+/).uniq().filter(function(t){return""!==t}).value():[],e.squash||(e.squash=t.squash),e.access_type||(e.access_type=t.access_type)}),t.fsal.sec_label_xattr=!1===t.security_label||"RGW"===t.fsal.name?null:t.sec_label_xattr,delete t.sec_label_xattr,t},t}(),_c=s["\u0275crt"]({encapsulation:0,styles:[[".cd-mb[_ngcontent-%COMP%]{margin-bottom:10px}"]],data:{}});function xc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["Loading..."]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Tc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- No cluster available --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function wc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- Select the cluster --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Sc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit),t(e,2,0,e.context.$implicit)},function(t,e){t(e,3,0,e.context.$implicit)})}function Oc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function Ic(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,24,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","cluster_id"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Cluster"])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,14,"select",[["class","form-control"],["formControlName","cluster_id"],["id","cluster_id"],["name","cluster_id"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,9).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,9).onTouched()&&a),"change"===e&&(a=!1!==r.onClusterChange()&&a),a},null,null)),s["\u0275did"](9,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](11,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](13,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](14,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,xc)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Tc)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,wc)),s["\u0275did"](20,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Sc)),s["\u0275did"](22,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Oc)),s["\u0275did"](24,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("cluster_id",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,11,0,"cluster_id"),t(e,16,0,null===n.allClusters),t(e,18,0,null!==n.allClusters&&0===n.allClusters.length),t(e,20,0,null!==n.allClusters&&n.allClusters.length>0),t(e,22,0,n.allClusters),t(e,24,0,n.nfsForm.showError("cluster_id",s["\u0275nov"](e.parent,6),"required"))},function(t,e){t(e,8,0,s["\u0275nov"](e,13).ngClassUntouched,s["\u0275nov"](e,13).ngClassTouched,s["\u0275nov"](e,13).ngClassPristine,s["\u0275nov"](e,13).ngClassDirty,s["\u0275nov"](e,13).ngClassValid,s["\u0275nov"](e,13).ngClassInvalid,s["\u0275nov"](e,13).ngClassPending)})}function Cc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,5,"div",[["class","input-group cd-mb"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"input",[["class","form-control"],["disabled",""],["type","text"]],[[8,"value",0]],null,null,null,null)),s["\u0275did"](3,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](4,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,1,"button",[["class","btn btn-default"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.removeDaemon(t.context.index,t.context.$implicit)&&a),a},null,null)),(t()(),s["\u0275eld"](6,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-remove fa-fw"]],null,null,null,null,null))],null,function(t,e){t(e,2,0,e.context.$implicit)})}function kc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["Loading..."]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Nc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- No data pools available --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Rc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- Select the storage backend --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Ac(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit.value),t(e,2,0,e.context.$implicit.value)},function(t,e){t(e,3,0,e.context.$implicit.descr)})}function Dc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function Ec(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["Loading..."]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Lc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- No users available --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Pc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- Select the object gateway user --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Mc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit),t(e,2,0,e.context.$implicit)},function(t,e){t(e,3,0,e.context.$implicit)})}function qc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function jc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,24,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","rgw_user_id"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Object Gateway User"])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,14,"select",[["class","form-control"],["formControlName","rgw_user_id"],["id","rgw_user_id"],["name","rgw_user_id"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,9).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,9).onTouched()&&a),"change"===e&&(a=!1!==r.rgwUserIdChangeHandler()&&a),a},null,null)),s["\u0275did"](9,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](11,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](13,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](14,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ec)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Lc)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Pc)),s["\u0275did"](20,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Mc)),s["\u0275did"](22,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,qc)),s["\u0275did"](24,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("rgw_user_id",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,11,0,"rgw_user_id"),t(e,16,0,null===n.allRgwUsers),t(e,18,0,null!==n.allRgwUsers&&0===n.allRgwUsers.length),t(e,20,0,null!==n.allRgwUsers&&n.allRgwUsers.length>0),t(e,22,0,n.allRgwUsers),t(e,24,0,n.nfsForm.showError("rgw_user_id",s["\u0275nov"](e.parent,6),"required"))},function(t,e){t(e,8,0,s["\u0275nov"](e,13).ngClassUntouched,s["\u0275nov"](e,13).ngClassTouched,s["\u0275nov"](e,13).ngClassPristine,s["\u0275nov"](e,13).ngClassDirty,s["\u0275nov"](e,13).ngClassValid,s["\u0275nov"](e,13).ngClassInvalid,s["\u0275nov"](e,13).ngClassPending)})}function Fc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["Loading..."]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function zc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- No clients available --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Gc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- Select the cephx client --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Yc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit),t(e,2,0,e.context.$implicit)},function(t,e){t(e,3,0,e.context.$implicit)})}function Vc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function Hc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,24,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","user_id"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["CephFS User ID"])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,14,"select",[["class","form-control"],["formControlName","user_id"],["id","user_id"],["name","user_id"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,9).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,9).onTouched()&&a),a},null,null)),s["\u0275did"](9,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](11,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](13,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](14,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Fc)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,zc)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Gc)),s["\u0275did"](20,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Yc)),s["\u0275did"](22,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Vc)),s["\u0275did"](24,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("user_id",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,11,0,"user_id"),t(e,16,0,null===n.allCephxClients),t(e,18,0,null!==n.allCephxClients&&0===n.allCephxClients.length),t(e,20,0,null!==n.allCephxClients&&n.allCephxClients.length>0),t(e,22,0,n.allCephxClients),t(e,24,0,n.nfsForm.showError("user_id",s["\u0275nov"](e.parent,6),"required"))},function(t,e){t(e,8,0,s["\u0275nov"](e,13).ngClassUntouched,s["\u0275nov"](e,13).ngClassTouched,s["\u0275nov"](e,13).ngClassPristine,s["\u0275nov"](e,13).ngClassDirty,s["\u0275nov"](e,13).ngClassValid,s["\u0275nov"](e,13).ngClassInvalid,s["\u0275nov"](e,13).ngClassPending)})}function Bc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["Loading..."]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Uc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- No CephFS filesystem available --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Wc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- Select the CephFS filesystem --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Kc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit.name),t(e,2,0,e.context.$implicit.name)},function(t,e){t(e,3,0,e.context.$implicit.name)})}function $c(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function Zc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,24,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","fs_name"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["CephFS Name"])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,14,"select",[["class","form-control"],["formControlName","fs_name"],["id","fs_name"],["name","fs_name"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,9).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,9).onTouched()&&a),"change"===e&&(a=!1!==r.rgwUserIdChangeHandler()&&a),a},null,null)),s["\u0275did"](9,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](11,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](13,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](14,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Bc)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Uc)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Wc)),s["\u0275did"](20,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Kc)),s["\u0275did"](22,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,$c)),s["\u0275did"](24,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("fs_name",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,11,0,"fs_name"),t(e,16,0,null===n.allFsNames),t(e,18,0,null!==n.allFsNames&&0===n.allFsNames.length),t(e,20,0,null!==n.allFsNames&&n.allFsNames.length>0),t(e,22,0,n.allFsNames),t(e,24,0,n.nfsForm.showError("fs_name",s["\u0275nov"](e.parent,6),"required"))},function(t,e){t(e,8,0,s["\u0275nov"](e,13).ngClassUntouched,s["\u0275nov"](e,13).ngClassTouched,s["\u0275nov"](e,13).ngClassPristine,s["\u0275nov"](e,13).ngClassDirty,s["\u0275nov"](e,13).ngClassValid,s["\u0275nov"](e,13).ngClassInvalid,s["\u0275nov"](e,13).ngClassPending)})}function Xc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function Jc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"input",[["class","form-control"],["formControlName","sec_label_xattr"],["id","sec_label_xattr"],["name","sec_label_xattr"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,1)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,1).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,1)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,1)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](1,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](3,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](5,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](6,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null)],function(t,e){t(e,3,0,"sec_label_xattr")},function(t,e){t(e,0,0,s["\u0275nov"](e,5).ngClassUntouched,s["\u0275nov"](e,5).ngClassTouched,s["\u0275nov"](e,5).ngClassPristine,s["\u0275nov"](e,5).ngClassDirty,s["\u0275nov"](e,5).ngClassValid,s["\u0275nov"](e,5).ngClassInvalid,s["\u0275nov"](e,5).ngClassPending)})}function Qc(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function tl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,23,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,4,"label",[["class","col-sm-3 control-label"],["for","security_label"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Security Label"])),(t()(),s["\u0275and"](16777216,null,null,1,null,Xc)),s["\u0275did"](7,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](8,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](9,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,6,"input",[["formControlName","security_label"],["id","security_label"],["name","security_label"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,11).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,11).onTouched()&&a),a},null,null)),s["\u0275did"](11,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](13,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](15,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](16,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](17,0,null,null,1,"label",[["for","security_label"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Enable security label"])),(t()(),s["\u0275eld"](19,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Jc)),s["\u0275did"](21,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Qc)),s["\u0275did"](23,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("security_label",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,7,0,n.nfsForm.getValue("security_label")),t(e,13,0,"security_label"),t(e,21,0,n.nfsForm.getValue("security_label")),t(e,23,0,n.nfsForm.showError("sec_label_xattr",s["\u0275nov"](e.parent,6),"required"))},function(t,e){t(e,10,0,s["\u0275nov"](e,15).ngClassUntouched,s["\u0275nov"](e,15).ngClassTouched,s["\u0275nov"](e,15).ngClassPristine,s["\u0275nov"](e,15).ngClassDirty,s["\u0275nov"](e,15).ngClassValid,s["\u0275nov"](e,15).ngClassInvalid,s["\u0275nov"](e,15).ngClassPending)})}function el(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function nl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Path need to start with a '/' and can be followed by a word"]))],null,null)}function al(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["New directory will be created"]))],null,null)}function rl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,21,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","path"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["CephFS Path"])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,14,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,16777216,null,null,7,"input",[["class","form-control"],["formControlName","path"],["id","path"],["name","path"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"typeaheadOnSelect"],[null,"blur"],[null,"input"],[null,"compositionstart"],[null,"compositionend"],[null,"keyup"],[null,"click"],[null,"focus"],[null,"keydown"]],function(t,e,n){var a=!0,r=t.component;return"input"===e&&(a=!1!==s["\u0275nov"](t,9)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,9).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,9)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,9)._compositionEnd(n.target.value)&&a),"input"===e&&(a=!1!==s["\u0275nov"](t,15).onInput(n)&&a),"keyup"===e&&(a=!1!==s["\u0275nov"](t,15).onChange(n)&&a),"click"===e&&(a=!1!==s["\u0275nov"](t,15).onFocus()&&a),"focus"===e&&(a=!1!==s["\u0275nov"](t,15).onFocus()&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,15).onBlur()&&a),"keydown"===e&&(a=!1!==s["\u0275nov"](t,15).onKeydown(n)&&a),"typeaheadOnSelect"===e&&(a=!1!==r.pathChangeHandler()&&a),"blur"===e&&(a=!1!==r.pathChangeHandler()&&a),a},null,null)),s["\u0275did"](9,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](11,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](13,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](14,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](15,212992,null,0,tc,[J.a,Qu,s.ChangeDetectorRef,s.ElementRef,Te.q,s.Renderer2,s.ViewContainerRef],{typeahead:[0,"typeahead"]},{typeaheadOnSelect:"typeaheadOnSelect"}),(t()(),s["\u0275and"](16777216,null,null,1,null,el)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,nl)),s["\u0275did"](19,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,al)),s["\u0275did"](21,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("path",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,11,0,"path"),t(e,15,0,n.pathDataSource),t(e,17,0,n.nfsForm.showError("path",s["\u0275nov"](e.parent,6),"required")),t(e,19,0,n.nfsForm.showError("path",s["\u0275nov"](e.parent,6),"pattern")),t(e,21,0,n.isNewDirectory&&!n.nfsForm.showError("path",s["\u0275nov"](e.parent,6)))},function(t,e){t(e,8,0,s["\u0275nov"](e,13).ngClassUntouched,s["\u0275nov"](e,13).ngClassTouched,s["\u0275nov"](e,13).ngClassPristine,s["\u0275nov"](e,13).ngClassDirty,s["\u0275nov"](e,13).ngClassValid,s["\u0275nov"](e,13).ngClassInvalid,s["\u0275nov"](e,13).ngClassPending)})}function il(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function sl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Path can only be a single '/' or a word"]))],null,null)}function ol(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["New bucket will be created"]))],null,null)}function ul(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,21,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","path"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Path"])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,14,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,16777216,null,null,7,"input",[["class","form-control"],["formControlName","path"],["id","path"],["name","path"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"typeaheadOnSelect"],[null,"blur"],[null,"input"],[null,"compositionstart"],[null,"compositionend"],[null,"keyup"],[null,"click"],[null,"focus"],[null,"keydown"]],function(t,e,n){var a=!0,r=t.component;return"input"===e&&(a=!1!==s["\u0275nov"](t,9)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,9).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,9)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,9)._compositionEnd(n.target.value)&&a),"input"===e&&(a=!1!==s["\u0275nov"](t,15).onInput(n)&&a),"keyup"===e&&(a=!1!==s["\u0275nov"](t,15).onChange(n)&&a),"click"===e&&(a=!1!==s["\u0275nov"](t,15).onFocus()&&a),"focus"===e&&(a=!1!==s["\u0275nov"](t,15).onFocus()&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,15).onBlur()&&a),"keydown"===e&&(a=!1!==s["\u0275nov"](t,15).onKeydown(n)&&a),"typeaheadOnSelect"===e&&(a=!1!==r.bucketChangeHandler()&&a),"blur"===e&&(a=!1!==r.bucketChangeHandler()&&a),a},null,null)),s["\u0275did"](9,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](11,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](13,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](14,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](15,212992,null,0,tc,[J.a,Qu,s.ChangeDetectorRef,s.ElementRef,Te.q,s.Renderer2,s.ViewContainerRef],{typeahead:[0,"typeahead"]},{typeaheadOnSelect:"typeaheadOnSelect"}),(t()(),s["\u0275and"](16777216,null,null,1,null,il)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,sl)),s["\u0275did"](19,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ol)),s["\u0275did"](21,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("path",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,11,0,"path"),t(e,15,0,n.bucketDataSource),t(e,17,0,n.nfsForm.showError("path",s["\u0275nov"](e.parent,6),"required")),t(e,19,0,n.nfsForm.showError("path",s["\u0275nov"](e.parent,6),"pattern")),t(e,21,0,n.isNewBucket&&!n.nfsForm.showError("path",s["\u0275nov"](e.parent,6)))},function(t,e){t(e,8,0,s["\u0275nov"](e,13).ngClassUntouched,s["\u0275nov"](e,13).ngClassTouched,s["\u0275nov"](e,13).ngClassPristine,s["\u0275nov"](e,13).ngClassDirty,s["\u0275nov"](e,13).ngClassValid,s["\u0275nov"](e,13).ngClassInvalid,s["\u0275nov"](e,13).ngClassPending)})}function cl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function ll(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,13,"label",[["class","col-sm-3 control-label"],["for","tag"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["NFS Tag"])),(t()(),s["\u0275eld"](4,0,null,null,10,"cd-helper",[],null,null,null,ks.b,ks.a)),s["\u0275did"](5,49152,null,0,Ns.a,[],null,null),(t()(),s["\u0275eld"](6,0,null,0,4,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Alternative access for "])),(t()(),s["\u0275eld"](8,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["NFS v3"])),(t()(),s["\u0275ted"](-1,null,[" mounts (it must not have a leading /)."])),(t()(),s["\u0275eld"](11,0,null,0,1,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz)."])),(t()(),s["\u0275eld"](13,0,null,0,1,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["By using different Tag options, the same Path may be exported multiple times."])),(t()(),s["\u0275eld"](15,0,null,null,7,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](16,0,null,null,6,"input",[["class","form-control"],["formControlName","tag"],["id","tag"],["name","tag"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,17)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,17).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,17)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,17)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](17,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](19,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](21,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](22,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null)],function(t,e){t(e,19,0,"tag")},function(t,e){t(e,16,0,s["\u0275nov"](e,21).ngClassUntouched,s["\u0275nov"](e,21).ngClassTouched,s["\u0275nov"](e,21).ngClassPristine,s["\u0275nov"](e,21).ngClassDirty,s["\u0275nov"](e,21).ngClassValid,s["\u0275nov"](e,21).ngClassInvalid,s["\u0275nov"](e,21).ngClassPending)})}function dl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function fl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or )."]))],null,null)}function pl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,30,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,15,"label",[["class","col-sm-3 control-label"],["for","pseudo"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Pseudo"])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,11,"cd-helper",[],null,null,null,ks.b,ks.a)),s["\u0275did"](8,49152,null,0,Ns.a,[],null,null),(t()(),s["\u0275eld"](9,0,null,0,7,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["The position that this "])),(t()(),s["\u0275eld"](11,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["NFS v4"])),(t()(),s["\u0275ted"](-1,null,[" export occupies in the "])),(t()(),s["\u0275eld"](14,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Pseudo FS"])),(t()(),s["\u0275ted"](-1,null,[" (it must be unique)."])),(t()(),s["\u0275eld"](17,0,null,0,1,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["By using different Pseudo options, the same Path may be exported multiple times."])),(t()(),s["\u0275eld"](19,0,null,null,11,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](20,0,null,null,6,"input",[["class","form-control"],["formControlName","pseudo"],["id","pseudo"],["name","pseudo"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,21)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,21).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,21)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,21)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](21,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](23,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](25,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](26,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,dl)),s["\u0275did"](28,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,fl)),s["\u0275did"](30,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.nfsForm.showError("pseudo",s["\u0275nov"](e.parent,6)));t(e,1,0,"form-group",a),t(e,23,0,"pseudo"),t(e,28,0,n.nfsForm.showError("pseudo",s["\u0275nov"](e.parent,6),"required")),t(e,30,0,n.nfsForm.showError("pseudo",s["\u0275nov"](e.parent,6),"pattern"))},function(t,e){t(e,20,0,s["\u0275nov"](e,25).ngClassUntouched,s["\u0275nov"](e,25).ngClassTouched,s["\u0275nov"](e,25).ngClassPristine,s["\u0275nov"](e,25).ngClassDirty,s["\u0275nov"](e,25).ngClassValid,s["\u0275nov"](e,25).ngClassInvalid,s["\u0275nov"](e,25).ngClassPending)})}function hl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["Loading..."]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function gl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- No access type available --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function bl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- Select the access type --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function ml(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit.value),t(e,2,0,e.context.$implicit.value)},function(t,e){t(e,3,0,e.context.$implicit.value)})}function yl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "]))],null,function(t,e){var n=e.component;t(e,1,0,n.getAccessTypeHelp(n.nfsForm.getValue("access_type")))})}function vl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"span",[["class","text-warning"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["The Object Gateway NFS backend has a number of limitations which will seriously affect applications writing to the share. Please consult the "])),(t()(),s["\u0275eld"](2,0,null,null,1,"a",[["target","_blank"]],[[8,"href",4]],null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[" documentation"])),(t()(),s["\u0275ted"](-1,null,[" for details before enabling write access."]))],null,function(t,e){t(e,2,0,s["\u0275inlineInterpolate"](1,"",e.component.docsUrl,""))})}function _l(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function xl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["Loading..."]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Tl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["-- No squash available --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function wl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[["value",""]],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](-1,null,["--Select what kind of user id squashing is performed --"]))],function(t,e){t(e,1,0,""),t(e,2,0,"")},null)}function Sl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit),t(e,2,0,e.context.$implicit)},function(t,e){t(e,3,0,e.context.$implicit)})}function Ol(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function Il(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Required field"]))],null,null)}function Cl(t){return s["\u0275vid"](0,[s["\u0275pid"](0,i.TitleCasePipe,[]),s["\u0275pid"](0,Rs.a,[]),s["\u0275qud"](402653184,1,{nfsClients:0}),(t()(),s["\u0275eld"](3,0,null,null,201,"div",[["class","col-sm-12 col-lg-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,200,"form",[["class","form-horizontal"],["name","nfsForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,6).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,6).onReset()&&a),a},null,null)),s["\u0275did"](5,16384,null,0,Te.D,[],null,null),s["\u0275did"](6,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](8,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](9,0,null,null,195,"div",[["class","panel panel-default"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,4,"div",[["class","panel-heading"]],null,null,null,null,null)),(t()(),s["\u0275eld"](11,0,null,null,3,"h3",[["class","panel-title"]],null,null,null,null,null)),(t()(),s["\u0275ted"](12,null,[""," ",""])),s["\u0275ppd"](13,1),s["\u0275ppd"](14,1),(t()(),s["\u0275eld"](15,0,null,null,180,"div",[["class","panel-body"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Ic)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](18,0,null,null,15,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](19,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](20,{"has-error":0}),(t()(),s["\u0275eld"](21,0,null,null,2,"label",[["class","col-sm-3 control-label"],["for","daemons"]],null,null,null,null,null)),(t()(),s["\u0275eld"](22,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Daemons"])),(t()(),s["\u0275eld"](24,0,null,null,9,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Cc)),s["\u0275did"](26,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](27,0,null,null,6,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](28,0,null,null,5,"div",[["class","col-md-12"]],null,null,null,null,null)),(t()(),s["\u0275eld"](29,0,null,null,4,"cd-select",[["elemClass","btn btn-default pull-right"]],null,[[null,"selection"]],function(t,e,n){var a=!0;return"selection"===e&&(a=!1!==t.component.onDaemonSelection()&&a),a},nc.b,nc.a)),s["\u0275did"](30,638976,null,0,ac.a,[xt.a],{elemClass:[0,"elemClass"],data:[1,"data"],options:[2,"options"],messages:[3,"messages"]},{selection:"selection"}),(t()(),s["\u0275eld"](31,0,null,0,0,"i",[["class","fa fa-fw fa-plus"]],null,null,null,null,null)),(t()(),s["\u0275eld"](32,0,null,0,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Add daemon"])),(t()(),s["\u0275eld"](34,0,null,null,34,"div",[["formGroupName","fsal"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,null,null)),s["\u0275did"](35,212992,null,0,Te.m,[[3,Te.d],[8,null],[8,null]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.m]),s["\u0275did"](37,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](38,0,null,null,24,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](39,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](40,{"has-error":0}),(t()(),s["\u0275eld"](41,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","name"]],null,null,null,null,null)),(t()(),s["\u0275eld"](42,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Storage Backend"])),(t()(),s["\u0275eld"](44,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](45,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](46,0,null,null,14,"select",[["class","form-control"],["formControlName","name"],["id","name"],["name","name"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,47).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,47).onTouched()&&a),"change"===e&&(a=!1!==r.fsalChangeHandler()&&a),a},null,null)),s["\u0275did"](47,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](49,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](51,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](52,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,kc)),s["\u0275did"](54,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Nc)),s["\u0275did"](56,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Rc)),s["\u0275did"](58,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ac)),s["\u0275did"](60,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Dc)),s["\u0275did"](62,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,jc)),s["\u0275did"](64,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Hc)),s["\u0275did"](66,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Zc)),s["\u0275did"](68,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,tl)),s["\u0275did"](70,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,rl)),s["\u0275did"](72,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ul)),s["\u0275did"](74,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](75,0,null,null,29,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](76,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](77,{"has-error":0}),(t()(),s["\u0275eld"](78,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","protocols"]],null,null,null,null,null)),(t()(),s["\u0275eld"](79,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["NFS Protocol"])),(t()(),s["\u0275eld"](81,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](82,0,null,null,22,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](83,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](84,0,null,null,6,"input",[["formControlName","protocolNfsv3"],["id","protocolNfsv3"],["name","protocolNfsv3"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,85).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,85).onTouched()&&a),a},null,null)),s["\u0275did"](85,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](87,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](89,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](90,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](91,0,null,null,1,"label",[["for","protocolNfsv3"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["NFSv3"])),(t()(),s["\u0275eld"](93,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](94,0,null,null,6,"input",[["formControlName","protocolNfsv4"],["id","protocolNfsv4"],["name","protocolNfsv4"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,95).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,95).onTouched()&&a),a},null,null)),s["\u0275did"](95,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](97,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](99,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](100,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](101,0,null,null,1,"label",[["for","protocolNfsv4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["NFSv4"])),(t()(),s["\u0275and"](16777216,null,null,1,null,cl)),s["\u0275did"](104,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ll)),s["\u0275did"](106,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,pl)),s["\u0275did"](108,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](109,0,null,null,28,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](110,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](111,{"has-error":0}),(t()(),s["\u0275eld"](112,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","access_type"]],null,null,null,null,null)),(t()(),s["\u0275eld"](113,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Access Type"])),(t()(),s["\u0275eld"](115,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](116,0,null,null,21,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](117,0,null,null,14,"select",[["class","form-control"],["formControlName","access_type"],["id","access_type"],["name","access_type"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,118).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,118).onTouched()&&a),"change"===e&&(a=!1!==r.accessTypeChangeHandler()&&a),a},null,null)),s["\u0275did"](118,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](120,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](122,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](123,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,hl)),s["\u0275did"](125,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,gl)),s["\u0275did"](127,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,bl)),s["\u0275did"](129,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ml)),s["\u0275did"](131,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,yl)),s["\u0275did"](133,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,vl)),s["\u0275did"](135,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,_l)),s["\u0275did"](137,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](138,0,null,null,24,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](139,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](140,{"has-error":0}),(t()(),s["\u0275eld"](141,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","squash"]],null,null,null,null,null)),(t()(),s["\u0275eld"](142,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Squash"])),(t()(),s["\u0275eld"](144,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](145,0,null,null,17,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](146,0,null,null,14,"select",[["class","form-control"],["formControlName","squash"],["id","squash"],["name","squash"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,147).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,147).onTouched()&&a),a},null,null)),s["\u0275did"](147,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](149,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](151,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](152,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,xl)),s["\u0275did"](154,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Tl)),s["\u0275did"](156,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,wl)),s["\u0275did"](158,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Sl)),s["\u0275did"](160,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ol)),s["\u0275did"](162,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](163,0,null,null,30,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](164,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](165,{"has-error":0}),(t()(),s["\u0275eld"](166,0,null,null,3,"label",[["class","col-sm-3 control-label"],["for","transports"]],null,null,null,null,null)),(t()(),s["\u0275eld"](167,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Transport Protocol"])),(t()(),s["\u0275eld"](169,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](170,0,null,null,23,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](171,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](172,0,null,null,6,"input",[["formControlName","transportUDP"],["id","transportUDP"],["name","transportUDP"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,173).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,173).onTouched()&&a),a},null,null)),s["\u0275did"](173,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](175,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](177,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](178,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](179,0,null,null,1,"label",[["for","transportUDP"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["UDP"])),(t()(),s["\u0275eld"](181,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](182,0,null,null,6,"input",[["formControlName","transportTCP"],["id","transportTCP"],["name","transportTCP"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,183).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,183).onTouched()&&a),a},null,null)),s["\u0275did"](183,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](185,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](187,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](188,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](189,0,null,null,1,"label",[["for","transportTCP"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["TCP"])),(t()(),s["\u0275and"](16777216,null,null,1,null,Il)),s["\u0275did"](192,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](193,0,null,null,0,"hr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](194,0,null,null,1,"cd-nfs-form-client",[],null,null,null,hc,sc)),s["\u0275did"](195,49152,[[1,4],["nfsClients",4]],0,ic,[Iu,xt.a],{form:[0,"form"]},null),(t()(),s["\u0275eld"](196,0,null,null,8,"div",[["class","panel-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](197,0,null,null,7,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),s["\u0275eld"](198,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.submitAction()&&a),a},$a.b,$a.a)),s["\u0275did"](199,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(t()(),s["\u0275ted"](200,0,[""," ",""])),s["\u0275ppd"](201,1),s["\u0275ppd"](202,1),(t()(),s["\u0275eld"](203,0,null,null,1,"cd-back-button",[],null,null,null,Xa.b,Xa.a)),s["\u0275did"](204,49152,null,0,Ja.a,[i.Location,Zn.b],null,null)],function(t,e){var n=e.component;t(e,6,0,n.nfsForm),t(e,17,0,!n.isDefaultCluster);var a=t(e,20,0,n.nfsForm.showError("daemons",s["\u0275nov"](e,6)));t(e,19,0,"form-group",a),t(e,26,0,n.nfsForm.getValue("daemons")),t(e,30,0,"btn btn-default pull-right",n.nfsForm.get("daemons").value,n.daemonsSelections,n.daemonsMessages),t(e,35,0,"fsal");var r=t(e,40,0,n.nfsForm.showError("name",s["\u0275nov"](e,6)));t(e,39,0,"form-group",r),t(e,49,0,"name"),t(e,54,0,null===n.allFsals),t(e,56,0,null!==n.allFsals&&0===n.allFsals.length),t(e,58,0,null!==n.allFsals&&n.allFsals.length>0),t(e,60,0,n.allFsals),t(e,62,0,n.nfsForm.showError("name",s["\u0275nov"](e,6),"required")),t(e,64,0,"RGW"===n.nfsForm.getValue("name")),t(e,66,0,"CEPH"===n.nfsForm.getValue("name")),t(e,68,0,"CEPH"===n.nfsForm.getValue("name")),t(e,70,0,"CEPH"===n.nfsForm.getValue("name")),t(e,72,0,"CEPH"===n.nfsForm.getValue("name")),t(e,74,0,"RGW"===n.nfsForm.getValue("name"));var i=t(e,77,0,n.nfsForm.showError("protocolNfsv3",s["\u0275nov"](e,6))||n.nfsForm.showError("protocolNfsv4",s["\u0275nov"](e,6)));t(e,76,0,"form-group",i),t(e,87,0,"protocolNfsv3"),t(e,97,0,"protocolNfsv4"),t(e,104,0,n.nfsForm.showError("protocolNfsv3",s["\u0275nov"](e,6),"required")||n.nfsForm.showError("protocolNfsv4",s["\u0275nov"](e,6),"required")),t(e,106,0,n.nfsForm.getValue("protocolNfsv3")),t(e,108,0,n.nfsForm.getValue("protocolNfsv4"));var o=t(e,111,0,n.nfsForm.showError("access_type",s["\u0275nov"](e,6)));t(e,110,0,"form-group",o),t(e,120,0,"access_type"),t(e,125,0,null===n.nfsAccessType),t(e,127,0,null!==n.nfsAccessType&&0===n.nfsAccessType.length),t(e,129,0,null!==n.nfsAccessType&&n.nfsAccessType.length>0),t(e,131,0,n.nfsAccessType),t(e,133,0,n.nfsForm.getValue("access_type")),t(e,135,0,"RW"===n.nfsForm.getValue("access_type")&&"RGW"===n.nfsForm.getValue("name")),t(e,137,0,n.nfsForm.showError("access_type",s["\u0275nov"](e,6),"required"));var u=t(e,140,0,n.nfsForm.showError("squash",s["\u0275nov"](e,6)));t(e,139,0,"form-group",u),t(e,149,0,"squash"),t(e,154,0,null===n.nfsSquash),t(e,156,0,null!==n.nfsSquash&&0===n.nfsSquash.length),t(e,158,0,null!==n.nfsSquash&&n.nfsSquash.length>0),t(e,160,0,n.nfsSquash),t(e,162,0,n.nfsForm.showError("squash",s["\u0275nov"](e,6),"required"));var c=t(e,165,0,n.nfsForm.showError("transportUDP",s["\u0275nov"](e,6))||n.nfsForm.showError("transportTCP",s["\u0275nov"](e,6)));t(e,164,0,"form-group",c),t(e,175,0,"transportUDP"),t(e,185,0,"transportTCP"),t(e,192,0,n.nfsForm.showError("transportUDP",s["\u0275nov"](e,6),"required")||n.nfsForm.showError("transportTCP",s["\u0275nov"](e,6),"required")),t(e,195,0,n.nfsForm),t(e,199,0,s["\u0275nov"](e,6),"button")},function(t,e){var n=e.component;t(e,4,0,s["\u0275nov"](e,8).ngClassUntouched,s["\u0275nov"](e,8).ngClassTouched,s["\u0275nov"](e,8).ngClassPristine,s["\u0275nov"](e,8).ngClassDirty,s["\u0275nov"](e,8).ngClassValid,s["\u0275nov"](e,8).ngClassInvalid,s["\u0275nov"](e,8).ngClassPending);var a=s["\u0275unv"](e,12,0,t(e,13,0,s["\u0275nov"](e,0),n.action)),r=s["\u0275unv"](e,12,1,t(e,14,0,s["\u0275nov"](e,1),n.resource));t(e,12,0,a,r),t(e,34,0,s["\u0275nov"](e,37).ngClassUntouched,s["\u0275nov"](e,37).ngClassTouched,s["\u0275nov"](e,37).ngClassPristine,s["\u0275nov"](e,37).ngClassDirty,s["\u0275nov"](e,37).ngClassValid,s["\u0275nov"](e,37).ngClassInvalid,s["\u0275nov"](e,37).ngClassPending),t(e,46,0,s["\u0275nov"](e,51).ngClassUntouched,s["\u0275nov"](e,51).ngClassTouched,s["\u0275nov"](e,51).ngClassPristine,s["\u0275nov"](e,51).ngClassDirty,s["\u0275nov"](e,51).ngClassValid,s["\u0275nov"](e,51).ngClassInvalid,s["\u0275nov"](e,51).ngClassPending),t(e,84,0,s["\u0275nov"](e,89).ngClassUntouched,s["\u0275nov"](e,89).ngClassTouched,s["\u0275nov"](e,89).ngClassPristine,s["\u0275nov"](e,89).ngClassDirty,s["\u0275nov"](e,89).ngClassValid,s["\u0275nov"](e,89).ngClassInvalid,s["\u0275nov"](e,89).ngClassPending),t(e,94,0,s["\u0275nov"](e,99).ngClassUntouched,s["\u0275nov"](e,99).ngClassTouched,s["\u0275nov"](e,99).ngClassPristine,s["\u0275nov"](e,99).ngClassDirty,s["\u0275nov"](e,99).ngClassValid,s["\u0275nov"](e,99).ngClassInvalid,s["\u0275nov"](e,99).ngClassPending),t(e,117,0,s["\u0275nov"](e,122).ngClassUntouched,s["\u0275nov"](e,122).ngClassTouched,s["\u0275nov"](e,122).ngClassPristine,s["\u0275nov"](e,122).ngClassDirty,s["\u0275nov"](e,122).ngClassValid,s["\u0275nov"](e,122).ngClassInvalid,s["\u0275nov"](e,122).ngClassPending),t(e,146,0,s["\u0275nov"](e,151).ngClassUntouched,s["\u0275nov"](e,151).ngClassTouched,s["\u0275nov"](e,151).ngClassPristine,s["\u0275nov"](e,151).ngClassDirty,s["\u0275nov"](e,151).ngClassValid,s["\u0275nov"](e,151).ngClassInvalid,s["\u0275nov"](e,151).ngClassPending),t(e,172,0,s["\u0275nov"](e,177).ngClassUntouched,s["\u0275nov"](e,177).ngClassTouched,s["\u0275nov"](e,177).ngClassPristine,s["\u0275nov"](e,177).ngClassDirty,s["\u0275nov"](e,177).ngClassValid,s["\u0275nov"](e,177).ngClassInvalid,s["\u0275nov"](e,177).ngClassPending),t(e,182,0,s["\u0275nov"](e,187).ngClassUntouched,s["\u0275nov"](e,187).ngClassTouched,s["\u0275nov"](e,187).ngClassPristine,s["\u0275nov"](e,187).ngClassDirty,s["\u0275nov"](e,187).ngClassValid,s["\u0275nov"](e,187).ngClassInvalid,s["\u0275nov"](e,187).ngClassPending);var i=s["\u0275unv"](e,200,0,t(e,201,0,s["\u0275nov"](e,0),n.action)),o=s["\u0275unv"](e,200,1,t(e,202,0,s["\u0275nov"](e,1),n.resource));t(e,200,0,i,o)})}function kl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-nfs-form",[],null,null,null,Cl,_c)),s["\u0275did"](1,114688,null,0,vc,[l.a,Iu,tt.a,tt.l,bc.a,ca.a,je.a,Ge.a,ku.a,s.ChangeDetectorRef,xt.a,Zn.b],null,null)],function(t,e){t(e,1,0)},null)}var Nl=s["\u0275ccf"]("cd-nfs-form",vc,kl,{},{},[]),Rl=function(){return function(){this.logoutUrl=window.location.origin+"/auth/saml2/slo"}}(),Al=s["\u0275crt"]({encapsulation:0,styles:[["h1[_ngcontent-%COMP%]{font-size:-webkit-xxx-large}*[_ngcontent-%COMP%]{font-family:monospace}img[_ngcontent-%COMP%]{width:50vw}"]],data:{}});function Dl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,16,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,15,"div",[["class","col-md-12 text-center"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"h1",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Sorry, the user does not exist in Ceph."])),(t()(),s["\u0275eld"](4,0,null,null,4,"h4",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Return to "])),(t()(),s["\u0275eld"](6,0,null,null,1,"a",[["class","sso-logout"]],[[8,"href",4]],null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Login Page"])),(t()(),s["\u0275ted"](-1,null,[". You'll be logged out from the Identity Provider when you retry logging in."])),(t()(),s["\u0275eld"](9,0,null,null,0,"img",[["class","img-responsive center-block img-rounded"],["src","assets/1280px-Nautilus_Octopus.jpg"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,6,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[' "'])),(t()(),s["\u0275eld"](12,0,null,null,1,"a",[["href","https://www.flickr.com/photos/146401137@N06/40335060661"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Nautilus Octopus"])),(t()(),s["\u0275ted"](-1,null,['" by Jin Kemoole is licensed under '])),(t()(),s["\u0275eld"](15,0,null,null,1,"a",[["class","external text"],["href","https://creativecommons.org/licenses/by/2.0/"],["rel","nofollow"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["CC BY 2.0"]))],null,function(t,e){t(e,6,0,e.component.logoutUrl)})}function El(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-sso-not-found",[],null,null,null,Dl,Al)),s["\u0275did"](1,49152,null,0,Rl,[],null,null)],null,null)}var Ll,Pl=s["\u0275ccf"]("cd-sso-not-found",Rl,El,{},{},[]),Ml=n("lHUG"),ql=function(){function t(t,e){this.http=t,this.localeId=e}return t.prototype.getLocale=function(){return this.localeId||"en-US"},t.prototype.setLocale=function(t){document.cookie="cd-lang="+t},t.prototype.getLanguages=function(){return this.http.get("ui-api/langs")},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c),s.inject(s.LOCALE_ID))},token:t,providedIn:"root"}),t}();!function(t){t.cs="\u010ce\u0161tina",t["de-DE"]="Deutsch",t["en-US"]="English",t["es-ES"]="Espa\xf1ol",t["fr-FR"]="Fran\xe7ais",t["id-ID"]="Bahasa Indonesia",t["it-IT"]="Italiano",t["ja-JP"]="\u65e5\u672c\u8a9e",t["ko-KR"]="\ud55c\uad6d\uc5b4",t["pl-PL"]="Polski",t["pt-BR"]="Portugu\xeas",t["zh-CN"]="\u4e2d\u6587 (\u7b80\u4f53)",t["zh-TW"]="\u4e2d\u6587 (\u7e41\u9ad4\uff09"}(Ll||(Ll={}));var jl={cs:Ml.a,de:Ml.b,es:Ml.e,fr:Ml.g,id:Ml.m,it:Ml.y,ja:Ml.z,ko:Ml.A,pl:Ml.C,pt:Ml.D,zh:Ml.H},Fl=function(){function t(t,e){this.localeService=t,this.languageService=e,this.isDropdown=!0,this.supportedLanguages=Ll}return t.prototype.ngOnInit=function(){var t=this;this.selectedLanguage=this.languageService.getLocale(),this.defineUsedLanguage(),this.languageService.getLanguages().subscribe(function(e){t.supportedLanguages=ft.pick(t.supportedLanguages,e)})},t.prototype.defineUsedLanguage=function(){var t=this.selectedLanguage.slice(0,2);t in jl&&(Object(Ml.c)(t,jl[t]),this.localeService.use(t))},t.prototype.reloadWindow=function(){window.location.reload()},t.prototype.changeLanguage=function(t){this.languageService.setLocale(t),this.reloadWindow()},t}(),zl=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Gl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"a",[["class","dropdown-item"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.changeLanguage(t.context.$implicit.key)&&a),a},null,null)),(t()(),s["\u0275ted"](2,null,["",""]))],null,function(t,e){t(e,2,0,e.context.$implicit.value)})}function Yl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"ul",[["class","dropdown-menu dropdown-menu-right"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,2,null,Gl)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),s["\u0275pid"](0,i.KeyValuePipe,[s.KeyValueDiffers])],function(t,e){var n=e.component;t(e,2,0,s["\u0275unv"](e,2,0,s["\u0275nov"](e,3).transform(n.supportedLanguages)))},null)}function Vl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,16777216,null,null,8,"div",[["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](2,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),(t()(),s["\u0275eld"](3,0,null,null,3,"a",[["class","dropdown-toggle"],["data-toggle","dropdown"],["dropdownToggle",""],["title","Select a Language"]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,4).onClick()&&a),a},null,null)),s["\u0275did"](4,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275ted"](5,null,[" "," "])),(t()(),s["\u0275eld"](6,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Yl)),s["\u0275did"](8,16384,null,0,bn.d,[bn.f,s.ViewContainerRef,s.TemplateRef],null,null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,2,0)},function(t,e){var n=e.component;t(e,0,0,s["\u0275nov"](e,2).dropup,s["\u0275nov"](e,2).isOpen,s["\u0275nov"](e,2).isOpen&&s["\u0275nov"](e,2).isBs4),t(e,3,0,!0,s["\u0275nov"](e,4).isDisabled,s["\u0275nov"](e,4).isOpen),t(e,5,0,n.supportedLanguages[n.selectedLanguage])})}function Hl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,["",""]))],function(t,e){t(e,1,0,e.context.$implicit.key),t(e,2,0,e.context.$implicit.key)},function(t,e){t(e,3,0,e.context.$implicit.value)})}function Bl(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,9,"select",[["class","form-control"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"ngModelChange"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,1).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,1).onTouched()&&a),"change"===e&&(a=!1!==r.changeLanguage(n.target.value)&&a),"ngModelChange"===e&&(a=!1!==(r.selectedLanguage=n)&&a),a},null,null)),s["\u0275did"](1,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](3,671744,null,0,Te.u,[[8,null],[8,null],[8,null],[6,Te.p]],{model:[0,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](5,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](6,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,2,null,Hl)),s["\u0275did"](8,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),s["\u0275pid"](0,i.KeyValuePipe,[s.KeyValueDiffers])],function(t,e){var n=e.component;t(e,3,0,n.selectedLanguage),t(e,8,0,s["\u0275unv"](e,8,0,s["\u0275nov"](e,9).transform(n.supportedLanguages)))},function(t,e){t(e,0,0,s["\u0275nov"](e,5).ngClassUntouched,s["\u0275nov"](e,5).ngClassTouched,s["\u0275nov"](e,5).ngClassPristine,s["\u0275nov"](e,5).ngClassDirty,s["\u0275nov"](e,5).ngClassValid,s["\u0275nov"](e,5).ngClassInvalid,s["\u0275nov"](e,5).ngClassPending)})}function Ul(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Vl)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Bl)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.isDropdown),t(e,3,0,!n.isDropdown)},null)}var Wl=n("IZUe"),Kl=n("D4zM"),$l=n("DSvg"),Zl=function(){return function(){}}(),Xl=function(){function t(t,e,n,a,r){this.authService=t,this.authStorageService=e,this.bsModalService=n,this.route=a,this.router=r,this.model=new Zl,this.isLoginActive=!1}return t.prototype.ngOnInit=function(){var t=this;if(this.authStorageService.isLoggedIn())this.router.navigate([""]);else{for(var e=this.bsModalService.getModalsCount(),n=1;n<=e;n++)this.bsModalService.hide(n);var a=null;if(-1!==window.location.hash.indexOf("access_token=")){a=window.location.hash.split("access_token=")[1];var r=window.location.toString();window.history.replaceState({},document.title,r.split("?")[0])}this.authService.check(a).subscribe(function(e){e.login_url?"#/login"===e.login_url?t.isLoginActive=!0:window.location.replace(e.login_url):(t.authStorageService.set(e.username,e.permissions),t.router.navigate([""]))})}},t.prototype.login=function(){var t=this;this.authService.login(this.model).then(function(){var e=ft.get(t.route.snapshot.queryParams,"returnUrl","/");t.router.navigate([e])})},t}(),Jl=s["\u0275crt"]({encapsulation:0,styles:[[".login{height:100%} .login .row{color:#fff;background-color:#374249} .login h1{margin-top:0;margin-bottom:30px} .login .btn-password, .login .form-control{color:#fff;background-color:#555} .login .btn-password:focus{outline-color:#2b99a8} .login .checkbox-primary input[type=checkbox]:checked+label::before, .login .checkbox-primary input[type=radio]:checked+label::before{background-color:#2b99a8;border-color:#2b99a8}"]],data:{}});function Ql(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"div",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Username is required"]))],null,null)}function td(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"div",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Password is required"]))],null,null)}function ed(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,49,"div",[["class","login"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,48,"div",[["class","row full-height vertical-align"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"div",[["class","col-sm-6 hidden-xs"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,0,"img",[["alt","Ceph"],["class","pull-right"],["src","assets/Ceph_Logo_Stacked_RGB_White_120411_fa_256x256.png"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,45,"div",[["class","col-xs-10 col-sm-4 col-lg-3 col-xs-offset-1 col-sm-offset-0 col-md-offset-0 col-lg-offset-0"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,1,"h1",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Welcome to Ceph!"])),(t()(),s["\u0275eld"](7,0,null,null,42,"form",[["name","loginForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngSubmit"],[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0,r=t.component;return"submit"===e&&(a=!1!==s["\u0275nov"](t,9).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,9).onReset()&&a),"ngSubmit"===e&&(a=!1!==r.login()&&a),a},null,null)),s["\u0275did"](8,16384,null,0,Te.D,[],null,null),s["\u0275did"](9,4210688,[["loginForm",4]],0,Te.t,[[8,null],[8,null]],null,{ngSubmit:"ngSubmit"}),s["\u0275prd"](2048,null,Te.d,null,[Te.t]),s["\u0275did"](11,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](12,0,null,null,2,"div",[["class","form-group has-feedback"]],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,1,"cd-language-selector",[],null,null,null,Ul,zl)),s["\u0275did"](14,114688,null,0,Fl,[Nr.j,ql],{isDropdown:[0,"isDropdown"]},null),(t()(),s["\u0275eld"](15,0,null,null,14,"div",[["class","form-group has-feedback"]],null,null,null,null,null)),s["\u0275did"](16,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](17,{"has-error":0}),(t()(),s["\u0275eld"](18,0,null,null,9,"input",[["autofocus",""],["class","form-control"],["name","username"],["placeholder","Enter your username..."],["required",""],["type","text"]],[[1,"required",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0,r=t.component;return"input"===e&&(a=!1!==s["\u0275nov"](t,19)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,19).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionEnd(n.target.value)&&a),"ngModelChange"===e&&(a=!1!==(r.model.username=n)&&a),a},null,null)),s["\u0275did"](19,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275did"](20,16384,null,0,Te.y,[],{required:[0,"required"]},null),s["\u0275prd"](1024,null,Te.o,function(t){return[t]},[Te.y]),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](23,671744,[["username",4]],0,Te.u,[[2,Te.d],[6,Te.o],[8,null],[6,Te.p]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](25,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](26,4210688,null,0,Wl.a,[s.ElementRef],null,null),s["\u0275did"](27,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ql)),s["\u0275did"](29,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](30,0,null,null,17,"div",[["class","form-group has-feedback"]],null,null,null,null,null)),s["\u0275did"](31,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](32,{"has-error":0}),(t()(),s["\u0275eld"](33,0,null,null,12,"div",[["class","input-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](34,0,null,null,8,"input",[["class","form-control"],["id","password"],["name","password"],["placeholder","Enter your password..."],["required",""],["type","password"]],[[1,"required",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0,r=t.component;return"input"===e&&(a=!1!==s["\u0275nov"](t,35)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,35).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,35)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,35)._compositionEnd(n.target.value)&&a),"ngModelChange"===e&&(a=!1!==(r.model.password=n)&&a),a},null,null)),s["\u0275did"](35,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275did"](36,16384,null,0,Te.y,[],{required:[0,"required"]},null),s["\u0275prd"](1024,null,Te.o,function(t){return[t]},[Te.y]),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](39,671744,[["password",4]],0,Te.u,[[2,Te.d],[6,Te.o],[8,null],[6,Te.p]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),s["\u0275prd"](2048,null,Te.q,null,[Te.u]),s["\u0275did"](41,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](42,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](43,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(t()(),s["\u0275eld"](44,0,null,null,1,"button",[["cdPasswordButton","password"],["class","btn btn-default btn-password"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,45).onClick()&&a),a},null,null)),s["\u0275did"](45,81920,null,0,Kl.a,[s.ElementRef,s.Renderer2],{cdPasswordButton:[0,"cdPasswordButton"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,td)),s["\u0275did"](47,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](48,0,null,null,1,"input",[["class","btn btn-primary btn-block"],["type","submit"],["value","Login"]],[[8,"disabled",0]],null,null,null,null)),s["\u0275did"](49,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null)],function(t,e){var n=e.component;t(e,14,0,!1);var a=t(e,17,0,(s["\u0275nov"](e,9).submitted||s["\u0275nov"](e,23).dirty)&&s["\u0275nov"](e,23).invalid);t(e,16,0,"form-group has-feedback",a),t(e,20,0,""),t(e,23,0,"username",n.model.username),t(e,29,0,(s["\u0275nov"](e,9).submitted||s["\u0275nov"](e,23).dirty)&&s["\u0275nov"](e,23).invalid);var r=t(e,32,0,(s["\u0275nov"](e,9).submitted||s["\u0275nov"](e,39).dirty)&&s["\u0275nov"](e,39).invalid);t(e,31,0,"form-group has-feedback",r),t(e,36,0,""),t(e,39,0,"password",n.model.password),t(e,45,0,"password"),t(e,47,0,(s["\u0275nov"](e,9).submitted||s["\u0275nov"](e,39).dirty)&&s["\u0275nov"](e,39).invalid)},function(t,e){t(e,7,0,s["\u0275nov"](e,11).ngClassUntouched,s["\u0275nov"](e,11).ngClassTouched,s["\u0275nov"](e,11).ngClassPristine,s["\u0275nov"](e,11).ngClassDirty,s["\u0275nov"](e,11).ngClassValid,s["\u0275nov"](e,11).ngClassInvalid,s["\u0275nov"](e,11).ngClassPending),t(e,18,0,s["\u0275nov"](e,20).required?"":null,s["\u0275nov"](e,25).ngClassUntouched,s["\u0275nov"](e,25).ngClassTouched,s["\u0275nov"](e,25).ngClassPristine,s["\u0275nov"](e,25).ngClassDirty,s["\u0275nov"](e,25).ngClassValid,s["\u0275nov"](e,25).ngClassInvalid,s["\u0275nov"](e,25).ngClassPending),t(e,34,0,s["\u0275nov"](e,36).required?"":null,s["\u0275nov"](e,41).ngClassUntouched,s["\u0275nov"](e,41).ngClassTouched,s["\u0275nov"](e,41).ngClassPristine,s["\u0275nov"](e,41).ngClassDirty,s["\u0275nov"](e,41).ngClassValid,s["\u0275nov"](e,41).ngClassInvalid,s["\u0275nov"](e,41).ngClassPending),t(e,48,0,s["\u0275nov"](e,9).invalid)})}function nd(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,ed)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,1,0,e.component.isLoginActive)},null)}function ad(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-login",[],null,null,null,nd,Jl)),s["\u0275did"](1,114688,null,0,Xl,[$l.a,l.a,pa.b,tt.a,tt.l],null,null)],function(t,e){t(e,1,0)},null)}var rd=s["\u0275ccf"]("cd-login",Xl,ad,{},{},[]),id=function(){return function(){}}(),sd=s["\u0275crt"]({encapsulation:0,styles:[["h1[_ngcontent-%COMP%]{font-size:-webkit-xxx-large;font-family:monospace}h2[_ngcontent-%COMP%]{font-size:xx-large;font-family:monospace}i[_ngcontent-%COMP%]{font-size:200px}"]],data:{}});function od(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,5,"div",[["class","col-md-12 text-center"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"h1",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Forbidden"])),(t()(),s["\u0275eld"](4,0,null,null,0,"i",[["class","fa fa-lock text-danger"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,1,"h2",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Sorry, you are not allowed to see what you were looking for."]))],null,null)}function ud(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-forbidden",[],null,null,null,od,sd)),s["\u0275did"](1,49152,null,0,id,[],null,null)],null,null)}var cd=s["\u0275ccf"]("cd-forbidden",id,ud,{},{},[]),ld=function(){return function(){}}(),dd=s["\u0275crt"]({encapsulation:0,styles:[["h1[_ngcontent-%COMP%]{font-size:-webkit-xxx-large}*[_ngcontent-%COMP%]{font-family:monospace}img[_ngcontent-%COMP%]{width:50vw}"]],data:{}});function fd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,11,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,10,"div",[["class","col-md-12 text-center"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"h1",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Sorry, we could not find what you were looking for"])),(t()(),s["\u0275eld"](4,0,null,null,0,"img",[["class","img-responsive center-block img-rounded"],["src","assets/1280px-Nautilus_Octopus.jpg"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,6,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[' "'])),(t()(),s["\u0275eld"](7,0,null,null,1,"a",[["href","https://www.flickr.com/photos/146401137@N06/40335060661"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Nautilus Octopus"])),(t()(),s["\u0275ted"](-1,null,['" by Jin Kemoole is licensed under '])),(t()(),s["\u0275eld"](10,0,null,null,1,"a",[["class","external text"],["href","https://creativecommons.org/licenses/by/2.0/"],["rel","nofollow"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["CC BY 2.0"]))],null,null)}function pd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-not-found",[],null,null,null,fd,dd)),s["\u0275did"](1,49152,null,0,ld,[],null,null)],null,null)}var hd=s["\u0275ccf"]("cd-not-found",ld,pd,{},{},[]),gd=n("iutN"),bd=n("ES0t"),md=n("MdoF"),yd=n("Xg1U"),vd=n("z5nN"),_d=n("EEJc"),xd=n("PEr+"),Td=n("a40w"),wd=n("SjWX"),Sd=n("Mxhz"),Od=function(){function t(t,e,n,a){this.modalRef=t,this.summaryService=e,this.userService=n,this.authStorageService=a,this.userPermission=this.authStorageService.getPermissions().user}return t.prototype.ngOnInit=function(){var t=this;this.copyright="Copyright(c) 2021 Ceph contributors.",this.projectConstants=Zn.c,this.hostAddr=window.location.hostname,this.modalVariables=this.setVariables(),this.subs=this.summaryService.subscribe(function(e){if(e){var n=e.version.replace("ceph version ","").split(" ");t.hostAddr=e.mgr_host.replace(/(^\w+:|^)\/\//,"").replace(/\/$/,""),t.versionNumber=n[0],t.versionHash=n[1],t.versionName=n.slice(2,n.length).join(" ")}})},t.prototype.ngOnDestroy=function(){this.subs.unsubscribe()},t.prototype.setVariables=function(){var t={};t.user=localStorage.getItem("dashboard_username"),t.role="user",this.userPermission.read&&this.userService.get(t.user).subscribe(function(e){t.role=e.roles});var e=Object(wd.detect)();return t.browserName=e&&e.name?e.name:"Not detected",t.browserVersion=e&&e.version?e.version:"Not detected",t.browserOS=e&&e.os?e.os:"Not detected",t},t}(),Id=s["\u0275crt"]({encapsulation:0,styles:[[".product-versions[_ngcontent-%COMP%]{margin-top:30px}.product-versions[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{margin-right:10px}.modal-header[_ngcontent-%COMP%]{border-bottom:none}.modal-body[_ngcontent-%COMP%]{padding-left:80px;padding-right:80px}.modal-footer[_ngcontent-%COMP%]{border-top:none;padding:15px 80px 35px}h2[_ngcontent-%COMP%]{font-size:3em}.ceph-logo[_ngcontent-%COMP%]{width:10%}.list-unstyled[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{margin-top:5px}.modal-body[_ngcontent-%COMP%]{margin-top:0;padding-top:0}.modal-body[_ngcontent-%COMP%] h2[_ngcontent-%COMP%]{margin-top:0}"]],data:{}});function Cd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"div",[["class","modal-header"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.modalRef.hide()&&a),a},null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xd7"])),(t()(),s["\u0275eld"](4,0,null,null,45,"div",[["class","modal-body"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,2,"h2",[],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,0,"img",[["class","ceph-logo"],["src","assets/Ceph_Logo_Stacked_RGB_120411_fa_348x348.png"]],[[8,"alt",0]],null,null,null,null)),(t()(),s["\u0275ted"](7,null,[" "," "])),(t()(),s["\u0275eld"](8,0,null,null,2,"h3",[],null,null,null,null,null)),(t()(),s["\u0275eld"](9,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](10,null,["",""])),(t()(),s["\u0275eld"](11,0,null,null,6,"div",[["class","product-versions"]],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Version"])),(t()(),s["\u0275eld"](14,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275ted"](15,null,[" "," "," "])),(t()(),s["\u0275eld"](16,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275ted"](17,null,[" "," "])),(t()(),s["\u0275eld"](18,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,30,"ul",[["class","list-unstyled"]],null,null,null,null,null)),(t()(),s["\u0275eld"](20,0,null,null,4,"li",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](21,0,null,null,1,"strong",[["class","col-xs-6 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Ceph Manager"])),(t()(),s["\u0275eld"](23,0,null,null,1,"span",[["class","col-xs-4 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](24,null,["",""])),(t()(),s["\u0275eld"](25,0,null,null,4,"li",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](26,0,null,null,1,"strong",[["class","col-xs-6 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["User"])),(t()(),s["\u0275eld"](28,0,null,null,1,"span",[["class","col-xs-4 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](29,null,["",""])),(t()(),s["\u0275eld"](30,0,null,null,4,"li",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](31,0,null,null,1,"strong",[["class","col-xs-6 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["User Role"])),(t()(),s["\u0275eld"](33,0,null,null,1,"span",[["class","col-xs-4 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](34,null,["",""])),(t()(),s["\u0275eld"](35,0,null,null,4,"li",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](36,0,null,null,1,"strong",[["class","col-xs-6 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Browser"])),(t()(),s["\u0275eld"](38,0,null,null,1,"span",[["class","col-xs-4 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](39,null,["",""])),(t()(),s["\u0275eld"](40,0,null,null,4,"li",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](41,0,null,null,1,"strong",[["class","col-xs-6 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Browser Version"])),(t()(),s["\u0275eld"](43,0,null,null,1,"span",[["class","col-xs-4 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](44,null,["",""])),(t()(),s["\u0275eld"](45,0,null,null,4,"li",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](46,0,null,null,1,"strong",[["class","col-xs-6 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Browser OS"])),(t()(),s["\u0275eld"](48,0,null,null,1,"span",[["class","col-xs-4 col-sm-4"]],null,null,null,null,null)),(t()(),s["\u0275ted"](49,null,["",""])),(t()(),s["\u0275eld"](50,0,null,null,2,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](51,0,null,null,1,"div",[["class","text-left"]],null,null,null,null,null)),(t()(),s["\u0275ted"](52,null,[" "," "," "]))],null,function(t,e){var n=e.component;t(e,6,0,s["\u0275inlineInterpolate"](1,"",n.projectConstants.organization,"")),t(e,7,0,n.projectConstants.organization),t(e,10,0,n.projectConstants.projectName),t(e,15,0,n.versionNumber,n.versionHash),t(e,17,0,n.versionName),t(e,24,0,n.hostAddr),t(e,29,0,n.modalVariables.user),t(e,34,0,n.modalVariables.role),t(e,39,0,n.modalVariables.browserName),t(e,44,0,n.modalVariables.browserVersion),t(e,49,0,n.modalVariables.browserOS),t(e,52,0,n.copyright,n.projectConstants.license)})}function kd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-about",[],null,null,null,Cd,Id)),s["\u0275did"](1,245760,null,0,Od,[pa.a,je.a,Sd.a,l.a],null,null)],function(t,e){t(e,1,0)},null)}var Nd=s["\u0275ccf"]("cd-about",Od,kd,{},{},[]),Rd=n("atuK"),Ad=s["\u0275crt"]({encapsulation:0,styles:[".dropdown[_nghost-%COMP%] {\n z-index: 1000;\n }"],data:{animation:[{type:7,name:"typeaheadAnimation",definitions:[{type:0,name:"animated-down",styles:{type:6,styles:{height:"*",overflow:"hidden"},offset:null},options:void 0},{type:1,expr:"* => animated-down",animation:[{type:6,styles:{height:0,overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:0,name:"animated-up",styles:{type:6,styles:{height:"*",overflow:"hidden"},offset:null},options:void 0},{type:1,expr:"* => animated-up",animation:[{type:6,styles:{height:"*",overflow:"hidden"},offset:null},{type:4,styles:null,timings:"220ms cubic-bezier(0, 0, 0.2, 1)"}],options:null},{type:1,expr:"* => unanimated",animation:{type:4,styles:null,timings:"0s"},options:null}],options:{}}]}});function Dd(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](0,null,null,0))],null,null)}function Ed(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"span",[],[[8,"innerHTML",1]],null,null,null,null))],null,function(t,e){t(e,0,0,e.component.highlight(e.context.match,e.context.query))})}function Ld(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,[[2,0],["liElements",1]],null,1,"li",[["class","dropdown-header"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit)})}function Pd(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](0,null,null,0))],null,null)}function Md(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,[[2,0],["liElements",1]],null,4,"li",[],[[24,"@typeaheadAnimation",0],[2,"active",null]],[[null,"@typeaheadAnimation.done"],[null,"mouseenter"]],function(t,e,n){var a=!0,r=t.component;return"@typeaheadAnimation.done"===e&&(a=!1!==r.positionServiceEnable()&&a),"mouseenter"===e&&(a=!1!==r.selectActive(t.parent.context.$implicit)&&a),a},null,null)),(t()(),s["\u0275eld"](1,0,null,null,3,"a",[["href","#"],["tabindex","-1"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.selectMatch(t.parent.context.$implicit,n)&&a),a},null,null)),(t()(),s["\u0275and"](16777216,null,null,2,null,Pd)),s["\u0275did"](3,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),s["\u0275pod"](4,{item:0,index:1,match:2,query:3})],function(t,e){var n=e.component,a=t(e,4,0,e.parent.context.$implicit.item,e.parent.context.index,e.parent.context.$implicit,n.query);t(e,3,0,a,n.itemTemplate||s["\u0275nov"](e.parent.parent.parent,5))},function(t,e){var n=e.component;t(e,0,0,n.animationState,n.isActive(e.parent.context.$implicit))})}function qd(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Ld)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Md)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){var n=e.context.$implicit.isHeader();t(e,1,0,n);var a=!e.context.$implicit.isHeader();t(e,3,0,a)},null)}function jd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,[[1,0],["ulElement",1]],null,2,"ul",[["class","dropdown-menu"]],[[4,"overflow-y",null],[4,"height",null]],null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,qd)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.component.matches)},function(t,e){var n=e.component;t(e,0,0,n.needScrollbar?"scroll":"auto",n.needScrollbar?n.guiHeight:"auto")})}function Fd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"h6",[["class","dropdown-header"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit)})}function zd(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](0,null,null,0))],null,null)}function Gd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,[[2,0],["liElements",1]],null,3,"button",[["class","dropdown-item"]],[[24,"@typeaheadAnimation",0],[2,"active",null]],[[null,"@typeaheadAnimation.done"],[null,"click"],[null,"mouseenter"]],function(t,e,n){var a=!0,r=t.component;return"@typeaheadAnimation.done"===e&&(a=!1!==r.positionServiceEnable()&&a),"click"===e&&(a=!1!==r.selectMatch(t.parent.context.$implicit,n)&&a),"mouseenter"===e&&(a=!1!==r.selectActive(t.parent.context.$implicit)&&a),a},null,null)),(t()(),s["\u0275and"](16777216,null,null,2,null,zd)),s["\u0275did"](2,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),s["\u0275pod"](3,{item:0,index:1,match:2,query:3})],function(t,e){var n=e.component,a=t(e,3,0,e.parent.context.$implicit.item,e.parent.context.index,e.parent.context.$implicit,n.query);t(e,2,0,a,n.itemTemplate||s["\u0275nov"](e.parent.parent.parent,5))},function(t,e){var n=e.component;t(e,0,0,n.animationState,n.isActive(e.parent.context.$implicit))})}function Yd(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Fd)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Gd)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){var n=e.context.$implicit.isHeader();t(e,1,0,n);var a=!e.context.$implicit.isHeader();t(e,3,0,a)},null)}function Vd(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Yd)),s["\u0275did"](1,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.component.matches)},null)}function Hd(t){return s["\u0275vid"](0,[s["\u0275qud"](671088640,1,{ulElement:0}),s["\u0275qud"](671088640,2,{liElements:1}),(t()(),s["\u0275and"](16777216,null,null,2,null,Dd)),s["\u0275did"](3,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),s["\u0275pod"](4,{matches:0,itemTemplate:1,query:2}),(t()(),s["\u0275and"](0,[["bsItemTemplate",2]],null,0,null,Ed)),(t()(),s["\u0275and"](0,[["bs3Template",2]],null,0,null,jd)),(t()(),s["\u0275and"](0,[["bs4Template",2]],null,0,null,Vd))],function(t,e){var n=e.component,a=t(e,4,0,n.matches,n.itemTemplate,n.query);t(e,3,0,a,n.optionsListTemplate||s["\u0275nov"](e,n.isBs4?7:6))},null)}function Bd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"typeahead-container",[["class","dropdown open bottom"],["style","position: absolute;display: block;"]],[[2,"dropdown-menu",null],[4,"overflow-y",null],[4,"height",null],[4,"visibility",null],[2,"dropup",null]],[[null,"mouseleave"],[null,"blur"]],function(t,e,n){var a=!0;return"mouseleave"===e&&(a=!1!==s["\u0275nov"](t,1).focusLost()&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,1).focusLost()&&a),a},Hd,Ad)),s["\u0275did"](1,49152,null,0,Ju,[Q.a,s.Renderer2,s.ElementRef],null,null)],null,function(t,e){t(e,0,0,s["\u0275nov"](e,1).isBs4,s["\u0275nov"](e,1).isBs4&&s["\u0275nov"](e,1).needScrollbar?"scroll":"visible",s["\u0275nov"](e,1).isBs4&&s["\u0275nov"](e,1).needScrollbar?s["\u0275nov"](e,1).guiHeight:"auto",s["\u0275nov"](e,1).visibility,s["\u0275nov"](e,1).dropup)})}var Ud=s["\u0275ccf"]("typeahead-container",Ju,Bd,{},{},[]),Wd=n("ajRT"),Kd=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function $d(t){return s["\u0275vid"](0,[(t()(),s["\u0275ted"](-1,null,["Deep "]))],null,null)}function Zd(t){return s["\u0275vid"](0,[(t()(),s["\u0275ted"](-1,null,["deep "]))],null,null)}function Xd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,10,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,9,"p",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["You are about to apply a "])),(t()(),s["\u0275eld"](3,0,null,null,3,null,null,null,null,null,null,null)),s["\u0275did"](4,16384,null,0,i.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Zd)),s["\u0275did"](6,278528,null,0,i.NgSwitchCase,[s.ViewContainerRef,s.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),s["\u0275ted"](-1,null,["scrub to the OSD "])),(t()(),s["\u0275eld"](8,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](9,null,["",""])),(t()(),s["\u0275ted"](-1,null,["."]))],function(t,e){t(e,4,0,e.component.deep),t(e,6,0,"1")},function(t,e){t(e,9,0,e.component.selected[0].id)})}function Jd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,23,"cd-modal",[],null,null,null,_d.c,_d.b)),s["\u0275did"](1,49152,null,0,Wd.a,[],{modalRef:[0,"modalRef"]},null),(t()(),s["\u0275eld"](2,0,null,0,6,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["OSDs "])),(t()(),s["\u0275eld"](4,0,null,null,3,null,null,null,null,null,null,null)),s["\u0275did"](5,16384,null,0,i.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,$d)),s["\u0275did"](7,278528,null,0,i.NgSwitchCase,[s.ViewContainerRef,s.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),s["\u0275ted"](-1,null,["Scrub"])),(t()(),s["\u0275eld"](9,0,null,1,14,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,13,"form",[["class","form-horizontal"],["name","scrubForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,12).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,12).onReset()&&a),a},null,null)),s["\u0275did"](11,16384,null,0,Te.D,[],null,null),s["\u0275did"](12,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](14,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](15,0,null,null,2,"div",[["class","modal-body"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Xd)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](18,0,null,null,5,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.scrub()&&a),a},$a.b,$a.a)),s["\u0275did"](20,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(t()(),s["\u0275ted"](-1,0,["Submit"])),(t()(),s["\u0275eld"](22,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,Xa.b,Xa.a)),s["\u0275did"](23,49152,null,0,Ja.a,[i.Location,Zn.b],{name:[0,"name"],back:[1,"back"]},null)],function(t,e){var n=e.component;t(e,1,0,n.bsModalRef),t(e,5,0,n.deep),t(e,7,0,"1"),t(e,12,0,n.scrubForm),t(e,17,0,1===n.selected.length),t(e,20,0,n.scrubForm),t(e,23,0,"Cancel",n.bsModalRef.hide)},function(t,e){t(e,10,0,s["\u0275nov"](e,14).ngClassUntouched,s["\u0275nov"](e,14).ngClassTouched,s["\u0275nov"](e,14).ngClassPristine,s["\u0275nov"](e,14).ngClassDirty,s["\u0275nov"](e,14).ngClassValid,s["\u0275nov"](e,14).ngClassInvalid,s["\u0275nov"](e,14).ngClassPending)})}function Qd(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-osd-scrub-modal",[],null,null,null,Jd,Kd)),s["\u0275did"](1,114688,null,0,da,[pa.a,Ln,Jn.a,xt.a],null,null)],function(t,e){t(e,1,0)},null)}var tf=s["\u0275ccf"]("cd-osd-scrub-modal",da,Qd,{},{},[]),ef=s["\u0275crt"]({encapsulation:0,styles:[[".osd-modal[_ngcontent-%COMP%] .oa-hr-small[_ngcontent-%COMP%]{margin:5px}"]],data:{}});function nf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"hr",[["class","oa-hr-small"]],null,null,null,null,null))],null,null)}function af(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,10,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"input",[["type","checkbox"]],[[8,"checked",0],[8,"name",0],[8,"id",0],[8,"disabled",0]],[[null,"change"]],function(t,e,n){var a=!0;return"change"===e&&(a=0!=(t.context.$implicit.value=!t.context.$implicit.value)&&a),a},null,null)),s["\u0275did"](2,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](3,0,null,null,5,"label",[["ng-class","['tc_' + key]"]],[[8,"htmlFor",0]],null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](5,null,["",""])),(t()(),s["\u0275eld"](6,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,1,"span",[["class","text-muted"]],null,null,null,null,null)),(t()(),s["\u0275ted"](8,null,["",""])),(t()(),s["\u0275and"](16777216,null,null,1,null,nf)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,10,0,!e.context.last)},function(t,e){t(e,1,0,e.context.$implicit.value,e.context.$implicit.code,e.context.$implicit.code,e.context.$implicit.disabled),t(e,3,0,e.context.$implicit.code),t(e,5,0,e.context.$implicit.name),t(e,8,0,e.context.$implicit.description)})}function rf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.submitAction()&&a),a},$a.b,$a.a)),s["\u0275did"](1,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(t()(),s["\u0275ted"](-1,0,["Submit"]))],function(t,e){t(e,1,0,e.component.osdFlagsForm)},null)}function sf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,19,"cd-modal",[],null,null,null,_d.c,_d.b)),s["\u0275did"](1,49152,null,0,Wd.a,[],{modalRef:[0,"modalRef"]},null),(t()(),s["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Cluster-wide OSD Flags"])),(t()(),s["\u0275eld"](4,0,null,1,15,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,14,"form",[["cdFormScope","osd"],["name","osdFlagsForm"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,8).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,8).onReset()&&a),a},null,null)),s["\u0275did"](6,16384,null,0,Se.a,[],{cdFormScope:[0,"cdFormScope"]},null),s["\u0275did"](7,16384,null,0,Te.D,[],null,null),s["\u0275did"](8,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](10,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](11,0,null,null,2,"div",[["class","modal-body osd-modal"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,af)),s["\u0275did"](13,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275eld"](14,0,null,null,5,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](15,0,null,null,4,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,rf)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](18,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,Xa.b,Xa.a)),s["\u0275did"](19,49152,null,0,Ja.a,[i.Location,Zn.b],{name:[0,"name"],back:[1,"back"]},null)],function(t,e){var n=e.component;t(e,1,0,n.bsModalRef),t(e,6,0,"osd"),t(e,8,0,n.osdFlagsForm),t(e,13,0,n.flags),t(e,17,0,n.permissions.osd.update),t(e,19,0,"Cancel",n.bsModalRef.hide)},function(t,e){t(e,5,0,s["\u0275nov"](e,10).ngClassUntouched,s["\u0275nov"](e,10).ngClassTouched,s["\u0275nov"](e,10).ngClassPristine,s["\u0275nov"](e,10).ngClassDirty,s["\u0275nov"](e,10).ngClassValid,s["\u0275nov"](e,10).ngClassInvalid,s["\u0275nov"](e,10).ngClassPending)})}function of(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-osd-flags-modal",[],null,null,null,sf,ef)),s["\u0275did"](1,114688,null,0,Qn,[pa.a,l.a,Ln,Jn.a,xt.a],null,null)],function(t,e){t(e,1,0)},null)}var uf=s["\u0275ccf"]("cd-osd-flags-modal",Qn,of,{},{},[]),cf=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function lf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,[" "," "]))],function(t,e){t(e,1,0,e.context.$implicit.name),t(e,2,0,e.context.$implicit.name)},function(t,e){t(e,3,0,e.context.$implicit.text)})}function df(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["This field is required."]))],null,null)}function ff(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-helper",[],null,null,null,ks.b,ks.a)),s["\u0275did"](1,49152,null,0,Ns.a,[],null,null),(t()(),s["\u0275ted"](2,0,["",""]))],null,function(t,e){t(e,2,0,e.parent.context.$implicit.value.desc)})}function pf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"span",[["class","required"]],null,null,null,null,null))],null,null)}function hf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function gf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit.value.patternHelpText)})}function bf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too high! It must not be greater than ","."]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit.value.maxValue)})}function mf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too low! It must not be lower than ","."]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit.value.minValue)})}function yf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,25,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,5,"label",[["class","control-label col-sm-6"]],[[8,"htmlFor",0]],null,null,null,null)),(t()(),s["\u0275ted"](4,null,[""," "])),(t()(),s["\u0275and"](16777216,null,null,1,null,ff)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,pf)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](9,0,null,null,16,"div",[["class","col-sm-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,7,"input",[["class","form-control"],["type","number"]],[[8,"id",0],[8,"readOnly",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,12)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,12).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,12)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,12)._compositionEnd(n.target.value)&&a),"change"===e&&(a=!1!==s["\u0275nov"](t,13).onChange(n.target.value)&&a),"input"===e&&(a=!1!==s["\u0275nov"](t,13).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,13).onTouched()&&a),a},null,null)),s["\u0275did"](11,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](12,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275did"](13,16384,null,0,Te.C,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t,e){return[t,e]},[Te.e,Te.C]),s["\u0275did"](15,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](17,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,hf)),s["\u0275did"](19,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,gf)),s["\u0275did"](21,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,bf)),s["\u0275did"](23,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,mf)),s["\u0275did"](25,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.osdRecvSpeedForm.getValue("customizePriority")&&n.osdRecvSpeedForm.showError(e.context.$implicit.key,s["\u0275nov"](e.parent,8)));t(e,1,0,"form-group",a),t(e,6,0,e.context.$implicit.value.desc),t(e,8,0,n.osdRecvSpeedForm.getValue("customizePriority")),t(e,15,0,e.context.$implicit.key),t(e,19,0,n.osdRecvSpeedForm.getValue("customizePriority")&&n.osdRecvSpeedForm.showError(e.context.$implicit.key,s["\u0275nov"](e.parent,8),"required")),t(e,21,0,n.osdRecvSpeedForm.getValue("customizePriority")&&n.osdRecvSpeedForm.showError(e.context.$implicit.key,s["\u0275nov"](e.parent,8),"pattern")),t(e,23,0,n.osdRecvSpeedForm.getValue("customizePriority")&&n.osdRecvSpeedForm.showError(e.context.$implicit.key,s["\u0275nov"](e.parent,8),"max")),t(e,25,0,n.osdRecvSpeedForm.getValue("customizePriority")&&n.osdRecvSpeedForm.showError(e.context.$implicit.key,s["\u0275nov"](e.parent,8),"min"))},function(t,e){var n=e.component;t(e,3,0,e.context.$implicit.key),t(e,4,0,e.context.$implicit.value.text),t(e,10,0,e.context.$implicit.key,!n.osdRecvSpeedForm.getValue("customizePriority"),s["\u0275nov"](e,17).ngClassUntouched,s["\u0275nov"](e,17).ngClassTouched,s["\u0275nov"](e,17).ngClassPristine,s["\u0275nov"](e,17).ngClassDirty,s["\u0275nov"](e,17).ngClassValid,s["\u0275nov"](e,17).ngClassInvalid,s["\u0275nov"](e,17).ngClassPending)})}function vf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.submitAction()&&a),a},$a.b,$a.a)),s["\u0275did"](1,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(t()(),s["\u0275ted"](-1,0,["Submit"]))],function(t,e){t(e,1,0,e.component.osdRecvSpeedForm)},null)}function _f(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,51,"cd-modal",[],null,null,null,_d.c,_d.b)),s["\u0275did"](1,49152,null,0,Wd.a,[],{modalRef:[0,"modalRef"]},null),(t()(),s["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["OSD Recovery Priority"])),(t()(),s["\u0275eld"](4,0,null,1,47,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,46,"form",[["cdFormScope","osd"],["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,8).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,8).onReset()&&a),a},null,null)),s["\u0275did"](6,16384,null,0,Se.a,[],{cdFormScope:[0,"cdFormScope"]},null),s["\u0275did"](7,16384,null,0,Te.D,[],null,null),s["\u0275did"](8,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](10,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](11,0,null,null,34,"div",[["class","modal-body"]],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](13,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](14,{"has-error":0}),(t()(),s["\u0275eld"](15,0,null,null,3,"label",[["class","control-label col-sm-6"],["for","priority"]],null,null,null,null,null)),(t()(),s["\u0275eld"](16,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Priority"])),(t()(),s["\u0275eld"](18,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,11,"div",[["class","col-sm-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](20,0,null,null,8,"select",[["class","form-control"],["formControlName","priority"],["id","priority"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,22).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,22).onTouched()&&a),"change"===e&&(a=!1!==r.onPriorityChange(n.target.value)&&a),a},null,null)),s["\u0275did"](21,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](22,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](24,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](26,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,lf)),s["\u0275did"](28,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,df)),s["\u0275did"](30,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](31,0,null,null,11,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](32,0,null,null,10,"div",[["class","col-sm-offset-6 col-sm-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](33,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](34,0,null,null,6,"input",[["formControlName","customizePriority"],["id","customizePriority"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0,r=t.component;return"change"===e&&(a=!1!==s["\u0275nov"](t,36).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,36).onTouched()&&a),"change"===e&&(a=!1!==r.onCustomizePriorityChange()&&a),a},null,null)),s["\u0275did"](35,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](36,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](38,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](40,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275eld"](41,0,null,null,1,"label",[["for","customizePriority"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Customize priority values"])),(t()(),s["\u0275and"](16777216,null,null,2,null,yf)),s["\u0275did"](44,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),s["\u0275pid"](0,i.KeyValuePipe,[s.KeyValueDiffers]),(t()(),s["\u0275eld"](46,0,null,null,5,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](47,0,null,null,4,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,vf)),s["\u0275did"](49,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](50,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,Xa.b,Xa.a)),s["\u0275did"](51,49152,null,0,Ja.a,[i.Location,Zn.b],{name:[0,"name"],back:[1,"back"]},null)],function(t,e){var n=e.component;t(e,1,0,n.bsModalRef),t(e,6,0,"osd"),t(e,8,0,n.osdRecvSpeedForm);var a=t(e,14,0,n.osdRecvSpeedForm.showError("priority",s["\u0275nov"](e,8)));t(e,13,0,"form-group",a),t(e,24,0,"priority"),t(e,28,0,n.priorities),t(e,30,0,n.osdRecvSpeedForm.showError("priority",s["\u0275nov"](e,8),"required")),t(e,38,0,"customizePriority"),t(e,44,0,s["\u0275unv"](e,44,0,s["\u0275nov"](e,45).transform(n.priorityAttrs))),t(e,49,0,n.permissions.configOpt.update),t(e,51,0,"Cancel",n.bsModalRef.hide)},function(t,e){t(e,5,0,s["\u0275nov"](e,10).ngClassUntouched,s["\u0275nov"](e,10).ngClassTouched,s["\u0275nov"](e,10).ngClassPristine,s["\u0275nov"](e,10).ngClassDirty,s["\u0275nov"](e,10).ngClassValid,s["\u0275nov"](e,10).ngClassInvalid,s["\u0275nov"](e,10).ngClassPending),t(e,20,0,s["\u0275nov"](e,26).ngClassUntouched,s["\u0275nov"](e,26).ngClassTouched,s["\u0275nov"](e,26).ngClassPristine,s["\u0275nov"](e,26).ngClassDirty,s["\u0275nov"](e,26).ngClassValid,s["\u0275nov"](e,26).ngClassInvalid,s["\u0275nov"](e,26).ngClassPending),t(e,34,0,s["\u0275nov"](e,40).ngClassUntouched,s["\u0275nov"](e,40).ngClassTouched,s["\u0275nov"](e,40).ngClassPristine,s["\u0275nov"](e,40).ngClassDirty,s["\u0275nov"](e,40).ngClassValid,s["\u0275nov"](e,40).ngClassInvalid,s["\u0275nov"](e,40).ngClassPending)})}function xf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-osd-recv-speed-modal",[],null,null,null,_f,cf)),s["\u0275did"](1,114688,null,0,ua,[pa.a,l.a,ea.a,Jn.a,xt.a,Ln],null,null)],function(t,e){t(e,1,0)},null)}var Tf=s["\u0275ccf"]("cd-osd-recv-speed-modal",ua,xf,{},{},[]),wf=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Sf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["This field is required."]))],null,null)}function Of(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["The value needs to be between 0 and 1."]))],null,null)}function If(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Sf)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Of)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,null==n.weight.errors?null:n.weight.errors.required),t(e,4,0,(null==n.weight.errors?null:n.weight.errors.max)||(null==n.weight.errors?null:n.weight.errors.min))},null)}function Cf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,32,"cd-modal",[],null,null,null,_d.c,_d.b)),s["\u0275did"](1,49152,null,0,Wd.a,[],{modalRef:[0,"modalRef"]},null),(t()(),s["\u0275eld"](2,0,null,0,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Reweight OSD"])),(t()(),s["\u0275eld"](4,0,null,1,28,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,27,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,7).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,7).onReset()&&a),a},null,null)),s["\u0275did"](6,16384,null,0,Te.D,[],null,null),s["\u0275did"](7,540672,null,0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](9,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](10,0,null,null,16,"div",[["class","modal-body"]],null,null,null,null,null)),s["\u0275did"](11,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](12,{"has-error":0}),(t()(),s["\u0275eld"](13,0,null,null,13,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](14,0,null,null,1,"label",[["class","col-sm-2 control-label"],["for","weight"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Weight"])),(t()(),s["\u0275eld"](16,0,null,null,10,"div",[["class","col-sm-10"]],null,null,null,null,null)),(t()(),s["\u0275eld"](17,0,null,null,7,"input",[["class","form-control"],["formControlName","weight"],["id","weight"],["max","1"],["min","0"],["step","0.1"],["type","number"]],[[8,"value",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"change"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,19)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,19).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,19)._compositionEnd(n.target.value)&&a),"change"===e&&(a=!1!==s["\u0275nov"](t,20).onChange(n.target.value)&&a),"input"===e&&(a=!1!==s["\u0275nov"](t,20).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,20).onTouched()&&a),a},null,null)),s["\u0275did"](18,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](19,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275did"](20,16384,null,0,Te.C,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t,e){return[t,e]},[Te.e,Te.C]),s["\u0275did"](22,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](24,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,If)),s["\u0275did"](26,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](27,0,null,null,5,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](28,0,null,null,2,"cd-submit-button",[],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.reweight()&&a),a},$a.b,$a.a)),s["\u0275did"](29,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"],disabled:[1,"disabled"]},{submitAction:"submitAction"}),(t()(),s["\u0275ted"](-1,0,["Reweight"])),(t()(),s["\u0275eld"](31,0,null,null,1,"cd-back-button",[["name","Cancel"]],null,null,null,Xa.b,Xa.a)),s["\u0275did"](32,49152,null,0,Ja.a,[i.Location,Zn.b],{name:[0,"name"],back:[1,"back"]},null)],function(t,e){var n=e.component;t(e,1,0,n.bsModalRef),t(e,7,0,n.reweightForm);var a=t(e,12,0,n.weight.errors);t(e,11,0,"modal-body",a),t(e,22,0,"weight"),t(e,26,0,n.weight.errors),t(e,29,0,n.reweightForm,n.reweightForm.invalid),t(e,32,0,"Cancel",n.bsModalRef.hide)},function(t,e){var n=e.component;t(e,5,0,s["\u0275nov"](e,9).ngClassUntouched,s["\u0275nov"](e,9).ngClassTouched,s["\u0275nov"](e,9).ngClassPristine,s["\u0275nov"](e,9).ngClassDirty,s["\u0275nov"](e,9).ngClassValid,s["\u0275nov"](e,9).ngClassInvalid,s["\u0275nov"](e,9).ngClassPending),t(e,17,0,n.currentWeight,s["\u0275nov"](e,24).ngClassUntouched,s["\u0275nov"](e,24).ngClassTouched,s["\u0275nov"](e,24).ngClassPristine,s["\u0275nov"](e,24).ngClassDirty,s["\u0275nov"](e,24).ngClassValid,s["\u0275nov"](e,24).ngClassInvalid,s["\u0275nov"](e,24).ngClassPending)})}function kf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-osd-reweight-modal",[],null,null,null,Cf,wf)),s["\u0275did"](1,114688,null,0,la,[pa.a,Ln,ca.a],null,null)],function(t,e){t(e,1,0)},null)}var Nf=s["\u0275ccf"]("cd-osd-reweight-modal",la,kf,{},{},[]),Rf=s["\u0275crt"]({encapsulation:0,styles:[["hr[_ngcontent-%COMP%]{margin-top:5px;margin-bottom:5px}.control-label[_ngcontent-%COMP%]{text-align:left}.checkbox-primary[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{width:23px;height:15px;margin-left:0;cursor:pointer}.checkbox-primary[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{cursor:auto}.checkbox-primary[_ngcontent-%COMP%] label[_ngcontent-%COMP%]:after, .checkbox-primary[_ngcontent-%COMP%] label[_ngcontent-%COMP%]:before{margin-left:0}.form-group[_ngcontent-%COMP%] .col-sm-6[_ngcontent-%COMP%]{padding-top:7px}"]],data:{}});function Af(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-helper",[],null,null,null,ks.b,ks.a)),s["\u0275did"](1,49152,null,0,Ns.a,[],null,null),(t()(),s["\u0275ted"](2,0,[" ",""]))],null,function(t,e){t(e,2,0,e.parent.parent.context.$implicit.long_desc)})}function Df(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,18,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,6,"label",[["class","col-sm-6 control-label"]],[[8,"htmlFor",0]],null,null,null,null)),(t()(),s["\u0275ted"](4,null,[" "," "])),(t()(),s["\u0275eld"](5,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,3,"span",[["class","text-muted"]],null,null,null,null,null)),(t()(),s["\u0275ted"](7,null,[" "," "])),(t()(),s["\u0275and"](16777216,null,null,1,null,Af)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](10,0,null,null,8,"div",[["class","col-sm-6 checkbox-primary checkbox"]],null,null,null,null,null)),(t()(),s["\u0275eld"](11,0,null,null,6,"input",[["type","checkbox"]],[[8,"id",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,12).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,12).onTouched()&&a),a},null,null)),s["\u0275did"](12,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](14,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](16,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](17,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](18,0,null,null,0,"label",[],null,null,null,null,null))],function(t,e){var n=e.component,a=t(e,2,0,n.optionsForm.showError(e.parent.context.$implicit.name,n.optionsFormDir));t(e,1,0,"form-group",a),t(e,9,0,e.parent.context.$implicit.long_desc),t(e,14,0,e.parent.context.$implicit.name)},function(t,e){t(e,3,0,e.parent.context.$implicit.name),t(e,4,0,e.parent.context.$implicit.text),t(e,7,0,e.parent.context.$implicit.desc),t(e,11,0,e.parent.context.$implicit.name,s["\u0275nov"](e,16).ngClassUntouched,s["\u0275nov"](e,16).ngClassTouched,s["\u0275nov"](e,16).ngClassPristine,s["\u0275nov"](e,16).ngClassDirty,s["\u0275nov"](e,16).ngClassValid,s["\u0275nov"](e,16).ngClassInvalid,s["\u0275nov"](e,16).ngClassPending)})}function Ef(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-helper",[],null,null,null,ks.b,ks.a)),s["\u0275did"](1,49152,null,0,Ns.a,[],null,null),(t()(),s["\u0275ted"](2,0,[" ",""]))],null,function(t,e){t(e,2,0,e.parent.parent.context.$implicit.long_desc)})}function Lf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"span",[["class","input-group-btn"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"button",[["class","btn btn-default"],["data-toggle","button"],["title","Remove the custom configuration value. The default configuration will be inherited and used instead."],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.resetValue(t.parent.parent.context.$implicit.name)&&a),a},null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-eraser"]],null,null,null,null,null))],null,null)}function Pf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" ",""]))],null,function(t,e){t(e,1,0,e.parent.parent.context.$implicit.additionalTypeInfo.patternHelpText)})}function Mf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" ",""]))],null,function(t,e){t(e,1,0,e.parent.parent.context.$implicit.additionalTypeInfo.patternHelpText)})}function qf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too high! It must not be greater than ","."]))],null,function(t,e){t(e,1,0,e.parent.parent.context.$implicit.maxValue)})}function jf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["The entered value is too low! It must not be lower than ","."]))],null,function(t,e){t(e,1,0,e.parent.parent.context.$implicit.minValue)})}function Ff(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,28,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{"has-error":0}),(t()(),s["\u0275eld"](3,0,null,null,6,"label",[["class","col-sm-6 control-label"]],[[8,"htmlFor",0]],null,null,null,null)),(t()(),s["\u0275ted"](4,null,[""," "])),(t()(),s["\u0275eld"](5,0,null,null,0,"br",[],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,3,"span",[["class","text-muted"]],null,null,null,null,null)),(t()(),s["\u0275ted"](7,null,[" "," "])),(t()(),s["\u0275and"](16777216,null,null,1,null,Ef)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](10,0,null,null,18,"div",[["class","col-sm-6"]],null,null,null,null,null)),(t()(),s["\u0275eld"](11,0,null,null,9,"div",[["class","input-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,6,"input",[["class","form-control"]],[[8,"type",0],[8,"id",0],[8,"placeholder",0],[8,"step",0],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,13)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,13).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,13)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,13)._compositionEnd(n.target.value)&&a),a},null,null)),s["\u0275did"](13,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](15,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](17,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](18,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Lf)),s["\u0275did"](20,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Pf)),s["\u0275did"](22,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Mf)),s["\u0275did"](24,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,qf)),s["\u0275did"](26,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,jf)),s["\u0275did"](28,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component,a=t(e,2,0,n.optionsForm.showError(e.parent.context.$implicit.name,n.optionsFormDir));t(e,1,0,"form-group",a),t(e,9,0,e.parent.context.$implicit.long_desc),t(e,15,0,e.parent.context.$implicit.name),t(e,20,0,n.optionsFormShowReset),t(e,22,0,n.optionsForm.showError(e.parent.context.$implicit.name,n.optionsFormDir,"pattern")),t(e,24,0,n.optionsForm.showError(e.parent.context.$implicit.name,n.optionsFormDir,"invalidUuid")),t(e,26,0,n.optionsForm.showError(e.parent.context.$implicit.name,n.optionsFormDir,"max")),t(e,28,0,n.optionsForm.showError(e.parent.context.$implicit.name,n.optionsFormDir,"min"))},function(t,e){var n=e.component;t(e,3,0,e.parent.context.$implicit.name),t(e,4,0,e.parent.context.$implicit.text),t(e,7,0,e.parent.context.$implicit.desc),t(e,12,1,[e.parent.context.$implicit.additionalTypeInfo.inputType,e.parent.context.$implicit.name,e.parent.context.$implicit.additionalTypeInfo.humanReadable,n.getStep(e.parent.context.$implicit.type,n.optionsForm.getValue(e.parent.context.$implicit.name)),s["\u0275nov"](e,17).ngClassUntouched,s["\u0275nov"](e,17).ngClassTouched,s["\u0275nov"](e,17).ngClassPristine,s["\u0275nov"](e,17).ngClassDirty,s["\u0275nov"](e,17).ngClassValid,s["\u0275nov"](e,17).ngClassInvalid,s["\u0275nov"](e,17).ngClassPending])})}function zf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,"hr",[],null,null,null,null,null))],null,null)}function Gf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"div",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Df)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ff)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,zf)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,2,0,"bool"===e.context.$implicit.type),t(e,4,0,"bool"!==e.context.$implicit.type),t(e,6,0,!e.context.last)},null)}function Yf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,1).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,1).onReset()&&a),a},null,null)),s["\u0275did"](1,540672,null,0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](3,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275and"](16777216,null,null,1,null,Gf)),s["\u0275did"](5,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){var n=e.component;t(e,1,0,n.optionsFormGroup),t(e,5,0,n.options)},function(t,e){t(e,0,0,s["\u0275nov"](e,3).ngClassUntouched,s["\u0275nov"](e,3).ngClassTouched,s["\u0275nov"](e,3).ngClassPristine,s["\u0275nov"](e,3).ngClassDirty,s["\u0275nov"](e,3).ngClassValid,s["\u0275nov"](e,3).ngClassInvalid,s["\u0275nov"](e,3).ngClassPending)})}var Vf=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Hf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"a",[["class","pull-right margin-right-md"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=0!=(t.component.advancedEnabled=!0)&&a),a},null,null)),(t()(),s["\u0275ted"](-1,null,["Advanced..."]))],null,null)}function Bf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"h2",[["class","page-header"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Advanced configuration options"])),(t()(),s["\u0275eld"](3,0,null,null,1,"cd-config-option",[],null,null,null,Yf,Rf)),s["\u0275did"](4,114688,[[2,4],["advancedOptionsValues",4]],0,ia,[ea.a],{optionNames:[0,"optionNames"],optionsForm:[1,"optionsForm"],optionsFormDir:[2,"optionsFormDir"],optionsFormGroupName:[3,"optionsFormGroupName"]},null)],function(t,e){var n=e.component;t(e,4,0,n.advancedOptions,n.osdPgScrubForm,s["\u0275nov"](e.parent,14),"advancedFormGroup")},null)}function Uf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,4,"cd-submit-button",[["type","button"]],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.submitAction()&&a),a},$a.b,$a.a)),s["\u0275did"](1,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"],type:[1,"type"]},{submitAction:"submitAction"}),(t()(),s["\u0275ted"](2,0,[""," ",""])),s["\u0275ppd"](3,1),s["\u0275ppd"](4,1)],function(t,e){t(e,1,0,e.component.osdPgScrubForm,"button")},function(t,e){var n=e.component,a=s["\u0275unv"](e,2,0,t(e,3,0,s["\u0275nov"](e.parent,0),n.action)),r=s["\u0275unv"](e,2,1,t(e,4,0,s["\u0275nov"](e.parent,1),n.resource));t(e,2,0,a,r)})}function Wf(t){return s["\u0275vid"](0,[s["\u0275pid"](0,i.TitleCasePipe,[]),s["\u0275pid"](0,Rs.a,[]),s["\u0275qud"](402653184,1,{basicOptionsValues:0}),s["\u0275qud"](671088640,2,{advancedOptionsValues:0}),(t()(),s["\u0275eld"](4,0,null,null,27,"cd-modal",[],null,null,null,_d.c,_d.b)),s["\u0275did"](5,49152,null,0,Wd.a,[],{modalRef:[0,"modalRef"]},null),(t()(),s["\u0275eld"](6,0,null,0,3,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](7,null,[""," ",""])),s["\u0275ppd"](8,1),s["\u0275ppd"](9,1),(t()(),s["\u0275eld"](10,0,null,1,21,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](11,0,null,null,20,"form",[["cdFormScope","osd"],["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,14).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,14).onReset()&&a),a},null,null)),s["\u0275did"](12,16384,null,0,Se.a,[],{cdFormScope:[0,"cdFormScope"]},null),s["\u0275did"](13,16384,null,0,Te.D,[],null,null),s["\u0275did"](14,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](16,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](17,0,null,null,8,"div",[["class","modal-body osd-modal"]],null,null,null,null,null)),(t()(),s["\u0275eld"](18,0,null,null,1,"cd-config-option",[],null,null,null,Yf,Rf)),s["\u0275did"](19,114688,[[1,4],["basicOptionsValues",4]],0,ia,[ea.a],{optionNames:[0,"optionNames"],optionsForm:[1,"optionsForm"],optionsFormDir:[2,"optionsFormDir"],optionsFormGroupName:[3,"optionsFormGroupName"]},null),(t()(),s["\u0275eld"](20,0,null,null,3,"div",[["class","row"]],null,null,null,null,null)),(t()(),s["\u0275eld"](21,0,null,null,2,"div",[["class","col-sm-12"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Hf)),s["\u0275did"](23,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Bf)),s["\u0275did"](25,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](26,0,null,null,5,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](27,0,null,null,4,"div",[["class","button-group text-right"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Uf)),s["\u0275did"](29,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](30,0,null,null,1,"cd-back-button",[],null,null,null,Xa.b,Xa.a)),s["\u0275did"](31,49152,null,0,Ja.a,[i.Location,Zn.b],{back:[0,"back"]},null)],function(t,e){var n=e.component;t(e,5,0,n.bsModalRef),t(e,12,0,"osd"),t(e,14,0,n.osdPgScrubForm),t(e,19,0,n.basicOptions,n.osdPgScrubForm,s["\u0275nov"](e,14),"basicFormGroup"),t(e,23,0,!n.advancedEnabled),t(e,25,0,n.advancedEnabled),t(e,29,0,n.permissions.configOpt.update),t(e,31,0,n.bsModalRef.hide)},function(t,e){var n=e.component,a=s["\u0275unv"](e,7,0,t(e,8,0,s["\u0275nov"](e,0),n.action)),r=s["\u0275unv"](e,7,1,t(e,9,0,s["\u0275nov"](e,1),n.resource));t(e,7,0,a,r),t(e,11,0,s["\u0275nov"](e,16).ngClassUntouched,s["\u0275nov"](e,16).ngClassTouched,s["\u0275nov"](e,16).ngClassPristine,s["\u0275nov"](e,16).ngClassDirty,s["\u0275nov"](e,16).ngClassValid,s["\u0275nov"](e,16).ngClassInvalid,s["\u0275nov"](e,16).ngClassPending)})}function Kf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-osd-pg-scrub-modal",[],null,null,null,Wf,Vf)),s["\u0275did"](1,49152,null,0,oa,[pa.a,l.a,Jn.a,xt.a,Zn.b],null,null)],null,null)}var $f=s["\u0275ccf"]("cd-osd-pg-scrub-modal",oa,Kf,{},{},[]),Zf=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Xf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](1,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{value:[0,"value"]},null),s["\u0275did"](2,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{value:[0,"value"]},null),(t()(),s["\u0275ted"](3,null,[" "," "]))],function(t,e){t(e,1,0,e.context.$implicit),t(e,2,0,e.context.$implicit)},function(t,e){t(e,3,0,e.context.$implicit)})}function Jf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function Qf(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","help-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["This field is required!"]))],null,null)}function tp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"div",[["id","match-state"]],[[8,"className",0]],null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[],[[8,"className",0]],null,null,null,null)),(t()(),s["\u0275ted"](2,null,[" "," "]))],null,function(t,e){var n=e.component;t(e,0,0,s["\u0275inlineInterpolate"](1,"col-sm-offset-3 col-sm-9 ",n.matcherMatch.cssClass,"")),t(e,1,0,s["\u0275inlineInterpolate"](1,"help-block ",n.matcherMatch.cssClass,"")),t(e,2,0,n.matcherMatch.status)})}function ep(t){return s["\u0275vid"](0,[(t()(),s["\u0275ted"](-1,null,["Update"]))],null,null)}function np(t){return s["\u0275vid"](0,[(t()(),s["\u0275ted"](-1,null,["Add"]))],null,null)}function ap(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"div",[["class","modal-header"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"h4",[["class","modal-title pull-left"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Matcher"])),(t()(),s["\u0275eld"](3,0,null,null,2,"button",[["aria-label","Close"],["class","close pull-right"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.bsModalRef.hide()&&a),a},null,null)),(t()(),s["\u0275eld"](4,0,null,null,1,"span",[["aria-hidden","true"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["\xd7"])),(t()(),s["\u0275eld"](6,0,null,null,73,"form",[["class","form-horizontal"],["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(t,e,n){var a=!0;return"submit"===e&&(a=!1!==s["\u0275nov"](t,8).onSubmit(n)&&a),"reset"===e&&(a=!1!==s["\u0275nov"](t,8).onReset()&&a),a},null,null)),s["\u0275did"](7,16384,null,0,Te.D,[],null,null),s["\u0275did"](8,540672,[["formDir",4]],0,Te.l,[[8,null],[8,null]],{form:[0,"form"]},null),s["\u0275prd"](2048,null,Te.d,null,[Te.l]),s["\u0275did"](10,16384,null,0,Te.s,[[4,Te.d]],null,null),(t()(),s["\u0275eld"](11,0,null,null,56,"div",[["class","modal-body"]],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,22,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](13,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](14,{"has-error":0}),(t()(),s["\u0275eld"](15,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","name"]],null,null,null,null,null)),(t()(),s["\u0275eld"](16,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Name"])),(t()(),s["\u0275eld"](18,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,15,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](20,0,null,null,12,"select",[["class","form-control"],["formControlName","name"],["id","name"],["name","name"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,22).onChange(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,22).onTouched()&&a),a},null,null)),s["\u0275did"](21,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](22,16384,null,0,Te.z,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.z]),s["\u0275did"](24,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](26,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275eld"](27,0,null,null,3,"option",[],null,null,null,null,null)),s["\u0275did"](28,147456,null,0,Te.v,[s.ElementRef,s.Renderer2,[2,Te.z]],{ngValue:[0,"ngValue"]},null),s["\u0275did"](29,147456,null,0,Te.G,[s.ElementRef,s.Renderer2,[8,null]],{ngValue:[0,"ngValue"]},null),(t()(),s["\u0275ted"](-1,null,["-- Select an attribute to match against --"])),(t()(),s["\u0275and"](16777216,null,null,1,null,Xf)),s["\u0275did"](32,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Jf)),s["\u0275did"](34,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](35,0,null,null,19,"div",[["class","form-group"]],null,null,null,null,null)),s["\u0275did"](36,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](37,{"has-error":0}),(t()(),s["\u0275eld"](38,0,null,null,3,"label",[["class","control-label col-sm-3"],["for","value"]],null,null,null,null,null)),(t()(),s["\u0275eld"](39,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Value"])),(t()(),s["\u0275eld"](41,0,null,null,0,"span",[["class","required"]],null,null,null,null,null)),(t()(),s["\u0275eld"](42,0,null,null,10,"div",[["class","col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](43,16777216,null,null,7,"input",[["class","form-control"],["formControlName","value"],["id","value"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"],[null,"keyup"],[null,"click"],[null,"focus"],[null,"keydown"]],function(t,e,n){var a=!0;return"input"===e&&(a=!1!==s["\u0275nov"](t,45)._handleInput(n.target.value)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,45).onTouched()&&a),"compositionstart"===e&&(a=!1!==s["\u0275nov"](t,45)._compositionStart()&&a),"compositionend"===e&&(a=!1!==s["\u0275nov"](t,45)._compositionEnd(n.target.value)&&a),"input"===e&&(a=!1!==s["\u0275nov"](t,50).onInput(n)&&a),"keyup"===e&&(a=!1!==s["\u0275nov"](t,50).onChange(n)&&a),"click"===e&&(a=!1!==s["\u0275nov"](t,50).onFocus()&&a),"focus"===e&&(a=!1!==s["\u0275nov"](t,50).onFocus()&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,50).onBlur()&&a),"keydown"===e&&(a=!1!==s["\u0275nov"](t,50).onKeydown(n)&&a),a},null,null)),s["\u0275did"](44,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](45,16384,null,0,Te.e,[s.Renderer2,s.ElementRef,[2,Te.b]],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.e]),s["\u0275did"](47,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](49,16384,null,0,Te.r,[[4,Te.q]],null,null),s["\u0275did"](50,212992,null,0,tc,[J.a,Qu,s.ChangeDetectorRef,s.ElementRef,Te.q,s.Renderer2,s.ViewContainerRef],{typeahead:[0,"typeahead"],typeaheadMinLength:[1,"typeaheadMinLength"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Qf)),s["\u0275did"](52,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,tp)),s["\u0275did"](54,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](55,0,null,null,12,"div",[["class","form-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](56,0,null,null,11,"div",[["class","col-sm-offset-3 col-sm-9"]],null,null,null,null,null)),(t()(),s["\u0275eld"](57,0,null,null,10,"div",[["class","input-group"]],null,null,null,null,null)),(t()(),s["\u0275eld"](58,0,null,null,9,"div",[["class","checkbox checkbox-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](59,0,null,null,6,"input",[["formControlName","isRegex"],["id","is-regex"],["type","checkbox"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"change"],[null,"blur"]],function(t,e,n){var a=!0;return"change"===e&&(a=!1!==s["\u0275nov"](t,61).onChange(n.target.checked)&&a),"blur"===e&&(a=!1!==s["\u0275nov"](t,61).onTouched()&&a),a},null,null)),s["\u0275did"](60,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),s["\u0275did"](61,16384,null,0,Te.c,[s.Renderer2,s.ElementRef],null,null),s["\u0275prd"](1024,null,Te.p,function(t){return[t]},[Te.c]),s["\u0275did"](63,671744,null,0,Te.j,[[3,Te.d],[8,null],[8,null],[6,Te.p],[2,Te.F]],{name:[0,"name"]},null),s["\u0275prd"](2048,null,Te.q,null,[Te.j]),s["\u0275did"](65,16384,null,0,Te.r,[[4,Te.q]],null,null),(t()(),s["\u0275eld"](66,0,null,null,1,"label",[["for","is-regex"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Use regular expression"])),(t()(),s["\u0275eld"](68,0,null,null,11,"div",[["class","modal-footer"]],null,null,null,null,null)),(t()(),s["\u0275eld"](69,0,null,null,8,"cd-submit-button",[],null,[[null,"submitAction"]],function(t,e,n){var a=!0;return"submitAction"===e&&(a=!1!==t.component.onSubmit()&&a),a},$a.b,$a.a)),s["\u0275did"](70,114688,null,0,Za.a,[s.ElementRef],{form:[0,"form"]},{submitAction:"submitAction"}),(t()(),s["\u0275eld"](71,0,null,0,6,null,null,null,null,null,null,null)),(t()(),s["\u0275eld"](72,0,null,null,5,null,null,null,null,null,null,null)),s["\u0275did"](73,16384,null,0,i.NgSwitch,[],{ngSwitch:[0,"ngSwitch"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ep)),s["\u0275did"](75,278528,null,0,i.NgSwitchCase,[s.ViewContainerRef,s.TemplateRef,i.NgSwitch],{ngSwitchCase:[0,"ngSwitchCase"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,np)),s["\u0275did"](77,16384,null,0,i.NgSwitchDefault,[s.ViewContainerRef,s.TemplateRef,i.NgSwitch],null,null),(t()(),s["\u0275eld"](78,0,null,null,1,"cd-back-button",[["name","Close"]],null,null,null,Xa.b,Xa.a)),s["\u0275did"](79,49152,null,0,Ja.a,[i.Location,Zn.b],{name:[0,"name"],back:[1,"back"]},null)],function(t,e){var n=e.component;t(e,8,0,n.form);var a=t(e,14,0,n.form.showError("name",s["\u0275nov"](e,8)));t(e,13,0,"form-group",a),t(e,24,0,"name"),t(e,28,0,null),t(e,29,0,null),t(e,32,0,n.nameAttributes),t(e,34,0,n.form.showError("name",s["\u0275nov"](e,8),"required"));var r=t(e,37,0,n.form.showError("value",s["\u0275nov"](e,8)));t(e,36,0,"form-group",r),t(e,47,0,"value"),t(e,50,0,n.possibleValues,0),t(e,52,0,n.form.showError("value",s["\u0275nov"](e,8),"required")),t(e,54,0,n.form.getValue("value")&&!n.form.getValue("isRegex")&&n.matcherMatch),t(e,63,0,"isRegex"),t(e,70,0,n.form),t(e,73,0,n.editMode),t(e,75,0,"1"),t(e,79,0,"Close",n.bsModalRef.hide)},function(t,e){t(e,6,0,s["\u0275nov"](e,10).ngClassUntouched,s["\u0275nov"](e,10).ngClassTouched,s["\u0275nov"](e,10).ngClassPristine,s["\u0275nov"](e,10).ngClassDirty,s["\u0275nov"](e,10).ngClassValid,s["\u0275nov"](e,10).ngClassInvalid,s["\u0275nov"](e,10).ngClassPending),t(e,20,0,s["\u0275nov"](e,26).ngClassUntouched,s["\u0275nov"](e,26).ngClassTouched,s["\u0275nov"](e,26).ngClassPristine,s["\u0275nov"](e,26).ngClassDirty,s["\u0275nov"](e,26).ngClassValid,s["\u0275nov"](e,26).ngClassInvalid,s["\u0275nov"](e,26).ngClassPending),t(e,43,0,s["\u0275nov"](e,49).ngClassUntouched,s["\u0275nov"](e,49).ngClassTouched,s["\u0275nov"](e,49).ngClassPristine,s["\u0275nov"](e,49).ngClassDirty,s["\u0275nov"](e,49).ngClassValid,s["\u0275nov"](e,49).ngClassInvalid,s["\u0275nov"](e,49).ngClassPending),t(e,59,0,s["\u0275nov"](e,65).ngClassUntouched,s["\u0275nov"](e,65).ngClassTouched,s["\u0275nov"](e,65).ngClassPristine,s["\u0275nov"](e,65).ngClassDirty,s["\u0275nov"](e,65).ngClassValid,s["\u0275nov"](e,65).ngClassInvalid,s["\u0275nov"](e,65).ngClassPending)})}function rp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-silence-matcher-modal",[],null,null,null,ap,Zf)),s["\u0275did"](1,49152,null,0,Es,[ca.a,As,pa.a],null,null)],null,null)}var ip=s["\u0275ccf"]("cd-silence-matcher-modal",Es,rp,{},{submitAction:"submitAction"},[]),sp=[Object(ju.h)({height:0,visibility:"hidden"}),Object(ju.e)("400ms cubic-bezier(0.4,0.0,0.2,1)",Object(ju.h)({height:"*",visibility:"visible"}))],op=[Object(ju.h)({height:"*",visibility:"visible"}),Object(ju.e)("400ms cubic-bezier(0.4,0.0,0.2,1)",Object(ju.h)({height:0,visibility:"hidden"}))],up=function(){function t(t,e,n){this._el=t,this._renderer=e,this.collapsed=new s.EventEmitter,this.collapses=new s.EventEmitter,this.expanded=new s.EventEmitter,this.expands=new s.EventEmitter,this.isExpanded=!0,this.isCollapsed=!1,this.isCollapse=!0,this.isCollapsing=!1,this.isAnimated=!1,this._display="block",this._stylesLoaded=!1,this._COLLAPSE_ACTION_NAME="collapse",this._EXPAND_ACTION_NAME="expand",this._factoryCollapseAnimation=n.build(op),this._factoryExpandAnimation=n.build(sp)}return Object.defineProperty(t.prototype,"display",{set:function(t){this.isAnimated?(this._display=t,"none"!==t?this.show():this.hide()):this._renderer.setStyle(this._el.nativeElement,"display",t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"collapse",{get:function(){return this.isExpanded},set:function(t){this.isExpanded=t,this.toggle()},enumerable:!0,configurable:!0}),t.prototype.ngAfterViewChecked=function(){this._stylesLoaded=!0},t.prototype.toggle=function(){this.isExpanded?this.hide():this.show()},t.prototype.hide=function(){var t=this;this.isCollapsing=!0,this.isExpanded=!1,this.isCollapsed=!0,this.isCollapsing=!1,this.collapses.emit(this),this.animationRun(this.isAnimated,this._COLLAPSE_ACTION_NAME)(function(){t.collapsed.emit(t),t._renderer.setStyle(t._el.nativeElement,"display","none")})},t.prototype.show=function(){var t=this;this._renderer.setStyle(this._el.nativeElement,"display",this._display),this.isCollapsing=!0,this.isExpanded=!0,this.isCollapsed=!1,this.isCollapsing=!1,this.expands.emit(this),this.animationRun(this.isAnimated,this._EXPAND_ACTION_NAME)(function(){t.expanded.emit(t)})},t.prototype.animationRun=function(t,e){var n=this;if(!t||!this._stylesLoaded)return function(t){return t()};this._renderer.setStyle(this._el.nativeElement,"overflow","hidden"),this._renderer.addClass(this._el.nativeElement,"collapse");var a=e===this._EXPAND_ACTION_NAME?this._factoryExpandAnimation:this._factoryCollapseAnimation;return this._player&&this._player.destroy(),this._player=a.create(this._el.nativeElement),this._player.play(),function(t){return n._player.onDone(t)}},t}(),cp=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[]}},t}(),lp=function(){function t(t,e){this.summaryService=t,this.taskMessageService=e,this.executingTasks=[],this.finishedTasks=[],this.icon="fa-hourglass-o"}return t.prototype.ngOnInit=function(){var t=this;this.summaryService.subscribe(function(e){e&&(t._handleTasks(e.executing_tasks,e.finished_tasks),t._setIcon(e.executing_tasks.length))})},t.prototype._handleTasks=function(t,e){for(var n=0,a=t;n0?1:0]},t}(),dp=s["\u0275crt"]({encapsulation:0,styles:[[".popover-content{padding:.5em;height:auto;max-height:70vh;overflow-x:hidden} .popover{min-width:276px!important}.separator[_ngcontent-%COMP%]{padding:5px 12px;color:#90949c;background-color:#eee;font-size:12px}.message[_ngcontent-%COMP%]{padding:10px 16px;color:#474544;font-size:12px}table[_ngcontent-%COMP%]{width:252px;margin:5px 12px 5px 5px;font-size:12px;color:#474544}.icon-col[_ngcontent-%COMP%]{width:50px;font-size:10px}.date[_ngcontent-%COMP%]{color:#555}hr[_ngcontent-%COMP%]{margin-top:0;margin-bottom:0}"]],data:{}});function fp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"td",[["class","text-right italic"],["nowrap",""]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](2,null,[""," %"]))],null,function(t,e){t(e,2,0,e.parent.context.$implicit.progress)})}function pp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,18,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,16,"table",[],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,15,"tbody",[],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,7,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,3,"td",[["class","icon-col text-center"],["rowspan","3"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,2,"span",[["class","fa-stack fa-2x text-info"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,0,"i",[["class","fa fa-circle fa-stack-2x"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,0,"i",[["class","fa fa-stack-1x fa-inverse fa-spinner fa-spin"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,2,"td",[["colspan","3"]],null,null,null,null,null)),(t()(),s["\u0275eld"](9,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](10,null,["",""])),(t()(),s["\u0275eld"](11,0,null,null,6,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,3,"td",[["colspan","2"]],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,2,"small",[["class","date"]],null,null,null,null,null)),(t()(),s["\u0275ted"](14,null,["",""])),s["\u0275ppd"](15,1),(t()(),s["\u0275and"](16777216,null,null,1,null,fp)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](18,0,null,null,0,"hr",[],null,null,null,null,null))],function(t,e){t(e,17,0,e.context.$implicit.progress)},function(t,e){t(e,10,0,e.context.$implicit.description);var n=s["\u0275unv"](e,14,0,t(e,15,0,s["\u0275nov"](e.parent.parent.parent,0),e.context.$implicit.begin_time));t(e,14,0,n)})}function hp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"div",[["class","separator"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["EXECUTING"])),(t()(),s["\u0275eld"](3,0,null,null,0,"hr",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,pp)),s["\u0275did"](5,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,5,0,e.component.executingTasks)},null)}function gp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,2,"span",[["class","fa-stack fa-2x text-success"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"i",[["class","fa fa-circle fa-stack-2x"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,0,"i",[["class","fa fa-stack-1x fa-inverse fa-check"]],null,null,null,null,null))],null,null)}function bp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"span",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,2,"span",[["class","fa-stack fa-2x text-danger"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"i",[["class","fa fa-circle fa-stack-2x"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,0,"i",[["class","fa fa-stack-1x fa-inverse fa-exclamation-triangle"]],null,null,null,null,null))],null,null)}function mp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[["class","text-danger"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" "," "]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit.errorMessage)})}function yp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,22,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,20,"table",[],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,19,"tbody",[],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,8,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,4,"td",[["class","icon-col text-center"],["rowspan","3"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,gp)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,bp)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](9,0,null,null,2,"td",[["colspan","2"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](11,null,["",""])),(t()(),s["\u0275eld"](12,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,0,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](14,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,mp)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](17,0,null,null,4,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](18,0,null,null,3,"td",[["colspan","2"]],null,null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,2,"small",[["class","date"]],null,null,null,null,null)),(t()(),s["\u0275ted"](20,null,["",""])),s["\u0275ppd"](21,1),(t()(),s["\u0275eld"](22,0,null,null,0,"hr",[],null,null,null,null,null))],function(t,e){t(e,6,0,!e.context.$implicit.errorMessage),t(e,8,0,e.context.$implicit.errorMessage),t(e,16,0,e.context.$implicit.errorMessage)},function(t,e){t(e,11,0,e.context.$implicit.description);var n=s["\u0275unv"](e,20,0,t(e,21,0,s["\u0275nov"](e.parent.parent.parent,0),e.context.$implicit.end_time));t(e,20,0,n)})}function vp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,5,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"div",[["class","separator"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["FINISHED"])),(t()(),s["\u0275eld"](3,0,null,null,0,"hr",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,yp)),s["\u0275did"](5,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,5,0,e.component.finishedTasks)},null)}function _p(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"div",[["class","message"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["There are no background tasks."]))],null,null)}function xp(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,hp)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,vp)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,_p)),s["\u0275did"](5,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,1,0,n.executingTasks.length>0),t(e,3,0,n.finishedTasks.length>0),t(e,5,0,0===n.executingTasks.length&&0===n.finishedTasks.length)},null)}function Tp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,[" (",")"]))],null,function(t,e){t(e,1,0,e.component.executingTasks.length)})}function wp(t){return s["\u0275vid"](0,[s["\u0275pid"](0,On.a,[i.DatePipe]),(t()(),s["\u0275and"](0,[["popTemplate",2]],null,0,null,xp)),(t()(),s["\u0275eld"](2,16777216,null,null,7,"a",[["container","body"],["outsideClick","true"],["placement","bottom"],["title","Background Tasks"]],null,null,null,null,null)),s["\u0275did"](3,212992,null,0,X.c,[X.a,s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,Q.a],{popover:[0,"popover"],placement:[1,"placement"],outsideClick:[2,"outsideClick"],container:[3,"container"]},null),(t()(),s["\u0275eld"](4,0,null,null,1,"i",[["class","fa fa-fw"]],null,null,null,null,null)),s["\u0275did"](5,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[["class","visible-xs-inline-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Background Tasks"])),(t()(),s["\u0275and"](16777216,null,null,1,null,Tp)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,3,0,s["\u0275nov"](e,1),"bottom","true","body"),t(e,5,0,"fa fa-fw",n.icon),t(e,9,0,n.executingTasks.length>0)},null)}var Sp=function(){function t(t,e){this.alertFormatter=t,this.prometheusService=e,this.backendFailure=!1,this.notifications=[]}return t.prototype.refresh=function(){var t=this;this.backendFailure||this.prometheusService.getNotifications(ft.last(this.notifications)).subscribe(function(e){return t.handleNotifications(e)},function(){return t.backendFailure=!0})},t.prototype.handleNotifications=function(t){var e=this;0!==t.length&&(this.notifications.length>0&&this.alertFormatter.sendNotifications(ft.flatten(t.map(function(t){return e.formatNotification(t)}))),this.notifications=this.notifications.concat(t))},t.prototype.formatNotification=function(t){var e=this;return this.alertFormatter.convertToCustomAlerts(t.alerts).map(function(t){return e.alertFormatter.convertAlertToNotification(t)})},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(Ki),s.inject(Ui))},token:t,providedIn:"root"}),t}(),Op=function(){function t(t,e,n,a,r){this.notificationService=t,this.prometheusNotificationService=e,this.authStorageService=n,this.prometheusAlertService=a,this.ngZone=r,this.notifications=[]}return t.prototype.ngOnDestroy=function(){window.clearInterval(this.interval)},t.prototype.ngOnInit=function(){var t=this;this.authStorageService.getPermissions().prometheus.read&&(this.triggerPrometheusAlerts(),this.ngZone.runOutsideAngular(function(){t.interval=window.setInterval(function(){t.ngZone.run(function(){t.triggerPrometheusAlerts()})},5e3)})),this.notificationService.data$.subscribe(function(e){t.notifications=ft.orderBy(e,["timestamp"],["desc"])})},t.prototype.triggerPrometheusAlerts=function(){this.prometheusAlertService.refresh(),this.prometheusNotificationService.refresh()},t.prototype.removeAll=function(){this.notificationService.removeAll()},t}(),Ip=s["\u0275crt"]({encapsulation:0,styles:[[".popover-content{padding:.5em;height:auto;max-height:70vh;overflow-x:hidden} .popover{min-width:276px!important}.separator[_ngcontent-%COMP%]{padding:5px 12px;color:#90949c;background-color:#eee;font-size:12px}.message[_ngcontent-%COMP%]{padding:10px 16px;color:#474544;font-size:12px}table[_ngcontent-%COMP%]{width:252px;margin:5px 12px 5px 5px;font-size:12px;color:#474544}.icon-col[_ngcontent-%COMP%]{width:50px;font-size:10px}.date[_ngcontent-%COMP%]{color:#555}hr[_ngcontent-%COMP%]{margin-top:0;margin-bottom:0}"]],data:{}});function Cp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,19,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,17,"table",[],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,16,"tbody",[],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,11,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,7,"td",[["class","icon-col text-center"],["rowspan","3"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,6,"span",[],null,null,null,null,null)),s["\u0275did"](6,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngClass:[0,"ngClass"]},null),s["\u0275pad"](7,2),(t()(),s["\u0275eld"](8,0,null,null,0,"i",[["class","fa fa-circle fa-stack-2x"]],null,null,null,null,null)),(t()(),s["\u0275eld"](9,0,null,null,2,"i",[],null,null,null,null,null)),s["\u0275did"](10,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngClass:[0,"ngClass"]},null),s["\u0275pad"](11,2),(t()(),s["\u0275eld"](12,0,null,null,2,"td",[],null,null,null,null,null)),(t()(),s["\u0275eld"](13,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](14,null,["",""])),(t()(),s["\u0275eld"](15,0,null,null,1,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](16,0,null,null,0,"td",[],[[8,"innerHTML",1]],null,null,null,null)),(t()(),s["\u0275eld"](17,0,null,null,1,"tr",[],null,null,null,null,null)),(t()(),s["\u0275eld"](18,0,null,null,0,"td",[],[[8,"innerHTML",1]],null,null,null,null)),(t()(),s["\u0275eld"](19,0,null,null,0,"hr",[],null,null,null,null,null))],function(t,e){var n=t(e,7,0,"fa-stack fa-2x",e.context.$implicit.textClass);t(e,6,0,n);var a=t(e,11,0,"fa fa-stack-1x fa-inverse",e.context.$implicit.iconClass);t(e,10,0,a)},function(t,e){var n=e.component;t(e,14,0,e.context.$implicit.title),t(e,16,0,e.context.$implicit.message),t(e,18,0,n.notificationService.renderTimeAndApplicationHtml(e.context.$implicit))})}function kp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,8,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,4,"button",[["class","btn btn-default btn-sm btn-block"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.removeAll()&&a),a},null,null)),(t()(),s["\u0275eld"](2,0,null,null,0,"i",[["aria-hidden","true"],["class","fa fa-trash-o"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[" \xa0 "])),(t()(),s["\u0275eld"](4,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Remove all"])),(t()(),s["\u0275eld"](6,0,null,null,0,"hr",[],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Cp)),s["\u0275did"](8,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,8,0,e.component.notifications)},null)}function Np(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,kp)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,e.component.notifications.length>0)},null)}function Rp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"div",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,1,"div",[["class","message"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,[" There are no notifications. "]))],null,null)}function Ap(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Rp)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,0===e.component.notifications.length)},null)}function Dp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function Ep(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,0,null,null,null,null,null,null,null))],null,null)}function Lp(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Dp)),s["\u0275did"](1,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Ep)),s["\u0275did"](3,540672,null,0,i.NgTemplateOutlet,[s.ViewContainerRef],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,1,0,s["\u0275nov"](e.parent,0)),t(e,3,0,s["\u0275nov"](e.parent,1))},null)}function Pp(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](0,[["notificationsTpl",2]],null,0,null,Np)),(t()(),s["\u0275and"](0,[["emptyTpl",2]],null,0,null,Ap)),(t()(),s["\u0275and"](0,[["popTpl",2]],null,0,null,Lp)),(t()(),s["\u0275eld"](3,16777216,null,null,4,"a",[["container","body"],["outsideClick","true"],["placement","bottom"],["title","Recent Notifications"]],null,null,null,null,null)),s["\u0275did"](4,212992,null,0,X.c,[X.a,s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,Q.a],{popover:[0,"popover"],placement:[1,"placement"],outsideClick:[2,"outsideClick"],container:[3,"container"]},null),(t()(),s["\u0275eld"](5,0,null,null,0,"i",[["class","fa fa-fw fa-bell"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[["class","visible-xs-inline-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Recent Notifications"]))],function(t,e){t(e,4,0,s["\u0275nov"](e,2),"bottom","true","body")},null)}var Mp=function(){function t(t,e,n){this.summaryService=t,this.cephReleaseNamePipe=e,this.modalService=n}return t.prototype.ngOnInit=function(){var t=this,e=this.summaryService.subscribe(function(n){if(n){var a=t.cephReleaseNamePipe.transform(n.version);t.docsUrl="http://docs.ceph.com/docs/"+a+"/mgr/dashboard/",setTimeout(function(){e.unsubscribe()},0)}})},t.prototype.openAboutModal=function(){this.modalRef=this.modalService.show(Od)},t.prototype.goToApiDocs=function(){this.docsFormElement.nativeElement.submit()},t}(),qp=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function jp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,11,"ul",[["class","dropdown-menu dropdown-menu-right"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,4,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,3,"a",[["class","dropdown-item"],["target","_blank"]],[[8,"href",4]],null,null,null,null)),s["\u0275did"](3,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](4,{disabled:0}),(t()(),s["\u0275ted"](-1,null,["Documentation"])),(t()(),s["\u0275eld"](6,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,1,"a",[["class","dropdown-item"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.goToApiDocs()&&a),a},null,null)),(t()(),s["\u0275ted"](-1,null,["API"])),(t()(),s["\u0275eld"](9,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,1,"a",[["class","dropdown-item"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.openAboutModal()&&a),a},null,null)),(t()(),s["\u0275ted"](-1,null,["About"]))],function(t,e){var n=t(e,4,0,!e.component.docsUrl);t(e,3,0,"dropdown-item",n)},function(t,e){t(e,2,0,s["\u0275inlineInterpolate"](1,"",e.component.docsUrl,""))})}function Fp(t){return s["\u0275vid"](0,[s["\u0275qud"](402653184,1,{docsFormElement:0}),(t()(),s["\u0275eld"](1,0,[[1,0],["docsForm",1]],null,2,"form",[["action","/docs"],["method","post"],["target","_blank"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,1,"input",[["name","token"],["type","hidden"]],null,null,null,null,null)),s["\u0275did"](3,4210688,null,0,we.a,[[2,Se.a],l.a,s.ElementRef],null,null),(t()(),s["\u0275eld"](4,16777216,null,null,10,"div",[["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](6,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),(t()(),s["\u0275eld"](7,0,null,null,5,"a",[["class","dropdown-toggle"],["data-toggle","dropdown"],["dropdownToggle",""],["title","Help"]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,8).onClick()&&a),a},null,null)),s["\u0275did"](8,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-fw fa-question-circle-o"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,1,"span",[["class","visible-xs-inline-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Help"])),(t()(),s["\u0275eld"](12,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,jp)),s["\u0275did"](14,16384,null,0,bn.d,[bn.f,s.ViewContainerRef,s.TemplateRef],null,null)],function(t,e){t(e,6,0)},function(t,e){t(e,4,0,s["\u0275nov"](e,6).dropup,s["\u0275nov"](e,6).isOpen,s["\u0275nov"](e,6).isOpen&&s["\u0275nov"](e,6).isBs4),t(e,7,0,!0,s["\u0275nov"](e,8).isDisabled,s["\u0275nov"](e,8).isOpen)})}var zp=function(){function t(t){this.authStorageService=t,this.userPermission=this.authStorageService.getPermissions().user}return t.prototype.ngOnInit=function(){},t}(),Gp=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Yp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,3,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/user-management"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,2).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](2,671744,null,0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["User management"]))],function(t,e){t(e,2,0,"/user-management")},function(t,e){t(e,1,0,s["\u0275nov"](e,2).target,s["\u0275nov"](e,2).href)})}function Vp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"ul",[["class","dropdown-menu dropdown-menu-right"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Yp)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,2,0,e.component.userPermission.read)},null)}function Hp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,16777216,null,null,10,"div",[["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](2,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),(t()(),s["\u0275eld"](3,0,null,null,5,"a",[["class","dropdown-toggle"],["data-toggle","dropdown"],["dropdownToggle",""],["title","Dashboard Settings"]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,4).onClick()&&a),a},null,null)),s["\u0275did"](4,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275eld"](5,0,null,null,0,"i",[["class","fa fa-fw fa-cog"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[["class","visible-xs-inline-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Dashboard Settings"])),(t()(),s["\u0275eld"](8,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Vp)),s["\u0275did"](10,16384,null,0,bn.d,[bn.f,s.ViewContainerRef,s.TemplateRef],null,null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,2,0)},function(t,e){t(e,0,0,s["\u0275nov"](e,2).dropup,s["\u0275nov"](e,2).isOpen,s["\u0275nov"](e,2).isOpen&&s["\u0275nov"](e,2).isBs4),t(e,3,0,!0,s["\u0275nov"](e,4).isDisabled,s["\u0275nov"](e,4).isOpen)})}function Bp(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Hp)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,1,0,e.component.userPermission.read)},null)}var Up=function(){function t(t,e){this.authStorageService=t,this.authService=e}return t.prototype.ngOnInit=function(){this.username=this.authStorageService.getUsername()},t.prototype.logout=function(){this.authService.logout()},t}(),Wp=s["\u0275crt"]({encapsulation:0,styles:[[""]],data:{}});function Kp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,11,"ul",[["class","dropdown-menu dropdown-menu-right"],["role","menu"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,4,"li",[["class","disabled"],["role","menuitem"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,3,"a",[["class","dropdown-item disabled"],["href","#"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Signed in as "])),(t()(),s["\u0275eld"](4,0,null,null,1,"strong",[],null,null,null,null,null)),(t()(),s["\u0275ted"](5,null,["",""])),(t()(),s["\u0275eld"](6,0,null,null,0,"li",[["class","divider dropdown-divider"]],null,null,null,null,null)),(t()(),s["\u0275eld"](7,0,null,null,4,"li",[["role","menuitem"]],null,null,null,null,null)),(t()(),s["\u0275eld"](8,0,null,null,3,"a",[["class","dropdown-item"]],null,[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==t.component.logout()&&a),a},null,null)),(t()(),s["\u0275eld"](9,0,null,null,0,"i",[["class","fa fa-sign-out fa-fw"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Sign out"]))],null,function(t,e){t(e,5,0,e.component.username)})}function $p(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,16777216,null,null,10,"div",[["dropdown",""]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](2,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),(t()(),s["\u0275eld"](3,0,null,null,5,"a",[["class","dropdown-toggle"],["data-toggle","dropdown"],["dropdownToggle",""],["title","Logged in user"]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,4).onClick()&&a),a},null,null)),s["\u0275did"](4,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275eld"](5,0,null,null,0,"i",[["class","fa fa-fw fa-user"]],null,null,null,null,null)),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[["class","visible-xs-inline-block"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Logged in user"])),(t()(),s["\u0275eld"](8,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Kp)),s["\u0275did"](10,16384,null,0,bn.d,[bn.f,s.ViewContainerRef,s.TemplateRef],null,null)],function(t,e){t(e,2,0)},function(t,e){t(e,0,0,s["\u0275nov"](e,2).dropup,s["\u0275nov"](e,2).isOpen,s["\u0275nov"](e,2).isOpen&&s["\u0275nov"](e,2).isBs4),t(e,3,0,!0,s["\u0275nov"](e,4).isDisabled,s["\u0275nov"](e,4).isOpen)})}var Zp=function(){function t(t,e,n,a,r){this.authStorageService=t,this.prometheusService=e,this.summaryService=n,this.featureToggles=a,this.prometheusAlertService=r,this.isCollapsed=!0,this.isAlertmanagerConfigured=!1,this.isPrometheusConfigured=!1,this.permissions=this.authStorageService.getPermissions(),this.enabledFeature$=this.featureToggles.get()}return t.prototype.ngOnInit=function(){var t=this;this.summaryService.subscribe(function(e){e&&(t.summaryData=e)}),this.permissions.configOpt.read&&(this.prometheusService.ifAlertmanagerConfigured(function(){t.isAlertmanagerConfigured=!0}),this.prometheusService.ifPrometheusConfigured(function(){t.isPrometheusConfigured=!0}))},t.prototype.blockHealthColor=function(){if(this.summaryData&&this.summaryData.rbd_mirroring){if(this.summaryData.rbd_mirroring.errors>0)return{color:"#d9534f"};if(this.summaryData.rbd_mirroring.warnings>0)return{color:"#f0ad4e"}}},t}(),Xp=s["\u0275crt"]({encapsulation:0,styles:[[".navbar-main{margin-bottom:0;background:#374249;border:0;border-radius:0;border-top:4px solid #2b99a8;font-size:1.2em} .navbar-main .navbar-header{display:-webkit-box;display:flex;float:none} .navbar-main .navbar-brand, .navbar-main .navbar-brand:hover{color:#eee;height:auto;margin:15px 0 15px 20px;padding:0;-webkit-align-self:flex-start;align-self:flex-start} .navbar-main .navbar-brand>img{height:25px} .navbar-main .navbar-toggle{margin-left:auto;border:0} .navbar-main .navbar-toggle:focus, .navbar-main .navbar-toggle:hover{background-color:transparent;outline:0} .navbar-main .navbar-toggle .icon-bar{background-color:#eee} .navbar-main .navbar-toggle:focus .icon-bar, .navbar-main .navbar-toggle:hover .icon-bar{box-shadow:0 0 3px #fff} .navbar-main .navbar-collapse{padding:0} .navbar-main .navbar-nav>li>.oa-navbar>[dropdown]>ul>li>.dropdown-item{font-size:12px} .navbar-main .navbar-nav>li>.oa-navbar>[dropdown]>a, .navbar-main .navbar-nav>li>.oa-navbar>a, .navbar-main .navbar-nav>li>a{color:#eee;line-height:1;padding:10px 18px;position:relative;display:block;text-decoration:none} .navbar-main .navbar-nav>li>.oa-navbar>[dropdown]>a:focus, .navbar-main .navbar-nav>li>.oa-navbar>[dropdown]>a:hover, .navbar-main .navbar-nav>li>.oa-navbar>a:focus, .navbar-main .navbar-nav>li>.oa-navbar>a:hover, .navbar-main .navbar-nav>li>a:focus, .navbar-main .navbar-nav>li>a:hover{color:#eee} .navbar-main .navbar-nav>li>.oa-navbar>[dropdown].open>a, .navbar-main .navbar-nav>li>.oa-navbar>[dropdown]>a:hover, .navbar-main .navbar-nav>li>.oa-navbar>a:hover, .navbar-main .navbar-nav>li>a:hover{background-color:#2b99a8} .navbar-main .navbar-nav>li a.dropdown-toggle span.caret{margin-left:5px} .navbar-main .navbar-nav>.open>.oa-navbar>[dropdown]>a, .navbar-main .navbar-nav>.open>.oa-navbar>[dropdown]>a:hover, .navbar-main .navbar-nav>.open>.oa-navbar>a, .navbar-main .navbar-nav>.open>.oa-navbar>a:focus, .navbar-main .navbar-nav>.open>.oa-navbar>a:hover, .navbar-main .navbar-nav>.open>.oa-navbar>li>a:focus, .navbar-main .navbar-nav>.open>a, .navbar-main .navbar-nav>.open>a:focus, .navbar-main .navbar-nav>.open>a:hover{color:#eee;border-color:transparent;background-color:transparent} .navbar-main .navbar-primary>li>a{border:0} .navbar-main .navbar-primary>.active>a, .navbar-main .navbar-primary>.active>a:focus, .navbar-main .navbar-primary>.active>a:hover{color:#eee;background-color:#2b99a8;border:0} .navbar-main .navbar-utility .fa, .navbar-main .navbar-utility a{font-size:1.1em} .navbar-main .navbar-utility>.active>a{color:#eee;background-color:#2b99a8} .navbar-main .navbar-utility>li>.open>a, .navbar-main .navbar-utility>li>.open>a:focus, .navbar-main .navbar-utility>li>.open>a:hover{color:#eee;border-color:transparent;background-color:transparent}@media (min-width:768px){ .navbar-main .navbar-primary>li>a{border-bottom:4px solid transparent} .navbar-main .navbar-primary>.active>a, .navbar-main .navbar-primary>.active>a:focus, .navbar-main .navbar-primary>.active>a:hover{background-color:transparent;border-bottom:4px solid #2b99a8} .navbar-main .navbar-utility{border-bottom:0;font-size:11px;position:absolute;right:0;top:0}}@media (max-width:calc(768px - 1px)){ .navbar-main .navbar-nav{margin:0} .navbar-main .navbar-nav .fa{margin-right:.5em} .navbar-main .navbar-collapse, .navbar-main .navbar-form{border-color:#eee} .navbar-main .navbar-collapse{padding:0} .navbar-main .navbar-nav .open .dropdown-menu{padding-top:0;padding-bottom:0;background-color:#2b99a8} .navbar-main .navbar-nav .open .dropdown-menu .dropdown-header, .navbar-main .navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 35px} .navbar-main .navbar-nav .open .dropdown-menu>li>a{color:#eee} .navbar-main .navbar-nav .open .dropdown-menu>.active>a{color:#eee;background-color:#2b99a8} .navbar-main .navbar-nav>li>a:hover{background-color:#2b99a8} .navbar-main .navbar-utility{border-top:1px solid #eee} .navbar-main .navbar-utility a{font-size:1em} .navbar-main .navbar-primary>.active>a, .navbar-main .navbar-primary>.active>a:focus, .navbar-main .navbar-primary>.active>a:hover{background-color:#2b99a8}}"]],data:{}});function Jp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_hosts"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,5,{links:1}),s["\u0275qud"](603979776,6,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/hosts"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[6,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Hosts"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/hosts")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function Qp(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_cluster_monitor"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,7,{links:1}),s["\u0275qud"](603979776,8,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/monitor/"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[8,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Monitors"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/monitor/")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function th(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_hosts"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,9,{links:1}),s["\u0275qud"](603979776,10,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/osd"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[10,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["OSDs"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/osd")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function eh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_configuration"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,11,{links:1}),s["\u0275qud"](603979776,12,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/configuration"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[12,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Configuration"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/configuration")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function nh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_crush"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,13,{links:1}),s["\u0275qud"](603979776,14,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/crush-map"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[14,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["CRUSH map"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/crush-map")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function ah(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_modules"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,15,{links:1}),s["\u0275qud"](603979776,16,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/mgr-modules"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[16,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Manager modules"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/mgr-modules")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function rh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_log"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,17,{links:1}),s["\u0275qud"](603979776,18,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/logs"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[18,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Logs"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/logs")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function ih(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"small",[["class","badge badge-danger"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.component.prometheusAlertService.alerts.length)})}function sh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,9,"li",[["class","tc_submenuitem tc_submenuitem_monitoring"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,19,{links:1}),s["\u0275qud"](603979776,20,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,5,"a",[["routerLink","/monitoring"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[20,4],[4,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275eld"](6,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Monitoring"])),(t()(),s["\u0275and"](16777216,null,null,1,null,ih)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"active"),t(e,5,0,"/monitoring"),t(e,9,0,n.prometheusAlertService.alerts.length>0)},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function oh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,16,"ul",[["class","dropdown-menu"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Jp)),s["\u0275did"](2,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Qp)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,th)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,eh)),s["\u0275did"](8,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,nh)),s["\u0275did"](10,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ah)),s["\u0275did"](12,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,rh)),s["\u0275did"](14,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,sh)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,2,0,n.permissions.hosts.read),t(e,4,0,n.permissions.monitor.read),t(e,6,0,n.permissions.osd.read),t(e,8,0,n.permissions.configOpt.read),t(e,10,0,n.permissions.hosts.read&&n.permissions.osd.read),t(e,12,0,n.permissions.configOpt.read),t(e,14,0,n.permissions.log.read),t(e,16,0,(n.isAlertmanagerConfigured||n.isPrometheusConfigured)&&n.permissions.prometheus.read)},null)}function uh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,16777216,null,null,12,"li",[["class","dropdown tc_menuitem tc_menuitem_cluster"],["dropdown",""],["routerLinkActive","active"]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](2,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),s["\u0275did"](3,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,3,{links:1}),s["\u0275qud"](603979776,4,{linksWithHrefs:1}),(t()(),s["\u0275eld"](6,0,null,null,4,"a",[["class","dropdown-toggle"],["data-toggle","dropdown"],["dropdownToggle",""]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,7).onClick()&&a),a},null,null)),s["\u0275did"](7,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275eld"](8,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Cluster"])),(t()(),s["\u0275eld"](10,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,oh)),s["\u0275did"](12,16384,null,0,bn.d,[bn.f,s.ViewContainerRef,s.TemplateRef],null,null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,2,0),t(e,3,0,"active")},function(t,e){t(e,0,0,s["\u0275nov"](e,2).dropup,s["\u0275nov"](e,2).isOpen,s["\u0275nov"](e,2).isOpen&&s["\u0275nov"](e,2).isBs4),t(e,6,0,!0,s["\u0275nov"](e,7).isDisabled,s["\u0275nov"](e,7).isOpen)})}function ch(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_menuitem tc_menuitem_pool"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,21,{links:1}),s["\u0275qud"](603979776,22,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["routerLink","/pool"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[22,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Pools"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/pool")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function lh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,25,{links:1}),s["\u0275qud"](603979776,26,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/block/rbd"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[26,4],[24,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Images"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/block/rbd")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function dh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"small",[["class","label label-warning"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["",""]))],null,function(t,e){var n=e.component;t(e,1,0,null==n.summaryData?null:null==n.summaryData.rbd_mirroring?null:n.summaryData.rbd_mirroring.warnings)})}function fh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"small",[["class","label label-danger"]],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["",""]))],null,function(t,e){var n=e.component;t(e,1,0,null==n.summaryData?null:null==n.summaryData.rbd_mirroring?null:n.summaryData.rbd_mirroring.errors)})}function ph(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,11,"li",[["class","tc_submenuitem tc_submenuitem_block_mirroring"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,27,{links:1}),s["\u0275qud"](603979776,28,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,7,"a",[["class","dropdown-item"],["routerLink","/block/mirroring"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[28,4],[24,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275eld"](6,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Mirroring"])),(t()(),s["\u0275and"](16777216,null,null,1,null,dh)),s["\u0275did"](9,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,fh)),s["\u0275did"](11,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=e.component;t(e,1,0,"active"),t(e,5,0,"/block/mirroring"),t(e,9,0,0!==(null==n.summaryData?null:null==n.summaryData.rbd_mirroring?null:n.summaryData.rbd_mirroring.warnings)),t(e,11,0,0!==(null==n.summaryData?null:null==n.summaryData.rbd_mirroring?null:n.summaryData.rbd_mirroring.errors))},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function hh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,29,{links:1}),s["\u0275qud"](603979776,30,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/block/iscsi"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[30,4],[24,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["iSCSI"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/block/iscsi")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function gh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,16777216,null,null,18,"li",[["class","dropdown tc_menuitem tc_menuitem_block"],["dropdown",""],["routerLinkActive","active"]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](2,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),s["\u0275did"](3,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,23,{links:1}),s["\u0275qud"](603979776,24,{linksWithHrefs:1}),(t()(),s["\u0275eld"](6,0,null,null,5,"a",[["class","dropdown-toggle"],["data-toggle","dropdown"],["dropdownToggle",""]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,8).onClick()&&a),a},null,null)),s["\u0275did"](7,278528,null,0,i.NgStyle,[s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngStyle:[0,"ngStyle"]},null),s["\u0275did"](8,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275eld"](9,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Block"])),(t()(),s["\u0275eld"](11,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),s["\u0275eld"](12,0,null,null,6,"ul",[["class","dropdown-menu"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,lh)),s["\u0275did"](14,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ph)),s["\u0275did"](16,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,hh)),s["\u0275did"](18,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){var n=e.component;t(e,2,0),t(e,3,0,"active"),t(e,7,0,n.blockHealthColor()),t(e,14,0,e.parent.context.ngIf.rbd&&n.permissions.rbdImage.read),t(e,16,0,e.parent.context.ngIf.mirroring&&n.permissions.rbdMirroring.read),t(e,18,0,e.parent.context.ngIf.iscsi&&n.permissions.iscsi.read)},function(t,e){t(e,0,0,s["\u0275nov"](e,2).dropup,s["\u0275nov"](e,2).isOpen,s["\u0275nov"](e,2).isOpen&&s["\u0275nov"](e,2).isBs4),t(e,6,0,!0,s["\u0275nov"](e,8).isDisabled,s["\u0275nov"](e,8).isOpen)})}function bh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_menuitem tc_menuitem_nfs"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,31,{links:1}),s["\u0275qud"](603979776,32,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["routerLink","/nfs"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[32,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["NFS"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/nfs")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function mh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","tc_menuitem tc_menuitem_cephs"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](1,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,33,{links:1}),s["\u0275qud"](603979776,34,{linksWithHrefs:1}),(t()(),s["\u0275eld"](4,0,null,null,2,"a",[["routerLink","/cephfs"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,5).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](5,671744,[[34,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Filesystems"]))],function(t,e){t(e,1,0,"active"),t(e,5,0,"/cephfs")},function(t,e){t(e,4,0,s["\u0275nov"](e,5).target,s["\u0275nov"](e,5).href)})}function yh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,21,"ul",[["class","dropdown-menu"]],null,null,null,null,null)),(t()(),s["\u0275eld"](1,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_rgw_daemons"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](2,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,37,{links:1}),s["\u0275qud"](603979776,38,{linksWithHrefs:1}),(t()(),s["\u0275eld"](5,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/rgw/daemon"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,6).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](6,671744,[[38,4],[36,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Daemons"])),(t()(),s["\u0275eld"](8,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_rgw_users"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](9,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,39,{links:1}),s["\u0275qud"](603979776,40,{linksWithHrefs:1}),(t()(),s["\u0275eld"](12,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/rgw/user"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,13).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](13,671744,[[40,4],[36,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Users"])),(t()(),s["\u0275eld"](15,0,null,null,6,"li",[["class","tc_submenuitem tc_submenuitem_rgw_buckets"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](16,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,41,{links:1}),s["\u0275qud"](603979776,42,{linksWithHrefs:1}),(t()(),s["\u0275eld"](19,0,null,null,2,"a",[["class","dropdown-item"],["routerLink","/rgw/bucket"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,20).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](20,671744,[[42,4],[36,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275ted"](-1,null,["Buckets"]))],function(t,e){t(e,2,0,"active"),t(e,6,0,"/rgw/daemon"),t(e,9,0,"active"),t(e,13,0,"/rgw/user"),t(e,16,0,"active"),t(e,20,0,"/rgw/bucket")},function(t,e){t(e,5,0,s["\u0275nov"](e,6).target,s["\u0275nov"](e,6).href),t(e,12,0,s["\u0275nov"](e,13).target,s["\u0275nov"](e,13).href),t(e,19,0,s["\u0275nov"](e,20).target,s["\u0275nov"](e,20).href)})}function vh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,16777216,null,null,12,"li",[["class","dropdown tc_menuitem tc_menuitem_rgw"],["dropdown",""],["routerLinkActive","active"]],[[2,"dropup",null],[2,"open",null],[2,"show",null]],null,null,null,null)),s["\u0275prd"](512,null,bn.f,bn.f,[]),s["\u0275did"](2,212992,null,0,bn.c,[s.ElementRef,s.Renderer2,s.ViewContainerRef,J.a,bn.a,bn.f],null,null),s["\u0275did"](3,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,35,{links:1}),s["\u0275qud"](603979776,36,{linksWithHrefs:1}),(t()(),s["\u0275eld"](6,0,null,null,4,"a",[["class","dropdown-toggle"],["data-toggle","dropdown"],["dropdownToggle",""]],[[1,"aria-haspopup",0],[1,"disabled",0],[1,"aria-expanded",0]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,7).onClick()&&a),a},null,null)),s["\u0275did"](7,147456,null,0,bn.g,[s.ChangeDetectorRef,bn.c,s.ElementRef,s.Renderer2,bn.f],null,null),(t()(),s["\u0275eld"](8,0,null,null,1,null,null,null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Object Gateway"])),(t()(),s["\u0275eld"](10,0,null,null,0,"span",[["class","caret"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,yh)),s["\u0275did"](12,16384,null,0,bn.d,[bn.f,s.ViewContainerRef,s.TemplateRef],null,null),(t()(),s["\u0275and"](0,null,null,0))],function(t,e){t(e,2,0),t(e,3,0,"active")},function(t,e){t(e,0,0,s["\u0275nov"](e,2).dropup,s["\u0275nov"](e,2).isOpen,s["\u0275nov"](e,2).isOpen&&s["\u0275nov"](e,2).isBs4),t(e,6,0,!0,s["\u0275nov"](e,7).isDisabled,s["\u0275nov"](e,7).isOpen)})}function _h(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,44,"div",[["class","collapse navbar-collapse"],["id","bs-example-navbar-collapse-1"]],[[2,"collapse",null],[2,"in",null],[2,"show",null],[1,"aria-expanded",0],[1,"aria-hidden",0],[2,"collapsing",null]],null,null,null,null)),s["\u0275did"](1,8404992,null,0,up,[s.ElementRef,s.Renderer2,ju.b],{collapse:[0,"collapse"]},null),(t()(),s["\u0275eld"](2,0,null,null,23,"ul",[["class","nav navbar-nav navbar-primary"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,10,"li",[["class","tc_menuitem tc_menuitem_dashboard"],["routerLinkActive","active"]],null,null,null,null,null)),s["\u0275did"](4,1720320,null,2,tt.n,[tt.l,s.ElementRef,s.Renderer2,s.ChangeDetectorRef],{routerLinkActive:[0,"routerLinkActive"]},null),s["\u0275qud"](603979776,1,{links:1}),s["\u0275qud"](603979776,2,{linksWithHrefs:1}),(t()(),s["\u0275eld"](7,0,null,null,6,"a",[["routerLink","/dashboard"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,8).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](8,671744,[[2,4]],0,tt.o,[tt.l,tt.a,i.LocationStrategy],{routerLink:[0,"routerLink"]},null),(t()(),s["\u0275eld"](9,0,null,null,2,"i",[["class","fa fa-heartbeat fa-fw"]],null,null,null,null,null)),s["\u0275did"](10,278528,null,0,i.NgStyle,[s.KeyValueDiffers,s.ElementRef,s.Renderer2],{ngStyle:[0,"ngStyle"]},null),s["\u0275ppd"](11,1),(t()(),s["\u0275eld"](12,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Dashboard"])),(t()(),s["\u0275and"](16777216,null,null,1,null,uh)),s["\u0275did"](15,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,ch)),s["\u0275did"](17,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,gh)),s["\u0275did"](19,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,bh)),s["\u0275did"](21,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,mh)),s["\u0275did"](23,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,vh)),s["\u0275did"](25,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](26,0,null,null,18,"ul",[["class","nav navbar-nav navbar-utility"]],null,null,null,null,null)),(t()(),s["\u0275eld"](27,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](28,0,null,null,1,"cd-language-selector",[["class","oa-navbar"]],null,null,null,Ul,zl)),s["\u0275did"](29,114688,null,0,Fl,[Nr.j,ql],null,null),(t()(),s["\u0275eld"](30,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](31,0,null,null,1,"cd-task-manager",[["class","oa-navbar"]],null,null,null,wp,dp)),s["\u0275did"](32,114688,null,0,lp,[je.a,Ou.a],null,null),(t()(),s["\u0275eld"](33,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](34,0,null,null,1,"cd-notifications",[["class","oa-navbar"]],null,null,null,Pp,Ip)),s["\u0275did"](35,245760,null,0,Op,[Jn.a,Sp,l.a,$i,s.NgZone],null,null),(t()(),s["\u0275eld"](36,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](37,0,null,null,1,"cd-dashboard-help",[["class","oa-navbar"]],null,null,null,Fp,qp)),s["\u0275did"](38,114688,null,0,Mp,[je.a,Ge.a,pa.b],null,null),(t()(),s["\u0275eld"](39,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](40,0,null,null,1,"cd-administration",[["class","oa-navbar"]],null,null,null,Bp,Gp)),s["\u0275did"](41,114688,null,0,zp,[l.a],null,null),(t()(),s["\u0275eld"](42,0,null,null,2,"li",[],null,null,null,null,null)),(t()(),s["\u0275eld"](43,0,null,null,1,"cd-identity",[["class","oa-navbar"]],null,null,null,$p,Wp)),s["\u0275did"](44,114688,null,0,Up,[l.a,$l.a],null,null)],function(t,e){var n=e.component;t(e,1,0,n.isCollapsed),t(e,4,0,"active"),t(e,8,0,"/dashboard");var a=s["\u0275unv"](e,10,0,t(e,11,0,s["\u0275nov"](e.parent,0),null==n.summaryData?null:n.summaryData.health_status));t(e,10,0,a),t(e,15,0,n.permissions.hosts.read||n.permissions.monitor.read||n.permissions.osd.read||n.permissions.configOpt.read),t(e,17,0,n.permissions.pool.read),t(e,19,0,(e.context.ngIf.rbd||e.context.ngIf.mirroring||e.context.ngIf.iscsi)&&(n.permissions.rbdImage.read||n.permissions.rbdMirroring.read||n.permissions.iscsi.read)),t(e,21,0,null==n.permissions?null:null==n.permissions.nfs?null:n.permissions.nfs.read),t(e,23,0,e.context.ngIf.cephfs&&n.permissions.cephfs.read),t(e,25,0,e.context.ngIf.rgw&&n.permissions.rgw.read),t(e,29,0),t(e,32,0),t(e,35,0),t(e,38,0),t(e,41,0),t(e,44,0)},function(t,e){t(e,0,0,s["\u0275nov"](e,1).isCollapse,s["\u0275nov"](e,1).isExpanded,s["\u0275nov"](e,1).isExpanded,s["\u0275nov"](e,1).isExpanded,s["\u0275nov"](e,1).isCollapsed,s["\u0275nov"](e,1).isCollapsing),t(e,7,0,s["\u0275nov"](e,8).target,s["\u0275nov"](e,8).href)})}function xh(t){return s["\u0275vid"](0,[s["\u0275pid"](0,vt,[]),(t()(),s["\u0275eld"](1,0,null,null,12,"nav",[["class","navbar navbar-default navbar-main"]],null,null,null,null,null)),(t()(),s["\u0275eld"](2,0,null,null,8,"div",[["class","navbar-header tc_logo_component"]],null,null,null,null,null)),(t()(),s["\u0275eld"](3,0,null,null,1,"a",[["class","navbar-brand"],["href","#"]],null,null,null,null,null)),(t()(),s["\u0275eld"](4,0,null,null,0,"img",[["alt","Ceph"],["src","assets/Ceph_Logo_Standard_RGB_White_120411_fa.png"]],null,null,null,null,null)),(t()(),s["\u0275eld"](5,0,null,null,5,"button",[["class","navbar-toggle collapsed"],["type","button"]],null,[[null,"click"]],function(t,e,n){var a=!0,r=t.component;return"click"===e&&(a=0!=(r.isCollapsed=!r.isCollapsed)&&a),a},null,null)),(t()(),s["\u0275eld"](6,0,null,null,1,"span",[["class","sr-only"]],null,null,null,null,null)),(t()(),s["\u0275ted"](-1,null,["Toggle navigation"])),(t()(),s["\u0275eld"](8,0,null,null,0,"span",[["class","icon-bar"]],null,null,null,null,null)),(t()(),s["\u0275eld"](9,0,null,null,0,"span",[["class","icon-bar"]],null,null,null,null,null)),(t()(),s["\u0275eld"](10,0,null,null,0,"span",[["class","icon-bar"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,2,null,_h)),s["\u0275did"](12,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),s["\u0275pid"](131072,i.AsyncPipe,[s.ChangeDetectorRef])],function(t,e){var n=e.component;t(e,12,0,s["\u0275unv"](e,12,0,s["\u0275nov"](e,13).transform(n.enabledFeature$)))},null)}var Th=n("ou9H"),wh=n("P6uZ"),Sh=n("wbK0"),Oh=function(){function t(){}return t.prototype.resolve=function(t){var e=t.routeConfig.data,n=null===e.path?null:this.getFullPath(t),a=[{text:"string"==typeof e.breadcrumbs?e.breadcrumbs:e.breadcrumbs.text||e.text||n,path:n}];return Object(gc.a)(a)},t.prototype.getFullPath=function(t){return t.pathFromRoot.reduce(function(t,e){return t+e.url.reduce(function(t,e){return t+"/"+e.path},"")},"")},t}(),Ih=function(){function t(t,e){var n=this;this.router=t,this.injector=e,this.crumbs=[],this.defaultResolver=new Oh,this.subscription=this.router.events.pipe(Object(Vu.a)(function(t){return t instanceof tt.d})).subscribe(function(){n._resolveCrumbs(t.routerState.snapshot.root).pipe(Object(Yu.a)(function(t){return t}),Object(Th.a)(function(t){return t.text}),Object(Hu.a)(),Object(Yu.a)(function(t){var e=n.postProcess(t);return n.wrapIntoObservable(e).pipe(Object(wh.a)())})).subscribe(function(t){n.crumbs=t})})}return t.prototype.ngOnDestroy=function(){this.subscription.unsubscribe()},t.prototype._resolveCrumbs=function(t){var e,n=t.routeConfig&&t.routeConfig.data;if(n&&n.breadcrumbs){var a=(n.breadcrumbs.prototype instanceof Oh?this.injector.get(n.breadcrumbs):this.defaultResolver).resolve(t);e=this.wrapIntoObservable(a).pipe(Object(wh.a)())}else e=Object(gc.a)([]);return t.firstChild&&(e=e.pipe(Object(Sh.a)(this._resolveCrumbs(t.firstChild)))),e},t.prototype.postProcess=function(t){var e=[];return t.forEach(function(t){var n=t.text.split("/");if(n.length>1){t.text=n[n.length-1];for(var a=0;a li[_ngcontent-%COMP%] + li[_ngcontent-%COMP%]:before{padding:0 5px 0 7px;color:#474544;font-family:ForkAwesome;content:'\\f101'}.breadcrumb[_ngcontent-%COMP%] > li[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{color:#474544}"]],data:{}});function kh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"a",[["preserveFragment",""]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(t,e,n){var a=!0;return"click"===e&&(a=!1!==s["\u0275nov"](t,1).onClick(n.button,n.ctrlKey,n.metaKey,n.shiftKey)&&a),a},null,null)),s["\u0275did"](1,671744,null,0,tt.o,[tt.l,tt.a,i.LocationStrategy],{preserveFragment:[0,"preserveFragment"],routerLink:[1,"routerLink"]},null),(t()(),s["\u0275ted"](2,null,["",""]))],function(t,e){t(e,1,0,"",e.parent.context.$implicit.path)},function(t,e){t(e,0,0,s["\u0275nov"](e,1).target,s["\u0275nov"](e,1).href),t(e,2,0,e.parent.context.$implicit.text)})}function Nh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"span",[],null,null,null,null,null)),(t()(),s["\u0275ted"](1,null,["",""]))],null,function(t,e){t(e,1,0,e.parent.context.$implicit.text)})}function Rh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,6,"li",[["class","breadcrumb-item"]],null,null,null,null,null)),s["\u0275did"](1,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](2,{active:0}),(t()(),s["\u0275and"](16777216,null,null,1,null,kh)),s["\u0275did"](4,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275and"](16777216,null,null,1,null,Nh)),s["\u0275did"](6,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){var n=t(e,2,0,e.context.last);t(e,1,0,"breadcrumb-item",n),t(e,4,0,!e.context.last&&null!==e.context.$implicit.path),t(e,6,0,e.context.last||null===e.context.$implicit.path)},null)}function Ah(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"ol",[["class","breadcrumb"]],null,null,null,null,null)),(t()(),s["\u0275and"](16777216,null,null,1,null,Rh)),s["\u0275did"](2,278528,null,0,i.NgForOf,[s.ViewContainerRef,s.TemplateRef,s.IterableDiffers],{ngForOf:[0,"ngForOf"]},null)],function(t,e){t(e,2,0,e.component.crumbs)},null)}function Dh(t){return s["\u0275vid"](0,[(t()(),s["\u0275and"](16777216,null,null,1,null,Ah)),s["\u0275did"](1,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null)],function(t,e){t(e,1,0,e.component.crumbs.length)},null)}var Eh=s["\u0275crt"]({encapsulation:0,styles:[[".dashboard[_ngcontent-%COMP%]{background-color:#f5f5f5;margin:0;padding:0} #toast-container{margin-top:2vw}@media (max-width:1600px){ #toast-container{margin-top:2.5vw}}@media (max-width:calc(992px - 1px)){ #toast-container{margin-top:9vw}}@media (max-width:900px){ #toast-container{margin-top:10vw}}@media (max-width:319px){ #toast-container{margin-top:11vw}}@media (max-width:260px){ #toast-container{margin-top:14vw}}"]],data:{}});function Lh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,1,"cd-navigation",[],null,null,null,xh,Xp)),s["\u0275did"](1,114688,null,0,Zp,[l.a,Ui,je.a,At.a,$i],null,null)],function(t,e){t(e,1,0)},null)}function Ph(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,12,"block-ui",[],null,null,null,I,O)),s["\u0275did"](1,114688,null,0,y,[m],null,null),(t()(),s["\u0275and"](16777216,null,0,1,null,Lh)),s["\u0275did"](3,16384,null,0,i.NgIf,[s.ViewContainerRef,s.TemplateRef],{ngIf:[0,"ngIf"]},null),(t()(),s["\u0275eld"](4,0,null,0,6,"div",[["class","container-fluid"]],null,null,null,null,null)),s["\u0275did"](5,278528,null,0,i.NgClass,[s.IterableDiffers,s.KeyValueDiffers,s.ElementRef,s.Renderer2],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s["\u0275pod"](6,{"full-height":0,dashboard:1}),(t()(),s["\u0275eld"](7,0,null,null,1,"cd-breadcrumbs",[],null,null,null,Dh,Ch)),s["\u0275did"](8,180224,null,0,Ih,[tt.l,s.Injector],null,null),(t()(),s["\u0275eld"](9,16777216,null,null,1,"router-outlet",[],null,null,null,null,null)),s["\u0275did"](10,212992,null,0,tt.q,[tt.b,s.ViewContainerRef,s.ComponentFactoryResolver,[8,null],s.ChangeDetectorRef],null,null),(t()(),s["\u0275eld"](11,0,null,0,1,"block-ui",[],null,null,null,I,O)),s["\u0275did"](12,114688,null,0,y,[m],null,null)],function(t,e){var n=e.component;t(e,1,0),t(e,3,0,!n.isLoginActive());var a=t(e,6,0,n.isLoginActive(),n.isDashboardPage());t(e,5,0,"container-fluid",a),t(e,10,0),t(e,12,0)},null)}function Mh(t){return s["\u0275vid"](0,[(t()(),s["\u0275eld"](0,0,null,null,2,"cd-root",[],null,null,null,Ph,Eh)),s["\u0275prd"](5120,null,c.a,d,[]),s["\u0275did"](2,49152,null,0,f,[l.a,tt.l],null,null)],null,null)}var qh=s["\u0275ccf"]("cd-root",f,Mh,{},{},[]),jh=n("XlPw"),Fh=n("9Z1F"),zh=function(){function t(t,e,n){this.router=t,this.authStorageService=e,this.notificationService=n}return t.prototype.intercept=function(t,e){var n=this;return e.handle(t).pipe(Object(Fh.a)(function(t){if(t instanceof kt.f){var e;switch(t.status){case 400:var a=new Cu.a,r=t.error.task;ft.isPlainObject(r)?(r.metadata.component=r.metadata.component||t.error.component,a.name=r.name,a.metadata=r.metadata):a.metadata=t.error,a.success=!1,a.exception=t.error,e=n.notificationService.notifyTask(a);break;case 401:n.authStorageService.remove(),n.router.navigate(["/login"]);break;case 403:n.router.navigate(["/403"]);break;default:e=n.prepareNotification(t)}t.preventDefault=function(){n.notificationService.cancel(e)},t.ignoreStatusCode=function(t){this.status===t&&this.preventDefault()}}return Object(jh.a)(t)}))},t.prototype.prepareNotification=function(t){return this.notificationService.show(function(){var e="";return ft.isPlainObject(t.error)&&ft.isString(t.error.detail)?e=t.error.detail:ft.isString(t.error)?e=t.error:ft.isString(t.message)&&(e=t.message),new Wi.b(Xn.a.error,t.status+" - "+t.statusText,e,void 0,t.application)})},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(tt.l),s.inject(l.a),s.inject(Jn.a))},token:t,providedIn:"root"}),t}();function Gh(){return"undefined"!=typeof process}function Yh(t){switch(t.length){case 0:return new ju.d;case 1:return t[0];default:return new ju.k(t)}}function Vh(t,e,n,a,r,i){void 0===r&&(r={}),void 0===i&&(i={});var s=[],o=[],u=-1,c=null;if(a.forEach(function(t){var n=t.offset,a=n==u,l=a&&c||{};Object.keys(t).forEach(function(n){var a=n,o=t[n];if("offset"!==n)switch(a=e.normalizePropertyName(a,s),o){case ju.l:o=r[n];break;case ju.a:o=i[n];break;default:o=e.normalizeStyleValue(n,a,o,s)}l[a]=o}),a||o.push(l),c=l,u=n}),s.length)throw new Error("Unable to animate due to the following errors:\n - "+s.join("\n - "));return o}function Hh(t,e,n,a){switch(e){case"start":t.onStart(function(){return a(n&&Bh(n,"start",t))});break;case"done":t.onDone(function(){return a(n&&Bh(n,"done",t))});break;case"destroy":t.onDestroy(function(){return a(n&&Bh(n,"destroy",t))})}}function Bh(t,e,n){var a=n.totalTime,r=Uh(t.element,t.triggerName,t.fromState,t.toState,e||t.phaseName,null==a?t.totalTime:a,!!n.disabled),i=t._data;return null!=i&&(r._data=i),r}function Uh(t,e,n,a,r,i,s){return void 0===r&&(r=""),void 0===i&&(i=0),{element:t,triggerName:e,fromState:n,toState:a,phaseName:r,totalTime:i,disabled:!!s}}function Wh(t,e,n){var a;return t instanceof Map?(a=t.get(e))||t.set(e,a=n):(a=t[e])||(a=t[e]=n),a}function Kh(t){var e=t.indexOf(":");return[t.substring(1,e),t.substr(e+1)]}var $h=function(t,e){return!1},Zh=function(t,e){return!1},Xh=function(t,e,n){return[]},Jh=Gh();if(Jh||"undefined"!=typeof Element){if($h=function(t,e){return t.contains(e)},Jh||Element.prototype.matches)Zh=function(t,e){return t.matches(e)};else{var Qh=Element.prototype,tg=Qh.matchesSelector||Qh.mozMatchesSelector||Qh.msMatchesSelector||Qh.oMatchesSelector||Qh.webkitMatchesSelector;tg&&(Zh=function(t,e){return tg.apply(t,[e])})}Xh=function(t,e,n){var a=[];if(n)a.push.apply(a,Object(p.__spread)(t.querySelectorAll(e)));else{var r=t.querySelector(e);r&&a.push(r)}return a}}var eg=null,ng=!1;function ag(t){eg||(eg=("undefined"!=typeof document?document.body:null)||{},ng=!!eg.style&&"WebkitAppearance"in eg.style);var e=!0;return eg.style&&!function(t){return"ebkit"==t.substring(1,6)}(t)&&!(e=t in eg.style)&&ng&&(e="Webkit"+t.charAt(0).toUpperCase()+t.substr(1)in eg.style),e}var rg=Zh,ig=$h,sg=Xh;function og(t){var e={};return Object.keys(t).forEach(function(n){var a=n.replace(/([a-z])([A-Z])/g,"$1-$2");e[a]=t[n]}),e}var ug=function(){function t(){}return t.prototype.validateStyleProperty=function(t){return ag(t)},t.prototype.matchesElement=function(t,e){return rg(t,e)},t.prototype.containsElement=function(t,e){return ig(t,e)},t.prototype.query=function(t,e,n){return sg(t,e,n)},t.prototype.computeStyle=function(t,e,n){return n||""},t.prototype.animate=function(t,e,n,a,r,i,s){return void 0===i&&(i=[]),new ju.d(n,a)},t}(),cg=function(){function t(){}return t.NOOP=new ug,t}(),lg=1e3;function dg(t){if("number"==typeof t)return t;var e=t.match(/^(-?[\.\d]+)(m?s)/);return!e||e.length<2?0:fg(parseFloat(e[1]),e[2])}function fg(t,e){switch(e){case"s":return t*lg;default:return t}}function pg(t,e,n){return t.hasOwnProperty("duration")?t:function(t,e,n){var a,r=0,i="";if("string"==typeof t){var s=t.match(/^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i);if(null===s)return e.push('The provided timing value "'+t+'" is invalid.'),{duration:0,delay:0,easing:""};a=fg(parseFloat(s[1]),s[2]);var o=s[3];null!=o&&(r=fg(parseFloat(o),s[4]));var u=s[5];u&&(i=u)}else a=t;if(!n){var c=!1,l=e.length;a<0&&(e.push("Duration values below 0 are not allowed for this animation step."),c=!0),r<0&&(e.push("Delay values below 0 are not allowed for this animation step."),c=!0),c&&e.splice(l,0,'The provided timing value "'+t+'" is invalid.')}return{duration:a,delay:r,easing:i}}(t,e,n)}function hg(t,e){return void 0===e&&(e={}),Object.keys(t).forEach(function(n){e[n]=t[n]}),e}function gg(t,e,n){if(void 0===n&&(n={}),e)for(var a in t)n[a]=t[a];else hg(t,n);return n}function bg(t,e,n){return n?e+":"+n+";":""}function mg(t){for(var e="",n=0;n *";case":leave":return"* => void";case":increment":return function(t,e){return parseFloat(e)>parseFloat(t)};case":decrement":return function(t,e){return parseFloat(e) *"}}(t,n);if("function"==typeof a)return void e.push(a);t=a}var r=t.match(/^(\*|[-\w]+)\s*()\s*(\*|[-\w]+)$/);if(null==r||r.length<4)return n.push('The provided transition expression "'+t+'" is not supported'),e;var i=r[1],s=r[2],o=r[3];e.push(Lg(i,o)),"<"!=s[0]||i==Ag&&o==Ag||e.push(Lg(o,i))}(t,r,a)}):r.push(n),r),animation:i,queryCount:e.queryCount,depCount:e.depCount,options:zg(t.options)}},t.prototype.visitSequence=function(t,e){var n=this;return{type:2,steps:t.steps.map(function(t){return Ng(n,t,e)}),options:zg(t.options)}},t.prototype.visitGroup=function(t,e){var n=this,a=e.currentTime,r=0,i=t.steps.map(function(t){e.currentTime=a;var i=Ng(n,t,e);return r=Math.max(r,e.currentTime),i});return e.currentTime=r,{type:3,steps:i,options:zg(t.options)}},t.prototype.visitAnimate=function(t,e){var n,a=function(t,e){var n=null;if(t.hasOwnProperty("duration"))n=t;else if("number"==typeof t)return Gg(pg(t,e).duration,0,"");var a=t;if(a.split(/\s+/).some(function(t){return"{"==t.charAt(0)&&"{"==t.charAt(1)})){var r=Gg(0,0,"");return r.dynamic=!0,r.strValue=a,r}return Gg((n=n||pg(a,e)).duration,n.delay,n.easing)}(t.timings,e.errors);e.currentAnimateTimings=a;var r=t.styles?t.styles:Object(ju.h)({});if(5==r.type)n=this.visitKeyframes(r,e);else{var i=t.styles,s=!1;if(!i){s=!0;var o={};a.easing&&(o.easing=a.easing),i=Object(ju.h)(o)}e.currentTime+=a.duration+a.delay;var u=this.visitStyle(i,e);u.isEmptyStep=s,n=u}return e.currentAnimateTimings=null,{type:4,timings:a,style:n,options:null}},t.prototype.visitStyle=function(t,e){var n=this._makeStyleAst(t,e);return this._validateStyleAst(n,e),n},t.prototype._makeStyleAst=function(t,e){var n=[];Array.isArray(t.styles)?t.styles.forEach(function(t){"string"==typeof t?t==ju.a?n.push(t):e.errors.push("The provided style string value "+t+" is not allowed."):n.push(t)}):n.push(t.styles);var a=!1,r=null;return n.forEach(function(t){if(Fg(t)){var e=t,n=e.easing;if(n&&(r=n,delete e.easing),!a)for(var i in e)if(e[i].toString().indexOf("{{")>=0){a=!0;break}}}),{type:6,styles:n,easing:r,offset:t.offset,containsDynamicStyles:a,options:null}},t.prototype._validateStyleAst=function(t,e){var n=this,a=e.currentAnimateTimings,r=e.currentTime,i=e.currentTime;a&&i>0&&(i-=a.duration+a.delay),t.styles.forEach(function(t){"string"!=typeof t&&Object.keys(t).forEach(function(a){if(n._driver.validateStyleProperty(a)){var s,o,u,c=e.collectedStyles[e.currentQuerySelector],l=c[a],d=!0;l&&(i!=r&&i>=l.startTime&&r<=l.endTime&&(e.errors.push('The CSS property "'+a+'" that exists between the times of "'+l.startTime+'ms" and "'+l.endTime+'ms" is also being animated in a parallel animation between the times of "'+i+'ms" and "'+r+'ms"'),d=!1),i=l.startTime),d&&(c[a]={startTime:i,endTime:r}),e.options&&(s=e.errors,o=e.options.params||{},(u=Tg(t[a])).length&&u.forEach(function(t){o.hasOwnProperty(t)||s.push("Unable to resolve the local animation param "+t+" in the given list of values")}))}else e.errors.push('The provided animation property "'+a+'" is not a supported CSS property for animations')})})},t.prototype.visitKeyframes=function(t,e){var n=this,a={type:5,styles:[],options:null};if(!e.currentAnimateTimings)return e.errors.push("keyframes() must be placed inside of a call to animate()"),a;var r=0,i=[],s=!1,o=!1,u=0,c=t.steps.map(function(t){var a=n._makeStyleAst(t,e),c=null!=a.offset?a.offset:function(t){if("string"==typeof t)return null;var e=null;if(Array.isArray(t))t.forEach(function(t){if(Fg(t)&&t.hasOwnProperty("offset")){var n=t;e=parseFloat(n.offset),delete n.offset}});else if(Fg(t)&&t.hasOwnProperty("offset")){var n=t;e=parseFloat(n.offset),delete n.offset}return e}(a.styles),l=0;return null!=c&&(r++,l=a.offset=c),o=o||l<0||l>1,s=s||l0&&r0?r==f?1:d*r:i[r],o=s*g;e.currentTime=p+h.delay+o,h.duration=o,n._validateStyleAst(t,e),t.offset=s,a.styles.push(t)}),a},t.prototype.visitReference=function(t,e){return{type:8,animation:Ng(this,_g(t.animation),e),options:zg(t.options)}},t.prototype.visitAnimateChild=function(t,e){return e.depCount++,{type:9,options:zg(t.options)}},t.prototype.visitAnimateRef=function(t,e){return{type:10,animation:this.visitReference(t.animation,e),options:zg(t.options)}},t.prototype.visitQuery=function(t,e){var n=e.currentQuerySelector,a=t.options||{};e.queryCount++,e.currentQuery=t;var r=Object(p.__read)(function(t){var e=!!t.split(/\s*,\s*/).find(function(t){return":self"==t});return e&&(t=t.replace(Pg,"")),[t=t.replace(/@\*/g,".ng-trigger").replace(/@\w+/g,function(t){return".ng-trigger-"+t.substr(1)}).replace(/:animating/g,".ng-animating"),e]}(t.selector),2),i=r[0],s=r[1];e.currentQuerySelector=n.length?n+" "+i:i,Wh(e.collectedStyles,e.currentQuerySelector,{});var o=Ng(this,_g(t.animation),e);return e.currentQuery=null,e.currentQuerySelector=n,{type:11,selector:i,limit:a.limit||0,optional:!!a.optional,includeSelf:s,animation:o,originalSelector:t.selector,options:zg(t.options)}},t.prototype.visitStagger=function(t,e){e.currentQuery||e.errors.push("stagger() can only be used inside of query()");var n="full"===t.timings?{duration:0,delay:0,easing:"full"}:pg(t.timings,e.errors,!0);return{type:12,animation:Ng(this,_g(t.animation),e),timings:n,options:null}},t}(),jg=function(){return function(t){this.errors=t,this.queryCount=0,this.depCount=0,this.currentTransition=null,this.currentQuery=null,this.currentQuerySelector=null,this.currentAnimateTimings=null,this.currentTime=0,this.collectedStyles={},this.options=null}}();function Fg(t){return!Array.isArray(t)&&"object"==typeof t}function zg(t){var e;return t?(t=hg(t)).params&&(t.params=(e=t.params)?hg(e):null):t={},t}function Gg(t,e,n){return{duration:t,delay:e,easing:n}}function Yg(t,e,n,a,r,i,s,o){return void 0===s&&(s=null),void 0===o&&(o=!1),{type:1,element:t,keyframes:e,preStyleProps:n,postStyleProps:a,duration:r,delay:i,totalTime:r+i,easing:s,subTimeline:o}}var Vg=function(){function t(){this._map=new Map}return t.prototype.consume=function(t){var e=this._map.get(t);return e?this._map.delete(t):e=[],e},t.prototype.append=function(t,e){var n=this._map.get(t);n||this._map.set(t,n=[]),n.push.apply(n,Object(p.__spread)(e))},t.prototype.has=function(t){return this._map.has(t)},t.prototype.clear=function(){this._map.clear()},t}(),Hg=new RegExp(":enter","g"),Bg=new RegExp(":leave","g");function Ug(t,e,n,a,r,i,s,o,u,c){return void 0===i&&(i={}),void 0===s&&(s={}),void 0===c&&(c=[]),(new Wg).buildKeyframes(t,e,n,a,r,i,s,o,u,c)}var Wg=function(){function t(){}return t.prototype.buildKeyframes=function(t,e,n,a,r,i,s,o,u,c){void 0===c&&(c=[]),u=u||new Vg;var l=new $g(t,e,u,a,r,c,[]);l.options=o,l.currentTimeline.setStyles([i],null,l.errors,o),Ng(this,n,l);var d=l.timelines.filter(function(t){return t.containsAnimation()});if(d.length&&Object.keys(s).length){var f=d[d.length-1];f.allowOnlyTimelineStyles()||f.setStyles([s],null,l.errors,o)}return d.length?d.map(function(t){return t.buildKeyframes()}):[Yg(e,[],[],[],0,0,"",!1)]},t.prototype.visitTrigger=function(t,e){},t.prototype.visitState=function(t,e){},t.prototype.visitTransition=function(t,e){},t.prototype.visitAnimateChild=function(t,e){var n=e.subInstructions.consume(e.element);if(n){var a=e.createSubContext(t.options),r=e.currentTimeline.currentTime,i=this._visitSubInstructions(n,a,a.options);r!=i&&e.transformIntoNewTimeline(i)}e.previousNode=t},t.prototype.visitAnimateRef=function(t,e){var n=e.createSubContext(t.options);n.transformIntoNewTimeline(),this.visitReference(t.animation,n),e.transformIntoNewTimeline(n.currentTimeline.currentTime),e.previousNode=t},t.prototype._visitSubInstructions=function(t,e,n){var a=e.currentTimeline.currentTime,r=null!=n.duration?dg(n.duration):null,i=null!=n.delay?dg(n.delay):null;return 0!==r&&t.forEach(function(t){var n=e.appendInstructionToTimeline(t,r,i);a=Math.max(a,n.duration+n.delay)}),a},t.prototype.visitReference=function(t,e){e.updateOptions(t.options,!0),Ng(this,t.animation,e),e.previousNode=t},t.prototype.visitSequence=function(t,e){var n=this,a=e.subContextCount,r=e,i=t.options;if(i&&(i.params||i.delay)&&((r=e.createSubContext(i)).transformIntoNewTimeline(),null!=i.delay)){6==r.previousNode.type&&(r.currentTimeline.snapshotCurrentStyles(),r.previousNode=Kg);var s=dg(i.delay);r.delayNextStep(s)}t.steps.length&&(t.steps.forEach(function(t){return Ng(n,t,r)}),r.currentTimeline.applyStylesToKeyframe(),r.subContextCount>a&&r.transformIntoNewTimeline()),e.previousNode=t},t.prototype.visitGroup=function(t,e){var n=this,a=[],r=e.currentTimeline.currentTime,i=t.options&&t.options.delay?dg(t.options.delay):0;t.steps.forEach(function(s){var o=e.createSubContext(t.options);i&&o.delayNextStep(i),Ng(n,s,o),r=Math.max(r,o.currentTimeline.currentTime),a.push(o.currentTimeline)}),a.forEach(function(t){return e.currentTimeline.mergeTimelineCollectedStyles(t)}),e.transformIntoNewTimeline(r),e.previousNode=t},t.prototype._visitTiming=function(t,e){if(t.dynamic){var n=t.strValue;return pg(e.params?wg(n,e.params,e.errors):n,e.errors)}return{duration:t.duration,delay:t.delay,easing:t.easing}},t.prototype.visitAnimate=function(t,e){var n=e.currentAnimateTimings=this._visitTiming(t.timings,e),a=e.currentTimeline;n.delay&&(e.incrementTime(n.delay),a.snapshotCurrentStyles());var r=t.style;5==r.type?this.visitKeyframes(r,e):(e.incrementTime(n.duration),this.visitStyle(r,e),a.applyStylesToKeyframe()),e.currentAnimateTimings=null,e.previousNode=t},t.prototype.visitStyle=function(t,e){var n=e.currentTimeline,a=e.currentAnimateTimings;!a&&n.getCurrentStyleProperties().length&&n.forwardFrame();var r=a&&a.easing||t.easing;t.isEmptyStep?n.applyEmptyStep(r):n.setStyles(t.styles,r,e.errors,e.options),e.previousNode=t},t.prototype.visitKeyframes=function(t,e){var n=e.currentAnimateTimings,a=e.currentTimeline.duration,r=n.duration,i=e.createSubContext().currentTimeline;i.easing=n.easing,t.styles.forEach(function(t){i.forwardTime((t.offset||0)*r),i.setStyles(t.styles,t.easing,e.errors,e.options),i.applyStylesToKeyframe()}),e.currentTimeline.mergeTimelineCollectedStyles(i),e.transformIntoNewTimeline(a+r),e.previousNode=t},t.prototype.visitQuery=function(t,e){var n=this,a=e.currentTimeline.currentTime,r=t.options||{},i=r.delay?dg(r.delay):0;i&&(6===e.previousNode.type||0==a&&e.currentTimeline.getCurrentStyleProperties().length)&&(e.currentTimeline.snapshotCurrentStyles(),e.previousNode=Kg);var s=a,o=e.invokeQuery(t.selector,t.originalSelector,t.limit,t.includeSelf,!!r.optional,e.errors);e.currentQueryTotal=o.length;var u=null;o.forEach(function(a,r){e.currentQueryIndex=r;var o=e.createSubContext(t.options,a);i&&o.delayNextStep(i),a===e.element&&(u=o.currentTimeline),Ng(n,t.animation,o),o.currentTimeline.applyStylesToKeyframe(),s=Math.max(s,o.currentTimeline.currentTime)}),e.currentQueryIndex=0,e.currentQueryTotal=0,e.transformIntoNewTimeline(s),u&&(e.currentTimeline.mergeTimelineCollectedStyles(u),e.currentTimeline.snapshotCurrentStyles()),e.previousNode=t},t.prototype.visitStagger=function(t,e){var n=e.parentContext,a=e.currentTimeline,r=t.timings,i=Math.abs(r.duration),s=i*(e.currentQueryTotal-1),o=i*e.currentQueryIndex;switch(r.duration<0?"reverse":r.easing){case"reverse":o=s-o;break;case"full":o=n.currentStaggerTime}var u=e.currentTimeline;o&&u.delayNextStep(o);var c=u.currentTime;Ng(this,t.animation,e),e.previousNode=t,n.currentStaggerTime=a.currentTime-c+(a.startTime-n.currentTimeline.startTime)},t}(),Kg={},$g=function(){function t(t,e,n,a,r,i,s,o){this._driver=t,this.element=e,this.subInstructions=n,this._enterClassName=a,this._leaveClassName=r,this.errors=i,this.timelines=s,this.parentContext=null,this.currentAnimateTimings=null,this.previousNode=Kg,this.subContextCount=0,this.options={},this.currentQueryIndex=0,this.currentQueryTotal=0,this.currentStaggerTime=0,this.currentTimeline=o||new Zg(this._driver,e,0),s.push(this.currentTimeline)}return Object.defineProperty(t.prototype,"params",{get:function(){return this.options.params},enumerable:!0,configurable:!0}),t.prototype.updateOptions=function(t,e){var n=this;if(t){var a=t,r=this.options;null!=a.duration&&(r.duration=dg(a.duration)),null!=a.delay&&(r.delay=dg(a.delay));var i=a.params;if(i){var s=r.params;s||(s=this.options.params={}),Object.keys(i).forEach(function(t){e&&s.hasOwnProperty(t)||(s[t]=wg(i[t],s,n.errors))})}}},t.prototype._copyOptions=function(){var t={};if(this.options){var e=this.options.params;if(e){var n=t.params={};Object.keys(e).forEach(function(t){n[t]=e[t]})}}return t},t.prototype.createSubContext=function(e,n,a){void 0===e&&(e=null);var r=n||this.element,i=new t(this._driver,r,this.subInstructions,this._enterClassName,this._leaveClassName,this.errors,this.timelines,this.currentTimeline.fork(r,a||0));return i.previousNode=this.previousNode,i.currentAnimateTimings=this.currentAnimateTimings,i.options=this._copyOptions(),i.updateOptions(e),i.currentQueryIndex=this.currentQueryIndex,i.currentQueryTotal=this.currentQueryTotal,i.parentContext=this,this.subContextCount++,i},t.prototype.transformIntoNewTimeline=function(t){return this.previousNode=Kg,this.currentTimeline=this.currentTimeline.fork(this.element,t),this.timelines.push(this.currentTimeline),this.currentTimeline},t.prototype.appendInstructionToTimeline=function(t,e,n){var a={duration:null!=e?e:t.duration,delay:this.currentTimeline.currentTime+(null!=n?n:0)+t.delay,easing:""},r=new Xg(this._driver,t.element,t.keyframes,t.preStyleProps,t.postStyleProps,a,t.stretchStartingKeyframe);return this.timelines.push(r),a},t.prototype.incrementTime=function(t){this.currentTimeline.forwardTime(this.currentTimeline.duration+t)},t.prototype.delayNextStep=function(t){t>0&&this.currentTimeline.delayNextStep(t)},t.prototype.invokeQuery=function(t,e,n,a,r,i){var s=[];if(a&&s.push(this.element),t.length>0){t=(t=t.replace(Hg,"."+this._enterClassName)).replace(Bg,"."+this._leaveClassName);var o=this._driver.query(this.element,t,1!=n);0!==n&&(o=n<0?o.slice(o.length+n,o.length):o.slice(0,n)),s.push.apply(s,Object(p.__spread)(o))}return r||0!=s.length||i.push('`query("'+e+'")` returned zero elements. (Use `query("'+e+'", { optional: true })` if you wish to allow this.)'),s},t}(),Zg=function(){function t(t,e,n,a){this._driver=t,this.element=e,this.startTime=n,this._elementTimelineStylesLookup=a,this.duration=0,this._previousKeyframe={},this._currentKeyframe={},this._keyframes=new Map,this._styleSummary={},this._pendingStyles={},this._backFill={},this._currentEmptyStepKeyframe=null,this._elementTimelineStylesLookup||(this._elementTimelineStylesLookup=new Map),this._localTimelineStyles=Object.create(this._backFill,{}),this._globalTimelineStyles=this._elementTimelineStylesLookup.get(e),this._globalTimelineStyles||(this._globalTimelineStyles=this._localTimelineStyles,this._elementTimelineStylesLookup.set(e,this._localTimelineStyles)),this._loadKeyframe()}return t.prototype.containsAnimation=function(){switch(this._keyframes.size){case 0:return!1;case 1:return this.getCurrentStyleProperties().length>0;default:return!0}},t.prototype.getCurrentStyleProperties=function(){return Object.keys(this._currentKeyframe)},Object.defineProperty(t.prototype,"currentTime",{get:function(){return this.startTime+this.duration},enumerable:!0,configurable:!0}),t.prototype.delayNextStep=function(t){var e=1==this._keyframes.size&&Object.keys(this._pendingStyles).length;this.duration||e?(this.forwardTime(this.currentTime+t),e&&this.snapshotCurrentStyles()):this.startTime+=t},t.prototype.fork=function(e,n){return this.applyStylesToKeyframe(),new t(this._driver,e,n||this.currentTime,this._elementTimelineStylesLookup)},t.prototype._loadKeyframe=function(){this._currentKeyframe&&(this._previousKeyframe=this._currentKeyframe),this._currentKeyframe=this._keyframes.get(this.duration),this._currentKeyframe||(this._currentKeyframe=Object.create(this._backFill,{}),this._keyframes.set(this.duration,this._currentKeyframe))},t.prototype.forwardFrame=function(){this.duration+=1,this._loadKeyframe()},t.prototype.forwardTime=function(t){this.applyStylesToKeyframe(),this.duration=t,this._loadKeyframe()},t.prototype._updateStyle=function(t,e){this._localTimelineStyles[t]=e,this._globalTimelineStyles[t]=e,this._styleSummary[t]={time:this.currentTime,value:e}},t.prototype.allowOnlyTimelineStyles=function(){return this._currentEmptyStepKeyframe!==this._currentKeyframe},t.prototype.applyEmptyStep=function(t){var e=this;t&&(this._previousKeyframe.easing=t),Object.keys(this._globalTimelineStyles).forEach(function(t){e._backFill[t]=e._globalTimelineStyles[t]||ju.a,e._currentKeyframe[t]=ju.a}),this._currentEmptyStepKeyframe=this._currentKeyframe},t.prototype.setStyles=function(t,e,n,a){var r=this;e&&(this._previousKeyframe.easing=e);var i=a&&a.params||{},s=function(t,e){var n,a={};return t.forEach(function(t){"*"===t?(n=n||Object.keys(e)).forEach(function(t){a[t]=ju.a}):gg(t,!1,a)}),a}(t,this._globalTimelineStyles);Object.keys(s).forEach(function(t){var e=wg(s[t],i,n);r._pendingStyles[t]=e,r._localTimelineStyles.hasOwnProperty(t)||(r._backFill[t]=r._globalTimelineStyles.hasOwnProperty(t)?r._globalTimelineStyles[t]:ju.a),r._updateStyle(t,e)})},t.prototype.applyStylesToKeyframe=function(){var t=this,e=this._pendingStyles,n=Object.keys(e);0!=n.length&&(this._pendingStyles={},n.forEach(function(n){t._currentKeyframe[n]=e[n]}),Object.keys(this._localTimelineStyles).forEach(function(e){t._currentKeyframe.hasOwnProperty(e)||(t._currentKeyframe[e]=t._localTimelineStyles[e])}))},t.prototype.snapshotCurrentStyles=function(){var t=this;Object.keys(this._localTimelineStyles).forEach(function(e){var n=t._localTimelineStyles[e];t._pendingStyles[e]=n,t._updateStyle(e,n)})},t.prototype.getFinalKeyframe=function(){return this._keyframes.get(this.duration)},Object.defineProperty(t.prototype,"properties",{get:function(){var t=[];for(var e in this._currentKeyframe)t.push(e);return t},enumerable:!0,configurable:!0}),t.prototype.mergeTimelineCollectedStyles=function(t){var e=this;Object.keys(t._styleSummary).forEach(function(n){var a=e._styleSummary[n],r=t._styleSummary[n];(!a||r.time>a.time)&&e._updateStyle(n,r.value)})},t.prototype.buildKeyframes=function(){var t=this;this.applyStylesToKeyframe();var e=new Set,n=new Set,a=1===this._keyframes.size&&0===this.duration,r=[];this._keyframes.forEach(function(i,s){var o=gg(i,!0);Object.keys(o).forEach(function(t){var a=o[t];a==ju.l?e.add(t):a==ju.a&&n.add(t)}),a||(o.offset=s/t.duration),r.push(o)});var i=e.size?Sg(e.values()):[],s=n.size?Sg(n.values()):[];if(a){var o=r[0],u=hg(o);o.offset=0,u.offset=1,r=[o,u]}return Yg(this.element,r,i,s,this.duration,this.startTime,this.easing,!1)},t}(),Xg=function(t){function e(e,n,a,r,i,s,o){void 0===o&&(o=!1);var u=t.call(this,e,n,s.delay)||this;return u.element=n,u.keyframes=a,u.preStyleProps=r,u.postStyleProps=i,u._stretchStartingKeyframe=o,u.timings={duration:s.duration,delay:s.delay,easing:s.easing},u}return Object(p.__extends)(e,t),e.prototype.containsAnimation=function(){return this.keyframes.length>1},e.prototype.buildKeyframes=function(){var t=this.keyframes,e=this.timings,n=e.delay,a=e.duration,r=e.easing;if(this._stretchStartingKeyframe&&n){var i=[],s=a+n,o=n/s,u=gg(t[0],!1);u.offset=0,i.push(u);var c=gg(t[0],!1);c.offset=Jg(o),i.push(c);for(var l=t.length-1,d=1;d<=l;d++){var f=gg(t[d],!1);f.offset=Jg((n+f.offset*a)/s),i.push(f)}a=s,n=0,r="",t=i}return Yg(this.element,t,this.preStyleProps,this.postStyleProps,a,n,r,!0)},e}(Zg);function Jg(t,e){void 0===e&&(e=3);var n=Math.pow(10,e-1);return Math.round(t*n)/n}var Qg=function(){return function(){}}(),tb=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return Object(p.__extends)(e,t),e.prototype.normalizePropertyName=function(t,e){return Ig(t)},e.prototype.normalizeStyleValue=function(t,e,n,a){var r="",i=n.toString().trim();if(eb[e]&&0!==n&&"0"!==n)if("number"==typeof n)r="px";else{var s=n.match(/^[+-]?[\d\.]+([a-z]*)$/);s&&0==s[1].length&&a.push("Please provide a CSS unit value for "+t+":"+n)}return i+r},e}(Qg),eb=nb("width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective".split(","));function nb(t){var e={};return t.forEach(function(t){return e[t]=!0}),e}function ab(t,e,n,a,r,i,s,o,u,c,l,d,f){return{type:0,element:t,triggerName:e,isRemovalTransition:r,fromState:n,fromStyles:i,toState:a,toStyles:s,timelines:o,queriedElements:u,preStyleProps:c,postStyleProps:l,totalTime:d,errors:f}}var rb={},ib=function(){function t(t,e,n){this._triggerName=t,this.ast=e,this._stateStyles=n}return t.prototype.match=function(t,e,n,a){return function(t,e,n,a,r){return t.some(function(t){return t(e,n,a,r)})}(this.ast.matchers,t,e,n,a)},t.prototype.buildStyles=function(t,e,n){var a=this._stateStyles["*"],r=this._stateStyles[t],i=a?a.buildStyles(e,n):{};return r?r.buildStyles(e,n):i},t.prototype.build=function(t,e,n,a,r,i,s,o,u,c){var l=[],d=this.ast.options&&this.ast.options.params||rb,f=this.buildStyles(n,s&&s.params||rb,l),h=o&&o.params||rb,g=this.buildStyles(a,h,l),b=new Set,m=new Map,y=new Map,v="void"===a,_={params:Object(p.__assign)({},d,h)},x=c?[]:Ug(t,e,this.ast.animation,r,i,f,g,_,u,l),T=0;if(x.forEach(function(t){T=Math.max(t.duration+t.delay,T)}),l.length)return ab(e,this._triggerName,n,a,v,f,g,[],[],m,y,T,l);x.forEach(function(t){var n=t.element,a=Wh(m,n,{});t.preStyleProps.forEach(function(t){return a[t]=!0});var r=Wh(y,n,{});t.postStyleProps.forEach(function(t){return r[t]=!0}),n!==e&&b.add(n)});var w=Sg(b.values());return ab(e,this._triggerName,n,a,v,f,g,x,w,m,y,T)},t}(),sb=function(){function t(t,e){this.styles=t,this.defaultParams=e}return t.prototype.buildStyles=function(t,e){var n={},a=hg(this.defaultParams);return Object.keys(t).forEach(function(e){var n=t[e];null!=n&&(a[e]=n)}),this.styles.styles.forEach(function(t){if("string"!=typeof t){var r=t;Object.keys(r).forEach(function(t){var i=r[t];i.length>1&&(i=wg(i,a,e)),n[t]=i})}}),n},t}(),ob=function(){function t(t,e){var n=this;this.name=t,this.ast=e,this.transitionFactories=[],this.states={},e.states.forEach(function(t){n.states[t.name]=new sb(t.style,t.options&&t.options.params||{})}),ub(this.states,"true","1"),ub(this.states,"false","0"),e.transitions.forEach(function(e){n.transitionFactories.push(new ib(t,e,n.states))}),this.fallbackTransition=new ib(t,{type:1,animation:{type:2,steps:[],options:null},matchers:[function(t,e){return!0}],options:null,queryCount:0,depCount:0},this.states)}return Object.defineProperty(t.prototype,"containsQueries",{get:function(){return this.ast.queryCount>0},enumerable:!0,configurable:!0}),t.prototype.matchTransition=function(t,e,n,a){return this.transitionFactories.find(function(r){return r.match(t,e,n,a)})||null},t.prototype.matchStyles=function(t,e,n){return this.fallbackTransition.buildStyles(t,e,n)},t}();function ub(t,e,n){t.hasOwnProperty(e)?t.hasOwnProperty(n)||(t[n]=t[e]):t.hasOwnProperty(n)&&(t[e]=t[n])}var cb=new Vg,lb=function(){function t(t,e,n){this.bodyNode=t,this._driver=e,this._normalizer=n,this._animations={},this._playersById={},this.players=[]}return t.prototype.register=function(t,e){var n=[],a=Mg(this._driver,e,n);if(n.length)throw new Error("Unable to build the animation due to the following errors: "+n.join("\n"));this._animations[t]=a},t.prototype._buildPlayer=function(t,e,n){var a=t.element,r=Vh(0,this._normalizer,0,t.keyframes,e,n);return this._driver.animate(a,r,t.duration,t.delay,t.easing,[],!0)},t.prototype.create=function(t,e,n){var a=this;void 0===n&&(n={});var r,i=[],s=this._animations[t],o=new Map;if(s?(r=Ug(this._driver,e,s,"ng-enter","ng-leave",{},{},n,cb,i)).forEach(function(t){var e=Wh(o,t.element,{});t.postStyleProps.forEach(function(t){return e[t]=null})}):(i.push("The requested animation doesn't exist or has already been destroyed"),r=[]),i.length)throw new Error("Unable to create the animation due to the following errors: "+i.join("\n"));o.forEach(function(t,e){Object.keys(t).forEach(function(n){t[n]=a._driver.computeStyle(e,n,ju.a)})});var u=Yh(r.map(function(t){var e=o.get(t.element);return a._buildPlayer(t,{},e)}));return this._playersById[t]=u,u.onDestroy(function(){return a.destroy(t)}),this.players.push(u),u},t.prototype.destroy=function(t){var e=this._getPlayer(t);e.destroy(),delete this._playersById[t];var n=this.players.indexOf(e);n>=0&&this.players.splice(n,1)},t.prototype._getPlayer=function(t){var e=this._playersById[t];if(!e)throw new Error("Unable to find the timeline player referenced by "+t);return e},t.prototype.listen=function(t,e,n,a){var r=Uh(e,"","","");return Hh(this._getPlayer(t),n,r,a),function(){}},t.prototype.command=function(t,e,n,a){if("register"!=n)if("create"!=n){var r=this._getPlayer(t);switch(n){case"play":r.play();break;case"pause":r.pause();break;case"reset":r.reset();break;case"restart":r.restart();break;case"finish":r.finish();break;case"init":r.init();break;case"setPosition":r.setPosition(parseFloat(a[0]));break;case"destroy":this.destroy(t)}}else this.create(t,e,a[0]||{});else this.register(t,a[0])},t}(),db=[],fb={namespaceId:"",setForRemoval:!1,setForMove:!1,hasAnimation:!1,removedBeforeQueried:!1},pb={namespaceId:"",setForMove:!1,setForRemoval:!1,hasAnimation:!1,removedBeforeQueried:!0},hb="__ng_removed",gb=function(){function t(t,e){void 0===e&&(e=""),this.namespaceId=e;var n=t&&t.hasOwnProperty("value");if(this.value=function(t){return null!=t?t:null}(n?t.value:t),n){var a=hg(t);delete a.value,this.options=a}else this.options={};this.options.params||(this.options.params={})}return Object.defineProperty(t.prototype,"params",{get:function(){return this.options.params},enumerable:!0,configurable:!0}),t.prototype.absorbOptions=function(t){var e=t.params;if(e){var n=this.options.params;Object.keys(e).forEach(function(t){null==n[t]&&(n[t]=e[t])})}},t}(),bb=new gb("void"),mb=function(){function t(t,e,n){this.id=t,this.hostElement=e,this._engine=n,this.players=[],this._triggers={},this._queue=[],this._elementListeners=new Map,this._hostClassName="ng-tns-"+t,Ob(e,this._hostClassName)}return t.prototype.listen=function(t,e,n,a){var r,i=this;if(!this._triggers.hasOwnProperty(e))throw new Error('Unable to listen on the animation trigger event "'+n+'" because the animation trigger "'+e+"\" doesn't exist!");if(null==n||0==n.length)throw new Error('Unable to listen on the animation trigger "'+e+'" because the provided event is undefined!');if("start"!=(r=n)&&"done"!=r)throw new Error('The provided animation trigger event "'+n+'" for the animation trigger "'+e+'" is not supported!');var s=Wh(this._elementListeners,t,[]),o={name:e,phase:n,callback:a};s.push(o);var u=Wh(this._engine.statesByElement,t,{});return u.hasOwnProperty(e)||(Ob(t,"ng-trigger"),Ob(t,"ng-trigger-"+e),u[e]=bb),function(){i._engine.afterFlush(function(){var t=s.indexOf(o);t>=0&&s.splice(t,1),i._triggers[e]||delete u[e]})}},t.prototype.register=function(t,e){return!this._triggers[t]&&(this._triggers[t]=e,!0)},t.prototype._getTrigger=function(t){var e=this._triggers[t];if(!e)throw new Error('The provided animation trigger "'+t+'" has not been registered!');return e},t.prototype.trigger=function(t,e,n,a){var r=this;void 0===a&&(a=!0);var i=this._getTrigger(e),s=new vb(this.id,e,t),o=this._engine.statesByElement.get(t);o||(Ob(t,"ng-trigger"),Ob(t,"ng-trigger-"+e),this._engine.statesByElement.set(t,o={}));var u=o[e],c=new gb(n,this.id);if(!(n&&n.hasOwnProperty("value"))&&u&&c.absorbOptions(u.options),o[e]=c,u||(u=bb),"void"===c.value||u.value!==c.value){var l=Wh(this._engine.playersByElement,t,[]);l.forEach(function(t){t.namespaceId==r.id&&t.triggerName==e&&t.queued&&t.destroy()});var d=i.matchTransition(u.value,c.value,t,c.params),f=!1;if(!d){if(!a)return;d=i.fallbackTransition,f=!0}return this._engine.totalQueuedPlayers++,this._queue.push({element:t,triggerName:e,transition:d,fromState:u,toState:c,player:s,isFallbackTransition:f}),f||(Ob(t,"ng-animate-queued"),s.onStart(function(){Ib(t,"ng-animate-queued")})),s.onDone(function(){var e=r.players.indexOf(s);e>=0&&r.players.splice(e,1);var n=r._engine.playersByElement.get(t);if(n){var a=n.indexOf(s);a>=0&&n.splice(a,1)}}),this.players.push(s),l.push(s),s}if(!function(t,e){var n=Object.keys(t),a=Object.keys(e);if(n.length!=a.length)return!1;for(var r=0;r=0){for(var a=!1,r=n;r>=0;r--)if(this.driver.containsElement(this._namespaceList[r].hostElement,e)){this._namespaceList.splice(r+1,0,t),a=!0;break}a||this._namespaceList.splice(0,0,t)}else this._namespaceList.push(t);return this.namespacesByHostElement.set(e,t),t},t.prototype.register=function(t,e){var n=this._namespaceLookup[t];return n||(n=this.createNamespace(t,e)),n},t.prototype.registerTrigger=function(t,e,n){var a=this._namespaceLookup[t];a&&a.register(e,n)&&this.totalAnimations++},t.prototype.destroy=function(t,e){var n=this;if(t){var a=this._fetchNamespace(t);this.afterFlush(function(){n.namespacesByHostElement.delete(a.hostElement),delete n._namespaceLookup[t];var e=n._namespaceList.indexOf(a);e>=0&&n._namespaceList.splice(e,1)}),this.afterFlushAnimationsDone(function(){return a.destroy(e)})}},t.prototype._fetchNamespace=function(t){return this._namespaceLookup[t]},t.prototype.fetchNamespacesByElement=function(t){var e=new Set,n=this.statesByElement.get(t);if(n)for(var a=Object.keys(n),r=0;r=0&&this.collectedLeaveElements.splice(i,1)}if(t){var s=this._fetchNamespace(t);s&&s.insertNode(e,n)}a&&this.collectEnterElement(e)}},t.prototype.collectEnterElement=function(t){this.collectedEnterElements.push(t)},t.prototype.markElementAsDisabled=function(t,e){e?this.disabledNodes.has(t)||(this.disabledNodes.add(t),Ob(t,"ng-animate-disabled")):this.disabledNodes.has(t)&&(this.disabledNodes.delete(t),Ib(t,"ng-animate-disabled"))},t.prototype.removeNode=function(t,e,n){if(_b(e)){var a=t?this._fetchNamespace(t):null;a?a.removeNode(e,n):this.markElementAsRemoved(t,e,!1,n)}else this._onRemovalComplete(e,n)},t.prototype.markElementAsRemoved=function(t,e,n,a){this.collectedLeaveElements.push(e),e[hb]={namespaceId:t,setForRemoval:a,hasAnimation:n,removedBeforeQueried:!1}},t.prototype.listen=function(t,e,n,a,r){return _b(e)?this._fetchNamespace(t).listen(e,n,a,r):function(){}},t.prototype._buildInstruction=function(t,e,n,a,r){return t.transition.build(this.driver,t.element,t.fromState.value,t.toState.value,n,a,t.fromState.options,t.toState.options,e,r)},t.prototype.destroyInnerAnimations=function(t){var e=this,n=this.driver.query(t,".ng-trigger",!0);n.forEach(function(t){return e.destroyActiveAnimationsForElement(t)}),0!=this.playersByQueriedElement.size&&(n=this.driver.query(t,".ng-animating",!0)).forEach(function(t){return e.finishActiveQueriedAnimationOnElement(t)})},t.prototype.destroyActiveAnimationsForElement=function(t){var e=this.playersByElement.get(t);e&&e.forEach(function(t){t.queued?t.markedForDestroy=!0:t.destroy()})},t.prototype.finishActiveQueriedAnimationOnElement=function(t){var e=this.playersByQueriedElement.get(t);e&&e.forEach(function(t){return t.finish()})},t.prototype.whenRenderingDone=function(){var t=this;return new Promise(function(e){if(t.players.length)return Yh(t.players).onDone(function(){return e()});e()})},t.prototype.processLeaveNode=function(t){var e=this,n=t[hb];if(n&&n.setForRemoval){if(t[hb]=fb,n.namespaceId){this.destroyInnerAnimations(t);var a=this._fetchNamespace(n.namespaceId);a&&a.clearElementCache(t)}this._onRemovalComplete(t,n.setForRemoval)}this.driver.matchesElement(t,".ng-animate-disabled")&&this.markElementAsDisabled(t,!1),this.driver.query(t,".ng-animate-disabled",!0).forEach(function(t){e.markElementAsDisabled(t,!1)})},t.prototype.flush=function(t){var e=this;void 0===t&&(t=-1);var n=[];if(this.newHostElements.size&&(this.newHostElements.forEach(function(t,n){return e._balanceNamespaceList(t,n)}),this.newHostElements.clear()),this.totalAnimations&&this.collectedEnterElements.length)for(var a=0;a=0;O--)this._namespaceList[O].drainQueuedTransitions(e).forEach(function(t){var e=t.player,i=t.element;if(w.push(e),n.collectedEnterElements.length){var l=i[hb];if(l&&l.setForMove)return void e.destroy()}var f=!d||!n.driver.containsElement(d,i),p=x.get(i),h=g.get(i),b=n._buildInstruction(t,a,h,p,f);if(b.errors&&b.errors.length)S.push(b);else{if(f)return e.onStart(function(){return vg(i,b.fromStyles)}),e.onDestroy(function(){return yg(i,b.toStyles)}),void r.push(e);if(t.isFallbackTransition)return e.onStart(function(){return vg(i,b.fromStyles)}),e.onDestroy(function(){return yg(i,b.toStyles)}),void r.push(e);b.timelines.forEach(function(t){return t.stretchStartingKeyframe=!0}),a.append(i,b.timelines),s.push({instruction:b,player:e,element:i}),b.queriedElements.forEach(function(t){return Wh(o,t,[]).push(e)}),b.preStyleProps.forEach(function(t,e){var n=Object.keys(t);if(n.length){var a=u.get(e);a||u.set(e,a=new Set),n.forEach(function(t){return a.add(t)})}}),b.postStyleProps.forEach(function(t,e){var n=Object.keys(t),a=c.get(e);a||c.set(e,a=new Set),n.forEach(function(t){return a.add(t)})})}});if(S.length){var I=[];S.forEach(function(t){I.push("@"+t.triggerName+" has failed due to:\n"),t.errors.forEach(function(t){return I.push("- "+t+"\n")})}),w.forEach(function(t){return t.destroy()}),this.reportError(I)}var C=new Map,k=new Map;s.forEach(function(t){var e=t.element;a.has(e)&&(k.set(e,e),n._beforeAnimationBuild(t.player.namespaceId,t.instruction,C))}),r.forEach(function(t){var e=t.element;n._getPreviousPlayers(e,!1,t.namespaceId,t.triggerName,null).forEach(function(t){Wh(C,e,[]).push(t),t.destroy()})});var N=m.filter(function(t){return kb(t,u,c)}),R=new Map;Tb(R,this.driver,v,c,ju.a).forEach(function(t){kb(t,u,c)&&N.push(t)});var A=new Map;h.forEach(function(t,e){Tb(A,n.driver,new Set(t),u,ju.l)}),N.forEach(function(t){var e=R.get(t),n=A.get(t);R.set(t,Object(p.__assign)({},e,n))});var D=[],E=[],L={};s.forEach(function(t){var e=t.element,s=t.player,o=t.instruction;if(a.has(e)){if(l.has(e))return s.onDestroy(function(){return yg(e,o.toStyles)}),s.disabled=!0,s.overrideTotalTime(o.totalTime),void r.push(s);var u=L;if(k.size>1){for(var c=e,d=[];c=c.parentNode;){var f=k.get(c);if(f){u=f;break}d.push(c)}d.forEach(function(t){return k.set(t,u)})}var p=n._buildAnimation(s.namespaceId,o,C,i,A,R);if(s.setRealPlayer(p),u===L)D.push(s);else{var h=n.playersByElement.get(u);h&&h.length&&(s.parentPlayer=Yh(h)),r.push(s)}}else vg(e,o.fromStyles),s.onDestroy(function(){return yg(e,o.toStyles)}),E.push(s),l.has(e)&&r.push(s)}),E.forEach(function(t){var e=i.get(t.element);if(e&&e.length){var n=Yh(e);t.setRealPlayer(n)}}),r.forEach(function(t){t.parentPlayer?t.syncPlayerEvents(t.parentPlayer):t.destroy()});for(var P=0;P0?this.driver.animate(t.element,e,t.duration,t.delay,t.easing,n):new ju.d(t.duration,t.delay)},t}(),vb=function(){function t(t,e,n){this.namespaceId=t,this.triggerName=e,this.element=n,this._player=new ju.d,this._containsRealPlayer=!1,this._queuedCallbacks={},this.destroyed=!1,this.markedForDestroy=!1,this.disabled=!1,this.queued=!0,this.totalTime=0}return t.prototype.setRealPlayer=function(t){var e=this;this._containsRealPlayer||(this._player=t,Object.keys(this._queuedCallbacks).forEach(function(n){e._queuedCallbacks[n].forEach(function(e){return Hh(t,n,void 0,e)})}),this._queuedCallbacks={},this._containsRealPlayer=!0,this.overrideTotalTime(t.totalTime),this.queued=!1)},t.prototype.getRealPlayer=function(){return this._player},t.prototype.overrideTotalTime=function(t){this.totalTime=t},t.prototype.syncPlayerEvents=function(t){var e=this,n=this._player;n.triggerCallback&&t.onStart(function(){return n.triggerCallback("start")}),t.onDone(function(){return e.finish()}),t.onDestroy(function(){return e.destroy()})},t.prototype._queueEvent=function(t,e){Wh(this._queuedCallbacks,t,[]).push(e)},t.prototype.onDone=function(t){this.queued&&this._queueEvent("done",t),this._player.onDone(t)},t.prototype.onStart=function(t){this.queued&&this._queueEvent("start",t),this._player.onStart(t)},t.prototype.onDestroy=function(t){this.queued&&this._queueEvent("destroy",t),this._player.onDestroy(t)},t.prototype.init=function(){this._player.init()},t.prototype.hasStarted=function(){return!this.queued&&this._player.hasStarted()},t.prototype.play=function(){!this.queued&&this._player.play()},t.prototype.pause=function(){!this.queued&&this._player.pause()},t.prototype.restart=function(){!this.queued&&this._player.restart()},t.prototype.finish=function(){this._player.finish()},t.prototype.destroy=function(){this.destroyed=!0,this._player.destroy()},t.prototype.reset=function(){!this.queued&&this._player.reset()},t.prototype.setPosition=function(t){this.queued||this._player.setPosition(t)},t.prototype.getPosition=function(){return this.queued?0:this._player.getPosition()},t.prototype.triggerCallback=function(t){var e=this._player;e.triggerCallback&&e.triggerCallback(t)},t}();function _b(t){return t&&1===t.nodeType}function xb(t,e){var n=t.style.display;return t.style.display=null!=e?e:"none",n}function Tb(t,e,n,a,r){var i=[];n.forEach(function(t){return i.push(xb(t))});var s=[];a.forEach(function(n,a){var i={};n.forEach(function(t){var n=i[t]=e.computeStyle(a,t,r);n&&0!=n.length||(a[hb]=pb,s.push(a))}),t.set(a,i)});var o=0;return n.forEach(function(t){return xb(t,i[o++])}),s}function wb(t,e){var n=new Map;if(t.forEach(function(t){return n.set(t,[])}),0==e.length)return n;var a=new Set(e),r=new Map;return e.forEach(function(t){var e=function t(e){if(!e)return 1;var i=r.get(e);if(i)return i;var s=e.parentNode;return i=n.has(s)?s:a.has(s)?1:t(s),r.set(e,i),i}(t);1!==e&&n.get(e).push(t)}),n}var Sb="$$classes";function Ob(t,e){if(t.classList)t.classList.add(e);else{var n=t[Sb];n||(n=t[Sb]={}),n[e]=!0}}function Ib(t,e){if(t.classList)t.classList.remove(e);else{var n=t[Sb];n&&delete n[e]}}function Cb(t,e,n){Yh(n).onDone(function(){return t.processLeaveNode(e)})}function kb(t,e,n){var a=n.get(t);if(!a)return!1;var r=e.get(t);return r?a.forEach(function(t){return r.add(t)}):e.set(t,a),n.delete(t),!0}var Nb=function(){function t(t,e,n){var a=this;this.bodyNode=t,this._driver=e,this._triggerCache={},this.onRemovalComplete=function(t,e){},this._transitionEngine=new yb(t,e,n),this._timelineEngine=new lb(t,e,n),this._transitionEngine.onRemovalComplete=function(t,e){return a.onRemovalComplete(t,e)}}return t.prototype.registerTrigger=function(t,e,n,a,r){var i=t+"-"+a,s=this._triggerCache[i];if(!s){var o=[],u=Mg(this._driver,r,o);if(o.length)throw new Error('The animation trigger "'+a+'" has failed to build due to the following errors:\n - '+o.join("\n - "));s=function(t,e){return new ob(t,e)}(a,u),this._triggerCache[i]=s}this._transitionEngine.registerTrigger(e,a,s)},t.prototype.register=function(t,e){this._transitionEngine.register(t,e)},t.prototype.destroy=function(t,e){this._transitionEngine.destroy(t,e)},t.prototype.onInsert=function(t,e,n,a){this._transitionEngine.insertNode(t,e,n,a)},t.prototype.onRemove=function(t,e,n){this._transitionEngine.removeNode(t,e,n)},t.prototype.disableAnimations=function(t,e){this._transitionEngine.markElementAsDisabled(t,e)},t.prototype.process=function(t,e,n,a){if("@"==n.charAt(0)){var r=Object(p.__read)(Kh(n),2);this._timelineEngine.command(r[0],e,r[1],a)}else this._transitionEngine.trigger(t,e,n,a)},t.prototype.listen=function(t,e,n,a,r){if("@"==n.charAt(0)){var i=Object(p.__read)(Kh(n),2);return this._timelineEngine.listen(i[0],e,i[1],r)}return this._transitionEngine.listen(t,e,n,a,r)},t.prototype.flush=function(t){void 0===t&&(t=-1),this._transitionEngine.flush(t)},Object.defineProperty(t.prototype,"players",{get:function(){return this._transitionEngine.players.concat(this._timelineEngine.players)},enumerable:!0,configurable:!0}),t.prototype.whenRenderingDone=function(){return this._transitionEngine.whenRenderingDone()},t}(),Rb="animation",Ab="animationend",Db=function(){function t(t,e,n,a,r,i,s){var o=this;this._element=t,this._name=e,this._duration=n,this._delay=a,this._easing=r,this._fillMode=i,this._onDoneFn=s,this._finished=!1,this._destroyed=!1,this._startTime=0,this._position=0,this._eventFn=function(t){return o._handleCallback(t)}}return t.prototype.apply=function(){var t,e,n;e=this._duration+"ms "+this._easing+" "+this._delay+"ms 1 normal "+this._fillMode+" "+this._name,(n=jb(t=this._element,"").trim()).length&&(function(t,e){for(var n=0;n=this._delay&&n>=this._duration&&this.finish()},t.prototype.finish=function(){this._finished||(this._finished=!0,this._onDoneFn(),Mb(this._element,this._eventFn,!0))},t.prototype.destroy=function(){var t,e,n,a;this._destroyed||(this._destroyed=!0,this.finish(),e=this._name,(a=Pb(n=jb(t=this._element,"").split(","),e))>=0&&(n.splice(a,1),qb(t,"",n.join(","))))},t}();function Eb(t,e,n){qb(t,"PlayState",n,Lb(t,e))}function Lb(t,e){var n=jb(t,"");return n.indexOf(",")>0?Pb(n.split(","),e):Pb([n],e)}function Pb(t,e){for(var n=0;n=0)return n;return-1}function Mb(t,e,n){n?t.removeEventListener(Ab,e):t.addEventListener(Ab,e)}function qb(t,e,n,a){var r=Rb+e;if(null!=a){var i=t.style[r];if(i.length){var s=i.split(",");s[a]=n,n=s.join(",")}}t.style[r]=n}function jb(t,e){return t.style[Rb+e]}var Fb="linear",zb=function(){function t(t,e,n,a,r,i,s){this.element=t,this.keyframes=e,this.animationName=n,this._duration=a,this._delay=r,this._finalStyles=s,this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this._started=!1,this.currentSnapshot={},this._state=0,this.easing=i||Fb,this.totalTime=a+r,this._buildStyler()}return t.prototype.onStart=function(t){this._onStartFns.push(t)},t.prototype.onDone=function(t){this._onDoneFns.push(t)},t.prototype.onDestroy=function(t){this._onDestroyFns.push(t)},t.prototype.destroy=function(){this.init(),this._state>=4||(this._state=4,this._styler.destroy(),this._flushStartFns(),this._flushDoneFns(),this._onDestroyFns.forEach(function(t){return t()}),this._onDestroyFns=[])},t.prototype._flushDoneFns=function(){this._onDoneFns.forEach(function(t){return t()}),this._onDoneFns=[]},t.prototype._flushStartFns=function(){this._onStartFns.forEach(function(t){return t()}),this._onStartFns=[]},t.prototype.finish=function(){this.init(),this._state>=3||(this._state=3,this._styler.finish(),this._flushStartFns(),this._flushDoneFns())},t.prototype.setPosition=function(t){this._styler.setPosition(t)},t.prototype.getPosition=function(){return this._styler.getPosition()},t.prototype.hasStarted=function(){return this._state>=2},t.prototype.init=function(){this._state>=1||(this._state=1,this._styler.apply(),this._delay&&this._styler.pause())},t.prototype.play=function(){this.init(),this.hasStarted()||(this._flushStartFns(),this._state=2),this._styler.resume()},t.prototype.pause=function(){this.init(),this._styler.pause()},t.prototype.restart=function(){this.reset(),this.play()},t.prototype.reset=function(){this._styler.destroy(),this._buildStyler(),this._styler.apply()},t.prototype._buildStyler=function(){var t=this;this._styler=new Db(this.element,this.animationName,this._duration,this._delay,this.easing,"forwards",function(){return t.finish()})},t.prototype.triggerCallback=function(t){var e="start"==t?this._onStartFns:this._onDoneFns;e.forEach(function(t){return t()}),e.length=0},t.prototype.beforeDestroy=function(){var t=this;this.init();var e={};if(this.hasStarted()){var n=this._state>=3;Object.keys(this._finalStyles).forEach(function(a){"offset"!=a&&(e[a]=n?t._finalStyles[a]:Rg(t.element,a))})}this.currentSnapshot=e},t}(),Gb=function(t){function e(e,n){var a=t.call(this)||this;return a.element=e,a._startingStyles={},a.__initialized=!1,a._styles=og(n),a}return Object(p.__extends)(e,t),e.prototype.init=function(){var e=this;!this.__initialized&&this._startingStyles&&(this.__initialized=!0,Object.keys(this._styles).forEach(function(t){e._startingStyles[t]=e.element.style[t]}),t.prototype.init.call(this))},e.prototype.play=function(){var e=this;this._startingStyles&&(this.init(),Object.keys(this._styles).forEach(function(t){return e.element.style.setProperty(t,e._styles[t])}),t.prototype.play.call(this))},e.prototype.destroy=function(){var e=this;this._startingStyles&&(Object.keys(this._startingStyles).forEach(function(t){var n=e._startingStyles[t];n?e.element.style.setProperty(t,n):e.element.style.removeProperty(t)}),this._startingStyles=null,t.prototype.destroy.call(this))},e}(ju.d),Yb=function(){function t(){this._count=0,this._head=document.querySelector("head"),this._warningIssued=!1}return t.prototype.validateStyleProperty=function(t){return ag(t)},t.prototype.matchesElement=function(t,e){return rg(t,e)},t.prototype.containsElement=function(t,e){return ig(t,e)},t.prototype.query=function(t,e,n){return sg(t,e,n)},t.prototype.computeStyle=function(t,e,n){return window.getComputedStyle(t)[e]},t.prototype.buildKeyframeElement=function(t,e,n){n=n.map(function(t){return og(t)});var a="@keyframes "+e+" {\n",r="";n.forEach(function(t){r=" ";var e=parseFloat(t.offset);a+=""+r+100*e+"% {\n",r+=" ",Object.keys(t).forEach(function(e){var n=t[e];switch(e){case"offset":return;case"easing":return void(n&&(a+=r+"animation-timing-function: "+n+";\n"));default:return void(a+=""+r+e+": "+n+";\n")}}),a+=r+"}\n"}),a+="}\n";var i=document.createElement("style");return i.innerHTML=a,i},t.prototype.animate=function(t,e,n,a,r,i,s){void 0===i&&(i=[]),s&&this._notifyFaultyScrubber();var o=i.filter(function(t){return t instanceof zb}),u={};Cg(n,a)&&o.forEach(function(t){var e=t.currentSnapshot;Object.keys(e).forEach(function(t){return u[t]=e[t]})});var c=function(t){var e={};return t&&(Array.isArray(t)?t:[t]).forEach(function(t){Object.keys(t).forEach(function(n){"offset"!=n&&"easing"!=n&&(e[n]=t[n])})}),e}(e=kg(t,e,u));if(0==n)return new Gb(t,c);var l="gen_css_kf_"+this._count++,d=this.buildKeyframeElement(t,l,e);document.querySelector("head").appendChild(d);var f=new zb(t,e,l,n,a,r,c);return f.onDestroy(function(){var t;(t=d).parentNode.removeChild(t)}),f},t.prototype._notifyFaultyScrubber=function(){this._warningIssued||(console.warn("@angular/animations: please load the web-animations.js polyfill to allow programmatic access...\n"," visit http://bit.ly/IWukam to learn more about using the web-animation-js polyfill."),this._warningIssued=!0)},t}(),Vb=function(){function t(t,e,n){this.element=t,this.keyframes=e,this.options=n,this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this._initialized=!1,this._finished=!1,this._started=!1,this._destroyed=!1,this.time=0,this.parentPlayer=null,this.currentSnapshot={},this._duration=n.duration,this._delay=n.delay||0,this.time=this._duration+this._delay}return t.prototype._onFinish=function(){this._finished||(this._finished=!0,this._onDoneFns.forEach(function(t){return t()}),this._onDoneFns=[])},t.prototype.init=function(){this._buildPlayer(),this._preparePlayerBeforeStart()},t.prototype._buildPlayer=function(){var t=this;if(!this._initialized){this._initialized=!0;var e=this.keyframes;this.domPlayer=this._triggerWebAnimation(this.element,e,this.options),this._finalKeyframe=e.length?e[e.length-1]:{},this.domPlayer.addEventListener("finish",function(){return t._onFinish()})}},t.prototype._preparePlayerBeforeStart=function(){this._delay?this._resetDomPlayerState():this.domPlayer.pause()},t.prototype._triggerWebAnimation=function(t,e,n){return t.animate(e,n)},t.prototype.onStart=function(t){this._onStartFns.push(t)},t.prototype.onDone=function(t){this._onDoneFns.push(t)},t.prototype.onDestroy=function(t){this._onDestroyFns.push(t)},t.prototype.play=function(){this._buildPlayer(),this.hasStarted()||(this._onStartFns.forEach(function(t){return t()}),this._onStartFns=[],this._started=!0),this.domPlayer.play()},t.prototype.pause=function(){this.init(),this.domPlayer.pause()},t.prototype.finish=function(){this.init(),this._onFinish(),this.domPlayer.finish()},t.prototype.reset=function(){this._resetDomPlayerState(),this._destroyed=!1,this._finished=!1,this._started=!1},t.prototype._resetDomPlayerState=function(){this.domPlayer&&this.domPlayer.cancel()},t.prototype.restart=function(){this.reset(),this.play()},t.prototype.hasStarted=function(){return this._started},t.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this._resetDomPlayerState(),this._onFinish(),this._onDestroyFns.forEach(function(t){return t()}),this._onDestroyFns=[])},t.prototype.setPosition=function(t){this.domPlayer.currentTime=t*this.time},t.prototype.getPosition=function(){return this.domPlayer.currentTime/this.time},Object.defineProperty(t.prototype,"totalTime",{get:function(){return this._delay+this._duration},enumerable:!0,configurable:!0}),t.prototype.beforeDestroy=function(){var t=this,e={};this.hasStarted()&&Object.keys(this._finalKeyframe).forEach(function(n){"offset"!=n&&(e[n]=t._finished?t._finalKeyframe[n]:Rg(t.element,n))}),this.currentSnapshot=e},t.prototype.triggerCallback=function(t){var e="start"==t?this._onStartFns:this._onDoneFns;e.forEach(function(t){return t()}),e.length=0},t}(),Hb=function(){function t(){this._isNativeImpl=/\{\s*\[native\s+code\]\s*\}/.test(Bb().toString()),this._cssKeyframesDriver=new Yb}return t.prototype.validateStyleProperty=function(t){return ag(t)},t.prototype.matchesElement=function(t,e){return rg(t,e)},t.prototype.containsElement=function(t,e){return ig(t,e)},t.prototype.query=function(t,e,n){return sg(t,e,n)},t.prototype.computeStyle=function(t,e,n){return window.getComputedStyle(t)[e]},t.prototype.overrideWebAnimationsSupport=function(t){this._isNativeImpl=t},t.prototype.animate=function(t,e,n,a,r,i,s){if(void 0===i&&(i=[]),!s&&!this._isNativeImpl)return this._cssKeyframesDriver.animate(t,e,n,a,r,i);var o={duration:n,delay:a,fill:0==a?"both":"forwards"};r&&(o.easing=r);var u={},c=i.filter(function(t){return t instanceof Vb});return Cg(n,a)&&c.forEach(function(t){var e=t.currentSnapshot;Object.keys(e).forEach(function(t){return u[t]=e[t]})}),e=kg(t,e=e.map(function(t){return gg(t,!1)}),u),new Vb(t,e,o)},t}();function Bb(){return"undefined"!=typeof window&&void 0!==window.document&&Element.prototype.animate||{}}var Ub=function(t){function e(e,n){var a=t.call(this)||this;return a._nextAnimationId=0,a._renderer=e.createRenderer(n.body,{id:"0",encapsulation:s.ViewEncapsulation.None,styles:[],data:{animation:[]}}),a}return Object(p.__extends)(e,t),e.prototype.build=function(t){var e=this._nextAnimationId.toString();this._nextAnimationId++;var n=Array.isArray(t)?Object(ju.f)(t):t;return $b(this._renderer,null,e,"register",[n]),new Wb(e,this._renderer)},e}(ju.b),Wb=function(t){function e(e,n){var a=t.call(this)||this;return a._id=e,a._renderer=n,a}return Object(p.__extends)(e,t),e.prototype.create=function(t,e){return new Kb(this._id,t,e||{},this._renderer)},e}(ju.c),Kb=function(){function t(t,e,n,a){this.id=t,this.element=e,this._renderer=a,this.parentPlayer=null,this._started=!1,this.totalTime=0,this._command("create",n)}return t.prototype._listen=function(t,e){return this._renderer.listen(this.element,"@@"+this.id+":"+t,e)},t.prototype._command=function(t){for(var e=[],n=1;n=0&&t0&&t.WHITELIST.includes(e.url[0].path))return Object(gc.a)(!0);var a=e.data.moduleStatusGuardConfig;return this.http.get("api/"+a.apiPath+"/status").pipe(Object(Bi.a)(function(t){return t.available||n.router.navigate([a.redirectTo,t.message||""]),t.available}),Object(Fh.a)(function(){return n.router.navigate([a.redirectTo]),Object(gc.a)(!1)}))},t.WHITELIST=["501"],t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c),s.inject(tt.l))},token:t,providedIn:"root"}),t}(),um=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return p.__extends(e,t),e.prototype.resolve=function(t){var e=[],n=t.queryParams.fromLink||null,a="";switch(n){case"/monitor":a="Monitors";break;case"/hosts":a="Hosts"}return e.push({text:"Cluster",path:null}),e.push({text:a,path:n}),e.push({text:"Performance Counters",path:""}),e},e}(Oh),cm=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return p.__extends(e,t),e.prototype.resolve=function(t){var e=t.params.name;return[{text:ft.startCase(e),path:e}]},e}(Oh),lm={breadcrumbs:"Cluster/Hosts"},dm={breadcrumbs:"Cluster/Monitors"},fm={breadcrumbs:"Cluster/OSDs"},pm={breadcrumbs:"Cluster/Configuration"},hm={breadcrumbs:Zn.a.EDIT},gm={breadcrumbs:"Cluster/CRUSH map"},bm={breadcrumbs:"Cluster/Logs"},mm={breadcrumbs:"Cluster/Monitoring"},ym={breadcrumbs:Zn.a.CREATE+" Silence"},vm={breadcrumbs:Zn.a.CREATE},_m={breadcrumbs:Zn.a.EDIT},xm={breadcrumbs:Zn.a.RECREATE},Tm={breadcrumbs:um},wm={breadcrumbs:"Cluster/Manager modules"},Sm={breadcrumbs:cm},Om={breadcrumbs:"Pools"},Im={breadcrumbs:!0,text:"Block",path:null},Cm={breadcrumbs:"Filesystems"},km={moduleStatusGuardConfig:{apiPath:"rgw",redirectTo:"rgw/501"},breadcrumbs:!0,text:"Object Gateway",path:null},Nm={breadcrumbs:"User management",path:null},Rm={breadcrumbs:"NFS"},Am={moduleStatusGuardConfig:{apiPath:"nfs-ganesha",redirectTo:"nfs/501"},breadcrumbs:"NFS"},Dm={breadcrumbs:Zn.a.CREATE},Em={breadcrumbs:Zn.a.EDIT},Lm=function(){return function(){}}(),Pm=n("IzCI"),Mm=n("Dwqy"),qm=n("uYzU"),jm=n("uhwM"),Fm=n("nSDx"),zm=n("SB+Q"),Gm=n("BQkM"),Ym=n("dEH0"),Vm=n("G1/K"),Hm=n("TJUb"),Bm=n("lTVp"),Um=n("FO+L"),Wm=n("nhM1"),Km=n("BARL"),$m=n("JZ5S"),Zm=n("Da1D"),Xm=function(){return function(){this.closeOthers=!1,this.isAnimated=!1}}(),Jm=function(){function t(){}return t.forRoot=function(){return{ngModule:t,providers:[Xm]}},t}(),Qm=function(){function t(t){this.http=t}return t.prototype.jsError=function(t,e,n){return this.http.post("ui-api/logging/js-error",{url:t,message:e,stack:n})},t.ngInjectableDef=s.defineInjectable({factory:function(){return new t(s.inject(kt.c))},token:t,providedIn:Nt.a}),t}(),ty=function(){function t(t){this.injector=t}return t.prototype.handleError=function(t){var e=this.injector.get(Qm),n=window.location.href;throw e.jsError(n,t&&t.message,t&&t.stack).subscribe(),t},t}(),ey=n("9Xeq"),ny=n("yGOH"),ay=n("V/fk"),ry=n("F8xH"),iy=n("ChqD"),sy=n("PCNd"),oy=n("LceX"),uy=function(){return function(){}}(),cy=function(){return function(){}}(),ly=n("G6Q+"),dy=n("STEd"),fy=function(){return function(){}}(),py=function(){return function(){}}(),hy=n("kJI8"),gy=function(){return function(){}}(),by=function(){return function(){}}(),my=function(){return function(){}}(),yy=function(){return function(){}}(),vy=s["\u0275cmf"](u,[f],function(t){return s["\u0275mod"]([s["\u0275mpd"](512,s.ComponentFactoryResolver,s["\u0275CodegenComponentFactoryResolver"],[[8,[k,M,W,K.a,Pe,on,gn,Na,Ka,mr,kr,Vi,Cs,Js,ao,go,Ho,hu,vu,Mu,Nl,Pl,rd,cd,hd,gd.a,bd.a,md.a,yd.a,vd.a,vd.b,_d.a,xd.a,Td.a,Nd,Rd.a,Rd.c,Rd.b,Ud,Wn,tf,uf,Tf,Nf,$f,ip,qh]],[3,s.ComponentFactoryResolver],s.NgModuleRef]),s["\u0275mpd"](4608,kt.j,kt.p,[i.DOCUMENT,s.PLATFORM_ID,kt.n]),s["\u0275mpd"](4608,kt.q,kt.q,[kt.j,kt.o]),s["\u0275mpd"](4608,l.a,l.a,[]),s["\u0275mpd"](5120,kt.a,function(t,e,n,a){return[t,new zh(e,n,a)]},[kt.q,tt.l,l.a,Jn.a]),s["\u0275mpd"](4608,kt.m,kt.m,[]),s["\u0275mpd"](6144,kt.k,null,[kt.m]),s["\u0275mpd"](4608,kt.i,kt.i,[kt.k]),s["\u0275mpd"](6144,kt.b,null,[kt.i]),s["\u0275mpd"](4608,kt.g,kt.l,[kt.b,s.Injector]),s["\u0275mpd"](4608,kt.c,kt.c,[kt.g]),s["\u0275mpd"](4352,s.LOCALE_ID,"en-US",[]),s["\u0275mpd"](4608,i.NgLocalization,i.NgLocaleLocalization,[s.LOCALE_ID,[2,i["\u0275angular_packages_common_common_a"]]]),s["\u0275mpd"](5120,s.APP_ID,s["\u0275angular_packages_core_core_h"],[]),s["\u0275mpd"](5120,s.IterableDiffers,s["\u0275angular_packages_core_core_q"],[]),s["\u0275mpd"](5120,s.KeyValueDiffers,s["\u0275angular_packages_core_core_r"],[]),s["\u0275mpd"](4608,Fe.DomSanitizer,Fe["\u0275DomSanitizerImpl"],[i.DOCUMENT]),s["\u0275mpd"](6144,s.Sanitizer,null,[Fe.DomSanitizer]),s["\u0275mpd"](4608,Fe.HAMMER_GESTURE_CONFIG,Fe.HammerGestureConfig,[]),s["\u0275mpd"](5120,Fe.EVENT_MANAGER_PLUGINS,function(t,e,n,a,r,i,s,o){return[new Fe["\u0275DomEventsPlugin"](t,e,n),new Fe["\u0275KeyEventsPlugin"](a),new Fe["\u0275HammerGesturesPlugin"](r,i,s,o)]},[i.DOCUMENT,s.NgZone,s.PLATFORM_ID,i.DOCUMENT,i.DOCUMENT,Fe.HAMMER_GESTURE_CONFIG,s["\u0275Console"],[2,Fe.HAMMER_LOADER]]),s["\u0275mpd"](4608,Fe.EventManager,Fe.EventManager,[Fe.EVENT_MANAGER_PLUGINS,s.NgZone]),s["\u0275mpd"](135680,Fe["\u0275DomSharedStylesHost"],Fe["\u0275DomSharedStylesHost"],[i.DOCUMENT]),s["\u0275mpd"](4608,Fe["\u0275DomRendererFactory2"],Fe["\u0275DomRendererFactory2"],[Fe.EventManager,Fe["\u0275DomSharedStylesHost"]]),s["\u0275mpd"](5120,cg,tm,[]),s["\u0275mpd"](5120,Qg,em,[]),s["\u0275mpd"](4608,Nb,Qb,[i.DOCUMENT,cg,Qg]),s["\u0275mpd"](5120,s.RendererFactory2,nm,[Fe["\u0275DomRendererFactory2"],Nb,s.NgZone]),s["\u0275mpd"](6144,Fe["\u0275SharedStylesHost"],null,[Fe["\u0275DomSharedStylesHost"]]),s["\u0275mpd"](4608,s.Testability,s.Testability,[s.NgZone]),s["\u0275mpd"](4608,ju.b,Ub,[s.RendererFactory2,Fe.DOCUMENT]),s["\u0275mpd"](5120,tt.a,tt.B,[tt.l]),s["\u0275mpd"](4608,tt.f,tt.f,[]),s["\u0275mpd"](6144,tt.g,null,[tt.f]),s["\u0275mpd"](135680,tt.r,tt.r,[tt.l,s.NgModuleFactoryLoader,s.Compiler,s.Injector,tt.g]),s["\u0275mpd"](4608,tt.e,tt.e,[]),s["\u0275mpd"](5120,tt.F,tt.x,[tt.l,i.ViewportScroller,tt.h]),s["\u0275mpd"](5120,tt.i,tt.E,[tt.C]),s["\u0275mpd"](5120,s.APP_BOOTSTRAP_LISTENER,function(t){return[t]},[tt.i]),s["\u0275mpd"](4608,cm,cm,[]),s["\u0275mpd"](4608,um,um,[]),s["\u0275mpd"](4608,Te.E,Te.E,[]),s["\u0275mpd"](4608,Te.h,Te.h,[]),s["\u0275mpd"](5120,s.TRANSLATIONS,o,[s.LOCALE_ID]),s["\u0275mpd"](4608,xt.a,xt.a,[s.TRANSLATIONS_FORMAT,s.TRANSLATIONS,s.LOCALE_ID,[2,xt.b]]),s["\u0275mpd"](4608,Aa.a,Aa.a,[xt.a]),s["\u0275mpd"](4608,i.DatePipe,i.DatePipe,[s.LOCALE_ID]),s["\u0275mpd"](4608,Ze.a,Ze.a,[]),s["\u0275mpd"](4608,Ge.a,Ge.a,[]),s["\u0275mpd"](4608,It.a,It.a,[]),s["\u0275mpd"](4608,ht.a,ht.a,[It.a]),s["\u0275mpd"](4608,Pm.a,Pm.a,[It.a]),s["\u0275mpd"](4608,gt.a,gt.a,[It.a]),s["\u0275mpd"](4608,Mm.a,Mm.a,[]),s["\u0275mpd"](4608,qm.a,qm.a,[]),s["\u0275mpd"](4608,jm.a,jm.a,[]),s["\u0275mpd"](4608,Ii.a,Ii.a,[]),s["\u0275mpd"](4608,On.a,On.a,[i.DatePipe]),s["\u0275mpd"](4608,Fm.a,Fm.a,[]),s["\u0275mpd"](4608,zm.a,zm.a,[]),s["\u0275mpd"](4608,rc.a,rc.a,[]),s["\u0275mpd"](4608,Gm.a,Gm.a,[]),s["\u0275mpd"](4608,Ym.a,Ym.a,[]),s["\u0275mpd"](4608,Vm.a,Vm.a,[xt.a]),s["\u0275mpd"](4608,Rs.a,Rs.a,[]),s["\u0275mpd"](4608,Hm.a,Hm.a,[]),s["\u0275mpd"](4608,Bm.b,Bm.b,[]),s["\u0275mpd"](4608,X.a,X.a,[]),s["\u0275mpd"](4608,Q.a,Q.a,[s.RendererFactory2,s.PLATFORM_ID]),s["\u0275mpd"](4608,J.a,J.a,[s.ComponentFactoryResolver,s.NgZone,s.Injector,Q.a,s.ApplicationRef]),s["\u0275mpd"](4608,c.a,c.a,[]),s["\u0275mpd"](4608,pa.b,pa.b,[s.RendererFactory2,J.a]),s["\u0275mpd"](4608,Um.ScrollbarHelper,Um.ScrollbarHelper,[Fe.DOCUMENT]),s["\u0275mpd"](4608,Wm.DimensionsHelper,Wm.DimensionsHelper,[]),s["\u0275mpd"](4608,Km.ColumnChangesService,Km.ColumnChangesService,[]),s["\u0275mpd"](4608,bn.f,bn.f,[]),s["\u0275mpd"](4608,im.a,im.a,[tt.l,l.a]),s["\u0275mpd"](4608,Z.e,Z.e,[]),s["\u0275mpd"](4608,_r.NodeDraggableService,_r.NodeDraggableService,[]),s["\u0275mpd"](4608,$m.NodeMenuService,$m.NodeMenuService,[]),s["\u0275mpd"](4608,vr.TreeService,vr.TreeService,[_r.NodeDraggableService]),s["\u0275mpd"](4608,Nr.r,Nr.r,[]),s["\u0275mpd"](4608,Nr.t,Nr.t,[]),s["\u0275mpd"](4608,Nr.a,Nr.a,[]),s["\u0275mpd"](4608,Nr.h,Nr.h,[]),s["\u0275mpd"](4608,Nr.d,Nr.d,[]),s["\u0275mpd"](4608,Nr.j,Nr.j,[]),s["\u0275mpd"](4608,Nr.s,Nr.s,[Nr.t,Nr.j]),s["\u0275mpd"](4608,Qu,Qu,[]),s["\u0275mpd"](4608,ti,ti,[]),s["\u0275mpd"](4608,Ar,Ar,[]),s["\u0275mpd"](4608,ai,ai,[]),s["\u0275mpd"](4608,Zm.c,Zm.c,[]),s["\u0275mpd"](5120,m,w,[T]),s["\u0275mpd"](4608,_,_,[m]),s["\u0275mpd"](4608,Xm,Xm,[]),s["\u0275mpd"](1073742336,kt.e,kt.e,[]),s["\u0275mpd"](1073742336,kt.d,kt.d,[]),s["\u0275mpd"](1073742336,i.CommonModule,i.CommonModule,[]),s["\u0275mpd"](1073742336,S,S,[]),s["\u0275mpd"](512,s.ErrorHandler,ty,[s.Injector]),s["\u0275mpd"](1024,s.NgProbeToken,function(){return[tt.w()]},[]),s["\u0275mpd"](512,tt.C,tt.C,[s.Injector]),s["\u0275mpd"](1024,s.APP_INITIALIZER,function(t,e){return[Fe["\u0275angular_packages_platform_browser_platform_browser_j"](t),tt.D(e)]},[[2,s.NgProbeToken],tt.C]),s["\u0275mpd"](512,s.ApplicationInitStatus,s.ApplicationInitStatus,[[2,s.APP_INITIALIZER]]),s["\u0275mpd"](131584,s.ApplicationRef,s.ApplicationRef,[s.NgZone,s["\u0275Console"],s.Injector,s.ErrorHandler,s.ComponentFactoryResolver,s.ApplicationInitStatus]),s["\u0275mpd"](1073742336,s.ApplicationModule,s.ApplicationModule,[s.ApplicationRef]),s["\u0275mpd"](1073742336,Fe.BrowserModule,Fe.BrowserModule,[[3,Fe.BrowserModule]]),s["\u0275mpd"](1073742336,rm,rm,[]),s["\u0275mpd"](1073742336,q.i,q.i,[]),s["\u0275mpd"](1024,tt.v,tt.z,[[3,tt.l]]),s["\u0275mpd"](512,tt.t,tt.c,[]),s["\u0275mpd"](512,tt.b,tt.b,[]),s["\u0275mpd"](256,tt.h,{useHash:!0,preloadingStrategy:tt.f},[]),s["\u0275mpd"](1024,i.LocationStrategy,tt.y,[i.PlatformLocation,[2,i.APP_BASE_HREF],tt.h]),s["\u0275mpd"](512,i.Location,i.Location,[i.LocationStrategy]),s["\u0275mpd"](512,s.Compiler,s.Compiler,[]),s["\u0275mpd"](512,s.NgModuleFactoryLoader,s.SystemJsNgModuleLoader,[s.Compiler,[2,s.SystemJsNgModuleLoaderConfig]]),s["\u0275mpd"](1024,tt.j,function(){return[[{path:"",redirectTo:"dashboard",pathMatch:"full"},{path:"dashboard",component:Ne,canActivate:[im.a]},{path:"hosts",component:Xe,canActivate:[im.a],data:lm},{path:"monitor",component:ln,canActivate:[im.a],data:dm},{path:"osd",canActivate:[im.a],canActivateChild:[im.a],data:fm,children:[{path:"",component:fa}]},{path:"configuration",data:pm,children:[{path:"",component:Fa},{path:"edit/:name",component:tr,data:hm}]},{path:"crush-map",component:Tr,canActivate:[im.a],data:gm},{path:"logs",component:ki,canActivate:[im.a],data:bm},{path:"monitoring",canActivate:[im.a],data:mm,children:[{path:"",component:ms},{path:"silence/create",component:Ls,data:ym},{path:"silence/create/:id",component:Ls,data:vm},{path:"silence/edit/:id",component:Ls,data:_m},{path:"silence/recreate/:id",component:Ls,data:xm}]},{path:"perf_counters/:type/:id",component:Qs,canActivate:[im.a],data:Tm},{path:"mgr-modules",canActivate:[im.a],canActivateChild:[im.a],data:wm,children:[{path:"",component:lo},{path:"edit/:name",component:_o,data:Sm}]},{path:"pool",canActivate:[im.a],canActivateChild:[im.a],data:Om,loadChildren:"./ceph/pool/pool.module#RoutedPoolModule"},{path:"block",canActivateChild:[im.a],canActivate:[im.a],data:Im,loadChildren:"./ceph/block/block.module#RoutedBlockModule"},{path:"cephfs",component:lu,canActivate:[sm.a,im.a],data:Cm},{path:"rgw",canActivateChild:[sm.a,om,im.a],data:km,loadChildren:"./ceph/rgw/rgw.module#RoutedRgwModule"},{path:"user-management",canActivate:[im.a],canActivateChild:[im.a],data:Nm,loadChildren:"./core/auth/auth.module#RoutedAuthModule"},{path:"nfs/501/:message",component:gu,canActivate:[im.a],data:Rm},{path:"nfs",canActivate:[im.a],canActivateChild:[im.a,om],data:Am,children:[{path:"",component:Nu},{path:"create",component:vc,data:Dm},{path:"edit/:cluster_id/:export_id",component:vc,data:Em}]},{path:"sso/404",component:Rl},{path:"login",component:Xl},{path:"logout",children:[]},{path:"403",component:id},{path:"404",component:ld},{path:"**",redirectTo:"/404"}]]},[]),s["\u0275mpd"](1024,tt.l,tt.A,[s.ApplicationRef,tt.t,tt.b,i.Location,s.Injector,s.NgModuleFactoryLoader,s.Compiler,tt.j,tt.h,[2,tt.s],[2,tt.k]]),s["\u0275mpd"](1073742336,tt.p,tt.p,[[2,tt.v],[2,tt.l]]),s["\u0275mpd"](1073742336,Lm,Lm,[]),s["\u0275mpd"](1073742336,bn.e,bn.e,[]),s["\u0275mpd"](1073742336,Te.B,Te.B,[]),s["\u0275mpd"](1073742336,Te.n,Te.n,[]),s["\u0275mpd"](1073742336,X.d,X.d,[]),s["\u0275mpd"](1073742336,Te.x,Te.x,[]),s["\u0275mpd"](1073742336,ey.a,ey.a,[]),s["\u0275mpd"](1073742336,Bm.c,Bm.c,[]),s["\u0275mpd"](1073742336,c.d,c.d,[]),s["\u0275mpd"](1073742336,lt.ChartsModule,lt.ChartsModule,[]),s["\u0275mpd"](1073742336,pa.e,pa.e,[]),s["\u0275mpd"](1073742336,ny.a,ny.a,[]),s["\u0275mpd"](1073742336,ay.a,ay.a,[]),s["\u0275mpd"](1073742336,ry.NgxDatatableModule,ry.NgxDatatableModule,[]),s["\u0275mpd"](1073742336,iy.a,iy.a,[]),s["\u0275mpd"](1073742336,Nt.a,Nt.a,[]),s["\u0275mpd"](1073742336,sy.a,sy.a,[]),s["\u0275mpd"](1073742336,Z.c,Z.c,[]),s["\u0275mpd"](1073742336,oy.a,oy.a,[]),s["\u0275mpd"](1073742336,cp,cp,[]),s["\u0275mpd"](1073742336,uy,uy,[]),s["\u0275mpd"](1073742336,cy,cy,[]),s["\u0275mpd"](1073742336,ly.a,ly.a,[]),s["\u0275mpd"](1073742336,Nr.g,Nr.g,[]),s["\u0275mpd"](1073742336,dy.TreeModule,dy.TreeModule,[]),s["\u0275mpd"](1073742336,fy,fy,[]),s["\u0275mpd"](1073742336,ec,ec,[]),s["\u0275mpd"](1073742336,ii,ii,[]),s["\u0275mpd"](1073742336,py,py,[]),s["\u0275mpd"](1073742336,hy.a,hy.a,[]),s["\u0275mpd"](1073742336,gy,gy,[]),s["\u0275mpd"](1073742336,Zm.d,Zm.d,[]),s["\u0275mpd"](1073742336,by,by,[]),s["\u0275mpd"](1073742336,my,my,[]),s["\u0275mpd"](1073742336,yy,yy,[]),s["\u0275mpd"](1073742336,Jm,Jm,[]),s["\u0275mpd"](1073742336,u,u,[]),s["\u0275mpd"](256,kt.n,"XSRF-TOKEN",[]),s["\u0275mpd"](256,kt.o,"X-XSRF-TOKEN",[]),s["\u0275mpd"](256,s["\u0275APP_ROOT"],!0,[]),s["\u0275mpd"](256,am,"BrowserAnimations",[]),s["\u0275mpd"](256,s.TRANSLATIONS_FORMAT,"xlf",[]),s["\u0275mpd"](256,bn.a,{autoClose:!0,insideClick:!1},[]),s["\u0275mpd"](256,T,{},[]),s["\u0275mpd"](256,q.b,{default:q.a,config:{positionClass:"toast-top-right",preventDuplicates:!0,enableHtml:!0}},[])])});i.registerLocaleData(r.a),Object(s.enableProdMode)(),Fe.platformBrowser().bootstrapModuleFactory(vy).catch(function(t){return console.log(t)})},zavE:function(t,e,n){!function(t){"use strict";n("wd/R").defineLocale("en-SG",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(t){var e=t%10;return t+(1==~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")},week:{dow:1,doy:4}})}()},zo3G:function(t,e,n){"use strict";var a=n("mrSG"),r=function(t){function e(e,n){var a=t.call(this,e,n)||this;return a.scheduler=e,a.work=n,a}return a.__extends(e,t),e.prototype.schedule=function(e,n){return void 0===n&&(n=0),n>0?t.prototype.schedule.call(this,e,n):(this.delay=n,this.state=e,this.scheduler.flush(this),this)},e.prototype.execute=function(e,n){return n>0||this.closed?t.prototype.execute.call(this,e,n):this._execute(e,n)},e.prototype.requestAsyncId=function(e,n,a){return void 0===a&&(a=0),null!==a&&a>0||null===a&&this.delay>0?t.prototype.requestAsyncId.call(this,e,n,a):e.flush(this)},e}(n("h9Dq").a),i=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return a.__extends(e,t),e}(n("CS9Q").a);n.d(e,"a",function(){return s});var s=new i(r)},zotm:function(t,e,n){"use strict";n.d(e,"a",function(){return s});var a=n("rPjj"),r=n("Fxb1"),i=n("6blF");function s(t,e,n,s,o){if(void 0===o&&(o=new a.a(t,n,s)),!o.closed)return e instanceof i.a?e.subscribe(o):Object(r.a)(e)(o)}},"zrt+":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var a=n("6blF");function r(t){return!!t&&(t instanceof a.a||"function"==typeof t.lift&&"function"==typeof t.subscribe)}},zx6S:function(t,e,n){!function(t){"use strict";var e={words:{ss:["sekunda","sekunde","sekundi"],m:["jedan minut","jedne minute"],mm:["minut","minute","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mesec","meseca","meseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(t,e){return 1===t?e[0]:t>=2&&t<=4?e[1]:e[2]},translate:function(t,n,a){var r=e.words[a];return 1===a.length?n?r[0]:r[1]:t+" "+e.correctGrammaticalCase(t,r)}};t.defineLocale("sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_\u010detvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._\u010det._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_\u010de_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[ju\u010de u] LT",lastWeek:function(){return["[pro\u0161le] [nedelje] [u] LT","[pro\u0161log] [ponedeljka] [u] LT","[pro\u0161log] [utorka] [u] LT","[pro\u0161le] [srede] [u] LT","[pro\u0161log] [\u010detvrtka] [u] LT","[pro\u0161log] [petka] [u] LT","[pro\u0161le] [subote] [u] LT"][this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",ss:e.translate,m:e.translate,mm:e.translate,h:e.translate,hh:e.translate,d:"dan",dd:e.translate,M:"mesec",MM:e.translate,y:"godinu",yy:e.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n("wd/R"))}},[[0,1]]]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.f31db31652a3fd9f4bca.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.f31db31652a3fd9f4bca.js new file mode 100644 index 00000000..6b77d727 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/polyfills.f31db31652a3fd9f4bca.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{"+auO":function(t,e,n){var r=n("XKFU"),o=n("lvtm");r(r.S,"Math",{cbrt:function(t){return o(t=+t)*Math.pow(Math.abs(t),1/3)}})},"+lvF":function(t,e,n){t.exports=n("VTer")("native-function-to-string",Function.toString)},"+oPb":function(t,e,n){"use strict";n("OGtf")("blink",function(t){return function(){return t(this,"blink","","")}})},"+rLv":function(t,e,n){var r=n("dyZX").document;t.exports=r&&r.documentElement},"/8Fb":function(t,e,n){var r=n("XKFU"),o=n("UExd")(!0);r(r.S,"Object",{entries:function(t){return o(t)}})},"/KAi":function(t,e,n){var r=n("XKFU"),o=n("dyZX").isFinite;r(r.S,"Number",{isFinite:function(t){return"number"==typeof t&&o(t)}})},"/SS/":function(t,e,n){var r=n("XKFU");r(r.S,"Object",{setPrototypeOf:n("i5dc").set})},"/e88":function(t,e){t.exports="\t\n\v\f\r \xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff"},"/uf1":function(t,e,n){"use strict";var r=n("XKFU"),o=n("S/j/"),i=n("2OiF"),a=n("hswa");n("nh4g")&&r(r.P+n("xbSm"),"Object",{__defineSetter__:function(t,e){a.f(o(this),t,{set:i(e),enumerable:!0,configurable:!0})}})},"0/R4":function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},"0E+W":function(t,e,n){n("elZq")("Array")},"0LDn":function(t,e,n){"use strict";n("OGtf")("italics",function(t){return function(){return t(this,"i","","")}})},"0TWp":function(t,e,n){!function(){"use strict";!function(t){var e=t.performance;function n(t){e&&e.mark&&e.mark(t)}function r(t,n){e&&e.measure&&e.measure(t,n)}n("Zone");var o=!0===t.__zone_symbol__forceDuplicateZoneCheck;if(t.Zone){if(o||"function"!=typeof t.Zone.__symbol__)throw new Error("Zone already loaded.");return t.Zone}var i,a=function(){function e(t,e){this._parent=t,this._name=e?e.name||"unnamed":"",this._properties=e&&e.properties||{},this._zoneDelegate=new c(this,this._parent&&this._parent._zoneDelegate,e)}return e.assertZonePatched=function(){if(t.Promise!==F.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")},Object.defineProperty(e,"root",{get:function(){for(var t=e.current;t.parent;)t=t.parent;return t},enumerable:!0,configurable:!0}),Object.defineProperty(e,"current",{get:function(){return P.zone},enumerable:!0,configurable:!0}),Object.defineProperty(e,"currentTask",{get:function(){return j},enumerable:!0,configurable:!0}),e.__load_patch=function(i,a){if(F.hasOwnProperty(i)){if(o)throw Error("Already loaded patch: "+i)}else if(!t["__Zone_disable_"+i]){var u="Zone:"+i;n(u),F[i]=a(t,e,O),r(u,u)}},Object.defineProperty(e.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"name",{get:function(){return this._name},enumerable:!0,configurable:!0}),e.prototype.get=function(t){var e=this.getZoneWith(t);if(e)return e._properties[t]},e.prototype.getZoneWith=function(t){for(var e=this;e;){if(e._properties.hasOwnProperty(t))return e;e=e._parent}return null},e.prototype.fork=function(t){if(!t)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,t)},e.prototype.wrap=function(t,e){if("function"!=typeof t)throw new Error("Expecting function got: "+t);var n=this._zoneDelegate.intercept(this,t,e),r=this;return function(){return r.runGuarded(n,this,arguments,e)}},e.prototype.run=function(t,e,n,r){P={parent:P,zone:this};try{return this._zoneDelegate.invoke(this,t,e,n,r)}finally{P=P.parent}},e.prototype.runGuarded=function(t,e,n,r){void 0===e&&(e=null),P={parent:P,zone:this};try{try{return this._zoneDelegate.invoke(this,t,e,n,r)}catch(o){if(this._zoneDelegate.handleError(this,o))throw o}}finally{P=P.parent}},e.prototype.runTask=function(t,e,n){if(t.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(t.zone||y).name+"; Execution: "+this.name+")");if(t.state!==m||t.type!==E&&t.type!==T){var r=t.state!=k;r&&t._transitionTo(k,_),t.runCount++;var o=j;j=t,P={parent:P,zone:this};try{t.type==T&&t.data&&!t.data.isPeriodic&&(t.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,t,e,n)}catch(i){if(this._zoneDelegate.handleError(this,i))throw i}}finally{t.state!==m&&t.state!==x&&(t.type==E||t.data&&t.data.isPeriodic?r&&t._transitionTo(_,k):(t.runCount=0,this._updateTaskCount(t,-1),r&&t._transitionTo(m,k,m))),P=P.parent,j=o}}},e.prototype.scheduleTask=function(t){if(t.zone&&t.zone!==this)for(var e=this;e;){if(e===t.zone)throw Error("can not reschedule task to "+this.name+" which is descendants of the original zone "+t.zone.name);e=e.parent}t._transitionTo(b,m);var n=[];t._zoneDelegates=n,t._zone=this;try{t=this._zoneDelegate.scheduleTask(this,t)}catch(r){throw t._transitionTo(x,b,m),this._zoneDelegate.handleError(this,r),r}return t._zoneDelegates===n&&this._updateTaskCount(t,1),t.state==b&&t._transitionTo(_,b),t},e.prototype.scheduleMicroTask=function(t,e,n,r){return this.scheduleTask(new s(w,t,e,n,r,void 0))},e.prototype.scheduleMacroTask=function(t,e,n,r,o){return this.scheduleTask(new s(T,t,e,n,r,o))},e.prototype.scheduleEventTask=function(t,e,n,r,o){return this.scheduleTask(new s(E,t,e,n,r,o))},e.prototype.cancelTask=function(t){if(t.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(t.zone||y).name+"; Execution: "+this.name+")");t._transitionTo(S,_,k);try{this._zoneDelegate.cancelTask(this,t)}catch(e){throw t._transitionTo(x,S),this._zoneDelegate.handleError(this,e),e}return this._updateTaskCount(t,-1),t._transitionTo(m,S),t.runCount=0,t},e.prototype._updateTaskCount=function(t,e){var n=t._zoneDelegates;-1==e&&(t._zoneDelegates=null);for(var r=0;r0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:t})},t}(),s=function(){function e(n,r,o,i,a,u){this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=n,this.source=r,this.data=i,this.scheduleFn=a,this.cancelFn=u,this.callback=o;var c=this;this.invoke=n===E&&i&&i.useG?e.invokeTask:function(){return e.invokeTask.call(t,c,this,arguments)}}return e.invokeTask=function(t,e,n){t||(t=this),M++;try{return t.runCount++,t.zone.runTask(t,e,n)}finally{1==M&&g(),M--}},Object.defineProperty(e.prototype,"zone",{get:function(){return this._zone},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"state",{get:function(){return this._state},enumerable:!0,configurable:!0}),e.prototype.cancelScheduleRequest=function(){this._transitionTo(m,b)},e.prototype._transitionTo=function(t,e,n){if(this._state!==e&&this._state!==n)throw new Error(this.type+" '"+this.source+"': can not transition to '"+t+"', expecting state '"+e+"'"+(n?" or '"+n+"'":"")+", was '"+this._state+"'.");this._state=t,t==m&&(this._zoneDelegates=null)},e.prototype.toString=function(){return this.data&&void 0!==this.data.handleId?this.data.handleId.toString():Object.prototype.toString.call(this)},e.prototype.toJSON=function(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}},e}(),f=I("setTimeout"),l=I("Promise"),h=I("then"),p=[],v=!1;function d(e){if(0===M&&0===p.length)if(i||t[l]&&(i=t[l].resolve(0)),i){var n=i[h];n||(n=i.then),n.call(i,g)}else t[f](g,0);e&&p.push(e)}function g(){if(!v){for(v=!0;p.length;){var t=p;p=[];for(var e=0;e=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}}};Zone.__load_patch("ZoneAwarePromise",function(e,n,r){var o=Object.getOwnPropertyDescriptor,i=Object.defineProperty,a=r.symbol,u=[],c=a("Promise"),s=a("then"),f="__creationTrace__";r.onUnhandledError=function(t){if(r.showUncaughtError()){var e=t&&t.rejection;e?console.error("Unhandled Promise rejection:",e instanceof Error?e.message:e,"; Zone:",t.zone.name,"; Task:",t.task&&t.task.source,"; Value:",e,e instanceof Error?e.stack:void 0):console.error(t)}},r.microtaskDrainDone=function(){for(;u.length;)for(var t=function(){var t=u.shift();try{t.zone.runGuarded(function(){throw t})}catch(e){h(e)}};u.length;)t()};var l=a("unhandledPromiseRejectionHandler");function h(t){r.onUnhandledError(t);try{var e=n[l];e&&"function"==typeof e&&e.call(this,t)}catch(o){}}function p(t){return t&&t.then}function v(t){return t}function d(t){return A.reject(t)}var g=a("state"),y=a("value"),m=a("finally"),b=a("parentPromiseValue"),_=a("parentPromiseState"),k="Promise.then",S=null,x=!0,w=!1,T=0;function E(t,e){return function(n){try{j(t,e,n)}catch(r){j(t,!1,r)}}}var F=function(){var t=!1;return function(e){return function(){t||(t=!0,e.apply(null,arguments))}}},O="Promise resolved with itself",P=a("currentTaskTrace");function j(t,e,o){var a,c=F();if(t===o)throw new TypeError(O);if(t[g]===S){var s=null;try{"object"!=typeof o&&"function"!=typeof o||(s=o&&o.then)}catch(d){return c(function(){j(t,!1,d)})(),t}if(e!==w&&o instanceof A&&o.hasOwnProperty(g)&&o.hasOwnProperty(y)&&o[g]!==S)D(o),j(t,o[g],o[y]);else if(e!==w&&"function"==typeof s)try{s.call(o,c(E(t,e)),c(E(t,!1)))}catch(d){c(function(){j(t,!1,d)})()}else{t[g]=e;var l=t[y];if(t[y]=o,t[m]===m&&e===x&&(t[g]=t[_],t[y]=t[b]),e===w&&o instanceof Error){var h=n.currentTask&&n.currentTask.data&&n.currentTask.data[f];h&&i(o,P,{configurable:!0,enumerable:!1,writable:!0,value:h})}for(var p=0;p1?c[1]:null,p=h&&h.signal;return new Promise(function(h,v){var d=e.current.scheduleMacroTask("fetch",l,c,function(){var u,s=e.current;try{s[a]=!0,u=r.apply(t,c)}catch(l){return void v(l)}finally{s[a]=!1}if(!(u instanceof o)){var f=u.constructor;f[i]||n.patchThen(f)}u.then(function(t){"notScheduled"!==d.state&&d.invoke(),h(t)},function(t){"notScheduled"!==d.state&&d.invoke(),v(t)})},function(){if(s)if(p&&p.abortController&&!p.aborted&&"function"==typeof p.abortController.abort&&f)try{e.current[u]=!0,f.call(p.abortController)}finally{e.current[u]=!1}else v("cancel fetch need a AbortController.signal");else v("No AbortController supported, can not cancel fetch")});p&&p.abortController&&(p.abortController.task=d)})}}});var e=Object.getOwnPropertyDescriptor,n=Object.defineProperty,r=Object.getPrototypeOf,o=Object.create,i=Array.prototype.slice,a="addEventListener",u="removeEventListener",c=Zone.__symbol__(a),s=Zone.__symbol__(u),f="true",l="false",h="__zone_symbol__";function p(t,e){return Zone.current.wrap(t,e)}function v(t,e,n,r,o){return Zone.current.scheduleMacroTask(t,e,n,r,o)}var d=Zone.__symbol__,g="undefined"!=typeof window,y=g?window:void 0,m=g&&y||"object"==typeof self&&self||global,b="removeAttribute",_=[null];function k(t,e){for(var n=t.length-1;n>=0;n--)"function"==typeof t[n]&&(t[n]=p(t[n],e+"_"+n));return t}function S(t){return!t||!1!==t.writable&&!("function"==typeof t.get&&void 0===t.set)}var x="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,w=!("nw"in m)&&void 0!==m.process&&"[object process]"==={}.toString.call(m.process),T=!w&&!x&&!(!g||!y.HTMLElement),E=void 0!==m.process&&"[object process]"==={}.toString.call(m.process)&&!x&&!(!g||!y.HTMLElement),F={},O=function(t){if(t=t||m.event){var e=F[t.type];e||(e=F[t.type]=d("ON_PROPERTY"+t.type));var n,r=this||t.target||m,o=r[e];return T&&r===y&&"error"===t.type?!0===(n=o&&o.call(this,t.message,t.filename,t.lineno,t.colno,t.error))&&t.preventDefault():null==(n=o&&o.apply(this,arguments))||n||t.preventDefault(),n}};function P(t,r,o){var i=e(t,r);if(!i&&o&&e(o,r)&&(i={enumerable:!0,configurable:!0}),i&&i.configurable){var a=d("on"+r+"patched");if(!t.hasOwnProperty(a)||!t[a]){delete i.writable,delete i.value;var u=i.get,c=i.set,s=r.substr(2),f=F[s];f||(f=F[s]=d("ON_PROPERTY"+s)),i.set=function(e){var n=this;n||t!==m||(n=m),n&&(n[f]&&n.removeEventListener(s,O),c&&c.apply(n,_),"function"==typeof e?(n[f]=e,n.addEventListener(s,O,!1)):n[f]=null)},i.get=function(){var e=this;if(e||t!==m||(e=m),!e)return null;var n=e[f];if(n)return n;if(u){var o=u&&u.call(this);if(o)return i.set.call(this,o),"function"==typeof e[b]&&e.removeAttribute(r),o}return null},n(t,r,i),t[a]=!0}}}function j(t,e,n){if(e)for(var r=0;r1?new r(t,n):new r(t),l=e(f,"onmessage");return l&&!1===l.configurable?(c=o(f),s=f,[a,u,"send","close"].forEach(function(t){c[t]=function(){var e=i.call(arguments);if(t===a||t===u){var n=e.length>0?e[0]:void 0;if(n){var r=Zone.__symbol__("ON_PROPERTY"+n);f[r]=c[r]}}return f[t].apply(f,e)}})):c=f,j(c,["close","error","message","open"],s),c};var c=n.WebSocket;for(var s in r)c[s]=r[s]}(0,c)}}var gt=d("unbound");function yt(t,n,r,o){var i=Zone.__symbol__(r);if(!t[i]){var a=t[i]=t[r];t[r]=function(i,u,c){return u&&u.prototype&&o.forEach(function(t){var o,i,a,c,s=n+"."+r+"::"+t,f=u.prototype;if(f.hasOwnProperty(t)){var l=e(f,t);l&&l.value?(l.value=p(l.value,s),c=(a=l).configurable,rt(o=u.prototype,i=t,a=nt(o,i,a),c)):f[t]&&(f[t]=p(f[t],s))}else f[t]&&(f[t]=p(f[t],s))}),a.call(t,i,u,c)},U(t[r],a)}}Zone.__load_patch("util",function(t,e,n){n.patchOnProperties=j,n.patchMethod=A,n.bindArguments=k}),Zone.__load_patch("timers",function(t){B(t,"set","clear","Timeout"),B(t,"set","clear","Interval"),B(t,"set","clear","Immediate")}),Zone.__load_patch("requestAnimationFrame",function(t){B(t,"request","cancel","AnimationFrame"),B(t,"mozRequest","mozCancel","AnimationFrame"),B(t,"webkitRequest","webkitCancel","AnimationFrame")}),Zone.__load_patch("blocking",function(t,e){for(var n=["alert","prompt","confirm"],r=0;r=0&&"function"==typeof n[r.cbIdx]?v(r.name,n[r.cbIdx],r,i):t.apply(e,n)}})}()}),Zone.__load_patch("XHR",function(t,e){!function(f){var l=XMLHttpRequest.prototype,h=l[c],p=l[s];if(!h){var g=t.XMLHttpRequestEventTarget;if(g){var y=g.prototype;h=y[c],p=y[s]}}var m="readystatechange",b="scheduled";function _(t){var e=t.data,r=e.target;r[i]=!1,r[u]=!1;var a=r[o];h||(h=r[c],p=r[s]),a&&p.call(r,m,a);var f=r[o]=function(){if(r.readyState===r.DONE)if(!e.aborted&&r[i]&&t.state===b){var n=r.__zone_symbol__loadfalse;if(n&&n.length>0){var o=t.invoke;t.invoke=function(){for(var n=r.__zone_symbol__loadfalse,i=0;is;)c.call(t,a=u[s++])&&e.push(a);return e}},"1TsA":function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},"1sa7":function(t,e){t.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&t<1e-8?t-t*t/2:Math.log(1+t)}},"25dN":function(t,e,n){var r=n("XKFU");r(r.S,"Object",{is:n("g6HL")})},"2OiF":function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},"2Spj":function(t,e,n){var r=n("XKFU");r(r.P,"Function",{bind:n("8MEG")})},"2atp":function(t,e,n){var r=n("XKFU"),o=Math.atanh;r(r.S+r.F*!(o&&1/o(-0)<0),"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},"3Lyj":function(t,e,n){var r=n("KroJ");t.exports=function(t,e,n){for(var o in e)r(t,o,e[o],n);return t}},"4A4+":function(t,e,n){n("2Spj"),n("f3/d"),n("IXt9"),t.exports=n("g3g5").Function},"4LiD":function(t,e,n){"use strict";var r=n("dyZX"),o=n("XKFU"),i=n("KroJ"),a=n("3Lyj"),u=n("Z6vF"),c=n("SlkY"),s=n("9gX7"),f=n("0/R4"),l=n("eeVq"),h=n("XMVh"),p=n("fyDq"),v=n("Xbzi");t.exports=function(t,e,n,d,g,y){var m=r[t],b=m,_=g?"set":"add",k=b&&b.prototype,S={},x=function(t){var e=k[t];i(k,t,"delete"==t?function(t){return!(y&&!f(t))&&e.call(this,0===t?0:t)}:"has"==t?function(t){return!(y&&!f(t))&&e.call(this,0===t?0:t)}:"get"==t?function(t){return y&&!f(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof b&&(y||k.forEach&&!l(function(){(new b).entries().next()}))){var w=new b,T=w[_](y?{}:-0,1)!=w,E=l(function(){w.has(1)}),F=h(function(t){new b(t)}),O=!y&&l(function(){for(var t=new b,e=5;e--;)t[_](e,e);return!t.has(-0)});F||((b=e(function(e,n){s(e,b,t);var r=v(new m,e,b);return null!=n&&c(n,g,r[_],r),r})).prototype=k,k.constructor=b),(E||O)&&(x("delete"),x("has"),g&&x("get")),(O||T)&&x(_),y&&k.clear&&delete k.clear}else b=d.getConstructor(e,t,g,_),a(b.prototype,n),u.NEED=!0;return p(b,t),S[t]=b,o(o.G+o.W+o.F*(b!=m),S),y||d.setStrong(b,t,g),b}},"4R4u":function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},"5Pf0":function(t,e,n){var r=n("S/j/"),o=n("OP3Y");n("Xtr8")("getPrototypeOf",function(){return function(t){return o(r(t))}})},"69bn":function(t,e,n){var r=n("y3w9"),o=n("2OiF"),i=n("K0xU")("species");t.exports=function(t,e){var n,a=r(t).constructor;return void 0===a||null==(n=r(a)[i])?e:o(n)}},"6AQ9":function(t,e,n){"use strict";var r=n("XKFU"),o=n("8a7r");r(r.S+r.F*n("eeVq")(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,e=arguments.length,n=new("function"==typeof this?this:Array)(e);e>t;)o(n,t,arguments[t++]);return n.length=e,n}})},"6FMO":function(t,e,n){var r=n("0/R4"),o=n("EWmC"),i=n("K0xU")("species");t.exports=function(t){var e;return o(t)&&("function"!=typeof(e=t.constructor)||e!==Array&&!o(e.prototype)||(e=void 0),r(e)&&null===(e=e[i])&&(e=void 0)),void 0===e?Array:e}},"7h0T":function(t,e,n){var r=n("XKFU");r(r.S,"Number",{isNaN:function(t){return t!=t}})},"8+KV":function(t,e,n){"use strict";var r=n("XKFU"),o=n("CkkT")(0),i=n("LyE8")([].forEach,!0);r(r.P+r.F*!i,"Array",{forEach:function(t){return o(this,t,arguments[1])}})},"84bF":function(t,e,n){"use strict";n("OGtf")("small",function(t){return function(){return t(this,"small","","")}})},"8MEG":function(t,e,n){"use strict";var r=n("2OiF"),o=n("0/R4"),i=n("MfQN"),a=[].slice,u={};t.exports=Function.bind||function(t){var e=r(this),n=a.call(arguments,1),c=function(){var r=n.concat(a.call(arguments));return this instanceof c?function(t,e,n){if(!(e in u)){for(var r=[],o=0;o0?arguments[0]:void 0)}},{get:function(t){var e=r.getEntry(o(this,"Map"),t);return e&&e.v},set:function(t,e){return r.def(o(this,"Map"),0===t?0:t,e)}},r,!0)},"9P93":function(t,e,n){var r=n("XKFU"),o=Math.imul;r(r.S+r.F*n("eeVq")(function(){return-5!=o(4294967295,5)||2!=o.length}),"Math",{imul:function(t,e){var n=+t,r=+e,o=65535&n,i=65535&r;return 0|o*i+((65535&n>>>16)*i+o*(65535&r>>>16)<<16>>>0)}})},"9VmF":function(t,e,n){"use strict";var r=n("XKFU"),o=n("ne8i"),i=n("0sh+"),a="".startsWith;r(r.P+r.F*n("UUeW")("startsWith"),"String",{startsWith:function(t){var e=i(this,t,"startsWith"),n=o(Math.min(arguments.length>1?arguments[1]:void 0,e.length)),r=String(t);return a?a.call(e,r,n):e.slice(n,n+r.length)===r}})},"9gX7":function(t,e){t.exports=function(t,e,n,r){if(!(t instanceof e)||void 0!==r&&r in t)throw TypeError(n+": incorrect invocation!");return t}},A2zW:function(t,e,n){"use strict";var r=n("XKFU"),o=n("RYi7"),i=n("vvmO"),a=n("l0Rn"),u=1..toFixed,c=Math.floor,s=[0,0,0,0,0,0],f="Number.toFixed: incorrect invocation!",l=function(t,e){for(var n=-1,r=e;++n<6;)s[n]=(r+=t*s[n])%1e7,r=c(r/1e7)},h=function(t){for(var e=6,n=0;--e>=0;)s[e]=c((n+=s[e])/t),n=n%t*1e7},p=function(){for(var t=6,e="";--t>=0;)if(""!==e||0===t||0!==s[t]){var n=String(s[t]);e=""===e?n:e+a.call("0",7-n.length)+n}return e},v=function(t,e,n){return 0===e?n:e%2==1?v(t,e-1,n*t):v(t*t,e/2,n)};r(r.P+r.F*(!!u&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!n("eeVq")(function(){u.call({})})),"Number",{toFixed:function(t){var e,n,r,u,c=i(this,f),s=o(t),d="",g="0";if(s<0||s>20)throw RangeError(f);if(c!=c)return"NaN";if(c<=-1e21||c>=1e21)return String(c);if(c<0&&(d="-",c=-c),c>1e-21)if(n=(e=function(t){for(var e=0,n=t;n>=4096;)e+=12,n/=4096;for(;n>=2;)e+=1,n/=2;return e}(c*v(2,69,1))-69)<0?c*v(2,-e,1):c/v(2,e,1),n*=4503599627370496,(e=52-e)>0){for(l(0,n),r=s;r>=7;)l(1e7,0),r-=7;for(l(v(10,r,1),0),r=e-1;r>=23;)h(1<<23),r-=23;h(1<0?d+((u=g.length)<=s?"0."+a.call("0",s-u)+g:g.slice(0,u-s)+"."+g.slice(u-s)):d+g}})},A5AN:function(t,e,n){"use strict";var r=n("AvRE")(!0);t.exports=function(t,e,n){return e+(n?r(t,e).length:1)}},Afnz:function(t,e,n){"use strict";var r=n("LQAc"),o=n("XKFU"),i=n("KroJ"),a=n("Mukb"),u=n("hPIQ"),c=n("QaDb"),s=n("fyDq"),f=n("OP3Y"),l=n("K0xU")("iterator"),h=!([].keys&&"next"in[].keys()),p=function(){return this};t.exports=function(t,e,n,v,d,g,y){c(n,e,v);var m,b,_,k=function(t){if(!h&&t in T)return T[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",x="values"==d,w=!1,T=t.prototype,E=T[l]||T["@@iterator"]||d&&T[d],F=E||k(d),O=d?x?k("entries"):F:void 0,P="Array"==e&&T.entries||E;if(P&&(_=f(P.call(new t)))!==Object.prototype&&_.next&&(s(_,S,!0),r||"function"==typeof _[l]||a(_,l,p)),x&&E&&"values"!==E.name&&(w=!0,F=function(){return E.call(this)}),r&&!y||!h&&!w&&T[l]||a(T,l,F),u[e]=F,u[S]=p,d)if(m={values:x?F:k("values"),keys:g?F:k("keys"),entries:O},y)for(b in m)b in T||i(T,b,m[b]);else o(o.P+o.F*(h||w),e,m);return m}},AphP:function(t,e,n){"use strict";var r=n("XKFU"),o=n("S/j/"),i=n("apmT");r(r.P+r.F*n("eeVq")(function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}),"Date",{toJSON:function(t){var e=o(this),n=i(e);return"number"!=typeof n||isFinite(n)?e.toISOString():null}})},AvRE:function(t,e,n){var r=n("RYi7"),o=n("vhPU");t.exports=function(t){return function(e,n){var i,a,u=String(o(e)),c=r(n),s=u.length;return c<0||c>=s?t?"":void 0:(i=u.charCodeAt(c))<55296||i>56319||c+1===s||(a=u.charCodeAt(c+1))<56320||a>57343?t?u.charAt(c):i:t?u.slice(c,c+2):a-56320+(i-55296<<10)+65536}}},BC7C:function(t,e,n){var r=n("XKFU");r(r.S,"Math",{fround:n("kcoS")})},"BJ/l":function(t,e,n){var r=n("XKFU");r(r.S,"Math",{log1p:n("1sa7")})},BP8U:function(t,e,n){var r=n("XKFU"),o=n("PKUr");r(r.S+r.F*(Number.parseInt!=o),"Number",{parseInt:o})},Btvt:function(t,e,n){"use strict";var r=n("I8a+"),o={};o[n("K0xU")("toStringTag")]="z",o+""!="[object z]"&&n("KroJ")(Object.prototype,"toString",function(){return"[object "+r(this)+"]"},!0)},"C/va":function(t,e,n){"use strict";var r=n("y3w9");t.exports=function(){var t=r(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},CkkT:function(t,e,n){var r=n("m0Pp"),o=n("Ymqv"),i=n("S/j/"),a=n("ne8i"),u=n("zRwo");t.exports=function(t,e){var n=1==t,c=2==t,s=3==t,f=4==t,l=6==t,h=5==t||l,p=e||u;return function(e,u,v){for(var d,g,y=i(e),m=o(y),b=r(u,v,3),_=a(m.length),k=0,S=n?p(e,_):c?p(e,0):void 0;_>k;k++)if((h||k in m)&&(g=b(d=m[k],k,y),t))if(n)S[k]=g;else if(g)switch(t){case 3:return!0;case 5:return d;case 6:return k;case 2:S.push(d)}else if(f)return!1;return l?-1:s||f?f:S}}},CuTL:function(t,e,n){n("fyVe"),n("U2t9"),n("2atp"),n("+auO"),n("MtdB"),n("Jcmo"),n("nzyx"),n("BC7C"),n("x8ZO"),n("9P93"),n("eHKK"),n("BJ/l"),n("pp/T"),n("CyHz"),n("bBoP"),n("x8Yj"),n("hLT2"),t.exports=n("g3g5").Math},CyHz:function(t,e,n){var r=n("XKFU");r(r.S,"Math",{sign:n("lvtm")})},DNiP:function(t,e,n){"use strict";var r=n("XKFU"),o=n("eyMr");r(r.P+r.F*!n("LyE8")([].reduce,!0),"Array",{reduce:function(t){return o(this,t,arguments.length,arguments[1],!1)}})},DVgA:function(t,e,n){var r=n("zhAb"),o=n("4R4u");t.exports=Object.keys||function(t){return r(t,o)}},DW2E:function(t,e,n){var r=n("0/R4"),o=n("Z6vF").onFreeze;n("Xtr8")("freeze",function(t){return function(e){return t&&r(e)?t(o(e)):e}})},EK0E:function(t,e,n){"use strict";var r,o=n("dyZX"),i=n("CkkT")(0),a=n("KroJ"),u=n("Z6vF"),c=n("czNK"),s=n("ZD67"),f=n("0/R4"),l=n("s5qY"),h=n("s5qY"),p=!o.ActiveXObject&&"ActiveXObject"in o,v=u.getWeak,d=Object.isExtensible,g=s.ufstore,y=function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},m={get:function(t){if(f(t)){var e=v(t);return!0===e?g(l(this,"WeakMap")).get(t):e?e[this._i]:void 0}},set:function(t,e){return s.def(l(this,"WeakMap"),t,e)}},b=t.exports=n("4LiD")("WeakMap",y,m,s,!0,!0);h&&p&&(c((r=s.getConstructor(y,"WeakMap")).prototype,m),u.NEED=!0,i(["delete","has","get","set"],function(t){var e=b.prototype,n=e[t];a(e,t,function(e,o){if(f(e)&&!d(e)){this._f||(this._f=new r);var i=this._f[t](e,o);return"set"==t?this:i}return n.call(this,e,o)})}))},EWmC:function(t,e,n){var r=n("LZWt");t.exports=Array.isArray||function(t){return"Array"==r(t)}},EemH:function(t,e,n){var r=n("UqcF"),o=n("RjD/"),i=n("aCFj"),a=n("apmT"),u=n("aagx"),c=n("xpql"),s=Object.getOwnPropertyDescriptor;e.f=n("nh4g")?s:function(t,e){if(t=i(t),e=a(e,!0),c)try{return s(t,e)}catch(n){}if(u(t,e))return o(!r.f.call(t,e),t[e])}},FEjr:function(t,e,n){"use strict";n("OGtf")("strike",function(t){return function(){return t(this,"strike","","")}})},FJW5:function(t,e,n){var r=n("hswa"),o=n("y3w9"),i=n("DVgA");t.exports=n("nh4g")?Object.defineProperties:function(t,e){o(t);for(var n,a=i(e),u=a.length,c=0;u>c;)r.f(t,n=a[c++],e[n]);return t}},FLlr:function(t,e,n){var r=n("XKFU");r(r.P,"String",{repeat:n("l0Rn")})},FlsD:function(t,e,n){var r=n("0/R4");n("Xtr8")("isExtensible",function(t){return function(e){return!!r(e)&&(!t||t(e))}})},GNAe:function(t,e,n){var r=n("XKFU"),o=n("PKUr");r(r.G+r.F*(parseInt!=o),{parseInt:o})},H6hf:function(t,e,n){var r=n("y3w9");t.exports=function(t,e,n,o){try{return o?e(r(n)[0],n[1]):e(n)}catch(a){var i=t.return;throw void 0!==i&&r(i.call(t)),a}}},"HAE/":function(t,e,n){var r=n("XKFU");r(r.S+r.F*!n("nh4g"),"Object",{defineProperty:n("hswa").f})},HEwt:function(t,e,n){"use strict";var r=n("m0Pp"),o=n("XKFU"),i=n("S/j/"),a=n("H6hf"),u=n("M6Qj"),c=n("ne8i"),s=n("8a7r"),f=n("J+6e");o(o.S+o.F*!n("XMVh")(function(t){Array.from(t)}),"Array",{from:function(t){var e,n,o,l,h=i(t),p="function"==typeof this?this:Array,v=arguments.length,d=v>1?arguments[1]:void 0,g=void 0!==d,y=0,m=f(h);if(g&&(d=r(d,v>2?arguments[2]:void 0,2)),null==m||p==Array&&u(m))for(n=new p(e=c(h.length));e>y;y++)s(n,y,g?d(h[y],y):h[y]);else for(l=m.call(h),n=new p;!(o=l.next()).done;y++)s(n,y,g?a(l,d,[o.value,y],!0):o.value);return n.length=y,n}})},I78e:function(t,e,n){"use strict";var r=n("XKFU"),o=n("+rLv"),i=n("LZWt"),a=n("d/Gc"),u=n("ne8i"),c=[].slice;r(r.P+r.F*n("eeVq")(function(){o&&c.call(o)}),"Array",{slice:function(t,e){var n=u(this.length),r=i(this);if(e=void 0===e?n:e,"Array"==r)return c.call(this,t,e);for(var o=a(t,n),s=a(e,n),f=u(s-o),l=new Array(f),h=0;h1?arguments[1]:void 0)}}),n("nGyu")(i)},"IU+Z":function(t,e,n){"use strict";n("sMXx");var r=n("KroJ"),o=n("Mukb"),i=n("eeVq"),a=n("vhPU"),u=n("K0xU"),c=n("Ugos"),s=u("species"),f=!i(function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")}),l=function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var n="ab".split(t);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();t.exports=function(t,e,n){var h=u(t),p=!i(function(){var e={};return e[h]=function(){return 7},7!=""[t](e)}),v=p?!i(function(){var e=!1,n=/a/;return n.exec=function(){return e=!0,null},"split"===t&&(n.constructor={},n.constructor[s]=function(){return n}),n[h](""),!e}):void 0;if(!p||!v||"replace"===t&&!f||"split"===t&&!l){var d=/./[h],g=n(a,h,""[t],function(t,e,n,r,o){return e.exec===c?p&&!o?{done:!0,value:d.call(e,n,r)}:{done:!0,value:t.call(n,e,r)}:{done:!1}}),y=g[1];r(String.prototype,t,g[0]),o(RegExp.prototype,h,2==e?function(t,e){return y.call(t,this,e)}:function(t){return y.call(t,this)})}}},IXt9:function(t,e,n){"use strict";var r=n("0/R4"),o=n("OP3Y"),i=n("K0xU")("hasInstance"),a=Function.prototype;i in a||n("hswa").f(a,i,{value:function(t){if("function"!=typeof this||!r(t))return!1;if(!r(this.prototype))return t instanceof this;for(;t=o(t);)if(this.prototype===t)return!0;return!1}})},Iw71:function(t,e,n){var r=n("0/R4"),o=n("dyZX").document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},"J+6e":function(t,e,n){var r=n("I8a+"),o=n("K0xU")("iterator"),i=n("hPIQ");t.exports=n("g3g5").getIteratorMethod=function(t){if(null!=t)return t[o]||t["@@iterator"]||i[r(t)]}},JCqj:function(t,e,n){"use strict";n("OGtf")("sup",function(t){return function(){return t(this,"sup","","")}})},Jcmo:function(t,e,n){var r=n("XKFU"),o=Math.exp;r(r.S,"Math",{cosh:function(t){return(o(t=+t)+o(-t))/2}})},JduL:function(t,e,n){n("Xtr8")("getOwnPropertyNames",function(){return n("e7yV").f})},JiEa:function(t,e){e.f=Object.getOwnPropertySymbols},K0xU:function(t,e,n){var r=n("VTer")("wks"),o=n("ylqs"),i=n("dyZX").Symbol,a="function"==typeof i;(t.exports=function(t){return r[t]||(r[t]=a&&i[t]||(a?i:o)("Symbol."+t))}).store=r},KKXr:function(t,e,n){"use strict";var r=n("quPj"),o=n("y3w9"),i=n("69bn"),a=n("A5AN"),u=n("ne8i"),c=n("Xxuz"),s=n("Ugos"),f=n("eeVq"),l=Math.min,h=[].push,p=!f(function(){RegExp(4294967295,"y")});n("IU+Z")("split",2,function(t,e,n,f){var v;return v="c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1).length||2!="ab".split(/(?:ab)*/).length||4!=".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length?function(t,e){var o=String(this);if(void 0===t&&0===e)return[];if(!r(t))return n.call(o,t,e);for(var i,a,u,c=[],f=0,l=void 0===e?4294967295:e>>>0,p=new RegExp(t.source,(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":"")+"g");(i=s.call(p,o))&&!((a=p.lastIndex)>f&&(c.push(o.slice(f,i.index)),i.length>1&&i.index=l));)p.lastIndex===i.index&&p.lastIndex++;return f===o.length?!u&&p.test("")||c.push(""):c.push(o.slice(f)),c.length>l?c.slice(0,l):c}:"0".split(void 0,0).length?function(t,e){return void 0===t&&0===e?[]:n.call(this,t,e)}:n,[function(n,r){var o=t(this),i=null==n?void 0:n[e];return void 0!==i?i.call(n,o,r):v.call(String(o),n,r)},function(t,e){var r=f(v,t,this,e,v!==n);if(r.done)return r.value;var s=o(t),h=String(this),d=i(s,RegExp),g=s.unicode,y=new d(p?s:"^(?:"+s.source+")",(s.ignoreCase?"i":"")+(s.multiline?"m":"")+(s.unicode?"u":"")+(p?"y":"g")),m=void 0===e?4294967295:e>>>0;if(0===m)return[];if(0===h.length)return null===c(y,h)?[h]:[];for(var b=0,_=0,k=[];_document.F=Object<\/script>"),t.close(),c=t.F;r--;)delete c.prototype[i[r]];return c()};t.exports=Object.create||function(t,e){var n;return null!==t?(u.prototype=r(t),n=new u,u.prototype=null,n[a]=t):n=c(),void 0===e?n:o(n,e)}},L9s1:function(t,e,n){"use strict";var r=n("XKFU"),o=n("0sh+");r(r.P+r.F*n("UUeW")("includes"),"String",{includes:function(t){return!!~o(this,t,"includes").indexOf(t,arguments.length>1?arguments[1]:void 0)}})},LK8F:function(t,e,n){var r=n("XKFU");r(r.S,"Array",{isArray:n("EWmC")})},LQAc:function(t,e){t.exports=!1},LVwc:function(t,e){var n=Math.expm1;t.exports=!n||n(10)>22025.465794806718||n(10)<22025.465794806718||-2e-17!=n(-2e-17)?function(t){return 0==(t=+t)?t:t>-1e-6&&t<1e-6?t+t*t/2:Math.exp(t)-1}:n},LZWt:function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},Ljet:function(t,e,n){var r=n("XKFU");r(r.S,"Number",{EPSILON:Math.pow(2,-52)})},Lmuc:function(t,e,n){n("xfY5"),n("A2zW"),n("VKir"),n("Ljet"),n("/KAi"),n("fN96"),n("7h0T"),n("sbF8"),n("h/M4"),n("knhD"),n("XfKG"),n("BP8U"),t.exports=n("g3g5").Number},LyE8:function(t,e,n){"use strict";var r=n("eeVq");t.exports=function(t,e){return!!t&&r(function(){e?t.call(null,function(){},1):t.call(null)})}},M6Qj:function(t,e,n){var r=n("hPIQ"),o=n("K0xU")("iterator"),i=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||i[o]===t)}},MfQN:function(t,e){t.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},MtdB:function(t,e,n){var r=n("XKFU");r(r.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},Mukb:function(t,e,n){var r=n("hswa"),o=n("RjD/");t.exports=n("nh4g")?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},N8g3:function(t,e,n){e.f=n("K0xU")},Nr18:function(t,e,n){"use strict";var r=n("S/j/"),o=n("d/Gc"),i=n("ne8i");t.exports=function(t){for(var e=r(this),n=i(e.length),a=arguments.length,u=o(a>1?arguments[1]:void 0,n),c=a>2?arguments[2]:void 0,s=void 0===c?n:o(c,n);s>u;)e[u++]=t;return e}},Nz9U:function(t,e,n){"use strict";var r=n("XKFU"),o=n("aCFj"),i=[].join;r(r.P+r.F*(n("Ymqv")!=Object||!n("LyE8")(i)),"Array",{join:function(t){return i.call(o(this),void 0===t?",":t)}})},OEbY:function(t,e,n){n("nh4g")&&"g"!=/./g.flags&&n("hswa").f(RegExp.prototype,"flags",{configurable:!0,get:n("C/va")})},OG14:function(t,e,n){"use strict";var r=n("y3w9"),o=n("g6HL"),i=n("Xxuz");n("IU+Z")("search",1,function(t,e,n,a){return[function(n){var r=t(this),o=null==n?void 0:n[e];return void 0!==o?o.call(n,r):new RegExp(n)[e](String(r))},function(t){var e=a(n,t,this);if(e.done)return e.value;var u=r(t),c=String(this),s=u.lastIndex;o(s,0)||(u.lastIndex=0);var f=i(u,c);return o(u.lastIndex,s)||(u.lastIndex=s),null===f?-1:f.index}]})},OGtf:function(t,e,n){var r=n("XKFU"),o=n("eeVq"),i=n("vhPU"),a=/"/g,u=function(t,e,n,r){var o=String(i(t)),u="<"+e;return""!==n&&(u+=" "+n+'="'+String(r).replace(a,""")+'"'),u+">"+o+""};t.exports=function(t,e){var n={};n[t]=e(u),r(r.P+r.F*o(function(){var e=""[t]('"');return e!==e.toLowerCase()||e.split('"').length>3}),"String",n)}},OP3Y:function(t,e,n){var r=n("aagx"),o=n("S/j/"),i=n("YTvA")("IE_PROTO"),a=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=o(t),r(t,i)?t[i]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?a:null}},OnI7:function(t,e,n){var r=n("dyZX"),o=n("g3g5"),i=n("LQAc"),a=n("N8g3"),u=n("hswa").f;t.exports=function(t){var e=o.Symbol||(o.Symbol=i?{}:r.Symbol||{});"_"==t.charAt(0)||t in e||u(e,t,{value:a.f(t)})}},Oyvg:function(t,e,n){var r=n("dyZX"),o=n("Xbzi"),i=n("hswa").f,a=n("kJMx").f,u=n("quPj"),c=n("C/va"),s=r.RegExp,f=s,l=s.prototype,h=/a/g,p=/a/g,v=new s(h)!==h;if(n("nh4g")&&(!v||n("eeVq")(function(){return p[n("K0xU")("match")]=!1,s(h)!=h||s(p)==p||"/a/i"!=s(h,"i")}))){s=function(t,e){var n=this instanceof s,r=u(t),i=void 0===e;return!n&&r&&t.constructor===s&&i?t:o(v?new f(r&&!i?t.source:t,e):f((r=t instanceof s)?t.source:t,r&&i?c.call(t):e),n?this:l,s)};for(var d=function(t){t in s||i(s,t,{configurable:!0,get:function(){return f[t]},set:function(e){f[t]=e}})},g=a(f),y=0;g.length>y;)d(g[y++]);l.constructor=s,s.prototype=l,n("KroJ")(r,"RegExp",s)}n("elZq")("RegExp")},PKUr:function(t,e,n){var r=n("dyZX").parseInt,o=n("qncB").trim,i=n("/e88"),a=/^[-+]?0[xX]/;t.exports=8!==r(i+"08")||22!==r(i+"0x16")?function(t,e){var n=o(String(t),3);return r(n,e>>>0||(a.test(n)?16:10))}:r},QaDb:function(t,e,n){"use strict";var r=n("Kuth"),o=n("RjD/"),i=n("fyDq"),a={};n("Mukb")(a,n("K0xU")("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(a,{next:o(1,n)}),i(t,e+" Iterator")}},RQRG:function(t,e,n){"use strict";var r=n("XKFU"),o=n("S/j/"),i=n("2OiF"),a=n("hswa");n("nh4g")&&r(r.P+n("xbSm"),"Object",{__defineGetter__:function(t,e){a.f(o(this),t,{get:i(e),enumerable:!0,configurable:!0})}})},RW0V:function(t,e,n){var r=n("S/j/"),o=n("DVgA");n("Xtr8")("keys",function(){return function(t){return o(r(t))}})},RYi7:function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},"RjD/":function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},"S/j/":function(t,e,n){var r=n("vhPU");t.exports=function(t){return Object(r(t))}},SMB2:function(t,e,n){"use strict";n("OGtf")("bold",function(t){return function(){return t(this,"b","","")}})},SPin:function(t,e,n){"use strict";var r=n("XKFU"),o=n("eyMr");r(r.P+r.F*!n("LyE8")([].reduceRight,!0),"Array",{reduceRight:function(t){return o(this,t,arguments.length,arguments[1],!0)}})},SRfc:function(t,e,n){"use strict";var r=n("y3w9"),o=n("ne8i"),i=n("A5AN"),a=n("Xxuz");n("IU+Z")("match",1,function(t,e,n,u){return[function(n){var r=t(this),o=null==n?void 0:n[e];return void 0!==o?o.call(n,r):new RegExp(n)[e](String(r))},function(t){var e=u(n,t,this);if(e.done)return e.value;var c=r(t),s=String(this);if(!c.global)return a(c,s);var f=c.unicode;c.lastIndex=0;for(var l,h=[],p=0;null!==(l=a(c,s));){var v=String(l[0]);h[p]=v,""===v&&(c.lastIndex=i(s,o(c.lastIndex),f)),p++}return 0===p?null:h}]})},SlkY:function(t,e,n){var r=n("m0Pp"),o=n("H6hf"),i=n("M6Qj"),a=n("y3w9"),u=n("ne8i"),c=n("J+6e"),s={},f={};(e=t.exports=function(t,e,n,l,h){var p,v,d,g,y=h?function(){return t}:c(t),m=r(n,l,e?2:1),b=0;if("function"!=typeof y)throw TypeError(t+" is not iterable!");if(i(y)){for(p=u(t.length);p>b;b++)if((g=e?m(a(v=t[b])[0],v[1]):m(t[b]))===s||g===f)return g}else for(d=y.call(t);!(v=d.next()).done;)if((g=o(d,m,v.value,e))===s||g===f)return g}).BREAK=s,e.RETURN=f},T39b:function(t,e,n){"use strict";var r=n("wmvG"),o=n("s5qY");t.exports=n("4LiD")("Set",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return r.def(o(this,"Set"),t=0===t?0:t,t)}},r)},Tze0:function(t,e,n){"use strict";n("qncB")("trim",function(t){return function(){return t(this,3)}})},U2t9:function(t,e,n){var r=n("XKFU"),o=Math.asinh;r(r.S+r.F*!(o&&1/o(0)>0),"Math",{asinh:function t(e){return isFinite(e=+e)&&0!=e?e<0?-t(-e):Math.log(e+Math.sqrt(e*e+1)):e}})},UExd:function(t,e,n){var r=n("DVgA"),o=n("aCFj"),i=n("UqcF").f;t.exports=function(t){return function(e){for(var n,a=o(e),u=r(a),c=u.length,s=0,f=[];c>s;)i.call(a,n=u[s++])&&f.push(t?[n,a[n]]:a[n]);return f}}},UUeW:function(t,e,n){var r=n("K0xU")("match");t.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[r]=!1,!"/./"[t](e)}catch(o){}}return!0}},Ugos:function(t,e,n){"use strict";var r,o,i=n("C/va"),a=RegExp.prototype.exec,u=String.prototype.replace,c=a,s=(o=/b*/g,a.call(r=/a/,"a"),a.call(o,"a"),0!==r.lastIndex||0!==o.lastIndex),f=void 0!==/()??/.exec("")[1];(s||f)&&(c=function(t){var e,n,r,o,c=this;return f&&(n=new RegExp("^"+c.source+"$(?!\\s)",i.call(c))),s&&(e=c.lastIndex),r=a.call(c,t),s&&r&&(c.lastIndex=c.global?r.index+r[0].length:e),f&&r&&r.length>1&&u.call(r[0],n,function(){for(o=1;oa;){if(e=+arguments[a++],o(e,1114111)!==e)throw RangeError(e+" is not a valid code point");n.push(e<65536?i(e):i(55296+((e-=65536)>>10),e%1024+56320))}return n.join("")}})},WLL4:function(t,e,n){var r=n("XKFU");r(r.S+r.F*!n("nh4g"),"Object",{defineProperties:n("FJW5")})},XKFU:function(t,e,n){var r=n("dyZX"),o=n("g3g5"),i=n("Mukb"),a=n("KroJ"),u=n("m0Pp"),c=function(t,e,n){var s,f,l,h,p=t&c.F,v=t&c.G,d=t&c.P,g=t&c.B,y=v?r:t&c.S?r[e]||(r[e]={}):(r[e]||{}).prototype,m=v?o:o[e]||(o[e]={}),b=m.prototype||(m.prototype={});for(s in v&&(n=e),n)l=((f=!p&&y&&void 0!==y[s])?y:n)[s],h=g&&f?u(l,r):d&&"function"==typeof l?u(Function.call,l):l,y&&a(y,s,l,t&c.U),m[s]!=l&&i(m,s,h),d&&b[s]!=l&&(b[s]=l)};r.core=o,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},XMVh:function(t,e,n){var r=n("K0xU")("iterator"),o=!1;try{var i=[7][r]();i.return=function(){o=!0},Array.from(i,function(){throw 2})}catch(a){}t.exports=function(t,e){if(!e&&!o)return!1;var n=!1;try{var i=[7],u=i[r]();u.next=function(){return{done:n=!0}},i[r]=function(){return u},t(i)}catch(a){}return n}},Xbzi:function(t,e,n){var r=n("0/R4"),o=n("i5dc").set;t.exports=function(t,e,n){var i,a=e.constructor;return a!==n&&"function"==typeof a&&(i=a.prototype)!==n.prototype&&r(i)&&o&&o(t,i),t}},XfKG:function(t,e,n){var r=n("XKFU"),o=n("11IZ");r(r.S+r.F*(Number.parseFloat!=o),"Number",{parseFloat:o})},XfO3:function(t,e,n){"use strict";var r=n("AvRE")(!0);n("Afnz")(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},Xtr8:function(t,e,n){var r=n("XKFU"),o=n("g3g5"),i=n("eeVq");t.exports=function(t,e){var n=(o.Object||{})[t]||Object[t],a={};a[t]=e(n),r(r.S+r.F*i(function(){n(1)}),"Object",a)}},Xxuz:function(t,e,n){"use strict";var r=n("I8a+"),o=RegExp.prototype.exec;t.exports=function(t,e){var n=t.exec;if("function"==typeof n){var i=n.call(t,e);if("object"!=typeof i)throw new TypeError("RegExp exec method returned something other than an Object or null");return i}if("RegExp"!==r(t))throw new TypeError("RegExp#exec called on incompatible receiver");return o.call(t,e)}},YJVH:function(t,e,n){"use strict";var r=n("XKFU"),o=n("CkkT")(4);r(r.P+r.F*!n("LyE8")([].every,!0),"Array",{every:function(t){return o(this,t,arguments[1])}})},YTvA:function(t,e,n){var r=n("VTer")("keys"),o=n("ylqs");t.exports=function(t){return r[t]||(r[t]=o(t))}},Ymqv:function(t,e,n){var r=n("LZWt");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},Z6vF:function(t,e,n){var r=n("ylqs")("meta"),o=n("0/R4"),i=n("aagx"),a=n("hswa").f,u=0,c=Object.isExtensible||function(){return!0},s=!n("eeVq")(function(){return c(Object.preventExtensions({}))}),f=function(t){a(t,r,{value:{i:"O"+ ++u,w:{}}})},l=t.exports={KEY:r,NEED:!1,fastKey:function(t,e){if(!o(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!i(t,r)){if(!c(t))return"F";if(!e)return"E";f(t)}return t[r].i},getWeak:function(t,e){if(!i(t,r)){if(!c(t))return!0;if(!e)return!1;f(t)}return t[r].w},onFreeze:function(t){return s&&l.NEED&&c(t)&&!i(t,r)&&f(t),t}}},ZD67:function(t,e,n){"use strict";var r=n("3Lyj"),o=n("Z6vF").getWeak,i=n("y3w9"),a=n("0/R4"),u=n("9gX7"),c=n("SlkY"),s=n("CkkT"),f=n("aagx"),l=n("s5qY"),h=s(5),p=s(6),v=0,d=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},y=function(t,e){return h(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=y(this,t);if(e)return e[1]},has:function(t){return!!y(this,t)},set:function(t,e){var n=y(this,t);n?n[1]=e:this.a.push([t,e])},delete:function(t){var e=p(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},t.exports={getConstructor:function(t,e,n,i){var s=t(function(t,r){u(t,s,e,"_i"),t._t=e,t._i=v++,t._l=void 0,null!=r&&c(r,n,t[i],t)});return r(s.prototype,{delete:function(t){if(!a(t))return!1;var n=o(t);return!0===n?d(l(this,e)).delete(t):n&&f(n,this._i)&&delete n[this._i]},has:function(t){if(!a(t))return!1;var n=o(t);return!0===n?d(l(this,e)).has(t):n&&f(n,this._i)}}),s},def:function(t,e,n){var r=o(i(e),!0);return!0===r?d(t).set(e,n):r[t._i]=n,t},ufstore:d}},"ZNX/":function(t,e,n){"use strict";var r=n("XKFU"),o=n("S/j/"),i=n("apmT"),a=n("OP3Y"),u=n("EemH").f;n("nh4g")&&r(r.P+n("xbSm"),"Object",{__lookupSetter__:function(t){var e,n=o(this),r=i(t,!0);do{if(e=u(n,r))return e.set}while(n=a(n))}})},Zshi:function(t,e,n){var r=n("0/R4");n("Xtr8")("isFrozen",function(t){return function(e){return!r(e)||!!t&&t(e)}})},Zz4T:function(t,e,n){"use strict";n("OGtf")("sub",function(t){return function(){return t(this,"sub","","")}})},a0L2:function(t,e,n){n("jm62"),n("hhXQ"),n("/8Fb"),n("RQRG"),n("/uf1"),n("uaHG"),n("ZNX/"),t.exports=n("g3g5").Object},a1Th:function(t,e,n){"use strict";n("OEbY");var r=n("y3w9"),o=n("C/va"),i=n("nh4g"),a=/./.toString,u=function(t){n("KroJ")(RegExp.prototype,"toString",t,!0)};n("eeVq")(function(){return"/a/b"!=a.call({source:"a",flags:"b"})})?u(function(){var t=r(this);return"/".concat(t.source,"/","flags"in t?t.flags:!i&&t instanceof RegExp?o.call(t):void 0)}):"toString"!=a.name&&u(function(){return a.call(this)})},aCFj:function(t,e,n){var r=n("Ymqv"),o=n("vhPU");t.exports=function(t){return r(o(t))}},aagx:function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},apmT:function(t,e,n){var r=n("0/R4");t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},bBoP:function(t,e,n){var r=n("XKFU"),o=n("LVwc"),i=Math.exp;r(r.S+r.F*n("eeVq")(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(o(t)-o(-t))/2:(i(t-1)-i(-t-1))*(Math.E/2)}})},bDcW:function(t,e,n){"use strict";n("OGtf")("fontcolor",function(t){return function(e){return t(this,"font","color",e)}})},bHtr:function(t,e,n){var r=n("XKFU");r(r.P,"Array",{fill:n("Nr18")}),n("nGyu")("fill")},bWfx:function(t,e,n){"use strict";var r=n("XKFU"),o=n("CkkT")(1);r(r.P+r.F*!n("LyE8")([].map,!0),"Array",{map:function(t){return o(this,t,arguments[1])}})},czNK:function(t,e,n){"use strict";var r=n("DVgA"),o=n("JiEa"),i=n("UqcF"),a=n("S/j/"),u=n("Ymqv"),c=Object.assign;t.exports=!c||n("eeVq")(function(){var t={},e={},n=Symbol(),r="abcdefghijklmnopqrst";return t[n]=7,r.split("").forEach(function(t){e[t]=t}),7!=c({},t)[n]||Object.keys(c({},e)).join("")!=r})?function(t,e){for(var n=a(t),c=arguments.length,s=1,f=o.f,l=i.f;c>s;)for(var h,p=u(arguments[s++]),v=f?r(p).concat(f(p)):r(p),d=v.length,g=0;d>g;)l.call(p,h=v[g++])&&(n[h]=p[h]);return n}:c},"d/Gc":function(t,e,n){var r=n("RYi7"),o=Math.max,i=Math.min;t.exports=function(t,e){return(t=r(t))<0?o(t+e,0):i(t,e)}},"dE+T":function(t,e,n){var r=n("XKFU");r(r.P,"Array",{copyWithin:n("upKx")}),n("nGyu")("copyWithin")},dQfE:function(t,e,n){n("XfO3"),n("LK8F"),n("HEwt"),n("6AQ9"),n("Nz9U"),n("I78e"),n("Vd3H"),n("8+KV"),n("bWfx"),n("0l/t"),n("dZ+Y"),n("YJVH"),n("DNiP"),n("SPin"),n("V+eJ"),n("mGWK"),n("dE+T"),n("bHtr"),n("dRSK"),n("INYr"),n("0E+W"),n("yt8O"),t.exports=n("g3g5").Array},dRSK:function(t,e,n){"use strict";var r=n("XKFU"),o=n("CkkT")(5),i=!0;"find"in[]&&Array(1).find(function(){i=!1}),r(r.P+r.F*i,"Array",{find:function(t){return o(this,t,arguments.length>1?arguments[1]:void 0)}}),n("nGyu")("find")},"dZ+Y":function(t,e,n){"use strict";var r=n("XKFU"),o=n("CkkT")(3);r(r.P+r.F*!n("LyE8")([].some,!0),"Array",{some:function(t){return o(this,t,arguments[1])}})},dyZX:function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},e7yV:function(t,e,n){var r=n("aCFj"),o=n("kJMx").f,i={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return a&&"[object Window]"==i.call(t)?function(t){try{return o(t)}catch(e){return a.slice()}}(t):o(r(t))}},eHKK:function(t,e,n){var r=n("XKFU");r(r.S,"Math",{log10:function(t){return Math.log(t)*Math.LOG10E}})},eI33:function(t,e,n){var r=n("XKFU"),o=n("aCFj"),i=n("ne8i");r(r.S,"String",{raw:function(t){for(var e=o(t.raw),n=i(e.length),r=arguments.length,a=[],u=0;n>u;)a.push(String(e[u++])),u=0:l>h;h+=p)h in f&&(u=e(u,f[h],h,s));return u}},"f3/d":function(t,e,n){var r=n("hswa").f,o=Function.prototype,i=/^\s*function ([^ (]*)/;"name"in o||n("nh4g")&&r(o,"name",{configurable:!0,get:function(){try{return(""+this).match(i)[1]}catch(t){return""}}})},fN96:function(t,e,n){var r=n("XKFU");r(r.S,"Number",{isInteger:n("nBIS")})},fyDq:function(t,e,n){var r=n("hswa").f,o=n("aagx"),i=n("K0xU")("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,i)&&r(t,i,{configurable:!0,value:e})}},fyVe:function(t,e,n){var r=n("XKFU"),o=n("1sa7"),i=Math.sqrt,a=Math.acosh;r(r.S+r.F*!(a&&710==Math.floor(a(Number.MAX_VALUE))&&a(1/0)==1/0),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:o(t-1+i(t-1)*i(t+1))}})},g3g5:function(t,e){var n=t.exports={version:"2.6.5"};"number"==typeof __e&&(__e=n)},g4EE:function(t,e,n){"use strict";var r=n("y3w9"),o=n("apmT");t.exports=function(t){if("string"!==t&&"number"!==t&&"default"!==t)throw TypeError("Incorrect hint");return o(r(this),"number"!=t)}},g6HL:function(t,e){t.exports=Object.is||function(t,e){return t===e?0!==t||1/t==1/e:t!=t&&e!=e}},"h/M4":function(t,e,n){var r=n("XKFU");r(r.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},h7Nl:function(t,e,n){var r=Date.prototype,o=r.toString,i=r.getTime;new Date(NaN)+""!="Invalid Date"&&n("KroJ")(r,"toString",function(){var t=i.call(this);return t==t?o.call(this):"Invalid Date"})},hEkN:function(t,e,n){"use strict";n("OGtf")("anchor",function(t){return function(e){return t(this,"a","name",e)}})},hHhE:function(t,e,n){var r=n("XKFU");r(r.S,"Object",{create:n("Kuth")})},hLT2:function(t,e,n){var r=n("XKFU");r(r.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},"hN/g":function(t,e,n){"use strict";n.r(e),n("dQfE"),n("nx1v"),n("4A4+"),n("qKs0"),n("CuTL"),n("Lmuc"),n("99sg"),n("ifmr"),n("oka+"),n("rfyP"),n("VXxg"),n("V5/Y"),n("vqGA"),n("hYbK"),n("a0L2"),n("0TWp")},hPIQ:function(t,e){t.exports={}},hYbK:function(t,e,n){n("Btvt"),n("yt8O"),n("EK0E"),t.exports=n("g3g5").WeakMap},hhXQ:function(t,e,n){var r=n("XKFU"),o=n("UExd")(!1);r(r.S,"Object",{values:function(t){return o(t)}})},hswa:function(t,e,n){var r=n("y3w9"),o=n("xpql"),i=n("apmT"),a=Object.defineProperty;e.f=n("nh4g")?Object.defineProperty:function(t,e,n){if(r(t),e=i(e,!0),r(n),o)try{return a(t,e,n)}catch(u){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},i5dc:function(t,e,n){var r=n("0/R4"),o=n("y3w9"),i=function(t,e){if(o(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,r){try{(r=n("m0Pp")(Function.call,n("EemH").f(Object.prototype,"__proto__").set,2))(t,[]),e=!(t instanceof Array)}catch(o){e=!0}return function(t,n){return i(t,n),e?t.__proto__=n:r(t,n),t}}({},!1):void 0),check:i}},ifmr:function(t,e,n){n("tyy+"),t.exports=n("g3g5").parseFloat},ioFf:function(t,e,n){"use strict";var r=n("dyZX"),o=n("aagx"),i=n("nh4g"),a=n("XKFU"),u=n("KroJ"),c=n("Z6vF").KEY,s=n("eeVq"),f=n("VTer"),l=n("fyDq"),h=n("ylqs"),p=n("K0xU"),v=n("N8g3"),d=n("OnI7"),g=n("1MBn"),y=n("EWmC"),m=n("y3w9"),b=n("0/R4"),_=n("aCFj"),k=n("apmT"),S=n("RjD/"),x=n("Kuth"),w=n("e7yV"),T=n("EemH"),E=n("hswa"),F=n("DVgA"),O=T.f,P=E.f,j=w.f,M=r.Symbol,D=r.JSON,I=D&&D.stringify,A=p("_hidden"),U=p("toPrimitive"),X={}.propertyIsEnumerable,Z=f("symbol-registry"),K=f("symbols"),C=f("op-symbols"),L=Object.prototype,R="function"==typeof M,z=r.QObject,N=!z||!z.prototype||!z.prototype.findChild,q=i&&s(function(){return 7!=x(P({},"a",{get:function(){return P(this,"a",{value:7}).a}})).a})?function(t,e,n){var r=O(L,e);r&&delete L[e],P(t,e,n),r&&t!==L&&P(L,e,r)}:P,V=function(t){var e=K[t]=x(M.prototype);return e._k=t,e},G=R&&"symbol"==typeof M.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof M},H=function(t,e,n){return t===L&&H(C,e,n),m(t),e=k(e,!0),m(n),o(K,e)?(n.enumerable?(o(t,A)&&t[A][e]&&(t[A][e]=!1),n=x(n,{enumerable:S(0,!1)})):(o(t,A)||P(t,A,S(1,{})),t[A][e]=!0),q(t,e,n)):P(t,e,n)},W=function(t,e){m(t);for(var n,r=g(e=_(e)),o=0,i=r.length;i>o;)H(t,n=r[o++],e[n]);return t},Y=function(t){var e=X.call(this,t=k(t,!0));return!(this===L&&o(K,t)&&!o(C,t))&&(!(e||!o(this,t)||!o(K,t)||o(this,A)&&this[A][t])||e)},B=function(t,e){if(t=_(t),e=k(e,!0),t!==L||!o(K,e)||o(C,e)){var n=O(t,e);return!n||!o(K,e)||o(t,A)&&t[A][e]||(n.enumerable=!0),n}},J=function(t){for(var e,n=j(_(t)),r=[],i=0;n.length>i;)o(K,e=n[i++])||e==A||e==c||r.push(e);return r},Q=function(t){for(var e,n=t===L,r=j(n?C:_(t)),i=[],a=0;r.length>a;)!o(K,e=r[a++])||n&&!o(L,e)||i.push(K[e]);return i};R||(u((M=function(){if(this instanceof M)throw TypeError("Symbol is not a constructor!");var t=h(arguments.length>0?arguments[0]:void 0),e=function(n){this===L&&e.call(C,n),o(this,A)&&o(this[A],t)&&(this[A][t]=!1),q(this,t,S(1,n))};return i&&N&&q(L,t,{configurable:!0,set:e}),V(t)}).prototype,"toString",function(){return this._k}),T.f=B,E.f=H,n("kJMx").f=w.f=J,n("UqcF").f=Y,n("JiEa").f=Q,i&&!n("LQAc")&&u(L,"propertyIsEnumerable",Y,!0),v.f=function(t){return V(p(t))}),a(a.G+a.W+a.F*!R,{Symbol:M});for(var $="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),tt=0;$.length>tt;)p($[tt++]);for(var et=F(p.store),nt=0;et.length>nt;)d(et[nt++]);a(a.S+a.F*!R,"Symbol",{for:function(t){return o(Z,t+="")?Z[t]:Z[t]=M(t)},keyFor:function(t){if(!G(t))throw TypeError(t+" is not a symbol!");for(var e in Z)if(Z[e]===t)return e},useSetter:function(){N=!0},useSimple:function(){N=!1}}),a(a.S+a.F*!R,"Object",{create:function(t,e){return void 0===e?x(t):W(x(t),e)},defineProperty:H,defineProperties:W,getOwnPropertyDescriptor:B,getOwnPropertyNames:J,getOwnPropertySymbols:Q}),D&&a(a.S+a.F*(!R||s(function(){var t=M();return"[null]"!=I([t])||"{}"!=I({a:t})||"{}"!=I(Object(t))})),"JSON",{stringify:function(t){for(var e,n,r=[t],o=1;arguments.length>o;)r.push(arguments[o++]);if(n=e=r[1],(b(e)||void 0!==t)&&!G(t))return y(e)||(e=function(t,e){if("function"==typeof n&&(e=n.call(this,t,e)),!G(e))return e}),r[1]=e,I.apply(D,r)}}),M.prototype[U]||n("Mukb")(M.prototype,U,M.prototype.valueOf),l(M,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},jm62:function(t,e,n){var r=n("XKFU"),o=n("mQtv"),i=n("aCFj"),a=n("EemH"),u=n("8a7r");r(r.S,"Object",{getOwnPropertyDescriptors:function(t){for(var e,n,r=i(t),c=a.f,s=o(r),f={},l=0;s.length>l;)void 0!==(n=c(r,e=s[l++]))&&u(f,e,n);return f}})},jqX0:function(t,e,n){var r=n("XKFU"),o=n("jtBr");r(r.P+r.F*(Date.prototype.toISOString!==o),"Date",{toISOString:o})},jtBr:function(t,e,n){"use strict";var r=n("eeVq"),o=Date.prototype.getTime,i=Date.prototype.toISOString,a=function(t){return t>9?t:"0"+t};t.exports=r(function(){return"0385-07-25T07:06:39.999Z"!=i.call(new Date(-5e13-1))})||!r(function(){i.call(new Date(NaN))})?function(){if(!isFinite(o.call(this)))throw RangeError("Invalid time value");var t=this,e=t.getUTCFullYear(),n=t.getUTCMilliseconds(),r=e<0?"-":e>9999?"+":"";return r+("00000"+Math.abs(e)).slice(r?-6:-4)+"-"+a(t.getUTCMonth()+1)+"-"+a(t.getUTCDate())+"T"+a(t.getUTCHours())+":"+a(t.getUTCMinutes())+":"+a(t.getUTCSeconds())+"."+(n>99?n:"0"+a(n))+"Z"}:i},kJMx:function(t,e,n){var r=n("zhAb"),o=n("4R4u").concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return r(t,o)}},kcoS:function(t,e,n){var r=n("lvtm"),o=Math.pow,i=o(2,-52),a=o(2,-23),u=o(2,127)*(2-a),c=o(2,-126);t.exports=Math.fround||function(t){var e,n,o=Math.abs(t),s=r(t);return ou||n!=n?s*(1/0):s*n}},knhD:function(t,e,n){var r=n("XKFU");r(r.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},l0Rn:function(t,e,n){"use strict";var r=n("RYi7"),o=n("vhPU");t.exports=function(t){var e=String(o(this)),n="",i=r(t);if(i<0||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},lvtm:function(t,e){t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},m0Pp:function(t,e,n){var r=n("2OiF");t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},mGWK:function(t,e,n){"use strict";var r=n("XKFU"),o=n("aCFj"),i=n("RYi7"),a=n("ne8i"),u=[].lastIndexOf,c=!!u&&1/[1].lastIndexOf(1,-0)<0;r(r.P+r.F*(c||!n("LyE8")(u)),"Array",{lastIndexOf:function(t){if(c)return u.apply(this,arguments)||0;var e=o(this),n=a(e.length),r=n-1;for(arguments.length>1&&(r=Math.min(r,i(arguments[1]))),r<0&&(r=n+r);r>=0;r--)if(r in e&&e[r]===t)return r||0;return-1}})},mQtv:function(t,e,n){var r=n("kJMx"),o=n("JiEa"),i=n("y3w9"),a=n("dyZX").Reflect;t.exports=a&&a.ownKeys||function(t){var e=r.f(i(t)),n=o.f;return n?e.concat(n(t)):e}},mYba:function(t,e,n){var r=n("aCFj"),o=n("EemH").f;n("Xtr8")("getOwnPropertyDescriptor",function(){return function(t,e){return o(r(t),e)}})},mura:function(t,e,n){var r=n("0/R4"),o=n("Z6vF").onFreeze;n("Xtr8")("preventExtensions",function(t){return function(e){return t&&r(e)?t(o(e)):e}})},nBIS:function(t,e,n){var r=n("0/R4"),o=Math.floor;t.exports=function(t){return!r(t)&&isFinite(t)&&o(t)===t}},nGyu:function(t,e,n){var r=n("K0xU")("unscopables"),o=Array.prototype;null==o[r]&&n("Mukb")(o,r,{}),t.exports=function(t){o[r][t]=!0}},nIY7:function(t,e,n){"use strict";n("OGtf")("big",function(t){return function(){return t(this,"big","","")}})},ne8i:function(t,e,n){var r=n("RYi7"),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},nh4g:function(t,e,n){t.exports=!n("eeVq")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},nsiH:function(t,e,n){"use strict";n("OGtf")("fontsize",function(t){return function(e){return t(this,"font","size",e)}})},nx1v:function(t,e,n){n("eM6i"),n("AphP"),n("jqX0"),n("h7Nl"),n("yM4b"),t.exports=Date},nzyx:function(t,e,n){var r=n("XKFU"),o=n("LVwc");r(r.S+r.F*(o!=Math.expm1),"Math",{expm1:o})},oDIu:function(t,e,n){"use strict";var r=n("XKFU"),o=n("AvRE")(!1);r(r.P,"String",{codePointAt:function(t){return o(this,t)}})},"oka+":function(t,e,n){n("GNAe"),t.exports=n("g3g5").parseInt},pIFo:function(t,e,n){"use strict";var r=n("y3w9"),o=n("S/j/"),i=n("ne8i"),a=n("RYi7"),u=n("A5AN"),c=n("Xxuz"),s=Math.max,f=Math.min,l=Math.floor,h=/\$([$&`']|\d\d?|<[^>]*>)/g,p=/\$([$&`']|\d\d?)/g;n("IU+Z")("replace",2,function(t,e,n,v){return[function(r,o){var i=t(this),a=null==r?void 0:r[e];return void 0!==a?a.call(r,i,o):n.call(String(i),r,o)},function(t,e){var o=v(n,t,this,e);if(o.done)return o.value;var l=r(t),h=String(this),p="function"==typeof e;p||(e=String(e));var g=l.global;if(g){var y=l.unicode;l.lastIndex=0}for(var m=[];;){var b=c(l,h);if(null===b)break;if(m.push(b),!g)break;""===String(b[0])&&(l.lastIndex=u(h,i(l.lastIndex),y))}for(var _,k="",S=0,x=0;x=S&&(k+=h.slice(S,T)+j,S=T+w.length)}return k+h.slice(S)}];function d(t,e,r,i,a,u){var c=r+t.length,s=i.length,f=p;return void 0!==a&&(a=o(a),f=h),n.call(u,f,function(n,o){var u;switch(o.charAt(0)){case"$":return"$";case"&":return t;case"`":return e.slice(0,r);case"'":return e.slice(c);case"<":u=a[o.slice(1,-1)];break;default:var f=+o;if(0===f)return n;if(f>s){var h=l(f/10);return 0===h?n:h<=s?void 0===i[h-1]?o.charAt(1):i[h-1]+o.charAt(1):n}u=i[f-1]}return void 0===u?"":u})}})},"pp/T":function(t,e,n){var r=n("XKFU");r(r.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},qKs0:function(t,e,n){n("Btvt"),n("XfO3"),n("rGqo"),n("9AAn"),t.exports=n("g3g5").Map},qncB:function(t,e,n){var r=n("XKFU"),o=n("vhPU"),i=n("eeVq"),a=n("/e88"),u="["+a+"]",c=RegExp("^"+u+u+"*"),s=RegExp(u+u+"*$"),f=function(t,e,n){var o={},u=i(function(){return!!a[t]()||"\u200b\x85"!="\u200b\x85"[t]()}),c=o[t]=u?e(l):a[t];n&&(o[n]=c),r(r.P+r.F*u,"String",o)},l=f.trim=function(t,e){return t=String(o(t)),1&e&&(t=t.replace(c,"")),2&e&&(t=t.replace(s,"")),t};t.exports=f},quPj:function(t,e,n){var r=n("0/R4"),o=n("LZWt"),i=n("K0xU")("match");t.exports=function(t){var e;return r(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==o(t))}},rGqo:function(t,e,n){for(var r=n("yt8O"),o=n("DVgA"),i=n("KroJ"),a=n("dyZX"),u=n("Mukb"),c=n("hPIQ"),s=n("K0xU"),f=s("iterator"),l=s("toStringTag"),h=c.Array,p={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},v=o(p),d=0;d1?arguments[1]:void 0,r=o(e.length),u=void 0===n?r:Math.min(o(n),r),c=String(t);return a?a.call(e,c,u):e.slice(u-c.length,u)===c}})},s5qY:function(t,e,n){var r=n("0/R4");t.exports=function(t,e){if(!r(t)||t._t!==e)throw TypeError("Incompatible receiver, "+e+" required!");return t}},sMXx:function(t,e,n){"use strict";var r=n("Ugos");n("XKFU")({target:"RegExp",proto:!0,forced:r!==/./.exec},{exec:r})},sbF8:function(t,e,n){var r=n("XKFU"),o=n("nBIS"),i=Math.abs;r(r.S,"Number",{isSafeInteger:function(t){return o(t)&&i(t)<=9007199254740991}})},tUrg:function(t,e,n){"use strict";n("OGtf")("link",function(t){return function(e){return t(this,"a","href",e)}})},"tyy+":function(t,e,n){var r=n("XKFU"),o=n("11IZ");r(r.G+r.F*(parseFloat!=o),{parseFloat:o})},uaHG:function(t,e,n){"use strict";var r=n("XKFU"),o=n("S/j/"),i=n("apmT"),a=n("OP3Y"),u=n("EemH").f;n("nh4g")&&r(r.P+n("xbSm"),"Object",{__lookupGetter__:function(t){var e,n=o(this),r=i(t,!0);do{if(e=u(n,r))return e.get}while(n=a(n))}})},upKx:function(t,e,n){"use strict";var r=n("S/j/"),o=n("d/Gc"),i=n("ne8i");t.exports=[].copyWithin||function(t,e){var n=r(this),a=i(n.length),u=o(t,a),c=o(e,a),s=arguments.length>2?arguments[2]:void 0,f=Math.min((void 0===s?a:o(s,a))-c,a-u),l=1;for(c0;)c in n?n[u]=n[c]:delete n[u],u+=l,c+=l;return n}},vhPU:function(t,e){t.exports=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t}},vqGA:function(t,e,n){n("ioFf"),n("Btvt"),t.exports=n("g3g5").Symbol},vvmO:function(t,e,n){var r=n("LZWt");t.exports=function(t,e){if("number"!=typeof t&&"Number"!=r(t))throw TypeError(e);return+t}},w2a5:function(t,e,n){var r=n("aCFj"),o=n("ne8i"),i=n("d/Gc");t.exports=function(t){return function(e,n,a){var u,c=r(e),s=o(c.length),f=i(a,s);if(t&&n!=n){for(;s>f;)if((u=c[f++])!=u)return!0}else for(;s>f;f++)if((t||f in c)&&c[f]===n)return t||f||0;return!t&&-1}}},wmvG:function(t,e,n){"use strict";var r=n("hswa").f,o=n("Kuth"),i=n("3Lyj"),a=n("m0Pp"),u=n("9gX7"),c=n("SlkY"),s=n("Afnz"),f=n("1TsA"),l=n("elZq"),h=n("nh4g"),p=n("Z6vF").fastKey,v=n("s5qY"),d=h?"_s":"size",g=function(t,e){var n,r=p(e);if("F"!==r)return t._i[r];for(n=t._f;n;n=n.n)if(n.k==e)return n};t.exports={getConstructor:function(t,e,n,s){var f=t(function(t,r){u(t,f,e,"_i"),t._t=e,t._i=o(null),t._f=void 0,t._l=void 0,t[d]=0,null!=r&&c(r,n,t[s],t)});return i(f.prototype,{clear:function(){for(var t=v(this,e),n=t._i,r=t._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete n[r.i];t._f=t._l=void 0,t[d]=0},delete:function(t){var n=v(this,e),r=g(n,t);if(r){var o=r.n,i=r.p;delete n._i[r.i],r.r=!0,i&&(i.n=o),o&&(o.p=i),n._f==r&&(n._f=o),n._l==r&&(n._l=i),n[d]--}return!!r},forEach:function(t){v(this,e);for(var n,r=a(t,arguments.length>1?arguments[1]:void 0,3);n=n?n.n:this._f;)for(r(n.v,n.k,this);n&&n.r;)n=n.p},has:function(t){return!!g(v(this,e),t)}}),h&&r(f.prototype,"size",{get:function(){return v(this,e)[d]}}),f},def:function(t,e,n){var r,o,i=g(t,e);return i?i.v=n:(t._l=i={i:o=p(e,!0),k:e,v:n,p:r=t._l,n:void 0,r:!1},t._f||(t._f=i),r&&(r.n=i),t[d]++,"F"!==o&&(t._i[o]=i)),t},getEntry:g,setStrong:function(t,e,n){s(t,e,function(t,n){this._t=v(t,e),this._k=n,this._l=void 0},function(){for(var t=this._k,e=this._l;e&&e.r;)e=e.p;return this._t&&(this._l=e=e?e.n:this._t._f)?f(0,"keys"==t?e.k:"values"==t?e.v:[e.k,e.v]):(this._t=void 0,f(1))},n?"entries":"values",!n,!0),l(e)}}},x8Yj:function(t,e,n){var r=n("XKFU"),o=n("LVwc"),i=Math.exp;r(r.S,"Math",{tanh:function(t){var e=o(t=+t),n=o(-t);return e==1/0?1:n==1/0?-1:(e-n)/(i(t)+i(-t))}})},x8ZO:function(t,e,n){var r=n("XKFU"),o=Math.abs;r(r.S,"Math",{hypot:function(t,e){for(var n,r,i=0,a=0,u=arguments.length,c=0;a0?(r=n/c)*r:n;return c===1/0?1/0:c*Math.sqrt(i)}})},xbSm:function(t,e,n){"use strict";t.exports=n("LQAc")||!n("eeVq")(function(){var t=Math.random();__defineSetter__.call(null,t,function(){}),delete n("dyZX")[t]})},xfY5:function(t,e,n){"use strict";var r=n("dyZX"),o=n("aagx"),i=n("LZWt"),a=n("Xbzi"),u=n("apmT"),c=n("eeVq"),s=n("kJMx").f,f=n("EemH").f,l=n("hswa").f,h=n("qncB").trim,p=r.Number,v=p,d=p.prototype,g="Number"==i(n("Kuth")(d)),y="trim"in String.prototype,m=function(t){var e=u(t,!1);if("string"==typeof e&&e.length>2){var n,r,o,i=(e=y?e.trim():h(e,3)).charCodeAt(0);if(43===i||45===i){if(88===(n=e.charCodeAt(2))||120===n)return NaN}else if(48===i){switch(e.charCodeAt(1)){case 66:case 98:r=2,o=49;break;case 79:case 111:r=8,o=55;break;default:return+e}for(var a,c=e.slice(2),s=0,f=c.length;so)return NaN;return parseInt(c,r)}}return+e};if(!p(" 0o1")||!p("0b1")||p("+0x1")){p=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof p&&(g?c(function(){d.valueOf.call(n)}):"Number"!=i(n))?a(new v(m(e)),n,p):m(e)};for(var b,_=n("nh4g")?s(v):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),k=0;_.length>k;k++)o(v,b=_[k])&&!o(p,b)&&l(p,b,f(v,b));p.prototype=d,d.constructor=p,n("KroJ")(r,"Number",p)}},xpql:function(t,e,n){t.exports=!n("nh4g")&&!n("eeVq")(function(){return 7!=Object.defineProperty(n("Iw71")("div"),"a",{get:function(){return 7}}).a})},y3w9:function(t,e,n){var r=n("0/R4");t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},yM4b:function(t,e,n){var r=n("K0xU")("toPrimitive"),o=Date.prototype;r in o||n("Mukb")(o,r,n("g4EE"))},ylqs:function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},yt8O:function(t,e,n){"use strict";var r=n("nGyu"),o=n("1TsA"),i=n("hPIQ"),a=n("aCFj");t.exports=n("Afnz")(Array,"Array",function(t,e){this._t=a(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,o(1)):o(0,"keys"==e?n:"values"==e?t[n]:[n,t[n]])},"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},z2o2:function(t,e,n){var r=n("0/R4"),o=n("Z6vF").onFreeze;n("Xtr8")("seal",function(t){return function(e){return t&&r(e)?t(o(e)):e}})},zRwo:function(t,e,n){var r=n("6FMO");t.exports=function(t,e){return new(r(t))(e)}},zhAb:function(t,e,n){var r=n("aagx"),o=n("aCFj"),i=n("w2a5")(!1),a=n("YTvA")("IE_PROTO");t.exports=function(t,e){var n,u=o(t),c=0,s=[];for(n in u)n!=a&&r(u,n)&&s.push(n);for(;e.length>c;)r(u,n=e[c++])&&(~i(s,n)||s.push(n));return s}}},[[1,1]]]); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.074db273ef932a67d91b.svg b/src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.074db273ef932a67d91b.svg new file mode 100644 index 00000000..5c51f66d --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/prometheus_logo.074db273ef932a67d91b.svg @@ -0,0 +1,50 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.ff444394af058f159c51.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.ff444394af058f159c51.js new file mode 100644 index 00000000..e2ef17c2 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/runtime.ff444394af058f159c51.js @@ -0,0 +1 @@ +!function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],p=0,d=[];pn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new r,i=this.values,a=n.values;for(var o in i)i.hasOwnProperty(o)&&("[object Array]"===(e={}.toString.call(t=i[o]))?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return n}},r.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},r.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},r.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]}function d(t){var e=u(t),n=e[0],i=e[1],a=e[2];return i/=100,a/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function h(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,a[u]=255*(r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e);return a}function c(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}}function f(t){var e,n,i,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),i=6*o-(e=Math.floor(6*o)),0!=(1&e)&&(i=1-i),a=s+i*((n=1-l)-s),e){default:case 6:case 0:r=n,g=a,b=s;break;case 1:r=a,g=n,b=s;break;case 2:r=s,g=n,b=a;break;case 3:r=s,g=a,b=n;break;case 4:r=a,g=s,b=n;break;case 5:r=n,g=s,b=a}return[255*r,255*g,255*b]}function m(t){var e=t[1]/100,n=t[2]/100,i=t[3]/100;return[255*(1-Math.min(1,t[0]/100*(1-i)+i)),255*(1-Math.min(1,e*(1-i)+i)),255*(1-Math.min(1,n*(1-i)+i))]}function p(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]}function v(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]}function y(t){var e,n,i,a,r=t[0],o=t[1],s=t[2];return r<=8?a=(n=100*r/903.3)/100*7.787+16/116:(n=100*Math.pow((r+16)/116,3),a=Math.pow(n/100,1/3)),[e=e/95.047<=.008856?e=95.047*(o/500+a-16/116)/7.787:95.047*Math.pow(o/500+a,3),n,i=i/108.883<=.008859?i=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3)]}function x(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]}function _(t){return p(y(t))}function k(t){var e,n=t[1];return e=t[2]/360*2*Math.PI,[t[0],n*Math.cos(e),n*Math.sin(e)]}function w(t){return M[t]}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return x(d(t))},hsl2rgb:h,hsl2hsv:function(t){var e=t[1]/100,n=t[2]/100;return 0===n?[0,0,0]:[t[0],2*(e*=(n*=2)<=1?n:2-n)/(n+e)*100,(n+e)/2*100]},hsl2hwb:function(t){return o(h(t))},hsl2cmyk:function(t){return s(h(t))},hsl2keyword:function(t){return l(h(t))},hsv2rgb:c,hsv2hsl:function(t){var e,n,i=t[1]/100,a=t[2]/100;return e=i*a,[t[0],100*(e=(e/=(n=(2-i)*a)<=1?n:2-n)||0),100*(n/=2)]},hsv2hwb:function(t){return o(c(t))},hsv2cmyk:function(t){return s(c(t))},hsv2keyword:function(t){return l(c(t))},hwb2rgb:f,hwb2hsl:function(t){return i(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:m,cmyk2hsl:function(t){return i(m(t))},cmyk2hsv:function(t){return a(m(t))},cmyk2hwb:function(t){return o(m(t))},cmyk2keyword:function(t){return l(m(t))},keyword2rgb:w,keyword2hsl:function(t){return i(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:p,xyz2lab:v,xyz2lch:function(t){return x(v(t))},lab2xyz:y,lab2rgb:_,lab2lch:x,lch2lab:k,lch2xyz:function(t){return y(k(t))},lch2rgb:function(t){return _(k(t))}};var M={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},S={};for(var D in M)S[JSON.stringify(M[D])]=D},{}],4:[function(t,e,n){var i=t(3),a=function(){return new u};for(var r in i){a[r+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(r);var o=/(\w+)2(\w+)/.exec(r),s=o[1],l=o[2];(a[s]=a[s]||{})[l]=a[r]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=i[t](e);if("string"==typeof n||void 0===n)return n;for(var a=0;a>>0,i=0;i0)for(n=0;n=0?n?"+":"":"-")+Math.pow(10,Math.max(0,e-i.length)).toString().substr(1)+i}var V=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,H=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,B={},E={};function j(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(E[t]=a),e&&(E[e[0]]=function(){return z(a.apply(this,arguments),e[1],e[2])}),n&&(E[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function U(t,e){return t.isValid()?(e=G(e,t.localeData()),B[e]=B[e]||function(t){var e,n,i,a=t.match(V);for(e=0,n=a.length;e=0&&H.test(t);)t=t.replace(H,i),H.lastIndex=0,n-=1;return t}var q=/\d/,Z=/\d\d/,$=/\d{3}/,X=/\d{4}/,J=/[+-]?\d{6}/,K=/\d\d?/,Q=/\d\d\d\d?/,tt=/\d\d\d\d\d\d?/,et=/\d{1,3}/,nt=/\d{1,4}/,it=/[+-]?\d{1,6}/,at=/\d+/,rt=/[+-]?\d+/,ot=/Z|[+-]\d\d:?\d\d/gi,st=/Z|[+-]\d\d(?::?\d\d)?/gi,lt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ut={};function dt(t,e,n){ut[t]=O(e)?e:function(t,i){return t&&n?n:e}}function ht(t,e){return h(ut,t)?ut[t](e._strict,e._locale):new RegExp(ct(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,a){return e||n||i||a})))}function ct(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ft={};function gt(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),l(e)&&(i=function(t,n){n[e]=w(t)}),n=0;n68?1900:2e3)};var Pt,Tt=Ot("FullYear",!0);function Ot(t,e){return function(n){return null!=n?(At(this,t,n),a.updateOffset(this,e),this):It(this,t)}}function It(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function At(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&Ct(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),Ft(n,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](n))}function Ft(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=(e%12+12)%12;return t+=(e-n)/12,1===n?Ct(t)?29:28:31-n%7%2}Pt=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function Et(t,e,n){var i=7+e-n;return-(7+Bt(t,0,i).getUTCDay()-e)%7+i-1}function jt(t,e,n,i,a){var r,o,s=1+7*(e-1)+(7+n-i)%7+Et(t,i,a);return s<=0?o=Dt(r=t-1)+s:s>Dt(t)?(r=t+1,o=s-Dt(t)):(r=t,o=s),{year:r,dayOfYear:o}}function Ut(t,e,n){var i,a,r=Et(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?i=o+Gt(a=t.year()-1,e,n):o>Gt(t.year(),e,n)?(i=o-Gt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Gt(t,e,n){var i=Et(t,e,n),a=Et(t+1,e,n);return(Dt(t)-i+a)/7}j("w",["ww",2],"wo","week"),j("W",["WW",2],"Wo","isoWeek"),R("week","w"),R("isoWeek","W"),N("week",5),N("isoWeek",5),dt("w",K),dt("ww",K,Z),dt("W",K),dt("WW",K,Z),mt(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=w(t)}),j("d",0,"do","day"),j("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),j("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),j("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),j("e",0,0,"weekday"),j("E",0,0,"isoWeekday"),R("day","d"),R("weekday","e"),R("isoWeekday","E"),N("day",11),N("weekday",11),N("isoWeekday",11),dt("d",K),dt("e",K),dt("E",K),dt("dd",function(t,e){return e.weekdaysMinRegex(t)}),dt("ddd",function(t,e){return e.weekdaysShortRegex(t)}),dt("dddd",function(t,e){return e.weekdaysRegex(t)}),mt(["dd","ddd","dddd"],function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t}),mt(["d","e","E"],function(t,e,n,i){e[i]=w(t)});var qt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Zt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$t="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Xt=lt,Jt=lt,Kt=lt;function Qt(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)n=f([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=ct(s[e]),l[e]=ct(l[e]),u[e]=ct(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function te(){return this.hours()%12||12}function ee(t,e){j(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function ne(t,e){return e._meridiemParse}j("H",["HH",2],0,"hour"),j("h",["hh",2],0,te),j("k",["kk",2],0,function(){return this.hours()||24}),j("hmm",0,0,function(){return""+te.apply(this)+z(this.minutes(),2)}),j("hmmss",0,0,function(){return""+te.apply(this)+z(this.minutes(),2)+z(this.seconds(),2)}),j("Hmm",0,0,function(){return""+this.hours()+z(this.minutes(),2)}),j("Hmmss",0,0,function(){return""+this.hours()+z(this.minutes(),2)+z(this.seconds(),2)}),ee("a",!0),ee("A",!1),R("hour","h"),N("hour",13),dt("a",ne),dt("A",ne),dt("H",K),dt("h",K),dt("k",K),dt("HH",K,Z),dt("hh",K,Z),dt("kk",K,Z),dt("hmm",Q),dt("hmmss",tt),dt("Hmm",Q),dt("Hmmss",tt),gt(["H","HH"],xt),gt(["k","kk"],function(t,e,n){var i=w(t);e[xt]=24===i?0:i}),gt(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),gt(["h","hh"],function(t,e,n){e[xt]=w(t),g(n).bigHour=!0}),gt("hmm",function(t,e,n){var i=t.length-2;e[xt]=w(t.substr(0,i)),e[_t]=w(t.substr(i)),g(n).bigHour=!0}),gt("hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=w(t.substr(0,i)),e[_t]=w(t.substr(i,2)),e[kt]=w(t.substr(a)),g(n).bigHour=!0}),gt("Hmm",function(t,e,n){var i=t.length-2;e[xt]=w(t.substr(0,i)),e[_t]=w(t.substr(i))}),gt("Hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=w(t.substr(0,i)),e[_t]=w(t.substr(i,2)),e[kt]=w(t.substr(a))});var ie,ae=Ot("Hours",!0),re={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Lt,monthsShort:Yt,week:{dow:0,doy:6},weekdays:qt,weekdaysMin:$t,weekdaysShort:Zt,meridiemParse:/[ap]\.?m?\.?/i},oe={},se={};function le(t){return t?t.toLowerCase().replace("_","-"):t}function ue(n){var i=null;if(!oe[n]&&void 0!==e&&e&&e.exports)try{i=ie._abbr,t("./locale/"+n),de(i)}catch(a){}return oe[n]}function de(t,e){var n;return t&&((n=s(e)?ce(t):he(t,e))?ie=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),ie._abbr}function he(t,e){if(null!==e){var n,i=re;if(e.abbr=t,null!=oe[t])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=oe[t]._config;else if(null!=e.parentLocale)if(null!=oe[e.parentLocale])i=oe[e.parentLocale]._config;else{if(null==(n=ue(e.parentLocale)))return se[e.parentLocale]||(se[e.parentLocale]=[]),se[e.parentLocale].push({name:t,config:e}),null;i=n._config}return oe[t]=new A(I(i,e)),se[t]&&se[t].forEach(function(t){he(t.name,t.config)}),de(t),oe[t]}return delete oe[t],null}function ce(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return ie;if(!r(t)){if(e=ue(t))return e;t=[t]}return function(t){for(var e,n,i,a,r=0;r0;){if(i=ue(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&M(a,n,!0)>=e-1)break;e--}r++}return ie}(t)}function fe(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[yt]<0||n[yt]>11?yt:n[bt]<1||n[bt]>Ft(n[vt],n[yt])?bt:n[xt]<0||n[xt]>24||24===n[xt]&&(0!==n[_t]||0!==n[kt]||0!==n[wt])?xt:n[_t]<0||n[_t]>59?_t:n[kt]<0||n[kt]>59?kt:n[wt]<0||n[wt]>999?wt:-1,g(t)._overflowDayOfYear&&(ebt)&&(e=bt),g(t)._overflowWeeks&&-1===e&&(e=Mt),g(t)._overflowWeekday&&-1===e&&(e=St),g(t).overflow=e),t}function ge(t,e,n){return null!=t?t:null!=e?e:n}function me(t){var e,n,i,r,o,s=[];if(!t._d){for(i=function(t){var e=new Date(a.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}(t),t._w&&null==t._a[bt]&&null==t._a[yt]&&function(t){var e,n,i,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,n=ge(e.GG,t._a[vt],Ut(Oe(),1,4).year),i=ge(e.W,1),((a=ge(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=Ut(Oe(),r,o);n=ge(e.gg,t._a[vt],u.year),i=ge(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}i<1||i>Gt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=jt(n,i,a,r,o),t._a[vt]=s.year,t._dayOfYear=s.dayOfYear)}(t),null!=t._dayOfYear&&(o=ge(t._a[vt],i[vt]),(t._dayOfYear>Dt(o)||0===t._dayOfYear)&&(g(t)._overflowDayOfYear=!0),n=Bt(o,0,t._dayOfYear),t._a[yt]=n.getUTCMonth(),t._a[bt]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=i[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[xt]&&0===t._a[_t]&&0===t._a[kt]&&0===t._a[wt]&&(t._nextDay=!0,t._a[xt]=0),t._d=(t._useUTC?Bt:function(t,e,n,i,a,r,o){var s=new Date(t,e,n,i,a,r,o);return t<100&&t>=0&&isFinite(s.getFullYear())&&s.setFullYear(t),s}).apply(null,s),r=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[xt]=24),t._w&&void 0!==t._w.d&&t._w.d!==r&&(g(t).weekdayMismatch=!0)}}var pe=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ve=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ye=/Z|[+-]\d\d(?::?\d\d)?/,be=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],xe=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],_e=/^\/?Date\((\-?\d+)/i;function ke(t){var e,n,i,a,r,o,s=t._i,l=pe.exec(s)||ve.exec(s);if(l){for(g(t).iso=!0,e=0,n=be.length;e0&&g(t).unusedInput.push(o),s=s.slice(s.indexOf(n)+n.length),u+=n.length),E[r]?(n?g(t).empty=!1:g(t).unusedTokens.push(r),pt(r,n,t)):t._strict&&!n&&g(t).unusedTokens.push(r);g(t).charsLeftOver=l-u,s.length>0&&g(t).unusedInput.push(s),t._a[xt]<=12&&!0===g(t).bigHour&&t._a[xt]>0&&(g(t).bigHour=void 0),g(t).parsedDateParts=t._a.slice(0),g(t).meridiem=t._meridiem,t._a[xt]=(d=t._locale,h=t._a[xt],null==(c=t._meridiem)?h:null!=d.meridiemHour?d.meridiemHour(h,c):null!=d.isPM?((f=d.isPM(c))&&h<12&&(h+=12),f||12!==h||(h=0),h):h),me(t),fe(t)}else De(t);else ke(t);var d,h,c,f}function Pe(t){var e=t._i,n=t._f;return t._locale=t._locale||ce(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),_(e)?new x(fe(e)):(u(e)?t._d=e:r(n)?function(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;athis?this:t:p()});function Fe(t,e){var n,i;if(1===e.length&&r(e[0])&&(e=e[0]),!e.length)return Oe();for(n=e[0],i=1;i(r=Gt(t,i,a))&&(e=r),(function(t,e,n,i,a){var r=jt(t,e,n,i,a),o=Bt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}).call(this,t,e,n,i,a))}j(0,["gg",2],0,function(){return this.weekYear()%100}),j(0,["GG",2],0,function(){return this.isoWeekYear()%100}),an("gggg","weekYear"),an("ggggg","weekYear"),an("GGGG","isoWeekYear"),an("GGGGG","isoWeekYear"),R("weekYear","gg"),R("isoWeekYear","GG"),N("weekYear",1),N("isoWeekYear",1),dt("G",rt),dt("g",rt),dt("GG",K,Z),dt("gg",K,Z),dt("GGGG",nt,X),dt("gggg",nt,X),dt("GGGGG",it,J),dt("ggggg",it,J),mt(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=w(t)}),mt(["gg","GG"],function(t,e,n,i){e[i]=a.parseTwoDigitYear(t)}),j("Q",0,"Qo","quarter"),R("quarter","Q"),N("quarter",7),dt("Q",q),gt("Q",function(t,e){e[yt]=3*(w(t)-1)}),j("D",["DD",2],"Do","date"),R("date","D"),N("date",9),dt("D",K),dt("DD",K,Z),dt("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),gt(["D","DD"],bt),gt("Do",function(t,e){e[bt]=w(t.match(K)[0])});var on=Ot("Date",!0);j("DDD",["DDDD",3],"DDDo","dayOfYear"),R("dayOfYear","DDD"),N("dayOfYear",4),dt("DDD",et),dt("DDDD",$),gt(["DDD","DDDD"],function(t,e,n){n._dayOfYear=w(t)}),j("m",["mm",2],0,"minute"),R("minute","m"),N("minute",14),dt("m",K),dt("mm",K,Z),gt(["m","mm"],_t);var sn=Ot("Minutes",!1);j("s",["ss",2],0,"second"),R("second","s"),N("second",15),dt("s",K),dt("ss",K,Z),gt(["s","ss"],kt);var ln,un=Ot("Seconds",!1);for(j("S",0,0,function(){return~~(this.millisecond()/100)}),j(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),j(0,["SSS",3],0,"millisecond"),j(0,["SSSS",4],0,function(){return 10*this.millisecond()}),j(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),j(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),j(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),j(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),j(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),R("millisecond","ms"),N("millisecond",16),dt("S",et,q),dt("SS",et,Z),dt("SSS",et,$),ln="SSSS";ln.length<=9;ln+="S")dt(ln,at);function dn(t,e){e[wt]=w(1e3*("0."+t))}for(ln="S";ln.length<=9;ln+="S")gt(ln,dn);var hn=Ot("Milliseconds",!1);j("z",0,0,"zoneAbbr"),j("zz",0,0,"zoneName");var cn=x.prototype;function fn(t){return t}cn.add=Je,cn.calendar=function(t,e){var n=t||Oe(),i=He(n,this).startOf("day"),r=a.calendarFormat(this,i)||"sameElse",o=e&&(O(e[r])?e[r].call(this,n):e[r]);return this.format(o||this.localeData().calendar(r,this,Oe(n)))},cn.clone=function(){return new x(this)},cn.diff=function(t,e,n){var i,a,r;if(!this.isValid())return NaN;if(!(i=He(t,this)).isValid())return NaN;switch(a=6e4*(i.utcOffset()-this.utcOffset()),e=L(e)){case"year":r=Qe(this,i)/12;break;case"month":r=Qe(this,i);break;case"quarter":r=Qe(this,i)/3;break;case"second":r=(this-i)/1e3;break;case"minute":r=(this-i)/6e4;break;case"hour":r=(this-i)/36e5;break;case"day":r=(this-i-a)/864e5;break;case"week":r=(this-i-a)/6048e5;break;default:r=this-i}return n?r:k(r)},cn.endOf=function(t){return void 0===(t=L(t))||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))},cn.format=function(t){t||(t=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var e=U(this,t);return this.localeData().postformat(e)},cn.from=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Oe(t).isValid())?Ge({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},cn.fromNow=function(t){return this.from(Oe(),t)},cn.to=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Oe(t).isValid())?Ge({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},cn.toNow=function(t){return this.to(Oe(),t)},cn.get=function(t){return O(this[t=L(t)])?this[t]():this},cn.invalidAt=function(){return g(this).overflow},cn.isAfter=function(t,e){var n=_(t)?t:Oe(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=L(s(e)?"millisecond":e))?this.valueOf()>n.valueOf():n.valueOf()9999?U(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):O(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",U(n,"Z")):U(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},cn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY";return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+e+'[")]')},cn.toJSON=function(){return this.isValid()?this.toISOString():null},cn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},cn.unix=function(){return Math.floor(this.valueOf()/1e3)},cn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},cn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},cn.year=Tt,cn.isLeapYear=function(){return Ct(this.year())},cn.weekYear=function(t){return rn.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},cn.isoWeekYear=function(t){return rn.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},cn.quarter=cn.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},cn.month=Nt,cn.daysInMonth=function(){return Ft(this.year(),this.month())},cn.week=cn.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},cn.isoWeek=cn.isoWeeks=function(t){var e=Ut(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},cn.weeksInYear=function(){var t=this.localeData()._week;return Gt(this.year(),t.dow,t.doy)},cn.isoWeeksInYear=function(){return Gt(this.year(),1,4)},cn.date=on,cn.day=cn.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=function(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}(t,this.localeData()),this.add(t-e,"d")):e},cn.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},cn.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=function(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7},cn.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},cn.hour=cn.hours=ae,cn.minute=cn.minutes=sn,cn.second=cn.seconds=un,cn.millisecond=cn.milliseconds=hn,cn.utcOffset=function(t,e,n){var i,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=Ve(st,t)))return this}else Math.abs(t)<16&&!n&&(t*=60);return!this._isUTC&&e&&(i=Be(this)),this._offset=t,this._isUTC=!0,null!=i&&this.add(i,"m"),r!==t&&(!e||this._changeInProgress?Xe(this,Ge(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Be(this)},cn.utc=function(t){return this.utcOffset(0,t)},cn.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Be(this),"m")),this},cn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=Ve(ot,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},cn.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Oe(t).utcOffset():0,(this.utcOffset()-t)%60==0)},cn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},cn.isLocal=function(){return!!this.isValid()&&!this._isUTC},cn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},cn.isUtc=Ee,cn.isUTC=Ee,cn.zoneAbbr=function(){return this._isUTC?"UTC":""},cn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},cn.dates=D("dates accessor is deprecated. Use date instead.",on),cn.months=D("months accessor is deprecated. Use month instead",Nt),cn.years=D("years accessor is deprecated. Use year instead",Tt),cn.zone=D("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}),cn.isDSTShifted=D("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(y(t,this),(t=Pe(t))._a){var e=t._isUTC?f(t._a):Oe(t._a);this._isDSTShifted=this.isValid()&&M(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var gn=A.prototype;function mn(t,e,n,i){var a=ce(),r=f().set(i,e);return a[n](r,t)}function pn(t,e,n){if(l(t)&&(e=t,t=void 0),t=t||"",null!=e)return mn(t,e,n,"month");var i,a=[];for(i=0;i<12;i++)a[i]=mn(t,i,n,"month");return a}function vn(t,e,n,i){"boolean"==typeof t?(l(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,l(e)&&(n=e,e=void 0),e=e||"");var a,r=ce(),o=t?r._week.dow:0;if(null!=n)return mn(e,(n+o)%7,i,"day");var s=[];for(a=0;a<7;a++)s[a]=mn(e,(a+o)%7,i,"day");return s}gn.calendar=function(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return O(i)?i.call(e,n):i},gn.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])},gn.invalidDate=function(){return this._invalidDate},gn.ordinal=function(t){return this._ordinal.replace("%d",t)},gn.preparse=fn,gn.postformat=fn,gn.relativeTime=function(t,e,n,i){var a=this._relativeTime[n];return O(a)?a(t,e,n,i):a.replace(/%d/i,t)},gn.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return O(n)?n(e):n.replace(/%s/i,e)},gn.set=function(t){var e,n;for(n in t)O(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},gn.months=function(t,e){return t?r(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||Rt).test(e)?"format":"standalone"][t.month()]:r(this._months)?this._months:this._months.standalone},gn.monthsShort=function(t,e){return t?r(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[Rt.test(e)?"format":"standalone"][t.month()]:r(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},gn.monthsParse=function(t,e,n){var i,a,r;if(this._monthsParseExact)return(function(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;i<12;++i)r=f([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(a=Pt.call(this._shortMonthsParse,o))?a:null:-1!==(a=Pt.call(this._longMonthsParse,o))?a:null:"MMM"===e?-1!==(a=Pt.call(this._shortMonthsParse,o))?a:-1!==(a=Pt.call(this._longMonthsParse,o))?a:null:-1!==(a=Pt.call(this._longMonthsParse,o))?a:-1!==(a=Pt.call(this._shortMonthsParse,o))?a:null}).call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=f([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},gn.monthsRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=Vt),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},gn.monthsShortRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=zt),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},gn.week=function(t){return Ut(t,this._week.dow,this._week.doy).week},gn.firstDayOfYear=function(){return this._week.doy},gn.firstDayOfWeek=function(){return this._week.dow},gn.weekdays=function(t,e){return t?r(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]:r(this._weekdays)?this._weekdays:this._weekdays.standalone},gn.weekdaysMin=function(t){return t?this._weekdaysMin[t.day()]:this._weekdaysMin},gn.weekdaysShort=function(t){return t?this._weekdaysShort[t.day()]:this._weekdaysShort},gn.weekdaysParse=function(t,e,n){var i,a,r;if(this._weekdaysParseExact)return(function(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=f([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null}).call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(a=f([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}},gn.weekdaysRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Qt.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=Xt),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},gn.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Qt.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Jt),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},gn.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Qt.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Kt),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},gn.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},gn.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},de("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===w(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),a.lang=D("moment.lang is deprecated. Use moment.locale instead.",de),a.langData=D("moment.langData is deprecated. Use moment.localeData instead.",ce);var yn=Math.abs;function bn(t,e,n,i){var a=Ge(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function xn(t){return t<0?Math.floor(t):Math.ceil(t)}function _n(t){return 4800*t/146097}function kn(t){return 146097*t/4800}function wn(t){return function(){return this.as(t)}}var Mn=wn("ms"),Sn=wn("s"),Dn=wn("m"),Cn=wn("h"),Pn=wn("d"),Tn=wn("w"),On=wn("M"),In=wn("y");function An(t){return function(){return this.isValid()?this._data[t]:NaN}}var Fn=An("milliseconds"),Rn=An("seconds"),Ln=An("minutes"),Yn=An("hours"),Wn=An("days"),Nn=An("months"),zn=An("years"),Vn=Math.round,Hn={ss:44,s:45,m:45,h:22,d:26,M:11},Bn=Math.abs;function En(t){return(t>0)-(t<0)||+t}function jn(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n=Bn(this._milliseconds)/1e3,i=Bn(this._days),a=Bn(this._months);t=k(n/60),e=k(t/60),n%=60,t%=60;var r=k(a/12),o=a%=12,s=i,l=e,u=t,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=En(this._months)!==En(h)?"-":"",g=En(this._days)!==En(h)?"-":"",m=En(this._milliseconds)!==En(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(o?f+o+"M":"")+(s?g+s+"D":"")+(l||u||d?"T":"")+(l?m+l+"H":"")+(u?m+u+"M":"")+(d?m+d+"S":"")}var Un=Le.prototype;return Un.isValid=function(){return this._isValid},Un.abs=function(){var t=this._data;return this._milliseconds=yn(this._milliseconds),this._days=yn(this._days),this._months=yn(this._months),t.milliseconds=yn(t.milliseconds),t.seconds=yn(t.seconds),t.minutes=yn(t.minutes),t.hours=yn(t.hours),t.months=yn(t.months),t.years=yn(t.years),this},Un.add=function(t,e){return bn(this,t,e,1)},Un.subtract=function(t,e){return bn(this,t,e,-1)},Un.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=L(t))||"year"===t)return n=this._months+_n(e=this._days+i/864e5),"month"===t?n:n/12;switch(e=this._days+Math.round(kn(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},Un.asMilliseconds=Mn,Un.asSeconds=Sn,Un.asMinutes=Dn,Un.asHours=Cn,Un.asDays=Pn,Un.asWeeks=Tn,Un.asMonths=On,Un.asYears=In,Un.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*w(this._months/12):NaN},Un._bubble=function(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*xn(kn(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=k(r/1e3),l.seconds=t%60,e=k(t/60),l.minutes=e%60,n=k(e/60),l.hours=n%24,o+=k(n/24),s+=a=k(_n(o)),o-=xn(kn(a)),i=k(s/12),s%=12,l.days=o,l.months=s,l.years=i,this},Un.clone=function(){return Ge(this)},Un.get=function(t){return t=L(t),this.isValid()?this[t+"s"]():NaN},Un.milliseconds=Fn,Un.seconds=Rn,Un.minutes=Ln,Un.hours=Yn,Un.days=Wn,Un.weeks=function(){return k(this.days()/7)},Un.months=Nn,Un.years=zn,Un.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=function(t,e,n){var i=Ge(t).abs(),a=Vn(i.as("s")),r=Vn(i.as("m")),o=Vn(i.as("h")),s=Vn(i.as("d")),l=Vn(i.as("M")),u=Vn(i.as("y")),d=a<=Hn.ss&&["s",a]||a0,d[4]=n,(function(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}).apply(null,d)}(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},Un.toISOString=jn,Un.toString=jn,Un.toJSON=jn,Un.locale=tn,Un.localeData=nn,Un.toIsoString=D("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",jn),Un.lang=en,j("X",0,0,"unix"),j("x",0,0,"valueOf"),dt("x",rt),dt("X",/[+-]?\d+(\.\d{1,3})?/),gt("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),gt("x",function(t,e,n){n._d=new Date(w(t))}),a.version="2.22.2",n=Oe,a.fn=cn,a.min=function(){return Fe("isBefore",[].slice.call(arguments,0))},a.max=function(){return Fe("isAfter",[].slice.call(arguments,0))},a.now=function(){return Date.now?Date.now():+new Date},a.utc=f,a.unix=function(t){return Oe(1e3*t)},a.months=function(t,e){return pn(t,e,"months")},a.isDate=u,a.locale=de,a.invalid=p,a.duration=Ge,a.isMoment=_,a.weekdays=function(t,e,n){return vn(t,e,n,"weekdays")},a.parseZone=function(){return Oe.apply(null,arguments).parseZone()},a.localeData=ce,a.isDuration=Ye,a.monthsShort=function(t,e){return pn(t,e,"monthsShort")},a.weekdaysMin=function(t,e,n){return vn(t,e,n,"weekdaysMin")},a.defineLocale=he,a.updateLocale=function(t,e){if(null!=e){var n,i,a=re;null!=(i=ue(t))&&(a=i._config),(n=new A(e=I(a,e))).parentLocale=oe[t],oe[t]=n,de(t)}else null!=oe[t]&&(null!=oe[t].parentLocale?oe[t]=oe[t].parentLocale:null!=oe[t]&&delete oe[t]);return oe[t]},a.locales=function(){return C(oe)},a.weekdaysShort=function(t,e,n){return vn(t,e,n,"weekdaysShort")},a.normalizeUnits=L,a.relativeTimeRounding=function(t){return void 0===t?Vn:"function"==typeof t&&(Vn=t,!0)},a.relativeTimeThreshold=function(t,e){return void 0!==Hn[t]&&(void 0===e?Hn[t]:(Hn[t]=e,"s"===t&&(Hn.ss=e-1),!0))},a.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},a.prototype=cn,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},a},"object"==typeof n&&void 0!==e?e.exports=i():this.moment=i()},{}],7:[function(t,e,n){var i=t(30)();i.helpers=t(46),t(28)(i),i.Animation=t(22),i.animationService=t(23),i.defaults=t(26),i.Element=t(27),i.elements=t(41),i.Interaction=t(29),i.layouts=t(31),i.platform=t(49),i.plugins=t(32),i.Scale=t(33),i.scaleService=t(34),i.Ticks=t(35),i.Tooltip=t(36),t(24)(i),t(25)(i),t(56)(i),t(54)(i),t(55)(i),t(57)(i),t(58)(i),t(59)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(21)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i);var a=t(50);for(var r in a)a.hasOwnProperty(r)&&i.plugins.register(a[r]);i.platform.initialize(),e.exports=i,"undefined"!=typeof window&&(window.Chart=i),i.Legend=a.legend._element,i.Title=a.title._element,i.pluginService=i.plugins,i.PluginBase=i.Element.extend({}),i.canvasHelpers=i.helpers.canvas,i.layoutService=i.layouts},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,41:41,46:46,49:49,50:50,54:54,55:55,56:56,57:57,58:58,59:59,8:8,9:9}],8:[function(t,e,n){"use strict";e.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},{}],9:[function(t,e,n){"use strict";e.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},{}],10:[function(t,e,n){"use strict";e.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},{}],11:[function(t,e,n){"use strict";e.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},{}],12:[function(t,e,n){"use strict";e.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},{}],13:[function(t,e,n){"use strict";e.exports=function(t){t.Radar=function(e,n){return n.type="radar",new t(e,n)}}},{}],14:[function(t,e,n){"use strict";e.exports=function(t){t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},{}],15:[function(t,e,n){"use strict";var i=t(26),a=t(41),r=t(46);i._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),i._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index0?Math.min(o,i-n):o,n=i;return o}(n,u):-1,pixels:u,start:s,end:l,stackCount:i,scale:n}},calculateBarValuePixels:function(t,e){var n,i,a,r,o,s,l=this.chart,u=this.getMeta(),d=this.getValueScale(),h=l.data.datasets,c=d.getRightValue(h[t].data[e]),f=d.options.stacked,g=u.stack,m=0;if(f||void 0===f&&void 0!==g)for(n=0;n=0&&a>0)&&(m+=a));return r=d.getPixelForValue(m),{size:s=((o=d.getPixelForValue(m+c))-r)/2,base:r,head:o,center:o+s/2}},calculateBarIndexPixels:function(t,e,n){var i=n.scale.options,a="flex"===i.barThickness?function(t,e,n){var i=e.pixels,a=i[t],r=t>0?i[t-1]:null,o=t');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r'),a[r]&&e.push(a[r]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,i){var a=t.getDatasetMeta(0),o=e.datasets[0],s=a.data[i],l=s&&s.custom||{},u=r.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:n,fillStyle:l.backgroundColor?l.backgroundColor:u(o.backgroundColor,i,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(o.borderColor,i,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(o.borderWidth,i,d.borderWidth),hidden:isNaN(o.data[i])||a.data[i].hidden,index:i}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n=Math.PI?-1:g<-Math.PI?1:0))+f,p={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(m),y:Math.sin(m)},y=g<=0&&m>=0||g<=2*Math.PI&&2*Math.PI<=m,b=g<=.5*Math.PI&&.5*Math.PI<=m||g<=2.5*Math.PI&&2.5*Math.PI<=m,x=g<=-Math.PI&&-Math.PI<=m||g<=Math.PI&&Math.PI<=m,_=g<=.5*-Math.PI&&.5*-Math.PI<=m||g<=1.5*Math.PI&&1.5*Math.PI<=m,k=c/100,w={x:x?-1:Math.min(p.x*(p.x<0?1:k),v.x*(v.x<0?1:k)),y:_?-1:Math.min(p.y*(p.y<0?1:k),v.y*(v.y<0?1:k))},M={x:y?1:Math.max(p.x*(p.x>0?1:k),v.x*(v.x>0?1:k)),y:b?1:Math.max(p.y*(p.y>0?1:k),v.y*(v.y>0?1:k))},S={width:.5*(M.x-w.x),height:.5*(M.y-w.y)};u=Math.min(s/S.width,l/S.height),d={x:-.5*(M.x+w.x),y:-.5*(M.y+w.y)}}n.borderWidth=e.getMaxBorderWidth(h.data),n.outerRadius=Math.max((u-n.borderWidth)/2,0),n.innerRadius=Math.max(c?n.outerRadius/100*c:0,0),n.radiusLength=(n.outerRadius-n.innerRadius)/n.getVisibleDatasetCount(),n.offsetX=d.x*n.outerRadius,n.offsetY=d.y*n.outerRadius,h.total=e.calculateTotal(),e.outerRadius=n.outerRadius-n.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-n.radiusLength,0),r.each(h.data,function(n,i){e.updateElement(n,i,t)})},updateElement:function(t,e,n){var i=this,a=i.chart,o=a.chartArea,s=a.options,l=s.animation,u=(o.left+o.right)/2,d=(o.top+o.bottom)/2,h=s.rotation,c=s.rotation,f=i.getDataset(),g=n&&l.animateRotate?0:t.hidden?0:i.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI));r.extend(t,{_datasetIndex:i.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:h,endAngle:c,circumference:g,outerRadius:n&&l.animateScale?0:i.outerRadius,innerRadius:n&&l.animateScale?0:i.innerRadius,label:(0,r.valueAtIndexOrDefault)(f.label,e,a.data.labels[e])}});var m=t._model,p=t.custom||{},v=r.valueAtIndexOrDefault,y=this.chart.options.elements.arc;m.backgroundColor=p.backgroundColor?p.backgroundColor:v(f.backgroundColor,e,y.backgroundColor),m.borderColor=p.borderColor?p.borderColor:v(f.borderColor,e,y.borderColor),m.borderWidth=p.borderWidth?p.borderWidth:v(f.borderWidth,e,y.borderWidth),n&&l.animateRotate||(m.startAngle=0===e?s.rotation:i.getMeta().data[e-1]._model.endAngle,m.endAngle=m.startAngle+m.circumference),t.pivot()},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),i=0;return r.each(n.data,function(n,a){t=e.data[a],isNaN(t)||n.hidden||(i+=Math.abs(t))}),i},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){for(var e,n,i=0,a=this.index,r=t.length,o=0;o(i=(e=t[o]._model?t[o]._model.borderWidth:0)>i?e:i)?n:i;return i}})}},{26:26,41:41,46:46}],18:[function(t,e,n){"use strict";var i=t(26),a=t(41),r=t(46);i._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return r.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var n,i,a,o=this,s=o.getMeta(),l=s.dataset,u=s.data||[],d=o.chart.options,h=d.elements.line,c=o.getScaleForId(s.yAxisID),f=o.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=c,l._datasetIndex=o.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:r.valueOrDefault(f.lineTension,h.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||h.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||h.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||h.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||h.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||h.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||h.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||h.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:h.fill,steppedLine:a.steppedLine?a.steppedLine:r.valueOrDefault(f.steppedLine,h.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:r.valueOrDefault(f.cubicInterpolationMode,h.cubicInterpolationMode)},l.pivot()),n=0,i=u.length;n');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r'),a[r]&&e.push(a[r]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,i){var a=t.getDatasetMeta(0),o=e.datasets[0],s=a.data[i].custom||{},l=r.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:n,fillStyle:s.backgroundColor?s.backgroundColor:l(o.backgroundColor,i,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(o.borderColor,i,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(o.borderWidth,i,u.borderWidth),hidden:isNaN(o.data[i])||a.data[i].hidden,index:i}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+n);var i=Date.now();t.dropFrames+=(i-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,n,i=this.animations,r=0;r=e.numSteps?(a.callback(e.onAnimationComplete,[e],n),n.animating=!1,i.splice(r,1)):++r}}},{26:26,46:46}],24:[function(t,e,n){"use strict";var i=t(22),a=t(23),r=t(26),o=t(46),s=t(29),l=t(31),u=t(49),d=t(32),h=t(34),c=t(36);e.exports=function(t){function e(t){return"top"===t||"bottom"===t}t.types={},t.instances={},t.controllers={},o.extend(t.prototype,{construct:function(e,n){var i=this;n=function(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=o.configMerge(r.global,r[t.type],t.options||{}),t}(n);var a=u.acquireContext(e,n),s=a&&a.canvas,l=s&&s.height,d=s&&s.width;i.id=o.uid(),i.ctx=a,i.canvas=s,i.config=n,i.width=d,i.height=l,i.aspectRatio=l?d/l:null,i.options=n.options,i._bufferedRender=!1,i.chart=i,i.controller=i,t.instances[i.id]=i,Object.defineProperty(i,"data",{get:function(){return i.config.data},set:function(t){i.config.data=t}}),a&&s?(i.initialize(),i.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return d.notify(t,"beforeInit"),o.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),d.notify(t,"afterInit"),t},clear:function(){return o.canvas.clear(this),this},stop:function(){return a.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(o.getMaximumWidth(i))),s=Math.max(0,Math.floor(a?r/a:o.getMaximumHeight(i)));if((e.width!==r||e.height!==s)&&(i.width=e.width=r,i.height=e.height=s,i.style.width=r+"px",i.style.height=s+"px",o.retinaScale(e,n.devicePixelRatio),!t)){var l={width:r,height:s};d.notify(e,"resize",[l]),e.options.onResize&&e.options.onResize(e,l),e.stop(),e.update({duration:e.options.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;o.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),o.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,n=t.options,i=t.scales||{},a=[],r=Object.keys(i).reduce(function(t,e){return t[e]=!1,t},{});n.scales&&(a=a.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&a.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),o.each(a,function(n){var a=n.options,s=a.id,l=o.valueOrDefault(a.type,n.dtype);e(a.position)!==e(n.dposition)&&(a.position=n.dposition),r[s]=!0;var u=null;if(s in i&&i[s].type===l)(u=i[s]).options=a,u.ctx=t.ctx,u.chart=t;else{var d=h.getScaleConstructor(l);if(!d)return;u=new d({id:s,type:l,options:a,ctx:t.ctx,chart:t}),i[u.id]=u}u.mergeTicksOptions(),n.isDefault&&(t.scale=u)}),o.each(r,function(t,e){t||delete i[e]}),t.scales=i,h.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,n=[],i=[];return o.each(e.data.datasets,function(a,r){var o=e.getDatasetMeta(r),s=a.type||e.config.type;if(o.type&&o.type!==s&&(e.destroyDatasetMeta(r),o=e.getDatasetMeta(r)),o.type=s,n.push(o.type),o.controller)o.controller.updateIndex(r),o.controller.linkScales();else{var l=t.controllers[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(e,r),i.push(o.controller)}},e),i},resetElements:function(){var t=this;o.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e){var n,i,a=this;if(e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]}),i=(n=a).options,o.each(n.scales,function(t){l.removeBox(n,t)}),i=o.configMerge(t.defaults.global,t.defaults[n.config.type],i),n.options=n.config.options=i,n.ensureScalesHaveIDs(),n.buildOrUpdateScales(),n.tooltip._options=i.tooltips,n.tooltip.initialize(),d._invalidate(a),!1!==d.notify(a,"beforeUpdate")){a.tooltip._data=a.data;var r=a.buildOrUpdateControllers();o.each(a.data.datasets,function(t,e){a.getDatasetMeta(e).controller.buildOrUpdateElements()},a),a.updateLayout(),a.options.animation&&a.options.animation.duration&&o.each(r,function(t){t.reset()}),a.updateDatasets(),a.tooltip.initialize(),a.lastActive=[],d.notify(a,"afterUpdate"),a._bufferedRender?a._bufferedRequest={duration:e.duration,easing:e.easing,lazy:e.lazy}:a.render(e)}},updateLayout:function(){!1!==d.notify(this,"beforeLayout")&&(l.update(this,this.width,this.height),d.notify(this,"afterScaleUpdate"),d.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==d.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t=0;--n)e.isDatasetVisible(n)&&e.drawDataset(n,t);d.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n=this.getDatasetMeta(t),i={meta:n,index:t,easingValue:e};!1!==d.notify(this,"beforeDatasetDraw",[i])&&(n.controller.draw(e),d.notify(this,"afterDatasetDraw",[i]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==d.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),d.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return s.modes.single(this,t)},getElementsAtEvent:function(t){return s.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return s.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=s.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return s.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e0||(e.forEach(function(e){delete t[e]}),delete t._chartjs)}}t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=n.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;n=e[t].length&&e[t].push({}),r.merge(e[t][a],!e[t][a].type||l.type&&l.type!==e[t][a].type?[o.getScaleDefaults(s),l]:l)}else r._merger(t,e,n,i)}})},r.where=function(t,e){if(r.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return r.each(t,function(t){e(t)&&n.push(t)}),n},r.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;i=0;i--){var a=t[i];if(e(a))return a}},r.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},r.almostEquals=function(t,e,n){return Math.abs(t-e)t},r.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},r.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},r.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0==(t=+t)||isNaN(t)?t:t>0?1:-1},r.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,n=Math.round(e);return t===Math.pow(10,n)?n:e},r.toRadians=function(t){return t*(Math.PI/180)},r.toDegrees=function(t){return t*(180/Math.PI)},r.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},r.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},r.aliasPixel=function(t){return t%2==0?0:.5},r.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},r.EPSILON=Number.EPSILON||1e-14,r.splineCurveMonotone=function(t){var e,n,i,a,o,s,l,u,d,h=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),c=h.length;for(e=0;e0?h[e-1]:null,(a=e0?h[e-1]:null)&&!n.model.skip&&(i.model.controlPointPreviousX=i.model.x-(d=(i.model.x-n.model.x)/3),i.model.controlPointPreviousY=i.model.y-d*i.mK),a&&!a.model.skip&&(i.model.controlPointNextX=i.model.x+(d=(a.model.x-i.model.x)/3),i.model.controlPointNextY=i.model.y+d*i.mK))},r.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},r.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},r.niceNum=function(t,e){var n=Math.floor(r.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},r.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},r.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,o=t.target||t.srcElement,s=o.getBoundingClientRect(),l=a.touches;l&&l.length>0?(n=l[0].clientX,i=l[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(r.getStyle(o,"padding-left")),d=parseFloat(r.getStyle(o,"padding-top")),h=parseFloat(r.getStyle(o,"padding-right")),c=parseFloat(r.getStyle(o,"padding-bottom")),f=s.bottom-s.top-d-c;return{x:n=Math.round((n-s.left-u)/(s.right-s.left-u-h)*o.width/e.currentDevicePixelRatio),y:i=Math.round((i-s.top-d)/f*o.height/e.currentDevicePixelRatio)}},r.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},r.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},r._calculatePadding=function(t,e,n){return(e=r.getStyle(t,e)).indexOf("%")>-1?n/parseInt(e,10):parseInt(e,10)},r._getParentNode=function(t){var e=t.parentNode;return e&&e.host&&(e=e.host),e},r.getMaximumWidth=function(t){var e=r._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-r._calculatePadding(e,"padding-left",n)-r._calculatePadding(e,"padding-right",n),a=r.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},r.getMaximumHeight=function(t){var e=r._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-r._calculatePadding(e,"padding-top",n)-r._calculatePadding(e,"padding-bottom",n),a=r.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},r.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},r.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},r.fontString=function(t,e,n){return e+" "+t+"px "+n},r.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},o=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},o=i.garbageCollect=[],i.font=e),t.font=e;var s=0;r.each(n,function(e){null!=e&&!0!==r.isArray(e)?s=r.measureText(t,a,o,s,e):r.isArray(e)&&r.each(e,function(e){null==e||r.isArray(e)||(s=r.measureText(t,a,o,s,e))})});var l=o.length/2;if(l>n.length){for(var u=0;ui&&(i=r),i},r.numberOfLabelLines=function(t){var e=1;return r.each(t,function(t){r.isArray(t)&&t.length>e&&(e=t.length)}),e},r.color=i?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),i(t)}:function(t){return console.error("Color.js not found!"),t},r.getHoverColor=function(t){return t instanceof CanvasPattern?t:r.color(t).saturate(.5).darken(.1).rgbString()}}},{2:2,26:26,34:34,46:46}],29:[function(t,e,n){"use strict";var i=t(46);function a(t,e){return t.native?{x:t.x,y:t.y}:i.getRelativePosition(t,e)}function r(t,e){var n,i,a,r,o;for(i=0,r=t.data.datasets.length;i0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return u(t,e,{intersect:!1})},point:function(t,e){return o(t,a(e,t))},nearest:function(t,e,n){var i=a(e,t);n.axis=n.axis||"xy";var r=l(n.axis),o=s(t,i,n.intersect,r);return o.length>1&&o.sort(function(t,e){var n=t.getArea()-e.getArea();return 0===n&&(n=t._datasetIndex-e._datasetIndex),n}),o.slice(0,1)},x:function(t,e,n){var i=a(e,t),o=[],s=!1;return r(t,function(t){t.inXRange(i.x)&&o.push(t),t.inRange(i.x,i.y)&&(s=!0)}),n.intersect&&!s&&(o=[]),o},y:function(t,e,n){var i=a(e,t),o=[],s=!1;return r(t,function(t){t.inYRange(i.y)&&o.push(t),t.inRange(i.x,i.y)&&(s=!0)}),n.intersect&&!s&&(o=[]),o}}}},{46:46}],30:[function(t,e,n){"use strict";t(26)._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{26:26}],31:[function(t,e,n){"use strict";var i=t(46);function a(t,e){return i.where(t,function(t){return t.position===e})}function r(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i._tmpIndex_-a._tmpIndex_:i.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}e.exports={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;-1!==n&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],r=a.length,o=0;oc&&ot.maxHeight){o--;break}o++,h=l*u}t.labelRotation=o},afterCalculateTickRotation:function(){r.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){r.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=s(t._ticks),i=t.options,a=i.ticks,o=i.scaleLabel,l=i.gridLines,c=i.display,f=t.isHorizontal(),g=d(a),m=i.gridLines.tickMarkLength;if(e.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:c&&l.drawTicks?m:0,e.height=f?c&&l.drawTicks?m:0:t.maxHeight,o.display&&c){var p=h(o)+r.options.toPadding(o.padding).height;f?e.height+=p:e.width+=p}if(a.display&&c){var v=r.longestText(t.ctx,g.font,n,t.longestTextCache),y=r.numberOfLabelLines(n),b=.5*g.size,x=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var _=r.toRadians(t.labelRotation),k=Math.cos(_),w=Math.sin(_);e.height=Math.min(t.maxHeight,e.height+(w*v+g.size*y+b*(y-1)+b)+x),t.ctx.font=g.font;var M=u(t.ctx,n[0],g.font),S=u(t.ctx,n[n.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===i.position?k*M+3:k*b+3,t.paddingRight="bottom"===i.position?k*b+3:k*S+3):(t.paddingLeft=M/2+3,t.paddingRight=S/2+3)}else a.mirror?v=0:v+=x+b,e.width=Math.min(t.maxWidth,e.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=e.width,t.height=e.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){r.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(r.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:r.noop,getPixelForValue:r.noop,getValueForPixel:r.noop,getPixelForTick:function(t){var e=this,n=e.options.offset;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(n?0:1),1),a=i*t+e.paddingLeft;return n&&(a+=i/2),e.left+Math.round(a)+(e.isFullWidth()?e.margins.left:0)}return e.top+t*((e.height-(e.paddingTop+e.paddingBottom))/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;return e.isHorizontal()?e.left+Math.round((e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft)+(e.isFullWidth()?e.margins.left:0):e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,o=this,s=o.isHorizontal(),l=o.options.ticks.minor,u=t.length,d=r.toRadians(o.labelRotation),h=Math.cos(d),c=o.longestLabelWidth*h,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),s&&(e=!1,(c+l.autoSkipPadding)*u>o.width-(o.paddingLeft+o.paddingRight)&&(e=1+Math.floor((c+l.autoSkipPadding)*u/(o.width-(o.paddingLeft+o.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),n=0;n1&&n%e>0||n%e==0&&n+e>=u)&&n!==u-1&&delete i.label,f.push(i);return f},draw:function(t){var e=this,n=e.options;if(n.display){var a=e.ctx,o=i.global,s=n.ticks.minor,u=n.ticks.major||s,c=n.gridLines,f=n.scaleLabel,g=0!==e.labelRotation,m=e.isHorizontal(),p=s.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=r.valueOrDefault(s.fontColor,o.defaultFontColor),y=d(s),b=r.valueOrDefault(u.fontColor,o.defaultFontColor),x=d(u),_=c.drawTicks?c.tickMarkLength:0,k=r.valueOrDefault(f.fontColor,o.defaultFontColor),w=d(f),M=r.options.toPadding(f.padding),S=r.toRadians(e.labelRotation),D=[],C=e.options.gridLines.lineWidth,P="right"===n.position?e.left:e.right-C-_,T="right"===n.position?e.left+_:e.right,O="bottom"===n.position?e.top+C:e.bottom-_-C,I="bottom"===n.position?e.top+C+_:e.bottom+C;if(r.each(p,function(i,a){if(!r.isNullOrUndef(i.label)){var u,d,h,f,v,y,b,x,k,w,M,A,F,R,L=i.label;a===e.zeroLineIndex&&n.offset===c.offsetGridLines?(u=c.zeroLineWidth,d=c.zeroLineColor,h=c.zeroLineBorderDash,f=c.zeroLineBorderDashOffset):(u=r.valueAtIndexOrDefault(c.lineWidth,a),d=r.valueAtIndexOrDefault(c.color,a),h=r.valueOrDefault(c.borderDash,o.borderDash),f=r.valueOrDefault(c.borderDashOffset,o.borderDashOffset));var Y="middle",W="middle",N=s.padding;if(m){var z=_+N;"bottom"===n.position?(W=g?"middle":"top",Y=g?"right":"center",R=e.top+z):(W=g?"middle":"bottom",Y=g?"left":"center",R=e.bottom-z);var V=l(e,a,c.offsetGridLines&&p.length>1);V1);E3?n[2]-n[1]:n[1]-n[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var r=i.log10(Math.abs(a)),o="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var s=i.log10(Math.abs(t));o=t.toExponential(Math.floor(s)-Math.floor(r))}else{var l=-1*Math.floor(r);l=Math.max(Math.min(l,20),0),o=t.toFixed(l)}else o="0";return o},logarithmic:function(t,e,n){var a=t/Math.pow(10,Math.floor(i.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===n.length-1?t.toExponential():""}}}},{46:46}],36:[function(t,e,n){"use strict";var i=t(26),a=t(27),r=t(46);i._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:r.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function d(t){var e=i.global,n=r.valueOrDefault;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:n(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:n(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:n(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:n(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:n(t.titleFontStyle,e.defaultFontStyle),titleFontSize:n(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:n(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:n(t.footerFontStyle,e.defaultFontStyle),footerFontSize:n(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function h(t){return l([],u(t))}(e.exports=a.extend({initialize:function(){this._model=d(this._options),this._lastActive=[]},getTitle:function(){var t=this._options.callbacks,e=t.beforeTitle.apply(this,arguments),n=t.title.apply(this,arguments),i=t.afterTitle.apply(this,arguments),a=[];return a=l(a,u(e)),a=l(a,u(n)),l(a,u(i))},getBeforeBody:function(){return h(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return r.each(t,function(t){var r={before:[],lines:[],after:[]};l(r.before,u(i.beforeLabel.call(n,t,e))),l(r.lines,i.label.call(n,t,e)),l(r.after,u(i.afterLabel.call(n,t,e))),a.push(r)}),a},getAfterBody:function(){return h(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this._options.callbacks,e=t.beforeFooter.apply(this,arguments),n=t.footer.apply(this,arguments),i=t.afterFooter.apply(this,arguments),a=[];return a=l(a,u(e)),a=l(a,u(n)),l(a,u(i))},update:function(t){var e,n,i,a,s,l,u,h=this,c=h._options,f=h._model,g=h._model=d(c),m=h._active,p=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},y={x:f.x,y:f.y},b={width:f.width,height:f.height},x={x:f.caretX,y:f.caretY};if(m.length){g.opacity=1;var _=[],k=[];x=o[c.position].call(h,m,h._eventPosition);var w=[];for(e=0,n=m.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===l?r+=u:r-="bottom"===l?e.height+u:e.height/2,"center"===l?"left"===s?a+=u:"right"===s&&(a-=u):"left"===s?a-=d:"right"===s&&(a+=d),{x:a,y:r}}(g,b,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,b),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=y.x,g.y=y.y,g.width=b.width,g.height=b.height,g.caretX=x.x,g.caretY=x.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this.getCaretPosition(t,e,this._view);n.lineTo(i.x1,i.y1),n.lineTo(i.x2,i.y2),n.lineTo(i.x3,i.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,m=e.width,p=e.height;if("center"===c)s=g+p/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+m)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+m-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+p)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n,i){var a=e.title;if(a.length){n.textAlign=e._titleAlign,n.textBaseline="top";var o,l,u=e.titleFontSize,d=e.titleSpacing;for(n.fillStyle=s(e.titleFontColor,i),n.font=r.fontString(u,e._titleFontStyle,e._titleFontFamily),o=0,l=a.length;o0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity;this._options.enabled&&(e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length)&&(this.drawBackground(i,e,t,n,a),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,a),this.drawBody(i,e,t,a),this.drawFooter(i,e,t,a))}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],n._active="mouseout"===t.type?[]:n._chart.getElementsAtEventForMode(t,i.mode,i),(e=!r.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}})).positioners=o},{26:26,27:27,46:46}],37:[function(t,e,n){"use strict";var i=t(26),a=t(27),r=t(46);i._set("global",{elements:{arc:{backgroundColor:i.global.defaultColor,borderColor:"#fff",borderWidth:2}}}),e.exports=a.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)l;)a-=2*Math.PI;for(;a=s&&a<=l&&o>=n.innerRadius&&o<=n.outerRadius}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t=this._chart.ctx,e=this._view,n=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,i),t.arc(e.x,e.y,e.innerRadius,i,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{26:26,27:27,46:46}],38:[function(t,e,n){"use strict";var i=t(26),a=t(27),r=t(46),o=i.global;i._set("global",{elements:{line:{tension:.4,backgroundColor:o.defaultColor,borderWidth:3,borderColor:o.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,n,i,a=this._view,s=this._chart.ctx,l=a.spanGaps,u=this._children.slice(),d=o.elements.line,h=-1;for(this._loop&&u.length&&u.push(u[0]),s.save(),s.lineCap=a.borderCapStyle||d.borderCapStyle,s.setLineDash&&s.setLineDash(a.borderDash||d.borderDash),s.lineDashOffset=a.borderDashOffset||d.borderDashOffset,s.lineJoin=a.borderJoinStyle||d.borderJoinStyle,s.lineWidth=a.borderWidth||d.borderWidth,s.strokeStyle=a.borderColor||o.defaultColor,s.beginPath(),h=-1,t=0;t=t.left&&1.01*t.right>=n.x&&n.y>=t.top&&1.01*t.bottom>=n.y)&&(a.strokeStyle=e.borderColor||o,a.lineWidth=r.valueOrDefault(e.borderWidth,i.global.elements.point.borderWidth),a.fillStyle=e.backgroundColor||o,r.canvas.drawPoint(a,s,u,d,h,l))}})},{26:26,27:27,46:46}],40:[function(t,e,n){"use strict";var i=t(26),a=t(27);function r(t){return void 0!==t._view.width}function o(t){var e,n,i,a,o=t._view;if(r(t)){var s=o.width/2;e=o.x-s,n=o.x+s,i=Math.min(o.y,o.base),a=Math.max(o.y,o.base)}else{var l=o.height/2;e=Math.min(o.x,o.base),n=Math.max(o.x,o.base),i=o.y-l,a=o.y+l}return{left:e,top:i,right:n,bottom:a}}i._set("global",{elements:{rectangle:{backgroundColor:i.global.defaultColor,borderColor:i.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),e.exports=a.extend({draw:function(){var t,e,n,i,a,r,o,s=this._chart.ctx,l=this._view,u=l.borderWidth;if(l.horizontal?(n=l.y-l.height/2,i=l.y+l.height/2,a=(e=l.x)>(t=l.base)?1:-1,r=1,o=l.borderSkipped||"left"):(t=l.x-l.width/2,e=l.x+l.width/2,a=1,r=(i=l.base)>(n=l.y)?1:-1,o=l.borderSkipped||"bottom"),u){var d=Math.min(Math.abs(t-e),Math.abs(n-i)),h=(u=u>d?d:u)/2,c=t+("left"!==o?h*a:0),f=e+("right"!==o?-h*a:0),g=n+("top"!==o?h*r:0),m=i+("bottom"!==o?-h*r:0);c!==f&&(n=g,i=m),g!==m&&(t=c,e=f)}s.beginPath(),s.fillStyle=l.backgroundColor,s.strokeStyle=l.borderColor,s.lineWidth=u;var p=[[t,i],[t,n],[e,n],[e,i]],v=["bottom","left","top","right"].indexOf(o,0);function y(t){return p[(v+t)%4]}-1===v&&(v=0);var b=y(0);s.moveTo(b[0],b[1]);for(var x=1;x<4;x++)b=y(x),s.lineTo(b[0],b[1]);s.fill(),u&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var n=!1;if(this._view){var i=o(this);n=t>=i.left&&t<=i.right&&e>=i.top&&e<=i.bottom}return n},inLabelRange:function(t,e){if(!this._view)return!1;var n=o(this);return r(this)?t>=n.left&&t<=n.right:e>=n.top&&e<=n.bottom},inXRange:function(t){var e=o(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=o(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,n=this._view;return r(this)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{26:26,27:27}],41:[function(t,e,n){"use strict";e.exports={},e.exports.Arc=t(37),e.exports.Line=t(38),e.exports.Point=t(39),e.exports.Rectangle=t(40)},{37:37,38:38,39:39,40:40}],42:[function(t,e,n){"use strict";var i=t(43);n=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2-1e-7,i/2-1e-7);t.moveTo(e+o,n),t.lineTo(e+i-o,n),t.arcTo(e+i,n,e+i,n+o,o),t.lineTo(e+i,n+a-o),t.arcTo(e+i,n+a,e+i-o,n+a,o),t.lineTo(e+o,n+a),t.arcTo(e,n+a,e,n+a-o,o),t.lineTo(e,n+o),t.arcTo(e,n,e+o,n,o),t.closePath(),t.moveTo(e,n)}else t.rect(e,n,i,a)},drawPoint:function(t,e,n,i,a,r){var o,s,l,u,d,h;if(r=r||0,!e||"object"!=typeof e||"[object HTMLImageElement]"!==(o=e.toString())&&"[object HTMLCanvasElement]"!==o){if(!(isNaN(n)||n<=0)){switch(t.save(),t.translate(i,a),t.rotate(r*Math.PI/180),t.beginPath(),e){default:t.arc(0,0,n,0,2*Math.PI),t.closePath();break;case"triangle":d=(s=3*n/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(-s/2,d/3),t.lineTo(s/2,d/3),t.lineTo(0,-2*d/3),t.closePath();break;case"rect":h=1/Math.SQRT2*n,t.rect(-h,-h,2*h,2*h);break;case"rectRounded":var c=n/Math.SQRT2,f=Math.SQRT2*n;this.roundedRect(t,-c,-c,f,f,.425*n);break;case"rectRot":h=1/Math.SQRT2*n,t.moveTo(-h,0),t.lineTo(0,h),t.lineTo(h,0),t.lineTo(0,-h),t.closePath();break;case"cross":t.moveTo(0,n),t.lineTo(0,-n),t.moveTo(-n,0),t.lineTo(n,0);break;case"crossRot":l=Math.cos(Math.PI/4)*n,u=Math.sin(Math.PI/4)*n,t.moveTo(-l,-u),t.lineTo(l,u),t.moveTo(-l,u),t.lineTo(l,-u);break;case"star":t.moveTo(0,n),t.lineTo(0,-n),t.moveTo(-n,0),t.lineTo(n,0),l=Math.cos(Math.PI/4)*n,u=Math.sin(Math.PI/4)*n,t.moveTo(-l,-u),t.lineTo(l,u),t.moveTo(-l,u),t.lineTo(l,-u);break;case"line":t.moveTo(-n,0),t.lineTo(n,0);break;case"dash":t.moveTo(0,0),t.lineTo(n,0)}t.fill(),t.stroke(),t.restore()}}else t.drawImage(e,i-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,n,i){if(n.steppedLine)return"after"===n.steppedLine&&!i||"after"!==n.steppedLine&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y),void t.lineTo(n.x,n.y);n.tension?t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):t.lineTo(n.x,n.y)}},i.clear=n.clear,i.drawRoundedRectangle=function(t){t.beginPath(),n.roundedRect.apply(n,arguments)}},{43:43}],43:[function(t,e,n){"use strict";var i,a={noop:function(){},uid:(i=0,function(){return i++}),isNullOrUndef:function(t){return null==t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,n){return a.valueOrDefault(a.isArray(t)?t[e]:t,n)},callback:function(t,e,n){if(t&&"function"==typeof t.call)return t.apply(n,e)},each:function(t,e,n,i){var r,o,s;if(a.isArray(t))if(o=t.length,i)for(r=o-1;r>=0;r--)e.call(n,t[r],r);else for(r=0;r=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-a.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},i.easingEffects=a},{43:43}],45:[function(t,e,n){"use strict";var i=t(43);e.exports={toLineHeight:function(t,e){var n=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!n||"normal"===n[1])return 1.2*e;switch(t=+n[2],n[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,n,a,r;return i.isObject(t)?(e=+t.top||0,n=+t.right||0,a=+t.bottom||0,r=+t.left||0):e=n=a=r=+t||0,{top:e,right:n,bottom:a,left:r,height:e+a,width:r+n}},resolve:function(t,e,n){var a,r,o;for(a=0,r=t.length;a
';var a=e.childNodes[0],r=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,r.scrollLeft=1e6,r.scrollTop=1e6};var o=function(){e._reset(),t()};return l(a,"scroll",o.bind(a,"expand")),l(r,"scroll",o.bind(r,"shrink")),e}((r=function(){if(h.resizer)return e(d("resize",n))},s=!1,u=[],function(){u=Array.prototype.slice.call(arguments),o=o||this,s||(s=!0,i.requestAnimFrame.call(window,function(){s=!1,r.apply(o,u)}))}));!function(t,e){var n=t.$chartjs||(t.$chartjs={}),r=n.renderProxy=function(t){"chartjs-render-animation"===t.animationName&&e()};i.each(a,function(e){l(t,e,r)}),n.reflow=!!t.offsetParent,t.classList.add("chartjs-render-monitor")}(t,function(){if(h.resizer){var e=t.parentNode;e&&e!==c.parentNode&&e.insertBefore(c,e.firstChild),c._reset()}})}(o,n,t)},removeEventListener:function(t,e,n){var r,o,s,l=t.canvas;if("resize"!==e){var d=((n.$chartjs||{}).proxies||{})[t.id+"_"+e];d&&u(l,e,d)}else s=(o=(r=l).$chartjs||{}).resizer,delete o.resizer,function(t){var e=t.$chartjs||{},n=e.renderProxy;n&&(i.each(a,function(e){u(t,e,n)}),delete e.renderProxy),t.classList.remove("chartjs-render-monitor")}(r),s&&s.parentNode&&s.parentNode.removeChild(s)}},i.addEvent=l,i.removeEvent=u},{46:46}],49:[function(t,e,n){"use strict";var i=t(46),a=t(47),r=t(48);e.exports=i.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},r._enabled?r:a)},{46:46,47:47,48:48}],50:[function(t,e,n){"use strict";e.exports={},e.exports.filler=t(51),e.exports.legend=t(52),e.exports.title=t(53)},{51:51,52:52,53:53}],51:[function(t,e,n){"use strict";var i=t(26),a=t(41),r=t(46);i._set("global",{plugins:{filler:{propagate:!0}}});var o={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function l(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,r=null;if(isFinite(a))return null;if("start"===a?r=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?r=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?r=n.scaleZero:i.getBasePosition?r=i.getBasePosition():i.getBasePixel&&(r=i.getBasePixel()),null!=r){if(void 0!==r.x&&void 0!==r.y)return r;if("number"==typeof r&&isFinite(r))return{x:(e=i.isHorizontal())?r:null,y:e?null:r}}return null}function u(t,e,n){var i,a=t[e].fill,r=[e];if(!n)return a;for(;!1!==a&&-1===r.indexOf(a);){if(!isFinite(a))return a;if(!(i=t[a]))return!1;if(i.visible)return a;r.push(a),a=i.fill}return!1}function d(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),o[n](t))}function h(t){return t&&!t.skip}function c(t,e,n,i,a){var o;if(i&&a){for(t.moveTo(e[0].x,e[0].y),o=1;o0;--o)r.canvas.lineTo(t,n[o],n[o-1],!0)}}e.exports={id:"filler",afterDatasetsUpdate:function(t,e){var n,i,r,o,h=(t.data.datasets||[]).length,c=e.propagate,f=[];for(i=0;i');for(var n=0;n'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("");return e.push(""),e.join("")}});var u=a.extend({initialize:function(t){r.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:s,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:function(){var t=this,e=t.options.labels||{},n=r.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(n=n.filter(function(n){return e.filter(n,t.chart.data)})),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=t.options,n=e.labels,a=e.display,o=t.ctx,s=i.global,u=r.valueOrDefault,d=u(n.fontSize,s.defaultFontSize),h=u(n.fontStyle,s.defaultFontStyle),c=u(n.fontFamily,s.defaultFontFamily),f=r.fontString(d,h,c),g=t.legendHitBoxes=[],m=t.minSize,p=t.isHorizontal();if(p?(m.width=t.maxWidth,m.height=a?10:0):(m.width=a?10:0,m.height=t.maxHeight),a)if(o.font=f,p){var v=t.lineWidths=[0],y=t.legendItems.length?d+n.padding:0;o.textAlign="left",o.textBaseline="top",r.each(t.legendItems,function(e,i){var a=l(n,d)+d/2+o.measureText(e.text).width;v[v.length-1]+a+n.padding>=t.width&&(y+=d+n.padding,v[v.length]=t.left),g[i]={left:0,top:0,width:a,height:d},v[v.length-1]+=a+n.padding}),m.height+=y}else{var b=n.padding,x=t.columnWidths=[],_=n.padding,k=0,w=0,M=d+b;r.each(t.legendItems,function(t,e){var i=l(n,d)+d/2+o.measureText(t.text).width;w+M>m.height&&(_+=k+n.padding,x.push(k),k=0,w=0),k=Math.max(k,i),w+=M,g[e]={left:0,top:0,width:i,height:d}}),_+=k,x.push(k),m.width+=_}t.width=m.width,t.height=m.height},afterFit:s,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,a=i.global,o=a.elements.line,s=t.width,u=t.lineWidths;if(e.display){var d,h=t.ctx,c=r.valueOrDefault,f=c(n.fontColor,a.defaultFontColor),g=c(n.fontSize,a.defaultFontSize),m=c(n.fontStyle,a.defaultFontStyle),p=c(n.fontFamily,a.defaultFontFamily),v=r.fontString(g,m,p);h.textAlign="left",h.textBaseline="middle",h.lineWidth=.5,h.strokeStyle=f,h.fillStyle=f,h.font=v;var y=l(n,g),b=t.legendHitBoxes,x=t.isHorizontal();d=x?{x:t.left+(s-u[0])/2,y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+n.padding,line:0};var _=g+n.padding;r.each(t.legendItems,function(i,l){var f=h.measureText(i.text).width,m=y+g/2+f,p=d.x,v=d.y;x?p+m>=s&&(v=d.y+=_,d.line++,p=d.x=t.left+(s-u[d.line])/2):v+_>t.bottom&&(p=d.x=p+t.columnWidths[d.line]+n.padding,v=d.y=t.top+n.padding,d.line++),function(t,n,i){if(!(isNaN(y)||y<=0)){h.save(),h.fillStyle=c(i.fillStyle,a.defaultColor),h.lineCap=c(i.lineCap,o.borderCapStyle),h.lineDashOffset=c(i.lineDashOffset,o.borderDashOffset),h.lineJoin=c(i.lineJoin,o.borderJoinStyle),h.lineWidth=c(i.lineWidth,o.borderWidth),h.strokeStyle=c(i.strokeStyle,a.defaultColor);var s=0===c(i.lineWidth,o.borderWidth);if(h.setLineDash&&h.setLineDash(c(i.lineDash,o.borderDash)),e.labels&&e.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2;r.canvas.drawPoint(h,i.pointStyle,l,t+u,n+u)}else s||h.strokeRect(t,n,y,g),h.fillRect(t,n,y,g);h.restore()}}(p,v,i),b[l].left=p,b[l].top=v,function(t,e,n,i){var a=g/2,r=y+a+t,o=e+a;h.fillText(n.text,r,o),n.hidden&&(h.beginPath(),h.lineWidth=2,h.moveTo(r,o),h.lineTo(r+i,o),h.stroke())}(p,v,i,f),x?d.x+=m+n.padding:d.y+=_})}},handleEvent:function(t){var e=this,n=e.options,i="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===i){if(!n.onHover)return}else{if("click"!==i)return;if(!n.onClick)return}var r=t.x,o=t.y;if(r>=e.left&&r<=e.right&&o>=e.top&&o<=e.bottom)for(var s=e.legendHitBoxes,l=0;l=u.left&&r<=u.left+u.width&&o>=u.top&&o<=u.top+u.height){if("click"===i){n.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===i){n.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}});function d(t,e){var n=new u({ctx:t.ctx,options:e,chart:t});o.configure(t,n,e),o.addBox(t,n),t.legend=n}e.exports={id:"legend",_element:u,beforeInit:function(t){var e=t.options.legend;e&&d(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(r.mergeIf(e,i.global.legend),n?(o.configure(t,n,e),n.options=e):d(t,e)):n&&(o.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}}},{26:26,27:27,31:31,46:46}],53:[function(t,e,n){"use strict";var i=t(26),a=t(27),r=t(46),o=t(31),s=r.noop;i._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}});var l=a.extend({initialize:function(t){r.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:s,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:s,afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=t.options,n=e.display,a=(0,r.valueOrDefault)(e.fontSize,i.global.defaultFontSize),o=t.minSize,s=r.isArray(e.text)?e.text.length:1,l=r.options.toLineHeight(e.lineHeight,a),u=n?s*l+2*e.padding:0;t.isHorizontal()?(o.width=t.maxWidth,o.height=u):(o.width=u,o.height=t.maxHeight),t.width=o.width,t.height=o.height},afterFit:s,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=r.valueOrDefault,a=t.options,o=i.global;if(a.display){var s,l,u,d=n(a.fontSize,o.defaultFontSize),h=n(a.fontStyle,o.defaultFontStyle),c=n(a.fontFamily,o.defaultFontFamily),f=r.fontString(d,h,c),g=r.options.toLineHeight(a.lineHeight,d),m=g/2+a.padding,p=0,v=t.top,y=t.left,b=t.bottom,x=t.right;e.fillStyle=n(a.fontColor,o.defaultFontColor),e.font=f,t.isHorizontal()?(l=y+(x-y)/2,u=v+m,s=x-y):(l="left"===a.position?y+m:x-m,u=v+(b-v)/2,s=b-v,p=Math.PI*("left"===a.position?-.5:.5)),e.save(),e.translate(l,u),e.rotate(p),e.textAlign="center",e.textBaseline="middle";var _=a.text;if(r.isArray(_))for(var k=0,w=0;w<_.length;++w)e.fillText(_[w],0,k,s),k+=g;else e.fillText(_,0,0,s);e.restore()}}});function u(t,e){var n=new l({ctx:t.ctx,options:e,chart:t});o.configure(t,n,e),o.addBox(t,n),t.titleBlock=n}e.exports={id:"title",_element:l,beforeInit:function(t){var e=t.options.title;e&&u(t,e)},beforeUpdate:function(t){var e=t.options.title,n=t.titleBlock;e?(r.mergeIf(e,i.global.title),n?(o.configure(t,n,e),n.options=e):u(t,e)):n&&(o.removeBox(t,n),delete t.titleBlock)}}},{26:26,27:27,31:31,46:46}],54:[function(t,e,n){"use strict";var i=t(33),a=t(34);e.exports=function(){var t=i.extend({getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t,e=this,n=e.getLabels();e.minIndex=0,e.maxIndex=n.length-1,void 0!==e.options.ticks.min&&(t=n.indexOf(e.options.ticks.min),e.minIndex=-1!==t?t:e.minIndex),void 0!==e.options.ticks.max&&(t=n.indexOf(e.options.ticks.max),e.maxIndex=-1!==t?t:e.maxIndex),e.min=n[e.minIndex],e.max=n[e.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.isHorizontal();return i.yLabels&&!a?n.getRightValue(i.datasets[e].data[t]):n.ticks[t-n.minIndex]},getPixelForValue:function(t,e){var n,i=this,a=i.options.offset,r=Math.max(i.maxIndex+1-i.minIndex-(a?0:1),1);if(null!=t&&(n=i.isHorizontal()?t.x:t.y),void 0!==n||void 0!==t&&isNaN(e)){var o=i.getLabels().indexOf(t=n||t);e=-1!==o?o:e}if(i.isHorizontal()){var s=i.width/r,l=s*(e-i.minIndex);return a&&(l+=s/2),i.left+Math.round(l)}var u=i.height/r,d=u*(e-i.minIndex);return a&&(d+=u/2),i.top+Math.round(d)},getPixelForTick:function(t){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null)},getValueForPixel:function(t){var e=this,n=e.options.offset,i=Math.max(e._ticks.length-(n?0:1),1),a=e.isHorizontal(),r=(a?e.width:e.height)/i;return t-=a?e.left:e.top,n&&(t-=r/2),(t<=0?0:Math.round(t/r))+e.minIndex},getBasePixel:function(){return this.bottom}});a.registerScaleType("category",t,{position:"bottom"})}},{33:33,34:34}],55:[function(t,e,n){"use strict";var i=t(26),a=t(46),r=t(34),o=t(35);e.exports=function(t){var e={position:"left",ticks:{callback:o.formatters.linear}},n=t.LinearScaleBase.extend({determineDataLimits:function(){var t=this,e=t.options,n=t.chart,i=n.data.datasets,r=t.isHorizontal();function o(e){return r?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null;var s=e.stacked;if(void 0===s&&a.each(i,function(t,e){if(!s){var i=n.getDatasetMeta(e);n.isDatasetVisible(e)&&o(i)&&void 0!==i.stack&&(s=!0)}}),e.stacked||s){var l={};a.each(i,function(i,r){var s=n.getDatasetMeta(r),u=[s.type,void 0===e.stacked&&void 0===s.stack?r:"",s.stack].join(".");void 0===l[u]&&(l[u]={positiveValues:[],negativeValues:[]});var d=l[u].positiveValues,h=l[u].negativeValues;n.isDatasetVisible(r)&&o(s)&&a.each(i.data,function(n,i){var a=+t.getRightValue(n);isNaN(a)||s.data[i].hidden||(d[i]=d[i]||0,h[i]=h[i]||0,e.relativePoints?d[i]=100:a<0?h[i]+=a:d[i]+=a)})}),a.each(l,function(e){var n=e.positiveValues.concat(e.negativeValues),i=a.min(n),r=a.max(n);t.min=null===t.min?i:Math.min(t.min,i),t.max=null===t.max?r:Math.max(t.max,r)})}else a.each(i,function(e,i){var r=n.getDatasetMeta(i);n.isDatasetVisible(i)&&o(r)&&a.each(e.data,function(e,n){var i=+t.getRightValue(e);isNaN(i)||r.data[n].hidden||(null===t.min?t.min=i:it.max&&(t.max=i))})});t.min=isFinite(t.min)&&!isNaN(t.min)?t.min:0,t.max=isFinite(t.max)&&!isNaN(t.max)?t.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this.options.ticks;if(this.isHorizontal())t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.width/50));else{var n=a.valueOrDefault(e.fontSize,i.global.defaultFontSize);t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.height/(2*n)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this,n=e.start,i=+e.getRightValue(t),a=e.end-n;return e.isHorizontal()?e.left+e.width/a*(i-n):e.bottom-e.height/a*(i-n)},getValueForPixel:function(t){var e=this,n=e.isHorizontal();return e.start+(n?t-e.left:e.bottom-t)/(n?e.width:e.height)*(e.end-e.start)},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});r.registerScaleType("linear",n,e)}},{26:26,34:34,35:35,46:46}],56:[function(t,e,n){"use strict";var i=t(46),a=t(33);e.exports=function(t){var e=i.noop;t.LinearScaleBase=a.extend({getRightValue:function(t){return"string"==typeof t?+t:a.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=i.sign(t.min),a=i.sign(t.max);n<0&&a<0?t.max=0:n>0&&a>0&&(t.min=0)}var r=void 0!==e.min||void 0!==e.suggestedMin,o=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(t.min=null===t.min?e.suggestedMin:Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(t.max=null===t.max?e.suggestedMax:Math.max(t.max,e.suggestedMax)),r!==o&&t.min>=t.max&&(r?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),a={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:i.valueOrDefault(e.fixedStepSize,e.stepSize)},r=t.ticks=function(t,e){var n,a,r,o=[];if(t.stepSize&&t.stepSize>0)r=t.stepSize;else{var s=i.niceNum(e.max-e.min,!1);r=i.niceNum(s/(t.maxTicks-1),!0),void 0!==(a=t.precision)&&(n=Math.pow(10,a),r=Math.ceil(r*n)/n)}var l=Math.floor(e.min/r)*r,u=Math.ceil(e.max/r)*r;i.isNullOrUndef(t.min)||i.isNullOrUndef(t.max)||!t.stepSize||i.almostWhole((t.max-t.min)/t.stepSize,r/1e3)&&(l=t.min,u=t.max);var d=(u-l)/r;d=i.almostEquals(d,Math.round(d),r/1e3)?Math.round(d):Math.ceil(d),a=1,r<1&&(a=Math.pow(10,1-Math.floor(i.log10(r))),l=Math.round(l*a)/a,u=Math.round(u*a)/a),o.push(void 0!==t.min?t.min:l);for(var h=1;h0){var n=i.min(e),a=i.max(e);t.min=null===t.min?n:Math.min(t.min,n),t.max=null===t.max?a:Math.max(t.max,a)}})}else i.each(a,function(e,a){var r=n.getDatasetMeta(a);n.isDatasetVisible(a)&&o(r)&&i.each(e.data,function(e,n){var i=+t.getRightValue(e);isNaN(i)||r.data[n].hidden||i<0||(null===t.min?t.min=i:it.max&&(t.max=i),0!==i&&(null===t.minNotZero||i0?t.min:t.max<1?Math.pow(10,Math.floor(i.log10(t.max))):1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),a=t.ticks=function(t,e){var n,a,r=[],o=i.valueOrDefault,s=o(t.min,Math.pow(10,Math.floor(i.log10(e.min)))),l=Math.floor(i.log10(e.max)),u=Math.ceil(e.max/Math.pow(10,l));0===s?(n=Math.floor(i.log10(e.minNotZero)),a=Math.floor(e.minNotZero/Math.pow(10,n)),r.push(s),s=a*Math.pow(10,n)):(n=Math.floor(i.log10(s)),a=Math.floor(s/Math.pow(10,n)));var d=n<0?Math.pow(10,Math.abs(n)):1;do{r.push(s),10==++a&&(a=1,d=++n>=0?1:d),s=Math.round(a*Math.pow(10,n)*d)/d}while(na?{start:e-n-5,end:e}:{start:e,end:e+n+5}}function d(t){return 0===t||180===t?"center":t<180?"left":"right"}function h(t,e,n,i){if(a.isArray(e))for(var r=n.y,o=1.5*i,s=0;s270||t<90)&&(n.y-=e.h)}function f(t){return a.isNumber(t)?t:0}var g=t.LinearScaleBase.extend({setDimensions:function(){var t=this,n=t.options,i=n.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var r=a.min([t.height,t.width]),o=a.valueOrDefault(i.fontSize,e.defaultFontSize);t.drawingArea=n.display?r/2-(o/2+i.backdropPaddingY):r/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;a.each(e.data.datasets,function(r,o){if(e.isDatasetVisible(o)){var s=e.getDatasetMeta(o);a.each(r.data,function(e,a){var r=+t.getRightValue(e);isNaN(r)||s.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))})}}),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,n=a.valueOrDefault(t.fontSize,e.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*n)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t;this.options.pointLabels.display?function(t){var e,n,i,r=l(t),o=Math.min(t.height/2,t.width/2),d={r:t.width,l:0,t:t.height,b:0},h={};t.ctx.font=r.font,t._pointLabelSizes=[];var c,f,g,m=s(t);for(e=0;ed.r&&(d.r=y.end,h.r=p),b.startd.b&&(d.b=b.end,h.b=p)}t.setReductions(o,d,h)}(this):(t=Math.min(this.height/2,this.width/2),this.drawingArea=Math.round(t),this.setCenterPoint(0,0,0,0))},setReductions:function(t,e,n){var i=e.l/Math.sin(n.l),a=Math.max(e.r-this.width,0)/Math.sin(n.r),r=-e.t/Math.cos(n.t),o=-Math.max(e.b-this.height,0)/Math.cos(n.b);i=f(i),a=f(a),r=f(r),o=f(o),this.drawingArea=Math.min(Math.round(t-(i+a)/2),Math.round(t-(r+o)/2)),this.setCenterPoint(i,a,r,o)},setCenterPoint:function(t,e,n,i){var a=this,r=n+a.drawingArea,o=a.height-i-a.drawingArea;a.xCenter=Math.round((t+a.drawingArea+(a.width-e-a.drawingArea))/2+a.left),a.yCenter=Math.round((r+o)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/s(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(n)*e)+this.xCenter,y:Math.round(Math.sin(n)*e)+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0)},draw:function(){var t=this,n=t.options,i=n.gridLines,r=n.ticks,o=a.valueOrDefault;if(n.display){var u=t.ctx,f=this.getIndexAngle(0),g=o(r.fontSize,e.defaultFontSize),m=o(r.fontStyle,e.defaultFontStyle),p=o(r.fontFamily,e.defaultFontFamily),v=a.fontString(g,m,p);a.each(t.ticks,function(n,l){if(l>0||r.reverse){var d=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]);if(i.display&&0!==l&&function(t,e,n,i){var r=t.ctx;if(r.strokeStyle=a.valueAtIndexOrDefault(e.color,i-1),r.lineWidth=a.valueAtIndexOrDefault(e.lineWidth,i-1),t.options.gridLines.circular)r.beginPath(),r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI),r.closePath(),r.stroke();else{var o=s(t);if(0===o)return;r.beginPath();var l=t.getPointPosition(0,n);r.moveTo(l.x,l.y);for(var u=1;u=0;g--){if(r.display){var m=t.getPointPosition(g,u);n.beginPath(),n.moveTo(t.xCenter,t.yCenter),n.lineTo(m.x,m.y),n.stroke(),n.closePath()}if(o.display){var p=t.getPointPosition(g,u+5),v=a.valueAtIndexOrDefault(o.fontColor,g,e.defaultFontColor);n.font=f.font,n.fillStyle=v;var y=t.getIndexAngle(g),b=a.toDegrees(y);n.textAlign=d(b),c(b,t._pointLabelSizes[g],p),h(n,t.pointLabels[g]||"",p,f.size)}}}(t)}}});r.registerScaleType("radialLinear",g,n)}},{26:26,34:34,35:35,46:46}],59:[function(t,e,n){"use strict";var i=t(6);i="function"==typeof i?i:window.moment;var a=t(26),r=t(46),o=t(33),s=t(34),l=Number.MIN_SAFE_INTEGER||-9007199254740991,u=Number.MAX_SAFE_INTEGER||9007199254740991,d={millisecond:{common:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{common:!0,size:1e3,steps:[1,2,5,10,15,30]},minute:{common:!0,size:6e4,steps:[1,2,5,10,15,30]},hour:{common:!0,size:36e5,steps:[1,2,3,6,12]},day:{common:!0,size:864e5,steps:[1,2,5]},week:{common:!1,size:6048e5,steps:[1,2,3,4]},month:{common:!0,size:2628e6,steps:[1,2,3]},quarter:{common:!1,size:7884e6,steps:[1,2,3,4]},year:{common:!0,size:3154e7}},h=Object.keys(d);function c(t,e){return t-e}function f(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e=0&&o<=s;){if(r=t[i=o+s>>1],!(a=t[i-1]||null))return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e];return r[i]+(o[i]-r[i])*(s?(n-r[e])/s:0)}function m(t,e){var n=e.parser,a=e.parser||e.format;return"function"==typeof n?n(t):"string"==typeof t&&"string"==typeof a?i(t,a):(t instanceof i||(t=i(t)),t.isValid()?t:"function"==typeof a?a(t):t)}function p(t,e){if(r.isNullOrUndef(t))return null;var n=e.options.time,i=m(e.getRightValue(t),n);return i.isValid()?(n.round&&i.startOf(n.round),i.valueOf()):null}function v(t){for(var e=h.indexOf(t)+1,n=h.length;e=o&&n<=s&&y.push(n);return a.min=o,a.max=s,a._unit=c.unit||function(t,e,n,r){var o,s,l=i.duration(i(a.max).diff(i(n)));for(o=h.length-1;o>=h.indexOf(e);o--)if(d[s=h[o]].common&&l.as(s)>=t.length)return s;return h[e?h.indexOf(e):0]}(y,c.minUnit,a.min),a._majorUnit=v(a._unit),a._table=function(t,e,n,i){if("linear"===l.distribution||!t.length)return[{time:e,pos:0},{time:n,pos:1}];var a,r,o,s,u,d=[],h=[e];for(a=0,r=t.length;ae&&s1?e[1]:i,"pos")-g(t,"time",r,"pos"))/2),a.time.max||(r=e.length>1?e[e.length-2]:n,s=(g(t,"time",e[e.length-1],"pos")-g(t,"time",r,"pos"))/2)),{left:o,right:s}}(a._table,y,o,s,l),a._labelFormat=function(t,e){var n,i,a,r=t.length;for(n=0;n=0&&t0?s:1}});s.registerScaleType("time",t,{position:"bottom",distribution:"linear",bounds:"data",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}})}},{26:26,33:33,34:34,46:46,6:6}]},{},[7])(7)}); \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f5317b15474518dffebc.css b/src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f5317b15474518dffebc.css new file mode 100644 index 00000000..c33da468 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/styles.f5317b15474518dffebc.css @@ -0,0 +1,27 @@ +.toast-center-center{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}.toast-title{font-weight:700}.toast-message{word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#fff;text-shadow:0 1px 0 #fff}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0}.toast-container{pointer-events:none;position:fixed;z-index:999999}.toast-container *{box-sizing:border-box}.toast-container .ngx-toastr{position:relative;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;background-size:24px;box-shadow:0 0 12px #999;color:#fff}.toast-container .ngx-toastr:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.toast-info{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' width='512' height='512'%3E%3Cpath fill='rgb(255,255,255)' d='M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z'/%3E%3C/svg%3E")}.toast-error{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' width='512' height='512'%3E%3Cpath fill='rgb(255,255,255)' d='M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z'/%3E%3C/svg%3E")}.toast-success{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' width='512' height='512'%3E%3Cpath fill='rgb(255,255,255)' d='M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z'/%3E%3C/svg%3E")}.toast-container.toast-bottom-center .ngx-toastr,.toast-container.toast-top-center .ngx-toastr{width:300px;margin-left:auto;margin-right:auto}.toast-container.toast-bottom-full-width .ngx-toastr,.toast-container.toast-top-full-width .ngx-toastr{width:96%;margin-left:auto;margin-right:auto}.ngx-toastr{background-color:#030303;pointer-events:auto}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-warning{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512' width='576' height='512'%3E%3Cpath fill='rgb(255,255,255)' d='M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z'/%3E%3C/svg%3E");background-color:#f89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4}@media all and (max-width:240px){.toast-container .ngx-toastr.div{padding:8px 8px 8px 50px;width:11em}.toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:241px) and (max-width:480px){.toast-container .ngx-toastr.div{padding:8px 8px 8px 50px;width:18em}.toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:481px) and (max-width:768px){.toast-container .ngx-toastr.div{padding:15px 15px 15px 50px;width:25em}}/*! + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,optgroup,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0;vertical-align:middle}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}textarea{overflow:auto}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:"Glyphicons Halflings";src:url(glyphicons-halflings-regular.f4769f9bdb7466be6508.eot);src:url(glyphicons-halflings-regular.f4769f9bdb7466be6508.eot?#iefix) format("embedded-opentype"),url(glyphicons-halflings-regular.448c34a56d699c29117a.woff2) format("woff2"),url(glyphicons-halflings-regular.fa2772327f55d8198301.woff) format("woff"),url(glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf) format("truetype"),url(glyphicons-halflings-regular.89889688147bd7575d63.svg#glyphicons_halflingsregular) format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:"Glyphicons Halflings";font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before,.glyphicon-btc:before,.glyphicon-xbt:before{content:"\e227"}.glyphicon-jpy:before,.glyphicon-yen:before{content:"\00a5"}.glyphicon-rub:before,.glyphicon-ruble:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*,:after,:before{box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a:focus{outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}figure{margin:0}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:.2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{box-sizing:content-box;height:0;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}abbr[data-original-title],abbr[title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:"\2014 \00A0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:""}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:"\00A0 \2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;box-shadow:none}pre{overflow:auto;display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{border-collapse:collapse;border-spacing:0;background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered,.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover,.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.checkbox label,.radio label{min-height:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px;outline:0}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child:not(:first-child){border-radius:0 0 4px 4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center;margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0;border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}@media (min-width:768px){.navbar{border-radius:4px}.navbar-header{float:left}.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}.navbar-static-top{z-index:1000;border-width:0 0 1px}.navbar-brand{float:left;height:50px;padding:15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}.navbar-static-top{border-radius:0}.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}.navbar-toggle{display:none}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}.navbar-form{padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin:8px -15px}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;box-shadow:none}.navbar-text{float:left;margin-right:15px;margin-left:15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-radius:4px 4px 0 0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-nav>li>a,.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>li>a,.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:2s linear infinite progress-bar-stripes;animation:2s linear infinite progress-bar-stripes}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-striped .progress-bar-info{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.list-group+.panel-footer,.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;text-align:center;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:left .6s ease-in-out;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}.visible-xs-block{display:block!important}.visible-xs-inline{display:inline!important}.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}.visible-sm-block{display:block!important}.visible-sm-inline{display:inline!important}.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}.visible-md-block{display:block!important}.visible-md-inline{display:inline!important}.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}.visible-lg-block{display:block!important}.visible-lg-inline{display:inline!important}.visible-lg-inline-block{display:inline-block!important}.hidden-lg{display:none!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}.hidden-print{display:none!important}}/*! +Fork Awesome 1.1.6 +License - https://forkaweso.me/Fork-Awesome/license + +Copyright 2018 Dave Gandy & Fork Awesome + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */@font-face{font-family:ForkAwesome;src:url(forkawesome-webfont.35e77a38ca9d85c4e897.eot?v=1.1.6);src:url(forkawesome-webfont.35e77a38ca9d85c4e897.eot?#iefix&v=1.1.6) format('embedded-opentype'),url(forkawesome-webfont.3a9e014c2469ffa65a0e.woff2?v=1.1.6) format('woff2'),url(forkawesome-webfont.44bbdbbfb5a10ba2d1ce.woff?v=1.1.6) format('woff'),url(forkawesome-webfont.fc46f3dae03b2b2e1cee.ttf?v=1.1.6) format('truetype'),url(forkawesome-webfont.78dcc9c4999659b8026a.svg?v=1.1.6#forkawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-refresh:before,.fa-sync:before{content:"\f021"}.fa-video-camera:before,.fa-video:before{content:"\f03d"}.fa-asterisk:before{content:"\f069"}.fa-bell-o:before{content:"\f0f3"}.fa-google-plus-g:before,.fa-google-plus:before{content:"\f0d5"}.fa-bell:before{content:"\f0a2"}.fa-cutlery:before,.fa-utensils:before{content:"\f0f5"}.fa-gbp:before,.fa-pound:before{content:"\f154"}.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-desc:before,.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-desc:before,.fa-sort-amount-up:before{content:"\f161"}.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-desc:before,.fa-sort-numeric-up:before{content:"\f163"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f1b1"}.fa-header:before,.fa-heading:before{content:"\f1dc"}.fa-cc:before,.fa-closed-captioning:before{content:"\f20a"}.fa-diamond:before,.fa-gem:before{content:"\f219"}.fa-vimeo-v:before,.fa-vimeo:before{content:"\f27d"}.fa-phone-volume:before,.fa-volume-control-phone:before{content:"\f2a0"}.fa-gnupg:before{content:"\f30d"}.fa-php:before{content:"\f30e"}.fa-ffmpeg:before{content:"\f30f"}.fa-joplin:before{content:"\f310"}.fa-syncthing:before{content:"\f311"}.fa-inkscape:before{content:"\f312"}.fa-matrix-org:before{content:"\f313"}.fa-pixelfed:before{content:"\f314"}.fa-bootstrap:before{content:"\f315"}.fa-dev-to:before{content:"\f316"}.fa-hashnode:before{content:"\f317"}.fa-jirafeau:before{content:"\f318"}.fa-emby:before{content:"\f319"}.fa-wikidata:before{content:"\f31a"}.fa-gimp:before{content:"\f31b"}.fa-c:before{content:"\f31c"}.fa-digitalocean:before{content:"\f31d"}.fa-att:before{content:"\f31e"}.fa-gitea:before{content:"\f31f"}.fa-file-epub:before{content:"\f321"}.fa-python:before{content:"\f322"}.fa-archlinux:before{content:"\f323"}.fa-pleroma:before{content:"\f324"}.fa-unsplash:before{content:"\f325"}.fa-hackster:before{content:"\f326"}.fa-spell-check:before{content:"\f327"}.fa-moon:before{content:"\f328"}.fa-sun:before{content:"\f329"}.fa-f-droid:before{content:"\f32a"}.fa-biometric:before{content:"\f32b"}.checkbox{padding-left:20px}.checkbox label{display:inline-block;vertical-align:middle;position:relative;padding-left:5px}.checkbox label::before{content:"";display:inline-block;position:absolute;width:17px;height:17px;left:0;margin-left:-20px;border:1px solid #ccc;border-radius:3px;background-color:#fff;-webkit-transition:border .15s ease-in-out,color .15s ease-in-out;transition:border .15s ease-in-out,color .15s ease-in-out}.checkbox label::after{display:inline-block;position:absolute;width:16px;height:16px;left:0;top:0;margin-left:-20px;padding-left:3px;padding-top:1px;font-size:11px;color:#555}.checkbox input[type=checkbox],.checkbox input[type=radio]{opacity:0;z-index:1}.checkbox input[type=checkbox]:focus+label::before,.checkbox input[type=radio]:focus+label::before{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.checkbox input[type=checkbox]:checked+label::after,.checkbox input[type=radio]:checked+label::after{font-family:FontAwesome;content:"\f00c"}.checkbox input[type=checkbox]:indeterminate+label::after,.checkbox input[type=radio]:indeterminate+label::after{display:block;content:"";width:10px;height:3px;background-color:#555;border-radius:2px;margin-left:-16.5px;margin-top:7px}.checkbox input[type=checkbox]:disabled+label,.checkbox input[type=radio]:disabled+label{opacity:.65}.checkbox input[type=checkbox]:disabled+label::before,.checkbox input[type=radio]:disabled+label::before{background-color:#eee;cursor:not-allowed}.checkbox.checkbox-circle label::before{border-radius:50%}.checkbox.checkbox-inline{margin-top:0}.checkbox-primary input[type=checkbox]:checked+label::before,.checkbox-primary input[type=radio]:checked+label::before{background-color:#337ab7;border-color:#337ab7}.checkbox-primary input[type=checkbox]:checked+label::after,.checkbox-primary input[type=radio]:checked+label::after{color:#fff}.checkbox-danger input[type=checkbox]:checked+label::before,.checkbox-danger input[type=radio]:checked+label::before{background-color:#d9534f;border-color:#d9534f}.checkbox-danger input[type=checkbox]:checked+label::after,.checkbox-danger input[type=radio]:checked+label::after{color:#fff}.checkbox-info input[type=checkbox]:checked+label::before,.checkbox-info input[type=radio]:checked+label::before{background-color:#5bc0de;border-color:#5bc0de}.checkbox-info input[type=checkbox]:checked+label::after,.checkbox-info input[type=radio]:checked+label::after{color:#fff}.checkbox-warning input[type=checkbox]:checked+label::before,.checkbox-warning input[type=radio]:checked+label::before{background-color:#f0ad4e;border-color:#f0ad4e}.checkbox-warning input[type=checkbox]:checked+label::after,.checkbox-warning input[type=radio]:checked+label::after{color:#fff}.checkbox-success input[type=checkbox]:checked+label::before,.checkbox-success input[type=radio]:checked+label::before{background-color:#5cb85c;border-color:#5cb85c}.checkbox-success input[type=checkbox]:checked+label::after,.checkbox-success input[type=radio]:checked+label::after{color:#fff}.checkbox-primary input[type=checkbox]:indeterminate+label::before,.checkbox-primary input[type=radio]:indeterminate+label::before{background-color:#337ab7;border-color:#337ab7}.checkbox-primary input[type=checkbox]:indeterminate+label::after,.checkbox-primary input[type=radio]:indeterminate+label::after{background-color:#fff}.checkbox-danger input[type=checkbox]:indeterminate+label::before,.checkbox-danger input[type=radio]:indeterminate+label::before{background-color:#d9534f;border-color:#d9534f}.checkbox-danger input[type=checkbox]:indeterminate+label::after,.checkbox-danger input[type=radio]:indeterminate+label::after{background-color:#fff}.checkbox-info input[type=checkbox]:indeterminate+label::before,.checkbox-info input[type=radio]:indeterminate+label::before{background-color:#5bc0de;border-color:#5bc0de}.checkbox-info input[type=checkbox]:indeterminate+label::after,.checkbox-info input[type=radio]:indeterminate+label::after{background-color:#fff}.checkbox-warning input[type=checkbox]:indeterminate+label::before,.checkbox-warning input[type=radio]:indeterminate+label::before{background-color:#f0ad4e;border-color:#f0ad4e}.checkbox-warning input[type=checkbox]:indeterminate+label::after,.checkbox-warning input[type=radio]:indeterminate+label::after{background-color:#fff}.checkbox-success input[type=checkbox]:indeterminate+label::before,.checkbox-success input[type=radio]:indeterminate+label::before{background-color:#5cb85c;border-color:#5cb85c}.checkbox-success input[type=checkbox]:indeterminate+label::after,.checkbox-success input[type=radio]:indeterminate+label::after{background-color:#fff}.radio{padding-left:20px}.radio label{display:inline-block;vertical-align:middle;position:relative;padding-left:5px}.radio label::before{content:"";display:inline-block;position:absolute;width:17px;height:17px;left:0;margin-left:-20px;border:1px solid #ccc;border-radius:50%;background-color:#fff;-webkit-transition:border .15s ease-in-out;transition:border .15s ease-in-out}.radio label::after{display:inline-block;position:absolute;content:" ";width:11px;height:11px;left:3px;top:3px;margin-left:-20px;border-radius:50%;background-color:#555;-webkit-transform:scale(0,0);transform:scale(0,0);-webkit-transition:-webkit-transform .1s cubic-bezier(.8,-.33,.2,1.33);transition:-webkit-transform .1s cubic-bezier(.8,-.33,.2,1.33);transition:transform .1s cubic-bezier(.8,-.33,.2,1.33);transition:transform .1s cubic-bezier(.8,-.33,.2,1.33),-webkit-transform .1s cubic-bezier(.8,-.33,.2,1.33)}.radio input[type=radio]{opacity:0;z-index:1}.radio input[type=radio]:focus+label::before{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.radio input[type=radio]:checked+label::after{-webkit-transform:scale(1,1);transform:scale(1,1)}.radio input[type=radio]:disabled+label{opacity:.65}.radio input[type=radio]:disabled+label::before{cursor:not-allowed}.radio.radio-inline{margin-top:0}.radio-primary input[type=radio]+label::after{background-color:#337ab7}.radio-primary input[type=radio]:checked+label::before{border-color:#337ab7}.radio-primary input[type=radio]:checked+label::after{background-color:#337ab7}.radio-danger input[type=radio]+label::after{background-color:#d9534f}.radio-danger input[type=radio]:checked+label::before{border-color:#d9534f}.radio-danger input[type=radio]:checked+label::after{background-color:#d9534f}.radio-info input[type=radio]+label::after{background-color:#5bc0de}.radio-info input[type=radio]:checked+label::before{border-color:#5bc0de}.radio-info input[type=radio]:checked+label::after{background-color:#5bc0de}.radio-warning input[type=radio]+label::after{background-color:#f0ad4e}.radio-warning input[type=radio]:checked+label::before{border-color:#f0ad4e}.radio-warning input[type=radio]:checked+label::after{background-color:#f0ad4e}.radio-success input[type=radio]+label::after{background-color:#5cb85c}.radio-success input[type=radio]:checked+label::before{border-color:#5cb85c}.radio-success input[type=radio]:checked+label::after{background-color:#5cb85c}input[type=checkbox].styled:checked+label:after,input[type=radio].styled:checked+label:after{font-family:FontAwesome;content:"\f00c"}input[type=checkbox] .styled:checked+label::after,input[type=checkbox] .styled:checked+label::before,input[type=radio] .styled:checked+label::after,input[type=radio] .styled:checked+label::before{color:#fff}.bs-datepicker{display:-webkit-box;display:flex;-webkit-box-align:stretch;align-items:stretch;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;background:#fff;box-shadow:0 0 10px 0 #aaa;position:relative;z-index:1}.bs-datepicker:after{clear:both;content:'';display:block}.bs-datepicker bs-day-picker{float:left}.bs-datepicker button:active,.bs-datepicker button:focus,.bs-datepicker button:hover,.bs-datepicker input:active,.bs-datepicker input:focus,.bs-datepicker input:hover,.bs-datepicker-btns button:active,.bs-datepicker-btns button:focus,.bs-datepicker-btns button:hover,.bs-datepicker-predefined-btns button:active,.bs-datepicker-predefined-btns button:focus{outline:0}.bs-datepicker-head{min-width:270px;height:50px;padding:10px;border-radius:3px 3px 0 0;text-align:justify}.bs-datepicker-head:after{content:"";display:inline-block;vertical-align:top;width:100%}.bs-datepicker-head button{display:inline-block;vertical-align:top;padding:0;height:30px;line-height:30px;border:0;background:0 0;text-align:center;cursor:pointer;color:#fff;-webkit-transition:.3s;transition:.3s}.bs-datepicker-head button[disabled],.bs-datepicker-head button[disabled]:active,.bs-datepicker-head button[disabled]:hover{background:rgba(221,221,221,.3);color:#f5f5f5;cursor:not-allowed}.bs-datepicker-head button.next,.bs-datepicker-head button.previous{border-radius:50%;width:30px;height:30px}.bs-datepicker-head button.next span,.bs-datepicker-head button.previous span{font-size:28px;line-height:1;display:inline-block;position:relative;height:100%;width:100%;border-radius:50%}.bs-datepicker-head button.current{border-radius:15px;max-width:155px;padding:0 13px}.bs-datepicker-head button:hover{background-color:rgba(0,0,0,.1)}.bs-datepicker-head button:active{background-color:rgba(0,0,0,.2)}.bs-datepicker-body{padding:10px;border-radius:0 0 3px 3px;min-height:232px;min-width:278px;border:1px solid #e9edf0}.bs-datepicker-body .days.weeks{position:relative;z-index:1}.bs-datepicker-body table{width:100%;border-collapse:separate;border-spacing:0}.bs-datepicker-body table th{font-size:13px;color:#9aaec1;font-weight:400;text-align:center}.bs-datepicker-body table td{color:#54708b;text-align:center;position:relative;padding:0}.bs-datepicker-body table td span{display:block;margin:0 auto;font-size:13px;border-radius:50%;position:relative;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.bs-datepicker-body table td:not(.disabled):not(.week) span:not(.disabled):not(.is-other-month){cursor:pointer}.bs-datepicker-body table td span.is-highlighted:not(.disabled):not(.selected),.bs-datepicker-body table td.is-highlighted:not(.disabled):not(.selected) span{background-color:#e9edf0;-webkit-transition:none;transition:0s}.bs-datepicker-body table td span.is-active-other-month:not(.disabled):not(.selected),.bs-datepicker-body table td.is-active-other-month:not(.disabled):not(.selected) span{background-color:#e9edf0;-webkit-transition:none;transition:0s;cursor:pointer}.bs-datepicker-body table td span.disabled,.bs-datepicker-body table td.disabled span{color:#9aaec1}.bs-datepicker-body table td span.selected,.bs-datepicker-body table td.selected span{color:#fff}.bs-datepicker-body table td span.is-other-month,.bs-datepicker-body table td.is-other-month span{color:rgba(0,0,0,.25)}.bs-datepicker-body table td.active{position:relative}.bs-datepicker-body table td.active.select-start:before{left:35%}.bs-datepicker-body table td.active.select-end:before{left:-85%}.bs-datepicker-body table td span.active.select-end:after,.bs-datepicker-body table td span.active.select-start:after,.bs-datepicker-body table td.active.select-end span:after,.bs-datepicker-body table td.active.select-start span:after{content:"";display:block;position:absolute;z-index:-1;width:100%;height:100%;-webkit-transition:.3s;transition:.3s;top:0;border-radius:50%}.bs-datepicker-body table td span:before,.bs-datepicker-body table td:before{content:"";display:block;position:absolute;z-index:-1;top:6px;bottom:6px;left:-2px;right:-2px;box-sizing:content-box;background:0 0}.bs-datepicker-body table td.active.select-start+td.active:before{left:-20%}.bs-datepicker-body table td:last-child.active:before{border-radius:0 3px 3px 0;width:125%;left:-25%}.bs-datepicker-body table td span[class*=select-],.bs-datepicker-body table td[class*=select-] span{border-radius:50%;color:#fff}.bs-datepicker-body table.days span.active:not(.select-start):before,.bs-datepicker-body table.days span.in-range:not(.select-start):before,.bs-datepicker-body table.days td.active:not(.select-start):before,.bs-datepicker-body table.days td.in-range:not(.select-start):before{background:#e9edf0}.bs-datepicker-body table.days span{width:32px;height:32px;line-height:32px}.bs-datepicker-body table.days span.select-start{z-index:2}.bs-datepicker-body table.days span.in-range.select-end:before,.bs-datepicker-body table.days span.is-highlighted.in-range:before{background:0 0;right:0;left:0}.bs-datepicker-body table.days td.active+td.is-highlighted:before,.bs-datepicker-body table.days td.active+td.select-end:before,.bs-datepicker-body table.days td.in-range+td.is-highlighted:before,.bs-datepicker-body table.days td.in-range+td.select-end:before,.bs-datepicker-body table.days td.select-start+td.is-highlighted:before,.bs-datepicker-body table.days td.select-start+td.select-end:before{background:#e9edf0;width:100%}.bs-datepicker-body table.weeks tr td:nth-child(2).active:before{border-radius:3px 0 0 3px;left:0;width:100%}.bs-datepicker-body table:not(.weeks) tr td:first-child:before{border-radius:3px 0 0 3px}.bs-datepicker-body table.years td span{width:46px;height:46px;line-height:45px;margin:0 auto}.bs-datepicker-body table.years tr:not(:last-child) td span{margin-bottom:8px}.bs-datepicker-body table.months td{height:52px}.bs-datepicker-body table.months td span{padding:6px;border-radius:15px}.bs-datepicker .current-timedate{color:#54708b;font-size:15px;text-align:center;height:30px;line-height:30px;border-radius:20px;border:1px solid #e9edf0;margin-bottom:10px;cursor:pointer;text-transform:uppercase;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.bs-datepicker .current-timedate span:not(:empty):before{content:"";width:15px;height:16px;display:inline-block;margin-right:4px;vertical-align:text-bottom;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAQCAYAAADJViUEAAABMklEQVQoU9VTwW3CQBCcOUgBtEBKSAukAnBKME+wFCAlYIhk8sQlxFABtJAScAsuAPBEewYcxCP8ouxrPDsza61uiVN1o6RNHD4htSCmq49RfO71BvMJqBBkITRf1kmUW49nQRC9h1I5AZlBClaL8aP1fKgOOxCx8aSLs+Q19eZuNO8QmPqJRtDFguy7OAcDbJPs+/BKVPDIPrvD2ZJgWAmVe7O0rI0Vqs1seyWUXpuJoppYCa5L+U++NpNPkr5OE2oMdARsb3gykJT5ydZcL8Z9Ww60nxg2LhjON9li9OwXZzo+xLbp3nC2s9CL2RrueGyVrgwNm8HpsCzZ9EEW6kqXlo1GQe03FzP/7W8Hl0dBtu7Bf7zt6mIwvX1RvzDCm7+q3mAW0Dl/GPdUCeXrZLT9BrDrGkm4qlPvAAAAAElFTkSuQmCC)}.bs-datepicker-multiple{border-radius:4px 0 0 4px}.bs-datepicker-multiple+.bs-datepicker-multiple{margin-left:10px}.bs-datepicker-multiple .bs-datepicker{box-shadow:none;position:relative}.bs-datepicker-multiple .bs-datepicker:not(:last-child){padding-right:10px}.bs-datepicker-multiple .bs-datepicker+.bs-datepicker:after{content:"";display:block;width:14px;height:10px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAKCAYAAABrGwT5AAAA1ElEQVQoU42RsQrCUAxF77VuDu7O4oMWW//BURBBpZvgKk4uIrjoqKOTf+DopIO4uYggtFTfw3+pkQqCW1/G5J7kJiFy4m5MxUlxAzgIPHX+lzMPzupRYlYgxiR7vqsOP8YKzsTx0yxFMCUZ+q7aZzlr+OvgoWcAFyAHgat2jLWu48252DdqAihDJGSSJNUUxYmQjs3+hPQBlAh2rG2LCOPnaw3IiGDX99TRCs7ASJsNhUOA7d/LcuHvRG22FIZvsNXw1MX6VZExCilOQKEfeLXr/10+aC9Ho7arh7oAAAAASUVORK5CYII=);position:absolute;top:25px;left:-8px}.bs-datepicker-multiple .bs-datepicker .left{float:left}.bs-datepicker-multiple .bs-datepicker .right{float:right}.bs-datepicker-container{padding:15px}.bs-datepicker .bs-media-container{display:-webkit-box;display:flex}@media (max-width:768px){.bs-datepicker .bs-media-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column}}.bs-datepicker-custom-range{padding:15px;background:#eee}.bs-datepicker-predefined-btns button{width:100%;display:block;height:30px;background-color:#9aaec1;border-radius:4px;color:#fff;border:0;margin-bottom:10px;padding:0 18px;text-align:left;-webkit-transition:.3s;transition:.3s}.bs-datepicker-predefined-btns button:active,.bs-datepicker-predefined-btns button:hover{background-color:#54708b}.bs-datepicker-buttons{display:-webkit-box;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;-webkit-box-pack:end;justify-content:flex-end;padding-top:10px;border-top:1px solid #e9edf0}.bs-datepicker-buttons .btn-default{margin-left:10px}.bs-timepicker-container{padding:10px 0}.bs-timepicker-label{color:#54708b;margin-bottom:10px}.bs-timepicker-controls{display:inline-block;vertical-align:top;margin-right:10px}.bs-timepicker-controls button{width:20px;height:20px;border-radius:50%;border:0;background-color:#e9edf0;color:#54708b;font-size:16px;font-weight:700;vertical-align:middle;line-height:0;padding:0;-webkit-transition:.3s;transition:.3s}.bs-timepicker-controls button:hover{background-color:#d5dadd}.bs-timepicker-controls input{width:35px;height:25px;border-radius:13px;text-align:center;border:1px solid #e9edf0}.bs-timepicker .switch-time-format{text-transform:uppercase;min-width:54px;height:25px;border-radius:20px;border:1px solid #e9edf0;background:#fff;color:#54708b;font-size:13px}.bs-timepicker .switch-time-format img{vertical-align:initial;margin-left:4px}bs-datepicker-container,bs-daterangepicker-container{z-index:1080}@media (max-width:768px){.bs-datepicker-multiple{display:-webkit-box;display:flex}.bs-datepicker-multiple+.bs-datepicker-multiple{margin-top:10px;margin-left:0}}.theme-default .bs-datepicker-body table td span.selected,.theme-default .bs-datepicker-body table td span[class*=select-]:after,.theme-default .bs-datepicker-body table td.selected span,.theme-default .bs-datepicker-body table td[class*=select-] span:after,.theme-default .bs-datepicker-head{background-color:#777}.theme-default .bs-datepicker-body table td.week span{color:#777}.theme-default .bs-datepicker-body table td.active-week span:hover{cursor:pointer;background-color:#777;color:#fff;opacity:.5;-webkit-transition:none;transition:0s}.theme-green .bs-datepicker-body table td span.selected,.theme-green .bs-datepicker-body table td span[class*=select-]:after,.theme-green .bs-datepicker-body table td.selected span,.theme-green .bs-datepicker-body table td[class*=select-] span:after,.theme-green .bs-datepicker-head{background-color:#5cb85c}.theme-green .bs-datepicker-body table td.week span{color:#5cb85c}.theme-green .bs-datepicker-body table td.active-week span:hover{cursor:pointer;background-color:#5cb85c;color:#fff;opacity:.5;-webkit-transition:none;transition:0s}.theme-blue .bs-datepicker-body table td span.selected,.theme-blue .bs-datepicker-body table td span[class*=select-]:after,.theme-blue .bs-datepicker-body table td.selected span,.theme-blue .bs-datepicker-body table td[class*=select-] span:after,.theme-blue .bs-datepicker-head{background-color:#5bc0de}.theme-blue .bs-datepicker-body table td.week span{color:#5bc0de}.theme-blue .bs-datepicker-body table td.active-week span:hover{cursor:pointer;background-color:#5bc0de;color:#fff;opacity:.5;-webkit-transition:none;transition:0s}.theme-dark-blue .bs-datepicker-body table td span.selected,.theme-dark-blue .bs-datepicker-body table td span[class*=select-]:after,.theme-dark-blue .bs-datepicker-body table td.selected span,.theme-dark-blue .bs-datepicker-body table td[class*=select-] span:after,.theme-dark-blue .bs-datepicker-head{background-color:#337ab7}.theme-dark-blue .bs-datepicker-body table td.week span{color:#337ab7}.theme-dark-blue .bs-datepicker-body table td.active-week span:hover{cursor:pointer;background-color:#337ab7;color:#fff;opacity:.5;-webkit-transition:none;transition:0s}.theme-red .bs-datepicker-body table td span.selected,.theme-red .bs-datepicker-body table td span[class*=select-]:after,.theme-red .bs-datepicker-body table td.selected span,.theme-red .bs-datepicker-body table td[class*=select-] span:after,.theme-red .bs-datepicker-head{background-color:#d9534f}.theme-red .bs-datepicker-body table td.week span{color:#d9534f}.theme-red .bs-datepicker-body table td.active-week span:hover{cursor:pointer;background-color:#d9534f;color:#fff;opacity:.5;-webkit-transition:none;transition:0s}.theme-orange .bs-datepicker-body table td span.selected,.theme-orange .bs-datepicker-body table td span[class*=select-]:after,.theme-orange .bs-datepicker-body table td.selected span,.theme-orange .bs-datepicker-body table td[class*=select-] span:after,.theme-orange .bs-datepicker-head{background-color:#f0ad4e}.theme-orange .bs-datepicker-body table td.week span{color:#f0ad4e}.theme-orange .bs-datepicker-body table td.active-week span:hover{cursor:pointer;background-color:#f0ad4e;color:#fff;opacity:.5;-webkit-transition:none;transition:0s}/*! +Fork Awesome 1.1.6 +License - https://forkaweso.me/Fork-Awesome/license + +Copyright 2018 Dave Gandy & Fork Awesome + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */@font-face{font-family:ForkAwesome;src:url(forkawesome-webfont.35e77a38ca9d85c4e897.eot?v=1.0.11);src:url(forkawesome-webfont.35e77a38ca9d85c4e897.eot?#iefix&v=1.0.11) format("embedded-opentype"),url(forkawesome-webfont.3a9e014c2469ffa65a0e.woff2?v=1.0.11) format("woff2"),url(forkawesome-webfont.44bbdbbfb5a10ba2d1ce.woff?v=1.0.11) format("woff"),url(forkawesome-webfont.fc46f3dae03b2b2e1cee.ttf?v=1.0.11) format("truetype"),url(forkawesome-webfont.78dcc9c4999659b8026a.svg?v=1.0.11#forkawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.form-group>.col-sm-12>.control-label>span.required,.form-group>.control-label>span.required{display:inline-block;font:14px/1 ForkAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.form-group>.col-sm-12>.control-label>span.fa-pull-left.required,.form-group>.control-label>span.fa-pull-left.required{margin-right:.3em}.fa.fa-pull-right,.form-group>.col-sm-12>.control-label>span.fa-pull-right.required,.form-group>.control-label>span.fa-pull-right.required{margin-left:.3em}.fa.pull-left,.form-group>.col-sm-12>.control-label>span.pull-left.required,.form-group>.control-label>span.pull-left.required{margin-right:.3em}.fa.pull-right,.form-group>.col-sm-12>.control-label>span.pull-right.required,.form-group>.control-label>span.pull-right.required{margin-left:.3em}.fa-spin{-webkit-animation:2s linear infinite fa-spin;animation:2s linear infinite fa-spin}.fa-pulse{-webkit-animation:1s steps(8) infinite fa-spin;animation:1s steps(8) infinite fa-spin}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before,.form-group>.col-sm-12>.control-label>span.required:before,.form-group>.control-label>span.required:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-globe-e:before{content:"\f304"}.fa-globe-w:before{content:"\f305"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-community:before,.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-medium-square:before{content:"\f2f8"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\f2a3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-address-card:before,.fa-vcard:before{content:"\f2bb"}.fa-address-card-o:before,.fa-vcard-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.fa-mastodon:before{content:"\f2e1"}.fa-mastodon-alt:before{content:"\f2e2"}.fa-fork-awesome:before,.fa-fork-circle:before{content:"\f2e3"}.fa-peertube:before{content:"\f2e4"}.fa-diaspora:before{content:"\f2e5"}.fa-friendica:before{content:"\f2e6"}.fa-gnu-social:before{content:"\f2e7"}.fa-liberapay-square:before{content:"\f2e8"}.fa-liberapay:before{content:"\f2e9"}.fa-scuttlebutt:before,.fa-ssb:before{content:"\f2ea"}.fa-hubzilla:before{content:"\f2eb"}.fa-social-home:before{content:"\f2ec"}.fa-artstation:before{content:"\f2ed"}.fa-discord:before{content:"\f2ee"}.fa-discord-alt:before{content:"\f2ef"}.fa-patreon:before{content:"\f2f0"}.fa-snowdrift:before{content:"\f2f1"}.fa-activitypub:before{content:"\f2f2"}.fa-ethereum:before{content:"\f2f3"}.fa-keybase:before{content:"\f2f4"}.fa-shaarli:before{content:"\f2f5"}.fa-shaarli-o:before{content:"\f2f6"}.fa-cut-key:before,.fa-key-modern:before{content:"\f2f7"}.fa-xmpp:before{content:"\f2f9"}.fa-archive-org:before{content:"\f2fc"}.fa-freedombox:before{content:"\f2fd"}.fa-facebook-messenger:before{content:"\f2fe"}.fa-debian:before{content:"\f2ff"}.fa-mastodon-square:before{content:"\f300"}.fa-tipeee:before{content:"\f301"}.fa-react:before{content:"\f302"}.fa-dogmazic:before{content:"\f303"}.fa-zotero:before{content:"\f309"}.fa-nodejs:before{content:"\f308"}.fa-nextcloud:before{content:"\f306"}.fa-nextcloud-square:before{content:"\f307"}.fa-hackaday:before{content:"\f30a"}.fa-laravel:before{content:"\f30b"}.fa-signalapp:before{content:"\f30c"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.info-card-popover-cluster-status{max-width:23vw;max-height:20vh}.info-card-popover-cluster-status .popover-body{max-width:100%;max-height:19vh;font-size:12px}@media (max-width:calc(1200px - 1px)){.info-card-popover-cluster-status{max-width:31vw}}@media (max-width:calc(992px - 1px)){.info-card-popover-cluster-status{max-width:46vw}}@media (max-width:calc(768px - 1px)){.info-card-popover-cluster-status{max-width:83vw}}.info-card-content-clickable{cursor:pointer;padding:7px;border:1px solid #efefef;border-radius:3px}.info-card-content-clickable:hover{border-color:#d1d1d1;background-color:#f3f3f3}html{-webkit-tap-highlight-color:transparent;background-color:#fff}body,html{width:100%;height:100%;font-size:12px}a{text-decoration:none;color:#2b99a8;cursor:pointer}a:focus,a:hover{text-decoration:underline;color:#474544}h1{letter-spacing:-1px;font-size:2em}h2{letter-spacing:-1px;font-size:1.833em}h3{display:block;font-size:1.583em;font-weight:400}h4{font-size:1.5em;line-height:normal}option{font-weight:400;font-style:normal}.checkbox input[type=checkbox]:checked+label:after{font-family:ForkAwesome}.full-height{height:100%}.vertical-align{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center}.loading{position:absolute;top:50%;left:50%}.margin-right-md{margin-right:15px}.no-border{border:0;box-shadow:0 0 0!important}.italic{font-style:italic}.bold{font-weight:700}.text-right{text-align:right}.text-monospace{font-family:monospace}.btn-primary{color:#eee;background-color:#ef5c55;border-color:#ef5c55;border-radius:1.875rem}.btn-primary.active,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open .dropdown-toggle.btn-primary{color:#eee;background-color:#f38984;border-color:#f38984}.btn-primary.active,.btn-primary:active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active:focus,.btn-primary:active:hover,.open .dropdown-toggle.btn-primary:focus,.open .dropdown-toggle.btn-primary:hover{background-color:#f38984;border-color:#f38984}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#ef5c55;border-color:#ef5c55}.btn-primary .badge{color:#2b99a8;background-color:#eee}.btn-primary .caret{color:#eee}.btn-default{border-radius:1.875rem}.form-group .btn-default{border-radius:4px}.btn-group>.btn>i.fa,button.btn.btn-label>i.fa{padding-right:5px}.dropdown-menu{min-width:50px;z-index:999999}.dropdown-menu>li>a{color:#474544;cursor:pointer}.dropdown-menu>li>a>i.fa{padding-right:5px}.dropdown-menu>.active>a{color:#eee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#21747f}.dataTables_wrapper .dropdown-menu>li.divider{cursor:auto}.container,.container-fluid{padding-left:30px;padding-right:30px}.row{margin-left:-30px;margin-right:-30px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{padding-left:30px;padding-right:30px}.caret{color:#fff}.progress-bar{background-image:none!important}.progress-bar-info{background-color:#2b99a8}.progress-bar-freespace{background-color:#d1d1d1}.oaprogress{position:relative;margin-bottom:0}.oaprogress div.progress-bar{position:static}.oaprogress span{position:absolute;display:block;width:100%;color:#000;font-weight:400}tags-input .tags{border-radius:4px;border:1px solid #d1d1d1;box-shadow:inset 0 1px 1px rgba(0,0,0,.09)}.panel .accordion-title,uib-accordion .panel-title{font-size:14px!important}.panel-body h2:first-child{margin-top:0}.disabled{pointer-events:none}.clickable{cursor:pointer}.has-error .has-error-btn,.has-error .has-error-btn:disabled:hover{background-color:#f2dede;border-color:#a94442}.noscript{padding-top:5em}.noscript p{color:#777}.form-group>.col-sm-12>.control-label>span.required,.form-group>.control-label>span.required,.required{color:#a94442}.form-group>.col-sm-12.form-group>.control-label>span.required,.form-group>.col-sm-12>.control-label>span.required,.form-group>.control-label>span.required{font-size:6px;padding-left:4px;vertical-align:text-top}.form-control{display:table-cell}.form-control:focus{border-color:rgba(43,153,168,.8);outline:0;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px 2px rgba(43,153,168,.5)}.modal-footer button.btn:not(:first-child),.panel-footer button.btn:not(:first-child){margin-left:5px}.margin-right-sm{margin-right:10px}.nav-tabs{margin-bottom:15px}.ceph-icon{background:url(Ceph_Logo_Stacked_RGB_120411_fa_228x228.1ed169ccc35367a2dab2.png)}.prometheus-icon{background:url(prometheus_logo.074db273ef932a67d91b.svg)}.custom-icon{padding:10px;margin-right:1em;background-clip:padding-box;background-size:contain;background-repeat:no-repeat}.toast-message .custom-icon{filter:brightness(0) invert(1);-webkit-filter:brightness(0) invert(1);-moz-filter:brightness(0) invert(1);-o-filter:brightness(0) invert(1);-ms-filter:brightness(0) invert(1)}.block-ui-wrapper{background:rgba(0,0,0,.7)!important}h3.page-header{margin-left:1em;margin-top:1em;border-color:#f0f0f0}.tooltip-wide .tooltip-inner{width:400px}.tooltip-inner{background-color:#fff;border:1px solid grey;color:#333;font-size:1.1em}.toast-message>ul{padding-left:1em;margin:0}.node-menu{position:relative;width:150px}.node-menu .node-menu-content{width:100%;padding:5px;position:absolute;border:1px solid #bdbdbd;border-radius:5%;box-shadow:0 0 5px #bdbdbd;background-color:#eee;color:#212121;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;z-index:999}.node-menu .node-menu-content li.node-menu-item{list-style:none;padding:3px}.node-menu .node-menu-content .node-menu-item:hover{border-radius:5%;opacity:unset;cursor:pointer;background-color:#bdbdbd;-webkit-transition:background-color .2s ease-out;transition:background-color .2s ease-out}.node-menu .node-menu-content .node-menu-item .node-menu-item-icon{display:inline-block;width:16px}.node-menu .node-menu-content .node-menu-item .node-menu-item-icon.new-tag:before{content:'\25CF'}.node-menu .node-menu-content .node-menu-item .node-menu-item-icon.new-folder:before{content:'\25B6'}.node-menu .node-menu-content .node-menu-item .node-menu-item-icon.rename:before{content:'\270E'}.node-menu .node-menu-content .node-menu-item .node-menu-item-icon.remove:before{content:'\2716'}.node-menu .node-menu-content .node-menu-item .node-menu-item-value{margin-left:5px}tree-internal ul{padding:3px 0 3px 25px}tree-internal li{padding:0;margin:0;list-style:none}tree-internal .over-drop-target{border:4px solid #757575;-webkit-transition:padding .2s ease-out;transition:padding .2s ease-out;padding:5px;border-radius:5%}tree-internal .tree{box-sizing:border-box;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}tree-internal .tree li{list-style:none;cursor:default}tree-internal .tree li div{display:inline-block;box-sizing:border-box}tree-internal .tree .node-value{display:inline-block;color:#212121}tree-internal .tree .node-value:after{display:block;width:0;height:2px;background-color:#212121;content:'';-webkit-transition:width .3s;transition:width .3s}tree-internal .tree .node-value:hover:after{width:100%}tree-internal .tree .node-left-menu{display:inline-block;height:100%;width:auto}tree-internal .tree .node-left-menu span:before{content:'\2026';color:#757575}tree-internal .tree .node-selected:after{width:100%}tree-internal .tree .folding{width:25px;display:inline-block;line-height:1px;padding:0 5px;font-weight:700}tree-internal .tree .folding.node-collapsed{cursor:pointer}tree-internal .tree .folding.node-collapsed:before{content:'\25B6';color:#757575}tree-internal .tree .folding.node-expanded{cursor:pointer}tree-internal .tree .folding.node-expanded:before{content:'\25BC';color:#757575}tree-internal .tree .folding.node-empty{color:#212121;text-align:center;font-size:.89em}tree-internal .tree .folding.node-empty:before{content:'\25B6';color:#757575}tree-internal .tree .folding.node-leaf{color:#212121;text-align:center;font-size:.89em}tree-internal .tree .folding.node-leaf:before{content:'\25CF';color:#757575}tree-internal ul.rootless{padding:0}tree-internal div.rootless{display:none!important}tree-internal .loading-children:after{content:' loading ...';color:#6a1b9a;font-style:italic;font-size:.9em;-webkit-animation-name:loading-children;animation-name:loading-children;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes loading-children{0%{color:#f3e5f5}12.5%{color:#e1bee7}25%{color:#ce93d8}37.5%{color:#ba68c8}50%{color:#ab47bc}62.5%{color:#9c27b0}75%{color:#8e24aa}87.5%{color:#7b1fa2}100%{color:#6a1b9a}}@keyframes loading-children{0%{color:#f3e5f5}12.5%{color:#e1bee7}25%{color:#ce93d8}37.5%{color:#ba68c8}50%{color:#ab47bc}62.5%{color:#9c27b0}75%{color:#8e24aa}87.5%{color:#7b1fa2}100%{color:#6a1b9a}} \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/dist/en-US/swagger-ui-bundle.js b/src/pybind/mgr/dashboard/frontend/dist/en-US/swagger-ui-bundle.js new file mode 100644 index 00000000..1e3fcbb3 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/dist/en-US/swagger-ui-bundle.js @@ -0,0 +1,134 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(function(){try{return require("esprima")}catch(e){}}()):"function"==typeof define&&define.amd?define(["esprima"],t):"object"==typeof exports?exports.SwaggerUIBundle=t(function(){try{return require("esprima")}catch(e){}}()):e.SwaggerUIBundle=t(e.esprima)}(window,function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=481)}([function(e,t,n){"use strict";e.exports=n(100)},function(e,t,n){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return a(e)?e:J(e)}function r(e){return s(e)?e:Y(e)}function o(e){return u(e)?e:K(e)}function i(e){return a(e)&&!c(e)?e:G(e)}function a(e){return!(!e||!e[p])}function s(e){return!(!e||!e[f])}function u(e){return!(!e||!e[h])}function c(e){return s(e)||u(e)}function l(e){return!(!e||!e[d])}t(r,n),t(o,n),t(i,n),n.isIterable=a,n.isKeyed=s,n.isIndexed=u,n.isAssociative=c,n.isOrdered=l,n.Keyed=r,n.Indexed=o,n.Set=i;var p="@@__IMMUTABLE_ITERABLE__@@",f="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m=5,v=1<>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?C(e)+t:t}function O(){return!0}function A(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return P(e,t,0)}function j(e,t){return P(e,t,t)}function P(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var I=0,M=1,N=2,R="function"==typeof Symbol&&Symbol.iterator,D="@@iterator",L=R||D;function U(e){this.next=e}function q(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function F(){return{value:void 0,done:!0}}function z(e){return!!H(e)}function B(e){return e&&"function"==typeof e.next}function V(e){var t=H(e);return t&&t.call(e)}function H(e){var t=e&&(R&&e[R]||e[D]);if("function"==typeof t)return t}function W(e){return e&&"number"==typeof e.length}function J(e){return null==e?ie():a(e)?e.toSeq():function(e){var t=ue(e)||"object"==typeof e&&new te(e);if(!t)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+e);return t}(e)}function Y(e){return null==e?ie().toKeyedSeq():a(e)?s(e)?e.toSeq():e.fromEntrySeq():ae(e)}function K(e){return null==e?ie():a(e)?s(e)?e.entrySeq():e.toIndexedSeq():se(e)}function G(e){return(null==e?ie():a(e)?s(e)?e.entrySeq():e:se(e)).toSetSeq()}U.prototype.toString=function(){return"[Iterator]"},U.KEYS=I,U.VALUES=M,U.ENTRIES=N,U.prototype.inspect=U.prototype.toSource=function(){return this.toString()},U.prototype[L]=function(){return this},t(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(e,t){return ce(this,e,t,!0)},J.prototype.__iterator=function(e,t){return le(this,e,t,!0)},t(Y,J),Y.prototype.toKeyedSeq=function(){return this},t(K,J),K.of=function(){return K(arguments)},K.prototype.toIndexedSeq=function(){return this},K.prototype.toString=function(){return this.__toString("Seq [","]")},K.prototype.__iterate=function(e,t){return ce(this,e,t,!1)},K.prototype.__iterator=function(e,t){return le(this,e,t,!1)},t(G,J),G.of=function(){return G(arguments)},G.prototype.toSetSeq=function(){return this},J.isSeq=oe,J.Keyed=Y,J.Set=G,J.Indexed=K;var $,Z,X,Q="@@__IMMUTABLE_SEQ__@@";function ee(e){this._array=e,this.size=e.length}function te(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function ne(e){this._iterable=e,this.size=e.length||e.size}function re(e){this._iterator=e,this._iteratorCache=[]}function oe(e){return!(!e||!e[Q])}function ie(){return $||($=new ee([]))}function ae(e){var t=Array.isArray(e)?new ee(e).fromEntrySeq():B(e)?new re(e).fromEntrySeq():z(e)?new ne(e).fromEntrySeq():"object"==typeof e?new te(e):void 0;if(!t)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e);return t}function se(e){var t=ue(e);if(!t)throw new TypeError("Expected Array or iterable object of values: "+e);return t}function ue(e){return W(e)?new ee(e):B(e)?new re(e):z(e)?new ne(e):void 0}function ce(e,t,n,r){var o=e._cache;if(o){for(var i=o.length-1,a=0;a<=i;a++){var s=o[n?i-a:a];if(!1===t(s[1],r?s[0]:a,e))return a+1}return a}return e.__iterateUncached(t,n)}function le(e,t,n,r){var o=e._cache;if(o){var i=o.length-1,a=0;return new U(function(){var e=o[n?i-a:a];return a++>i?{value:void 0,done:!0}:q(t,r?e[0]:a-1,e[1])})}return e.__iteratorUncached(t,n)}function pe(e,t){return t?function e(t,n,r,o){return Array.isArray(n)?t.call(o,r,K(n).map(function(r,o){return e(t,r,o,n)})):he(n)?t.call(o,r,Y(n).map(function(r,o){return e(t,r,o,n)})):n}(t,e,"",{"":e}):fe(e)}function fe(e){return Array.isArray(e)?K(e).map(fe).toList():he(e)?Y(e).map(fe).toMap():e}function he(e){return e&&(e.constructor===Object||void 0===e.constructor)}function de(e,t){if(e===t||e!=e&&t!=t)return!0;if(!e||!t)return!1;if("function"==typeof e.valueOf&&"function"==typeof t.valueOf){if(e=e.valueOf(),t=t.valueOf(),e===t||e!=e&&t!=t)return!0;if(!e||!t)return!1}return!("function"!=typeof e.equals||"function"!=typeof t.equals||!e.equals(t))}function me(e,t){if(e===t)return!0;if(!a(t)||void 0!==e.size&&void 0!==t.size&&e.size!==t.size||void 0!==e.__hash&&void 0!==t.__hash&&e.__hash!==t.__hash||s(e)!==s(t)||u(e)!==u(t)||l(e)!==l(t))return!1;if(0===e.size&&0===t.size)return!0;var n=!c(e);if(l(e)){var r=e.entries();return t.every(function(e,t){var o=r.next().value;return o&&de(o[1],e)&&(n||de(o[0],t))})&&r.next().done}var o=!1;if(void 0===e.size)if(void 0===t.size)"function"==typeof e.cacheResult&&e.cacheResult();else{o=!0;var i=e;e=t,t=i}var p=!0,f=t.__iterate(function(t,r){if(n?!e.has(t):o?!de(t,e.get(r,y)):!de(e.get(r,y),t))return p=!1,!1});return p&&e.size===f}function ve(e,t){if(!(this instanceof ve))return new ve(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(Z)return Z;Z=this}}function ge(e,t){if(!e)throw new Error(t)}function ye(e,t,n){if(!(this instanceof ye))return new ye(e,t,n);if(ge(0!==n,"Cannot step a Range by 0"),e=e||0,void 0===t&&(t=1/0),n=void 0===n?1:Math.abs(n),tr?{value:void 0,done:!0}:q(e,o,n[t?r-o++:o++])})},t(te,Y),te.prototype.get=function(e,t){return void 0===t||this.has(e)?this._object[e]:t},te.prototype.has=function(e){return this._object.hasOwnProperty(e)},te.prototype.__iterate=function(e,t){for(var n=this._object,r=this._keys,o=r.length-1,i=0;i<=o;i++){var a=r[t?o-i:i];if(!1===e(n[a],a,this))return i+1}return i},te.prototype.__iterator=function(e,t){var n=this._object,r=this._keys,o=r.length-1,i=0;return new U(function(){var a=r[t?o-i:i];return i++>o?{value:void 0,done:!0}:q(e,a,n[a])})},te.prototype[d]=!0,t(ne,K),ne.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var n=this._iterable,r=V(n),o=0;if(B(r))for(var i;!(i=r.next()).done&&!1!==e(i.value,o++,this););return o},ne.prototype.__iteratorUncached=function(e,t){if(t)return this.cacheResult().__iterator(e,t);var n=this._iterable,r=V(n);if(!B(r))return new U(F);var o=0;return new U(function(){var t=r.next();return t.done?t:q(e,o++,t.value)})},t(re,K),re.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var n,r=this._iterator,o=this._iteratorCache,i=0;i=r.length){var t=n.next();if(t.done)return t;r[o]=t.value}return q(e,o,r[o++])})},t(ve,K),ve.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},ve.prototype.get=function(e,t){return this.has(e)?this._value:t},ve.prototype.includes=function(e){return de(this._value,e)},ve.prototype.slice=function(e,t){var n=this.size;return A(e,t,n)?this:new ve(this._value,j(t,n)-T(e,n))},ve.prototype.reverse=function(){return this},ve.prototype.indexOf=function(e){return de(this._value,e)?0:-1},ve.prototype.lastIndexOf=function(e){return de(this._value,e)?this.size:-1},ve.prototype.__iterate=function(e,t){for(var n=0;n=0&&t=0&&nn?{value:void 0,done:!0}:q(e,i++,a)})},ye.prototype.equals=function(e){return e instanceof ye?this._start===e._start&&this._end===e._end&&this._step===e._step:me(this,e)},t(be,n),t(_e,be),t(we,be),t(xe,be),be.Keyed=_e,be.Indexed=we,be.Set=xe;var Ee="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(e,t){var n=65535&(e|=0),r=65535&(t|=0);return n*r+((e>>>16)*r+n*(t>>>16)<<16>>>0)|0};function Se(e){return e>>>1&1073741824|3221225471&e}function Ce(e){if(!1===e||null==e)return 0;if("function"==typeof e.valueOf&&(!1===(e=e.valueOf())||null==e))return 0;if(!0===e)return 1;var t=typeof e;if("number"===t){if(e!=e||e===1/0)return 0;var n=0|e;for(n!==e&&(n^=4294967295*e);e>4294967295;)n^=e/=4294967295;return Se(n)}if("string"===t)return e.length>Me?function(e){var t=De[e];return void 0===t&&(t=ke(e),Re===Ne&&(Re=0,De={}),Re++,De[e]=t),t}(e):ke(e);if("function"==typeof e.hashCode)return e.hashCode();if("object"===t)return function(e){var t;if(je&&void 0!==(t=Oe.get(e)))return t;if(void 0!==(t=e[Ie]))return t;if(!Te){if(void 0!==(t=e.propertyIsEnumerable&&e.propertyIsEnumerable[Ie]))return t;if(void 0!==(t=function(e){if(e&&e.nodeType>0)switch(e.nodeType){case 1:return e.uniqueID;case 9:return e.documentElement&&e.documentElement.uniqueID}}(e)))return t}if(t=++Pe,1073741824&Pe&&(Pe=0),je)Oe.set(e,t);else{if(void 0!==Ae&&!1===Ae(e))throw new Error("Non-extensible objects are not allowed as keys.");if(Te)Object.defineProperty(e,Ie,{enumerable:!1,configurable:!1,writable:!1,value:t});else if(void 0!==e.propertyIsEnumerable&&e.propertyIsEnumerable===e.constructor.prototype.propertyIsEnumerable)e.propertyIsEnumerable=function(){return this.constructor.prototype.propertyIsEnumerable.apply(this,arguments)},e.propertyIsEnumerable[Ie]=t;else{if(void 0===e.nodeType)throw new Error("Unable to set a non-enumerable property on object.");e[Ie]=t}}return t}(e);if("function"==typeof e.toString)return ke(e.toString());throw new Error("Value type "+t+" cannot be hashed.")}function ke(e){for(var t=0,n=0;n=t.length)throw new Error("Missing value for key: "+t[n]);e.set(t[n],t[n+1])}})},Ue.prototype.toString=function(){return this.__toString("Map {","}")},Ue.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},Ue.prototype.set=function(e,t){return Qe(this,e,t)},Ue.prototype.setIn=function(e,t){return this.updateIn(e,y,function(){return t})},Ue.prototype.remove=function(e){return Qe(this,e,y)},Ue.prototype.deleteIn=function(e){return this.updateIn(e,function(){return y})},Ue.prototype.update=function(e,t,n){return 1===arguments.length?e(this):this.updateIn([e],t,n)},Ue.prototype.updateIn=function(e,t,n){n||(n=t,t=void 0);var r=function e(t,n,r,o){var i=t===y,a=n.next();if(a.done){var s=i?r:t,u=o(s);return u===s?t:u}ge(i||t&&t.set,"invalid keyPath");var c=a.value,l=i?y:t.get(c,y),p=e(l,n,r,o);return p===l?t:p===y?t.remove(c):(i?Xe():t).set(c,p)}(this,rn(e),t,n);return r===y?void 0:r},Ue.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):Xe()},Ue.prototype.merge=function(){return rt(this,void 0,arguments)},Ue.prototype.mergeWith=function(t){var n=e.call(arguments,1);return rt(this,t,n)},Ue.prototype.mergeIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,Xe(),function(e){return"function"==typeof e.merge?e.merge.apply(e,n):n[n.length-1]})},Ue.prototype.mergeDeep=function(){return rt(this,ot,arguments)},Ue.prototype.mergeDeepWith=function(t){var n=e.call(arguments,1);return rt(this,it(t),n)},Ue.prototype.mergeDeepIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,Xe(),function(e){return"function"==typeof e.mergeDeep?e.mergeDeep.apply(e,n):n[n.length-1]})},Ue.prototype.sort=function(e){return Tt(Jt(this,e))},Ue.prototype.sortBy=function(e,t){return Tt(Jt(this,t,e))},Ue.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},Ue.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new E)},Ue.prototype.asImmutable=function(){return this.__ensureOwner()},Ue.prototype.wasAltered=function(){return this.__altered},Ue.prototype.__iterator=function(e,t){return new Ke(this,e,t)},Ue.prototype.__iterate=function(e,t){var n=this,r=0;return this._root&&this._root.iterate(function(t){return r++,e(t[1],t[0],n)},t),r},Ue.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?Ze(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Ue.isMap=qe;var Fe,ze="@@__IMMUTABLE_MAP__@@",Be=Ue.prototype;function Ve(e,t){this.ownerID=e,this.entries=t}function He(e,t,n){this.ownerID=e,this.bitmap=t,this.nodes=n}function We(e,t,n){this.ownerID=e,this.count=t,this.nodes=n}function Je(e,t,n){this.ownerID=e,this.keyHash=t,this.entries=n}function Ye(e,t,n){this.ownerID=e,this.keyHash=t,this.entry=n}function Ke(e,t,n){this._type=t,this._reverse=n,this._stack=e._root&&$e(e._root)}function Ge(e,t){return q(e,t[0],t[1])}function $e(e,t){return{node:e,index:0,__prev:t}}function Ze(e,t,n,r){var o=Object.create(Be);return o.size=e,o._root=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function Xe(){return Fe||(Fe=Ze(0))}function Qe(e,t,n){var r,o;if(e._root){var i=w(b),a=w(_);if(r=et(e._root,e.__ownerID,0,void 0,t,n,i,a),!a.value)return e;o=e.size+(i.value?n===y?-1:1:0)}else{if(n===y)return e;o=1,r=new Ve(e.__ownerID,[[t,n]])}return e.__ownerID?(e.size=o,e._root=r,e.__hash=void 0,e.__altered=!0,e):r?Ze(o,r):Xe()}function et(e,t,n,r,o,i,a,s){return e?e.update(t,n,r,o,i,a,s):i===y?e:(x(s),x(a),new Ye(t,r,[o,i]))}function tt(e){return e.constructor===Ye||e.constructor===Je}function nt(e,t,n,r,o){if(e.keyHash===r)return new Je(t,r,[e.entry,o]);var i,a=(0===n?e.keyHash:e.keyHash>>>n)&g,s=(0===n?r:r>>>n)&g,u=a===s?[nt(e,t,n+m,r,o)]:(i=new Ye(t,r,o),a>1&1431655765))+(e>>2&858993459))+(e>>4)&252645135,e+=e>>8,127&(e+=e>>16)}function ut(e,t,n,r){var o=r?e:S(e);return o[t]=n,o}Be[ze]=!0,Be.delete=Be.remove,Be.removeIn=Be.deleteIn,Ve.prototype.get=function(e,t,n,r){for(var o=this.entries,i=0,a=o.length;i=ct)return function(e,t,n,r){e||(e=new E);for(var o=new Ye(e,Ce(n),[n,r]),i=0;i>>e)&g),i=this.bitmap;return 0==(i&o)?r:this.nodes[st(i&o-1)].get(e+m,t,n,r)},He.prototype.update=function(e,t,n,r,o,i,a){void 0===n&&(n=Ce(r));var s=(0===t?n:n>>>t)&g,u=1<=lt)return function(e,t,n,r,o){for(var i=0,a=new Array(v),s=0;0!==n;s++,n>>>=1)a[s]=1&n?t[i++]:void 0;return a[r]=o,new We(e,i+1,a)}(e,f,c,s,d);if(l&&!d&&2===f.length&&tt(f[1^p]))return f[1^p];if(l&&d&&1===f.length&&tt(d))return d;var b=e&&e===this.ownerID,_=l?d?c:c^u:c|u,w=l?d?ut(f,p,d,b):function(e,t,n){var r=e.length-1;if(n&&t===r)return e.pop(),e;for(var o=new Array(r),i=0,a=0;a>>e)&g,i=this.nodes[o];return i?i.get(e+m,t,n,r):r},We.prototype.update=function(e,t,n,r,o,i,a){void 0===n&&(n=Ce(r));var s=(0===t?n:n>>>t)&g,u=o===y,c=this.nodes,l=c[s];if(u&&!l)return this;var p=et(l,e,t+m,n,r,o,i,a);if(p===l)return this;var f=this.count;if(l){if(!p&&--f0&&r=0&&e=e.size||t<0)return e.withMutations(function(e){t<0?kt(e,t).set(0,n):kt(e,0,t+1).set(t,n)});t+=e._origin;var r=e._tail,o=e._root,i=w(_);return t>=At(e._capacity)?r=Et(r,e.__ownerID,0,t,n,i):o=Et(o,e.__ownerID,e._level,t,n,i),i.value?e.__ownerID?(e._root=o,e._tail=r,e.__hash=void 0,e.__altered=!0,e):wt(e._origin,e._capacity,e._level,o,r):e}(this,e,t)},ft.prototype.remove=function(e){return this.has(e)?0===e?this.shift():e===this.size-1?this.pop():this.splice(e,1):this},ft.prototype.insert=function(e,t){return this.splice(e,0,t)},ft.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=m,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):xt()},ft.prototype.push=function(){var e=arguments,t=this.size;return this.withMutations(function(n){kt(n,0,t+e.length);for(var r=0;r>>t&g;if(r>=this.array.length)return new vt([],e);var o,i=0===r;if(t>0){var a=this.array[r];if((o=a&&a.removeBefore(e,t-m,n))===a&&i)return this}if(i&&!o)return this;var s=St(this,e);if(!i)for(var u=0;u>>t&g;if(o>=this.array.length)return this;if(t>0){var i=this.array[o];if((r=i&&i.removeAfter(e,t-m,n))===i&&o===this.array.length-1)return this}var a=St(this,e);return a.array.splice(o+1),r&&(a.array[o]=r),a};var gt,yt,bt={};function _t(e,t){var n=e._origin,r=e._capacity,o=At(r),i=e._tail;return a(e._root,e._level,0);function a(e,s,u){return 0===s?function(e,a){var s=a===o?i&&i.array:e&&e.array,u=a>n?0:n-a,c=r-a;return c>v&&(c=v),function(){if(u===c)return bt;var e=t?--c:u++;return s&&s[e]}}(e,u):function(e,o,i){var s,u=e&&e.array,c=i>n?0:n-i>>o,l=1+(r-i>>o);return l>v&&(l=v),function(){for(;;){if(s){var e=s();if(e!==bt)return e;s=null}if(c===l)return bt;var n=t?--l:c++;s=a(u&&u[n],o-m,i+(n<>>n&g,u=e&&s0){var c=e&&e.array[s],l=Et(c,t,n-m,r,o,i);return l===c?e:((a=St(e,t)).array[s]=l,a)}return u&&e.array[s]===o?e:(x(i),a=St(e,t),void 0===o&&s===a.array.length-1?a.array.pop():a.array[s]=o,a)}function St(e,t){return t&&e&&t===e.ownerID?e:new vt(e?e.array.slice():[],t)}function Ct(e,t){if(t>=At(e._capacity))return e._tail;if(t<1<0;)n=n.array[t>>>r&g],r-=m;return n}}function kt(e,t,n){void 0!==t&&(t|=0),void 0!==n&&(n|=0);var r=e.__ownerID||new E,o=e._origin,i=e._capacity,a=o+t,s=void 0===n?i:n<0?i+n:o+n;if(a===o&&s===i)return e;if(a>=s)return e.clear();for(var u=e._level,c=e._root,l=0;a+l<0;)c=new vt(c&&c.array.length?[void 0,c]:[],r),l+=1<<(u+=m);l&&(a+=l,o+=l,s+=l,i+=l);for(var p=At(i),f=At(s);f>=1<p?new vt([],r):h;if(h&&f>p&&am;y-=m){var b=p>>>y&g;v=v.array[b]=St(v.array[b],r)}v.array[p>>>m&g]=h}if(s=f)a-=f,s-=f,u=m,c=null,d=d&&d.removeBefore(r,0,a);else if(a>o||f>>u&g;if(_!==f>>>u&g)break;_&&(l+=(1<o&&(c=c.removeBefore(r,u,a-l)),c&&fi&&(i=c.size),a(u)||(c=c.map(function(e){return pe(e)})),r.push(c)}return i>e.size&&(e=e.setSize(i)),at(e,t,r)}function At(e){return e>>m<=v&&a.size>=2*i.size?(o=a.filter(function(e,t){return void 0!==e&&s!==t}),r=o.toKeyedSeq().map(function(e){return e[0]}).flip().toMap(),e.__ownerID&&(r.__ownerID=o.__ownerID=e.__ownerID)):(r=i.remove(t),o=s===a.size-1?a.pop():a.set(s,void 0))}else if(u){if(n===a.get(s)[1])return e;r=i,o=a.set(s,[t,n])}else r=i.set(t,a.size),o=a.set(a.size,[t,n]);return e.__ownerID?(e.size=r.size,e._map=r,e._list=o,e.__hash=void 0,e):Pt(r,o)}function Nt(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function Rt(e){this._iter=e,this.size=e.size}function Dt(e){this._iter=e,this.size=e.size}function Lt(e){this._iter=e,this.size=e.size}function Ut(e){var t=en(e);return t._iter=e,t.size=e.size,t.flip=function(){return e},t.reverse=function(){var t=e.reverse.apply(this);return t.flip=function(){return e.reverse()},t},t.has=function(t){return e.includes(t)},t.includes=function(t){return e.has(t)},t.cacheResult=tn,t.__iterateUncached=function(t,n){var r=this;return e.__iterate(function(e,n){return!1!==t(n,e,r)},n)},t.__iteratorUncached=function(t,n){if(t===N){var r=e.__iterator(t,n);return new U(function(){var e=r.next();if(!e.done){var t=e.value[0];e.value[0]=e.value[1],e.value[1]=t}return e})}return e.__iterator(t===M?I:M,n)},t}function qt(e,t,n){var r=en(e);return r.size=e.size,r.has=function(t){return e.has(t)},r.get=function(r,o){var i=e.get(r,y);return i===y?o:t.call(n,i,r,e)},r.__iterateUncached=function(r,o){var i=this;return e.__iterate(function(e,o,a){return!1!==r(t.call(n,e,o,a),o,i)},o)},r.__iteratorUncached=function(r,o){var i=e.__iterator(N,o);return new U(function(){var o=i.next();if(o.done)return o;var a=o.value,s=a[0];return q(r,s,t.call(n,a[1],s,e),o)})},r}function Ft(e,t){var n=en(e);return n._iter=e,n.size=e.size,n.reverse=function(){return e},e.flip&&(n.flip=function(){var t=Ut(e);return t.reverse=function(){return e.flip()},t}),n.get=function(n,r){return e.get(t?n:-1-n,r)},n.has=function(n){return e.has(t?n:-1-n)},n.includes=function(t){return e.includes(t)},n.cacheResult=tn,n.__iterate=function(t,n){var r=this;return e.__iterate(function(e,n){return t(e,n,r)},!n)},n.__iterator=function(t,n){return e.__iterator(t,!n)},n}function zt(e,t,n,r){var o=en(e);return r&&(o.has=function(r){var o=e.get(r,y);return o!==y&&!!t.call(n,o,r,e)},o.get=function(r,o){var i=e.get(r,y);return i!==y&&t.call(n,i,r,e)?i:o}),o.__iterateUncached=function(o,i){var a=this,s=0;return e.__iterate(function(e,i,u){if(t.call(n,e,i,u))return s++,o(e,r?i:s-1,a)},i),s},o.__iteratorUncached=function(o,i){var a=e.__iterator(N,i),s=0;return new U(function(){for(;;){var i=a.next();if(i.done)return i;var u=i.value,c=u[0],l=u[1];if(t.call(n,l,c,e))return q(o,r?c:s++,l,i)}})},o}function Bt(e,t,n,r){var o=e.size;if(void 0!==t&&(t|=0),void 0!==n&&(n===1/0?n=o:n|=0),A(t,n,o))return e;var i=T(t,o),a=j(n,o);if(i!=i||a!=a)return Bt(e.toSeq().cacheResult(),t,n,r);var s,u=a-i;u==u&&(s=u<0?0:u);var c=en(e);return c.size=0===s?s:e.size&&s||void 0,!r&&oe(e)&&s>=0&&(c.get=function(t,n){return(t=k(this,t))>=0&&ts)return{value:void 0,done:!0};var e=o.next();return r||t===M?e:q(t,u-1,t===I?void 0:e.value[1],e)})},c}function Vt(e,t,n,r){var o=en(e);return o.__iterateUncached=function(o,i){var a=this;if(i)return this.cacheResult().__iterate(o,i);var s=!0,u=0;return e.__iterate(function(e,i,c){if(!s||!(s=t.call(n,e,i,c)))return u++,o(e,r?i:u-1,a)}),u},o.__iteratorUncached=function(o,i){var a=this;if(i)return this.cacheResult().__iterator(o,i);var s=e.__iterator(N,i),u=!0,c=0;return new U(function(){var e,i,l;do{if((e=s.next()).done)return r||o===M?e:q(o,c++,o===I?void 0:e.value[1],e);var p=e.value;i=p[0],l=p[1],u&&(u=t.call(n,l,i,a))}while(u);return o===N?e:q(o,i,l,e)})},o}function Ht(e,t){var n=s(e),o=[e].concat(t).map(function(e){return a(e)?n&&(e=r(e)):e=n?ae(e):se(Array.isArray(e)?e:[e]),e}).filter(function(e){return 0!==e.size});if(0===o.length)return e;if(1===o.length){var i=o[0];if(i===e||n&&s(i)||u(e)&&u(i))return i}var c=new ee(o);return n?c=c.toKeyedSeq():u(e)||(c=c.toSetSeq()),(c=c.flatten(!0)).size=o.reduce(function(e,t){if(void 0!==e){var n=t.size;if(void 0!==n)return e+n}},0),c}function Wt(e,t,n){var r=en(e);return r.__iterateUncached=function(r,o){var i=0,s=!1;return function e(u,c){var l=this;u.__iterate(function(o,u){return(!t||c0}function Gt(e,t,r){var o=en(e);return o.size=new ee(r).map(function(e){return e.size}).min(),o.__iterate=function(e,t){for(var n,r=this.__iterator(M,t),o=0;!(n=r.next()).done&&!1!==e(n.value,o++,this););return o},o.__iteratorUncached=function(e,o){var i=r.map(function(e){return e=n(e),V(o?e.reverse():e)}),a=0,s=!1;return new U(function(){var n;return s||(n=i.map(function(e){return e.next()}),s=n.some(function(e){return e.done})),s?{value:void 0,done:!0}:q(e,a++,t.apply(null,n.map(function(e){return e.value})))})},o}function $t(e,t){return oe(e)?t:e.constructor(t)}function Zt(e){if(e!==Object(e))throw new TypeError("Expected [K, V] tuple: "+e)}function Xt(e){return Le(e.size),C(e)}function Qt(e){return s(e)?r:u(e)?o:i}function en(e){return Object.create((s(e)?Y:u(e)?K:G).prototype)}function tn(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):J.prototype.cacheResult.call(this)}function nn(e,t){return e>t?1:e=0;n--)t={value:arguments[n],next:t};return this.__ownerID?(this.size=e,this._head=t,this.__hash=void 0,this.__altered=!0,this):An(e,t)},En.prototype.pushAll=function(e){if(0===(e=o(e)).size)return this;Le(e.size);var t=this.size,n=this._head;return e.reverse().forEach(function(e){t++,n={value:e,next:n}}),this.__ownerID?(this.size=t,this._head=n,this.__hash=void 0,this.__altered=!0,this):An(t,n)},En.prototype.pop=function(){return this.slice(1)},En.prototype.unshift=function(){return this.push.apply(this,arguments)},En.prototype.unshiftAll=function(e){return this.pushAll(e)},En.prototype.shift=function(){return this.pop.apply(this,arguments)},En.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Tn()},En.prototype.slice=function(e,t){if(A(e,t,this.size))return this;var n=T(e,this.size),r=j(t,this.size);if(r!==this.size)return we.prototype.slice.call(this,e,t);for(var o=this.size-n,i=this._head;n--;)i=i.next;return this.__ownerID?(this.size=o,this._head=i,this.__hash=void 0,this.__altered=!0,this):An(o,i)},En.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?An(this.size,this._head,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},En.prototype.__iterate=function(e,t){if(t)return this.reverse().__iterate(e);for(var n=0,r=this._head;r&&!1!==e(r.value,n++,this);)r=r.next;return n},En.prototype.__iterator=function(e,t){if(t)return this.reverse().__iterator(e);var n=0,r=this._head;return new U(function(){if(r){var t=r.value;return r=r.next,q(e,n++,t)}return{value:void 0,done:!0}})},En.isStack=Sn;var Cn,kn="@@__IMMUTABLE_STACK__@@",On=En.prototype;function An(e,t,n,r){var o=Object.create(On);return o.size=e,o._head=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function Tn(){return Cn||(Cn=An(0))}function jn(e,t){var n=function(n){e.prototype[n]=t[n]};return Object.keys(t).forEach(n),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(t).forEach(n),e}On[kn]=!0,On.withMutations=Be.withMutations,On.asMutable=Be.asMutable,On.asImmutable=Be.asImmutable,On.wasAltered=Be.wasAltered,n.Iterator=U,jn(n,{toArray:function(){Le(this.size);var e=new Array(this.size||0);return this.valueSeq().__iterate(function(t,n){e[n]=t}),e},toIndexedSeq:function(){return new Rt(this)},toJS:function(){return this.toSeq().map(function(e){return e&&"function"==typeof e.toJS?e.toJS():e}).__toJS()},toJSON:function(){return this.toSeq().map(function(e){return e&&"function"==typeof e.toJSON?e.toJSON():e}).__toJS()},toKeyedSeq:function(){return new Nt(this,!0)},toMap:function(){return Ue(this.toKeyedSeq())},toObject:function(){Le(this.size);var e={};return this.__iterate(function(t,n){e[n]=t}),e},toOrderedMap:function(){return Tt(this.toKeyedSeq())},toOrderedSet:function(){return gn(s(this)?this.valueSeq():this)},toSet:function(){return cn(s(this)?this.valueSeq():this)},toSetSeq:function(){return new Dt(this)},toSeq:function(){return u(this)?this.toIndexedSeq():s(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return En(s(this)?this.valueSeq():this)},toList:function(){return ft(s(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(e,t){return 0===this.size?e+t:e+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+t},concat:function(){var t=e.call(arguments,0);return $t(this,Ht(this,t))},includes:function(e){return this.some(function(t){return de(t,e)})},entries:function(){return this.__iterator(N)},every:function(e,t){Le(this.size);var n=!0;return this.__iterate(function(r,o,i){if(!e.call(t,r,o,i))return n=!1,!1}),n},filter:function(e,t){return $t(this,zt(this,e,t,!0))},find:function(e,t,n){var r=this.findEntry(e,t);return r?r[1]:n},forEach:function(e,t){return Le(this.size),this.__iterate(t?e.bind(t):e)},join:function(e){Le(this.size),e=void 0!==e?""+e:",";var t="",n=!0;return this.__iterate(function(r){n?n=!1:t+=e,t+=null!=r?r.toString():""}),t},keys:function(){return this.__iterator(I)},map:function(e,t){return $t(this,qt(this,e,t))},reduce:function(e,t,n){var r,o;return Le(this.size),arguments.length<2?o=!0:r=t,this.__iterate(function(t,i,a){o?(o=!1,r=t):r=e.call(n,r,t,i,a)}),r},reduceRight:function(e,t,n){var r=this.toKeyedSeq().reverse();return r.reduce.apply(r,arguments)},reverse:function(){return $t(this,Ft(this,!0))},slice:function(e,t){return $t(this,Bt(this,e,t,!0))},some:function(e,t){return!this.every(Rn(e),t)},sort:function(e){return $t(this,Jt(this,e))},values:function(){return this.__iterator(M)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(e,t){return C(e?this.toSeq().filter(e,t):this)},countBy:function(e,t){return function(e,t,n){var r=Ue().asMutable();return e.__iterate(function(o,i){r.update(t.call(n,o,i,e),0,function(e){return e+1})}),r.asImmutable()}(this,e,t)},equals:function(e){return me(this,e)},entrySeq:function(){var e=this;if(e._cache)return new ee(e._cache);var t=e.toSeq().map(Nn).toIndexedSeq();return t.fromEntrySeq=function(){return e.toSeq()},t},filterNot:function(e,t){return this.filter(Rn(e),t)},findEntry:function(e,t,n){var r=n;return this.__iterate(function(n,o,i){if(e.call(t,n,o,i))return r=[o,n],!1}),r},findKey:function(e,t){var n=this.findEntry(e,t);return n&&n[0]},findLast:function(e,t,n){return this.toKeyedSeq().reverse().find(e,t,n)},findLastEntry:function(e,t,n){return this.toKeyedSeq().reverse().findEntry(e,t,n)},findLastKey:function(e,t){return this.toKeyedSeq().reverse().findKey(e,t)},first:function(){return this.find(O)},flatMap:function(e,t){return $t(this,function(e,t,n){var r=Qt(e);return e.toSeq().map(function(o,i){return r(t.call(n,o,i,e))}).flatten(!0)}(this,e,t))},flatten:function(e){return $t(this,Wt(this,e,!0))},fromEntrySeq:function(){return new Lt(this)},get:function(e,t){return this.find(function(t,n){return de(n,e)},void 0,t)},getIn:function(e,t){for(var n,r=this,o=rn(e);!(n=o.next()).done;){var i=n.value;if((r=r&&r.get?r.get(i,y):y)===y)return t}return r},groupBy:function(e,t){return function(e,t,n){var r=s(e),o=(l(e)?Tt():Ue()).asMutable();e.__iterate(function(i,a){o.update(t.call(n,i,a,e),function(e){return(e=e||[]).push(r?[a,i]:i),e})});var i=Qt(e);return o.map(function(t){return $t(e,i(t))})}(this,e,t)},has:function(e){return this.get(e,y)!==y},hasIn:function(e){return this.getIn(e,y)!==y},isSubset:function(e){return e="function"==typeof e.includes?e:n(e),this.every(function(t){return e.includes(t)})},isSuperset:function(e){return(e="function"==typeof e.isSubset?e:n(e)).isSubset(this)},keyOf:function(e){return this.findKey(function(t){return de(t,e)})},keySeq:function(){return this.toSeq().map(Mn).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(e){return this.toKeyedSeq().reverse().keyOf(e)},max:function(e){return Yt(this,e)},maxBy:function(e,t){return Yt(this,t,e)},min:function(e){return Yt(this,e?Dn(e):qn)},minBy:function(e,t){return Yt(this,t?Dn(t):qn,e)},rest:function(){return this.slice(1)},skip:function(e){return this.slice(Math.max(0,e))},skipLast:function(e){return $t(this,this.toSeq().reverse().skip(e).reverse())},skipWhile:function(e,t){return $t(this,Vt(this,e,t,!0))},skipUntil:function(e,t){return this.skipWhile(Rn(e),t)},sortBy:function(e,t){return $t(this,Jt(this,t,e))},take:function(e){return this.slice(0,Math.max(0,e))},takeLast:function(e){return $t(this,this.toSeq().reverse().take(e).reverse())},takeWhile:function(e,t){return $t(this,function(e,t,n){var r=en(e);return r.__iterateUncached=function(r,o){var i=this;if(o)return this.cacheResult().__iterate(r,o);var a=0;return e.__iterate(function(e,o,s){return t.call(n,e,o,s)&&++a&&r(e,o,i)}),a},r.__iteratorUncached=function(r,o){var i=this;if(o)return this.cacheResult().__iterator(r,o);var a=e.__iterator(N,o),s=!0;return new U(function(){if(!s)return{value:void 0,done:!0};var e=a.next();if(e.done)return e;var o=e.value,u=o[0],c=o[1];return t.call(n,c,u,i)?r===N?e:q(r,u,c,e):(s=!1,{value:void 0,done:!0})})},r}(this,e,t))},takeUntil:function(e,t){return this.takeWhile(Rn(e),t)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=function(e){if(e.size===1/0)return 0;var t=l(e),n=s(e),r=t?1:0;return function(e,t){return t=Ee(t,3432918353),t=Ee(t<<15|t>>>-15,461845907),t=Ee(t<<13|t>>>-13,5),t=Ee((t=(t+3864292196|0)^e)^t>>>16,2246822507),t=Se((t=Ee(t^t>>>13,3266489909))^t>>>16)}(e.__iterate(n?t?function(e,t){r=31*r+Fn(Ce(e),Ce(t))|0}:function(e,t){r=r+Fn(Ce(e),Ce(t))|0}:t?function(e){r=31*r+Ce(e)|0}:function(e){r=r+Ce(e)|0}),r)}(this))}});var Pn=n.prototype;Pn[p]=!0,Pn[L]=Pn.values,Pn.__toJS=Pn.toArray,Pn.__toStringMapper=Ln,Pn.inspect=Pn.toSource=function(){return this.toString()},Pn.chain=Pn.flatMap,Pn.contains=Pn.includes,jn(r,{flip:function(){return $t(this,Ut(this))},mapEntries:function(e,t){var n=this,r=0;return $t(this,this.toSeq().map(function(o,i){return e.call(t,[i,o],r++,n)}).fromEntrySeq())},mapKeys:function(e,t){var n=this;return $t(this,this.toSeq().flip().map(function(r,o){return e.call(t,r,o,n)}).flip())}});var In=r.prototype;function Mn(e,t){return t}function Nn(e,t){return[t,e]}function Rn(e){return function(){return!e.apply(this,arguments)}}function Dn(e){return function(){return-e.apply(this,arguments)}}function Ln(e){return"string"==typeof e?JSON.stringify(e):String(e)}function Un(){return S(arguments)}function qn(e,t){return et?-1:0}function Fn(e,t){return e^t+2654435769+(e<<6)+(e>>2)|0}return In[f]=!0,In[L]=Pn.entries,In.__toJS=Pn.toObject,In.__toStringMapper=function(e,t){return JSON.stringify(t)+": "+Ln(e)},jn(o,{toKeyedSeq:function(){return new Nt(this,!1)},filter:function(e,t){return $t(this,zt(this,e,t,!1))},findIndex:function(e,t){var n=this.findEntry(e,t);return n?n[0]:-1},indexOf:function(e){var t=this.keyOf(e);return void 0===t?-1:t},lastIndexOf:function(e){var t=this.lastKeyOf(e);return void 0===t?-1:t},reverse:function(){return $t(this,Ft(this,!1))},slice:function(e,t){return $t(this,Bt(this,e,t,!1))},splice:function(e,t){var n=arguments.length;if(t=Math.max(0|t,0),0===n||2===n&&!t)return this;e=T(e,e<0?this.count():this.size);var r=this.slice(0,e);return $t(this,1===n?r:r.concat(S(arguments,2),this.slice(e+t)))},findLastIndex:function(e,t){var n=this.findLastEntry(e,t);return n?n[0]:-1},first:function(){return this.get(0)},flatten:function(e){return $t(this,Wt(this,e,!1))},get:function(e,t){return(e=k(this,e))<0||this.size===1/0||void 0!==this.size&&e>this.size?t:this.find(function(t,n){return n===e},void 0,t)},has:function(e){return(e=k(this,e))>=0&&(void 0!==this.size?this.size===1/0||e5e3)return e.textContent;return function(e){for(var n,r,o,i,a,s=e.textContent,u=0,c=s[0],l=1,p=e.innerHTML="",f=0;r=n,n=f<7&&"\\"==n?1:l;){if(l=c,c=s[++u],i=p.length>1,!l||f>8&&"\n"==l||[/\S/.test(l),1,1,!/[$\w]/.test(l),("/"==n||"\n"==n)&&i,'"'==n&&i,"'"==n&&i,s[u-4]+r+n=="--\x3e",r+n=="*/"][f])for(p&&(e.appendChild(a=t.createElement("span")).setAttribute("style",["color: #555; font-weight: bold;","","","color: #555;",""][f?f<3?2:f>6?4:f>3?3:+/^(a(bstract|lias|nd|rguments|rray|s(m|sert)?|uto)|b(ase|egin|ool(ean)?|reak|yte)|c(ase|atch|har|hecked|lass|lone|ompl|onst|ontinue)|de(bugger|cimal|clare|f(ault|er)?|init|l(egate|ete)?)|do|double|e(cho|ls?if|lse(if)?|nd|nsure|num|vent|x(cept|ec|p(licit|ort)|te(nds|nsion|rn)))|f(allthrough|alse|inal(ly)?|ixed|loat|or(each)?|riend|rom|unc(tion)?)|global|goto|guard|i(f|mp(lements|licit|ort)|n(it|clude(_once)?|line|out|stanceof|t(erface|ernal)?)?|s)|l(ambda|et|ock|ong)|m(icrolight|odule|utable)|NaN|n(amespace|ative|ext|ew|il|ot|ull)|o(bject|perator|r|ut|verride)|p(ackage|arams|rivate|rotected|rotocol|ublic)|r(aise|e(adonly|do|f|gister|peat|quire(_once)?|scue|strict|try|turn))|s(byte|ealed|elf|hort|igned|izeof|tatic|tring|truct|ubscript|uper|ynchronized|witch)|t(emplate|hen|his|hrows?|ransient|rue|ry|ype(alias|def|id|name|of))|u(n(checked|def(ined)?|ion|less|signed|til)|se|sing)|v(ar|irtual|oid|olatile)|w(char_t|hen|here|hile|ith)|xor|yield)$/.test(p):0]),a.appendChild(t.createTextNode(p))),o=f&&f<7?f:o,p="",f=11;![1,/[\/{}[(\-+*=<>:;|\\.,?!&@~]/.test(l),/[\])]/.test(l),/[$\w]/.test(l),"/"==l&&o<2&&"<"!=n,'"'==l,"'"==l,l+c+s[u+1]+s[u+2]=="\x3c!--",l+c=="/*",l+c=="//","#"==l][--f];);p+=l}}(e)}function G(e){var t;if([/filename\*=[^']+'\w*'"([^"]+)";?/i,/filename\*=[^']+'\w*'([^;]+);?/i,/filename="([^;]*);?"/i,/filename=([^;]*);?/i].some(function(n){return null!==(t=n.exec(e))}),null!==t&&t.length>1)try{return decodeURIComponent(t[1])}catch(e){console.error(e)}return null}function $(e){return t=e.replace(/\.[^.\/]*$/,""),b()(g()(t));var t}var Z=function(e,t){if(e>t)return"Value must be less than Maximum"},X=function(e,t){if(et)return"Value must be less than MaxLength"},se=function(e,t){if(e.length2&&void 0!==arguments[2]?arguments[2]:{},r=n.isOAS3,o=void 0!==r&&r,i=n.bypassRequiredCheck,a=void 0!==i&&i,s=[],u=e.get("required"),c=Object(P.a)(e,{isOAS3:o});if(!c)return s;var p=c.get("maximum"),h=c.get("minimum"),m=c.get("type"),v=c.get("format"),g=c.get("maxLength"),y=c.get("minLength"),b=c.get("pattern");if(m&&(u||t)){var _="string"===m&&t,w="array"===m&&l()(t)&&t.length,x="array"===m&&d.a.List.isList(t)&&t.count(),E="array"===m&&"string"==typeof t&&t,S="file"===m&&t instanceof A.a.File,C="boolean"===m&&(t||!1===t),k="number"===m&&(t||0===t),O="integer"===m&&(t||0===t),T="object"===m&&"object"===f()(t)&&null!==t,j="object"===m&&"string"==typeof t&&t,I=[_,w,x,E,S,C,k,O,T,j],M=I.some(function(e){return!!e});if(u&&!M&&!a)return s.push("Required field is not provided"),s;if(b){var N=ue(t,b);N&&s.push(N)}if(g||0===g){var R=ae(t,g);R&&s.push(R)}if(y){var D=se(t,y);D&&s.push(D)}if(p||0===p){var L=Z(t,p);L&&s.push(L)}if(h||0===h){var U=X(t,h);U&&s.push(U)}if("string"===m){var q;if(!(q="date-time"===v?oe(t):"uuid"===v?ie(t):re(t)))return s;s.push(q)}else if("boolean"===m){var F=ne(t);if(!F)return s;s.push(F)}else if("number"===m){var z=Q(t);if(!z)return s;s.push(z)}else if("integer"===m){var B=ee(t);if(!B)return s;s.push(B)}else if("array"===m){var V;if(!x||!t.count())return s;V=c.getIn(["items","type"]),t.forEach(function(e,t){var n;"number"===V?n=Q(e):"integer"===V?n=ee(e):"string"===V&&(n=re(e)),n&&s.push({index:t,error:n})})}else if("file"===m){var H=te(t);if(!H)return s;s.push(H)}}return s},le=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(/xml/.test(t)){if(!e.xml||!e.xml.name){if(e.xml=e.xml||{},!e.$$ref)return e.type||e.items||e.properties||e.additionalProperties?'\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e':null;var r=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=r[1]}return Object(k.memoizedCreateXMLExample)(e,n)}var i=Object(k.memoizedSampleFromSchema)(e,n);return"object"===f()(i)?o()(i,null,2):i},pe=function(){var e={},t=A.a.location.search;if(!t)return{};if(""!=t){var n=t.substr(1).split("&");for(var r in n)n.hasOwnProperty(r)&&(r=n[r].split("="),e[decodeURIComponent(r[0])]=r[1]&&decodeURIComponent(r[1])||"")}return e},fe=function(t){return(t instanceof e?t:new e(t.toString(),"utf-8")).toString("base64")},he={operationsSorter:{alpha:function(e,t){return e.get("path").localeCompare(t.get("path"))},method:function(e,t){return e.get("method").localeCompare(t.get("method"))}},tagsSorter:{alpha:function(e,t){return e.localeCompare(t)}}},de=function(e){var t=[];for(var n in e){var r=e[n];void 0!==r&&""!==r&&t.push([n,"=",encodeURIComponent(r).replace(/%20/g,"+")].join(""))}return t.join("&")},me=function(e,t,n){return!!E()(n,function(n){return C()(e[n],t[n])})};function ve(e){return"string"!=typeof e||""===e?"":Object(m.sanitizeUrl)(e)}function ge(e){if(!d.a.OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;var t=e.find(function(e,t){return t.startsWith("2")&&u()(e.get("content")||{}).length>0}),n=e.get("default")||d.a.OrderedMap(),r=(n.get("content")||d.a.OrderedMap()).keySeq().toJS().length?n:null;return t||r}var ye=function(e){return"string"==typeof e||e instanceof String?e.trim().replace(/\s/g,"%20"):""},be=function(e){return j()(ye(e).replace(/%20/g,"_"))},_e=function(e){return e.filter(function(e,t){return/^x-/.test(t)})},we=function(e){return e.filter(function(e,t){return/^pattern|maxLength|minLength|maximum|minimum/.test(t)})};function xe(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){return!0};if("object"!==f()(e)||l()(e)||null===e||!t)return e;var r=a()({},e);return u()(r).forEach(function(e){e===t&&n(r[e],e)?delete r[e]:r[e]=xe(r[e],t,n)}),r}function Ee(e){if("string"==typeof e)return e;if(e&&e.toJS&&(e=e.toJS()),"object"===f()(e)&&null!==e)try{return o()(e,null,2)}catch(t){return String(e)}return null==e?"":e.toString()}function Se(e){return"number"==typeof e?e.toString():e}function Ce(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.returnAll,r=void 0!==n&&n,o=t.allowHashes,i=void 0===o||o;if(!d.a.Map.isMap(e))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");var a=e.get("name"),s=e.get("in"),u=[];return e&&e.hashCode&&s&&a&&i&&u.push("".concat(s,".").concat(a,".hash-").concat(e.hashCode())),s&&a&&u.push("".concat(s,".").concat(a)),u.push(a),r?u:u[0]||""}function ke(e,t){return Ce(e,{returnAll:!0}).map(function(e){return t[e]}).filter(function(e){return void 0!==e})[0]}}).call(this,n(61).Buffer)},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t,n){var r=n(51);function o(e,t){for(var n=0;n1?t-1:0),o=1;o2?n-2:0),i=2;i>",i={listOf:function(e){return c(e,"List",r.List.isList)},mapOf:function(e,t){return l(e,t,"Map",r.Map.isMap)},orderedMapOf:function(e,t){return l(e,t,"OrderedMap",r.OrderedMap.isOrderedMap)},setOf:function(e){return c(e,"Set",r.Set.isSet)},orderedSetOf:function(e){return c(e,"OrderedSet",r.OrderedSet.isOrderedSet)},stackOf:function(e){return c(e,"Stack",r.Stack.isStack)},iterableOf:function(e){return c(e,"Iterable",r.Iterable.isIterable)},recordOf:function(e){return s(function(t,n,o,i,s){for(var u=arguments.length,c=Array(u>5?u-5:0),l=5;l6?u-6:0),l=6;l5?c-5:0),p=5;p5?i-5:0),s=5;s key("+l[p]+")"].concat(a));if(h instanceof Error)return h}})).apply(void 0,i);var u})}function p(e){var t=void 0===arguments[1]?"Iterable":arguments[1],n=void 0===arguments[2]?r.Iterable.isIterable:arguments[2];return s(function(r,o,i,s,u){for(var c=arguments.length,l=Array(c>5?c-5:0),p=5;p4)}function u(e){var t=e.get("swagger");return"string"==typeof t&&t.startsWith("2.0")}function c(e){return function(t,n){return function(r){return n&&n.specSelectors&&n.specSelectors.specJson?s(n.specSelectors.specJson())?a.a.createElement(e,o()({},r,n,{Ori:t})):a.a.createElement(t,r):(console.warn("OAS3 wrapper: couldn't get spec"),null)}}}},function(e,t,n){"use strict"; +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,s,u=a(e),c=1;c0){var o=n.map(function(e){return console.error(e),e.line=e.fullPath?g(y,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",A()(e,"message",{enumerable:!0,value:e.message}),e});i.newThrownErrBatch(o)}return r.updateResolved(t)})}},_e=[],we=V()(k()(S.a.mark(function e(){var t,n,r,o,i,a,s,u,c,l,p,f,h,d,m,v,g;return S.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t=_e.system){e.next=4;break}return console.error("debResolveSubtrees: don't have a system to operate on, aborting."),e.abrupt("return");case 4:if(n=t.errActions,r=t.errSelectors,o=t.fn,i=o.resolveSubtree,a=o.AST,s=void 0===a?{}:a,u=t.specSelectors,c=t.specActions,i){e.next=8;break}return console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing."),e.abrupt("return");case 8:return l=s.getLineNumberForPath?s.getLineNumberForPath:function(){},p=u.specStr(),f=t.getConfigs(),h=f.modelPropertyMacro,d=f.parameterMacro,m=f.requestInterceptor,v=f.responseInterceptor,e.prev=11,e.next=14,_e.reduce(function(){var e=k()(S.a.mark(function e(t,o){var a,s,c,f,g,y,b;return S.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,t;case 2:return a=e.sent,s=a.resultMap,c=a.specWithCurrentSubtrees,e.next=7,i(c,o,{baseDoc:u.url(),modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:v});case 7:return f=e.sent,g=f.errors,y=f.spec,r.allErrors().size&&n.clearBy(function(e){return"thrown"!==e.get("type")||"resolver"!==e.get("source")||!e.get("fullPath").every(function(e,t){return e===o[t]||void 0===o[t]})}),j()(g)&&g.length>0&&(b=g.map(function(e){return e.line=e.fullPath?l(p,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",A()(e,"message",{enumerable:!0,value:e.message}),e}),n.newThrownErrBatch(b)),W()(s,o,y),W()(c,o,y),e.abrupt("return",{resultMap:s,specWithCurrentSubtrees:c});case 15:case"end":return e.stop()}},e)}));return function(t,n){return e.apply(this,arguments)}}(),x.a.resolve({resultMap:(u.specResolvedSubtree([])||Object(R.Map)()).toJS(),specWithCurrentSubtrees:u.specJson().toJS()}));case 14:g=e.sent,delete _e.system,_e=[],e.next=22;break;case 19:e.prev=19,e.t0=e.catch(11),console.error(e.t0);case 22:c.updateResolvedSubtree([],g.resultMap);case 23:case"end":return e.stop()}},e,null,[[11,19]])})),35),xe=function(e){return function(t){_e.map(function(e){return e.join("@@")}).indexOf(e.join("@@"))>-1||(_e.push(e),_e.system=t,we())}};function Ee(e,t,n,r,o){return{type:X,payload:{path:e,value:r,paramName:t,paramIn:n,isXml:o}}}function Se(e,t,n,r){return{type:X,payload:{path:e,param:t,value:n,isXml:r}}}var Ce=function(e,t){return{type:le,payload:{path:e,value:t}}},ke=function(){return{type:le,payload:{path:[],value:Object(R.Map)()}}},Oe=function(e,t){return{type:ee,payload:{pathMethod:e,isOAS3:t}}},Ae=function(e,t,n,r){return{type:Q,payload:{pathMethod:e,paramName:t,paramIn:n,includeEmptyValue:r}}};function Te(e){return{type:se,payload:{pathMethod:e}}}function je(e,t){return{type:ue,payload:{path:e,value:t,key:"consumes_value"}}}function Pe(e,t){return{type:ue,payload:{path:e,value:t,key:"produces_value"}}}var Ie=function(e,t,n){return{payload:{path:e,method:t,res:n},type:te}},Me=function(e,t,n){return{payload:{path:e,method:t,req:n},type:ne}},Ne=function(e,t,n){return{payload:{path:e,method:t,req:n},type:re}},Re=function(e){return{payload:e,type:oe}},De=function(e){return function(t){var n=t.fn,r=t.specActions,o=t.specSelectors,i=t.getConfigs,a=t.oas3Selectors,s=e.pathName,u=e.method,c=e.operation,l=i(),p=l.requestInterceptor,f=l.responseInterceptor,h=c.toJS();if(c&&c.get("parameters")&&c.get("parameters").filter(function(e){return e&&!0===e.get("allowEmptyValue")}).forEach(function(t){if(o.parameterInclusionSettingFor([s,u],t.get("name"),t.get("in"))){e.parameters=e.parameters||{};var n=Object(J.A)(t,e.parameters);(!n||n&&0===n.size)&&(e.parameters[t.get("name")]="")}}),e.contextUrl=L()(o.url()).toString(),h&&h.operationId?e.operationId=h.operationId:h&&s&&u&&(e.operationId=n.opId(h,s,u)),o.isOAS3()){var d="".concat(s,":").concat(u);e.server=a.selectedServer(d)||a.selectedServer();var m=a.serverVariables({server:e.server,namespace:d}).toJS(),g=a.serverVariables({server:e.server}).toJS();e.serverVariables=_()(m).length?m:g,e.requestContentType=a.requestContentType(s,u),e.responseContentType=a.responseContentType(s,u)||"*/*";var b=a.requestBodyValue(s,u);Object(J.r)(b)?e.requestBody=JSON.parse(b):b&&b.toJS?e.requestBody=b.toJS():e.requestBody=b}var w=y()({},e);w=n.buildRequest(w),r.setRequest(e.pathName,e.method,w);e.requestInterceptor=function(t){var n=p.apply(this,[t]),o=y()({},n);return r.setMutatedRequest(e.pathName,e.method,o),n},e.responseInterceptor=f;var x=v()();return n.execute(e).then(function(t){t.duration=v()()-x,r.setResponse(e.pathName,e.method,t)}).catch(function(t){console.error(t),r.setResponse(e.pathName,e.method,{error:!0,err:q()(t)})})}},Le=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.path,n=e.method,r=d()(e,["path","method"]);return function(e){var o=e.fn.fetch,i=e.specSelectors,a=e.specActions,s=i.specJsonWithResolvedSubtrees().toJS(),u=i.operationScheme(t,n),c=i.contentTypeValues([t,n]).toJS(),l=c.requestContentType,p=c.responseContentType,f=/xml/i.test(l),h=i.parameterValues([t,n],f).toJS();return a.executeRequest(K({},r,{fetch:o,spec:s,pathName:t,method:n,parameters:h,requestContentType:l,scheme:u,responseContentType:p}))}};function Ue(e,t){return{type:ie,payload:{path:e,method:t}}}function qe(e,t){return{type:ae,payload:{path:e,method:t}}}function Fe(e,t,n){return{type:pe,payload:{scheme:e,path:t,method:n}}}},function(e,t,n){var r=n(32),o=n(22),i=n(60),a=n(71),s=n(69),u=function(e,t,n){var c,l,p,f=e&u.F,h=e&u.G,d=e&u.S,m=e&u.P,v=e&u.B,g=e&u.W,y=h?o:o[t]||(o[t]={}),b=y.prototype,_=h?r:d?r[t]:(r[t]||{}).prototype;for(c in h&&(n=t),n)(l=!f&&_&&void 0!==_[c])&&s(y,c)||(p=l?_[c]:n[c],y[c]=h&&"function"!=typeof _[c]?n[c]:v&&l?i(p,r):g&&_[c]==p?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(p):m&&"function"==typeof p?i(Function.call,p):p,m&&((y.virtual||(y.virtual={}))[c]=p,e&u.R&&b&&!b[c]&&a(b,c,p)))};u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},function(e,t,n){"use strict";var r=n(135),o=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],i=["scalar","sequence","mapping"];e.exports=function(e,t){var n,a;if(t=t||{},Object.keys(t).forEach(function(t){if(-1===o.indexOf(t))throw new r('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=(n=t.styleAliases||null,a={},null!==n&&Object.keys(n).forEach(function(e){n[e].forEach(function(t){a[String(t)]=e})}),a),-1===i.indexOf(this.kind))throw new r('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){var r=n(328)("wks"),o=n(195),i=n(43).Symbol,a="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}).store=r},function(e,t,n){var r=n(206)("wks"),o=n(155),i=n(32).Symbol,a="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}).store=r},function(e,t){var n=Array.isArray;e.exports=n},function(e,t,n){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),o={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen,isInWorker:!r};e.exports=o},function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty;function o(e,t){return!!e&&r.call(e,t)}var i=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;function a(e){return!(e>=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!=(65535&e)&&65534!=(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function s(e){if(e>65535){var t=55296+((e-=65536)>>10),n=56320+(1023&e);return String.fromCharCode(t,n)}return String.fromCharCode(e)}var u=/&([a-z#][a-z0-9]{1,31});/gi,c=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,l=n(457);function p(e,t){var n=0;return o(l,t)?l[t]:35===t.charCodeAt(0)&&c.test(t)&&a(n="x"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10))?s(n):e}var f=/[&<>"]/,h=/[&<>"]/g,d={"&":"&","<":"<",">":">",'"':"""};function m(e){return d[e]}t.assign=function(e){return[].slice.call(arguments,1).forEach(function(t){if(t){if("object"!=typeof t)throw new TypeError(t+"must be object");Object.keys(t).forEach(function(n){e[n]=t[n]})}}),e},t.isString=function(e){return"[object String]"===function(e){return Object.prototype.toString.call(e)}(e)},t.has=o,t.unescapeMd=function(e){return e.indexOf("\\")<0?e:e.replace(i,"$1")},t.isValidEntityCode=a,t.fromCodePoint=s,t.replaceEntities=function(e){return e.indexOf("&")<0?e:e.replace(u,p)},t.escapeHtml=function(e){return f.test(e)?e.replace(h,m):e}},function(e,t,n){var r=n(43),o=n(78),i=n(76),a=n(95),s=n(150),u=function(e,t,n){var c,l,p,f,h=e&u.F,d=e&u.G,m=e&u.S,v=e&u.P,g=e&u.B,y=d?r:m?r[t]||(r[t]={}):(r[t]||{}).prototype,b=d?o:o[t]||(o[t]={}),_=b.prototype||(b.prototype={});for(c in d&&(n=t),n)p=((l=!h&&y&&void 0!==y[c])?y:n)[c],f=g&&l?s(p,r):v&&"function"==typeof p?s(Function.call,p):p,y&&a(y,c,p,e&u.U),b[c]!=p&&i(b,c,f),v&&_[c]!=p&&(_[c]=p)};r.core=o,u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},function(e,t,n){var r=n(38),o=n(123),i=n(68),a=/"/g,s=function(e,t,n,r){var o=String(i(e)),s="<"+t;return""!==n&&(s+=" "+n+'="'+String(r).replace(a,""")+'"'),s+">"+o+""};e.exports=function(e,t){var n={};n[e]=t(s),r(r.P+r.F*o(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";n.r(t),n.d(t,"NEW_THROWN_ERR",function(){return i}),n.d(t,"NEW_THROWN_ERR_BATCH",function(){return a}),n.d(t,"NEW_SPEC_ERR",function(){return s}),n.d(t,"NEW_SPEC_ERR_BATCH",function(){return u}),n.d(t,"NEW_AUTH_ERR",function(){return c}),n.d(t,"CLEAR",function(){return l}),n.d(t,"CLEAR_BY",function(){return p}),n.d(t,"newThrownErr",function(){return f}),n.d(t,"newThrownErrBatch",function(){return h}),n.d(t,"newSpecErr",function(){return d}),n.d(t,"newSpecErrBatch",function(){return m}),n.d(t,"newAuthErr",function(){return v}),n.d(t,"clear",function(){return g}),n.d(t,"clearBy",function(){return y});var r=n(115),o=n.n(r),i="err_new_thrown_err",a="err_new_thrown_err_batch",s="err_new_spec_err",u="err_new_spec_err_batch",c="err_new_auth_err",l="err_clear",p="err_clear_by";function f(e){return{type:i,payload:o()(e)}}function h(e){return{type:a,payload:e}}function d(e){return{type:s,payload:e}}function m(e){return{type:u,payload:e}}function v(e){return{type:c,payload:e}}function g(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{type:l,payload:e}}function y(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!0};return{type:p,payload:e}}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){var r=n(40);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){e.exports=!n(80)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t,n){var r=n(52),o=n(756);e.exports=function(e,t){if(null==e)return{};var n,i,a=o(e,t);if(r){var s=r(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}},function(e,t,n){var r=n(44),o=n(344),i=n(210),a=Object.defineProperty;t.f=n(45)?Object.defineProperty:function(e,t,n){if(r(e),t=i(t,!0),r(n),o)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){var r=n(361),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();e.exports=i},function(e,t){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},function(e,t,n){"use strict";e.exports={debugTool:null}},function(e,t,n){e.exports=n(562)},function(e,t,n){e.exports=n(755)},function(e,t,n){e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=45)}([function(e,t){e.exports=n(17)},function(e,t){e.exports=n(14)},function(e,t){e.exports=n(26)},function(e,t){e.exports=n(16)},function(e,t){e.exports=n(119)},function(e,t){e.exports=n(57)},function(e,t){e.exports=n(58)},function(e,t){e.exports=n(52)},function(e,t){e.exports=n(2)},function(e,t){e.exports=n(51)},function(e,t){e.exports=n(92)},function(e,t){e.exports=n(28)},function(e,t){e.exports=n(916)},function(e,t){e.exports=n(12)},function(e,t){e.exports=n(189)},function(e,t){e.exports=n(922)},function(e,t){e.exports=n(91)},function(e,t){e.exports=n(190)},function(e,t){e.exports=n(925)},function(e,t){e.exports=n(929)},function(e,t){e.exports=n(930)},function(e,t){e.exports=n(90)},function(e,t){e.exports=n(13)},function(e,t){e.exports=n(143)},function(e,t){e.exports=n(4)},function(e,t){e.exports=n(5)},function(e,t){e.exports=n(932)},function(e,t){e.exports=n(414)},function(e,t){e.exports=n(935)},function(e,t){e.exports=n(49)},function(e,t){e.exports=n(61)},function(e,t){e.exports=n(275)},function(e,t){e.exports=n(264)},function(e,t){e.exports=n(936)},function(e,t){e.exports=n(142)},function(e,t){e.exports=n(937)},function(e,t){e.exports=n(945)},function(e,t){e.exports=n(946)},function(e,t){e.exports=n(947)},function(e,t){e.exports=n(46)},function(e,t){e.exports=n(256)},function(e,t){e.exports=n(35)},function(e,t){e.exports=n(950)},function(e,t){e.exports=n(951)},function(e,t){e.exports=n(952)},function(e,t,n){e.exports=n(50)},function(e,t){e.exports=n(953)},function(e,t){e.exports=n(954)},function(e,t){e.exports=n(955)},function(e,t){e.exports=n(956)},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"path",function(){return dn}),n.d(r,"query",function(){return mn}),n.d(r,"header",function(){return gn}),n.d(r,"cookie",function(){return yn});var o=n(9),i=n.n(o),a=n(10),s=n.n(a),u=n(5),c=n.n(u),l=n(6),p=n.n(l),f=n(7),h=n.n(f),d=n(0),m=n.n(d),v=n(8),g=n.n(v),y=(n(46),n(15)),b=n.n(y),_=n(20),w=n.n(_),x=n(12),E=n.n(x),S=n(4),C=n.n(S),k=n(22),O=n.n(k),A=n(11),T=n.n(A),j=n(2),P=n.n(j),I=n(1),M=n.n(I),N=n(17),R=n.n(N),D=(n(47),n(26)),L=n.n(D),U=n(23),q=n.n(U),F=n(31),z=n.n(F),B={serializeRes:J,mergeInQueryOrForm:Z};function V(e){return H.apply(this,arguments)}function H(){return(H=R()(C.a.mark(function e(t){var n,r,o,i,a,s=arguments;return C.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(n=s.length>1&&void 0!==s[1]?s[1]:{},"object"===P()(t)&&(t=(n=t).url),n.headers=n.headers||{},B.mergeInQueryOrForm(n),n.headers&&m()(n.headers).forEach(function(e){var t=n.headers[e];"string"==typeof t&&(n.headers[e]=t.replace(/\n+/g," "))}),!n.requestInterceptor){e.next=12;break}return e.next=8,n.requestInterceptor(n);case 8:if(e.t0=e.sent,e.t0){e.next=11;break}e.t0=n;case 11:n=e.t0;case 12:return r=n.headers["content-type"]||n.headers["Content-Type"],/multipart\/form-data/i.test(r)&&(delete n.headers["content-type"],delete n.headers["Content-Type"]),e.prev=14,e.next=17,(n.userFetch||fetch)(n.url,n);case 17:return o=e.sent,e.next=20,B.serializeRes(o,t,n);case 20:if(o=e.sent,!n.responseInterceptor){e.next=28;break}return e.next=24,n.responseInterceptor(o);case 24:if(e.t1=e.sent,e.t1){e.next=27;break}e.t1=o;case 27:o=e.t1;case 28:e.next=38;break;case 30:if(e.prev=30,e.t2=e.catch(14),o){e.next=34;break}throw e.t2;case 34:throw(i=new Error(o.statusText)).statusCode=i.status=o.status,i.responseError=e.t2,i;case 38:if(o.ok){e.next=43;break}throw(a=new Error(o.statusText)).statusCode=a.status=o.status,a.response=o,a;case 43:return e.abrupt("return",o);case 44:case"end":return e.stop()}},e,null,[[14,30]])}))).apply(this,arguments)}var W=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return/(json|xml|yaml|text)\b/.test(e)};function J(e,t){var n=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).loadSpec,r=void 0!==n&&n,o={ok:e.ok,url:e.url||t,status:e.status,statusText:e.statusText,headers:Y(e.headers)},i=o.headers["content-type"],a=r||W(i);return(a?e.text:e.blob||e.buffer).call(e).then(function(e){if(o.text=e,o.data=e,a)try{var t=function(e,t){return t&&(0===t.indexOf("application/json")||t.indexOf("+json")>0)?JSON.parse(e):q.a.safeLoad(e)}(e,i);o.body=t,o.obj=t}catch(e){o.parseError=e}return o})}function Y(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t={};return"function"==typeof e.forEach?(e.forEach(function(e,n){void 0!==t[n]?(t[n]=M()(t[n])?t[n]:[t[n]],t[n].push(e)):t[n]=e}),t):t}function K(e,t){return t||"undefined"==typeof navigator||(t=navigator),t&&"ReactNative"===t.product?!(!e||"object"!==P()(e)||"string"!=typeof e.uri):"undefined"!=typeof File?e instanceof File:null!==e&&"object"===P()(e)&&"function"==typeof e.pipe}function G(e,t){var n=e.collectionFormat,r=e.allowEmptyValue,o="object"===P()(e)?e.value:e;if(void 0===o&&r)return"";if(K(o)||"boolean"==typeof o)return o;var i=encodeURIComponent;return t&&(i=z()(o)?function(e){return e}:function(e){return T()(e)}),"object"!==P()(o)||M()(o)?M()(o)?M()(o)&&!n?o.map(i).join(","):"multi"===n?o.map(i):o.map(i).join({csv:",",ssv:"%20",tsv:"%09",pipes:"|"}[n]):i(o):""}function $(e){var t=m()(e).reduce(function(t,n){var r,o=e[n],i=!!o.skipEncoding,a=i?n:encodeURIComponent(n),s=(r=o)&&"object"===P()(r)&&!M()(o);return t[a]=G(s?o:{value:o},i),t},{});return L.a.stringify(t,{encode:!1,indices:!1})||""}function Z(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.url,r=void 0===t?"":t,o=e.query,i=e.form;if(i){var a=m()(i).some(function(e){return K(i[e].value)}),s=e.headers["content-type"]||e.headers["Content-Type"];if(a||/multipart\/form-data/i.test(s)){var u=n(48);e.body=new u,m()(i).forEach(function(t){e.body.append(t,G(i[t],!0))})}else e.body=$(i);delete e.form}if(o){var c=r.split("?"),l=O()(c,2),p=l[0],f=l[1],h="";if(f){var d=L.a.parse(f);m()(o).forEach(function(e){return delete d[e]}),h=L.a.stringify(d,{encode:!0})}var v=function(){for(var e=arguments.length,t=new Array(e),n=0;n0){var o=t(e,n[n.length-1],n);o&&(r=r.concat(o))}if(M()(e)){var i=e.map(function(e,r){return Ce(e,t,n.concat(r))});i&&(r=r.concat(i))}else if(Te(e)){var a=m()(e).map(function(r){return Ce(e[r],t,n.concat(r))});a&&(r=r.concat(a))}return r=Oe(r)}function ke(e){return M()(e)?e:[e]}function Oe(e){var t;return(t=[]).concat.apply(t,he()(e.map(function(e){return M()(e)?Oe(e):e})))}function Ae(e){return e.filter(function(e){return void 0!==e})}function Te(e){return e&&"object"===P()(e)}function je(e){return e&&"function"==typeof e}function Pe(e){if(Ne(e)){var t=e.op;return"add"===t||"remove"===t||"replace"===t}return!1}function Ie(e){return Pe(e)||Ne(e)&&"mutation"===e.type}function Me(e){return Ie(e)&&("add"===e.op||"replace"===e.op||"merge"===e.op||"mergeDeep"===e.op)}function Ne(e){return e&&"object"===P()(e)}function Re(e,t){try{return me.a.getValueByPointer(e,t)}catch(e){return console.error(e),{}}}var De=n(35),Le=n.n(De),Ue=n(36),qe=n(28),Fe=n.n(qe);function ze(e,t){function n(){Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack;for(var e=arguments.length,n=new Array(e),r=0;r-1&&-1===We.indexOf(n)||Je.indexOf(r)>-1||Ye.some(function(e){return r.indexOf(e)>-1})}function Ge(e,t){var n=e.split("#"),r=O()(n,2),o=r[0],i=r[1],a=E.a.resolve(o||"",t||"");return i?"".concat(a,"#").concat(i):a}var $e=new RegExp("^([a-z]+://|//)","i"),Ze=ze("JSONRefError",function(e,t,n){this.originalError=n,ie()(this,t||{})}),Xe={},Qe=new Le.a,et=[function(e){return"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"example"===e[7]},function(e){return"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"example"===e[6]}],tt={key:"$ref",plugin:function(e,t,n,r){var o=r.getInstance(),i=n.slice(0,-1);if(!Ke(i)&&(a=i,!et.some(function(e){return e(a)}))){var a,s=r.getContext(n).baseDoc;if("string"!=typeof e)return new Ze("$ref: must be a string (JSON-Ref)",{$ref:e,baseDoc:s,fullPath:n});var u,c,l,p=at(e),f=p[0],h=p[1]||"";try{u=s||f?ot(f,s):null}catch(t){return it(t,{pointer:h,$ref:e,basePath:u,fullPath:n})}if(function(e,t,n,r){var o=Qe.get(r);o||(o={},Qe.set(r,o));var i=function(e){if(0===e.length)return"";return"/".concat(e.map(ft).join("/"))}(n),a="".concat(t||"","#").concat(e),s=i.replace(/allOf\/\d+\/?/g,""),u=r.contextTree.get([]).baseDoc;if(t==u&&dt(s,e))return!0;var c="";if(n.some(function(e){return c="".concat(c,"/").concat(ft(e)),o[c]&&o[c].some(function(e){return dt(e,a)||dt(a,e)})}))return!0;o[s]=(o[s]||[]).concat(a)}(h,u,i,r)&&!o.useCircularStructures){var d=Ge(e,u);return e===d?null:_e.replace(n,d)}if(null==u?(l=lt(h),void 0===(c=r.get(l))&&(c=new Ze("Could not resolve reference: ".concat(e),{pointer:h,$ref:e,baseDoc:s,fullPath:n}))):c=null!=(c=st(u,h)).__value?c.__value:c.catch(function(t){throw it(t,{pointer:h,$ref:e,baseDoc:s,fullPath:n})}),c instanceof Error)return[_e.remove(n),c];var v=Ge(e,u),g=_e.replace(i,c,{$$ref:v});if(u&&u!==s)return[g,_e.context(i,{baseDoc:u})];try{if(!function(e,t){var n=[e];return t.path.reduce(function(e,t){return n.push(e[t]),e[t]},e),function e(t){return _e.isObject(t)&&(n.indexOf(t)>=0||m()(t).some(function(n){return e(t[n])}))}(t.value)}(r.state,g)||o.useCircularStructures)return g}catch(e){return null}}}},nt=ie()(tt,{docCache:Xe,absoluteify:ot,clearCache:function(e){void 0!==e?delete Xe[e]:m()(Xe).forEach(function(e){delete Xe[e]})},JSONRefError:Ze,wrapError:it,getDoc:ut,split:at,extractFromDoc:st,fetchJSON:function(e){return Object(Ue.fetch)(e,{headers:{Accept:"application/json, application/yaml"},loadSpec:!0}).then(function(e){return e.text()}).then(function(e){return q.a.safeLoad(e)})},extract:ct,jsonPointerToArray:lt,unescapeJsonPointerToken:pt}),rt=nt;function ot(e,t){if(!$e.test(e)){if(!t)throw new Ze("Tried to resolve a relative URL, without having a basePath. path: '".concat(e,"' basePath: '").concat(t,"'"));return E.a.resolve(t,e)}return e}function it(e,t){var n;return n=e&&e.response&&e.response.body?"".concat(e.response.body.code," ").concat(e.response.body.message):e.message,new Ze("Could not resolve reference: ".concat(n),t,e)}function at(e){return(e+"").split("#")}function st(e,t){var n=Xe[e];if(n&&!_e.isPromise(n))try{var r=ct(t,n);return ie()(Q.a.resolve(r),{__value:r})}catch(e){return Q.a.reject(e)}return ut(e).then(function(e){return ct(t,e)})}function ut(e){var t=Xe[e];return t?_e.isPromise(t)?t:Q.a.resolve(t):(Xe[e]=nt.fetchJSON(e).then(function(t){return Xe[e]=t,t}),Xe[e])}function ct(e,t){var n=lt(e);if(n.length<1)return t;var r=_e.getIn(t,n);if(void 0===r)throw new Ze("Could not resolve pointer: ".concat(e," does not exist in document"),{pointer:e});return r}function lt(e){if("string"!=typeof e)throw new TypeError("Expected a string, got a ".concat(P()(e)));return"/"===e[0]&&(e=e.substr(1)),""===e?[]:e.split("/").map(pt)}function pt(e){return"string"!=typeof e?e:Fe.a.unescape(e.replace(/~1/g,"/").replace(/~0/g,"~"))}function ft(e){return Fe.a.escape(e.replace(/~/g,"~0").replace(/\//g,"~1"))}var ht=function(e){return!e||"/"===e||"#"===e};function dt(e,t){if(ht(t))return!0;var n=e.charAt(t.length),r=t.slice(-1);return 0===e.indexOf(t)&&(!n||"/"===n||"#"===n)&&"#"!==r}var mt={key:"allOf",plugin:function(e,t,n,r,o){if(!o.meta||!o.meta.$$ref){var i=n.slice(0,-1);if(!Ke(i)){if(!M()(e)){var a=new TypeError("allOf must be an array");return a.fullPath=n,a}var s=!1,u=o.value;i.forEach(function(e){u&&(u=u[e])}),delete(u=ie()({},u)).allOf;var c=[];return c.push(r.replace(i,{})),e.forEach(function(e,t){if(!r.isObject(e)){if(s)return null;s=!0;var o=new TypeError("Elements in allOf must be objects");return o.fullPath=n,c.push(o)}c.push(r.mergeDeep(i,e));var a=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.specmap,o=n.getBaseUrlForNodePath,i=void 0===o?function(e){return r.getContext([].concat(he()(t),he()(e))).baseDoc}:o,a=n.targetKeys,s=void 0===a?["$ref","$$ref"]:a,u=[];return Ve()(e).forEach(function(){if(s.indexOf(this.key)>-1){var e=this.path,n=t.concat(this.path),o=Ge(this.node,i(e));u.push(r.replace(n,o))}}),u}(e,n.slice(0,-1),{getBaseUrlForNodePath:function(e){return r.getContext([].concat(he()(n),[t],he()(e))).baseDoc},specmap:r});c.push.apply(c,he()(a))}),c.push(r.mergeDeep(i,u)),u.$$ref||c.push(r.remove([].concat(i,"$$ref"))),c}}}},vt={key:"parameters",plugin:function(e,t,n,r,o){if(M()(e)&&e.length){var i=ie()([],e),a=n.slice(0,-1),s=ie()({},_e.getIn(r.spec,a));return e.forEach(function(e,t){try{i[t].default=r.parameterMacro(s,e)}catch(e){var o=new Error(e);return o.fullPath=n,o}}),_e.replace(n,i)}return _e.replace(n,e)}},gt={key:"properties",plugin:function(e,t,n,r){var o=ie()({},e);for(var i in e)try{o[i].default=r.modelPropertyMacro(o[i])}catch(e){var a=new Error(e);return a.fullPath=n,a}return _e.replace(n,o)}};function yt(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}var bt=function(){function e(t){se()(this,e),this.root=_t(t||{})}return ce()(e,[{key:"set",value:function(e,t){var n=this.getParent(e,!0);if(n){var r=e[e.length-1],o=n.children;o[r]?wt(o[r],t,n):o[r]=_t(t,n)}else wt(this.root,t,null)}},{key:"get",value:function(e){if((e=e||[]).length<1)return this.root.value;for(var t,n,r=this.root,o=0;o1?n-1:0),o=1;o1?n-1:0),o=1;o0})}},{key:"nextPromisedPatch",value:function(){if(this.promisedPatches.length>0)return Q.a.race(this.promisedPatches.map(function(e){return e.value}))}},{key:"getPluginHistory",value:function(e){var t=this.getPluginName(e);return this.pluginHistory[t]||[]}},{key:"getPluginRunCount",value:function(e){return this.getPluginHistory(e).length}},{key:"getPluginHistoryTip",value:function(e){var t=this.getPluginHistory(e);return t&&t[t.length-1]||{}}},{key:"getPluginMutationIndex",value:function(e){var t=this.getPluginHistoryTip(e).mutationIndex;return"number"!=typeof t?-1:t}},{key:"getPluginName",value:function(e){return e.pluginName}},{key:"updatePluginHistory",value:function(e,t){var n=this.getPluginName(e);(this.pluginHistory[n]=this.pluginHistory[n]||[]).push(t)}},{key:"updatePatches",value:function(e,t){var n=this;_e.normalizeArray(e).forEach(function(e){if(e instanceof Error)n.errors.push(e);else try{if(!_e.isObject(e))return void n.debug("updatePatches","Got a non-object patch",e);if(n.showDebug&&n.allPatches.push(e),_e.isPromise(e.value))return n.promisedPatches.push(e),void n.promisedPatchThen(e);if(_e.isContextPatch(e))return void n.setContext(e.path,e.value);if(_e.isMutation(e))return void n.updateMutations(e)}catch(e){console.error(e),n.errors.push(e)}})}},{key:"updateMutations",value:function(e){"object"===P()(e.value)&&!M()(e.value)&&this.allowMetaPatches&&(e.value=ie()({},e.value));var t=_e.applyPatch(this.state,e,{allowMetaPatches:this.allowMetaPatches});t&&(this.mutations.push(e),this.state=t)}},{key:"removePromisedPatch",value:function(e){var t=this.promisedPatches.indexOf(e);t<0?this.debug("Tried to remove a promisedPatch that isn't there!"):this.promisedPatches.splice(t,1)}},{key:"promisedPatchThen",value:function(e){var t=this;return e.value=e.value.then(function(n){var r=ie()({},e,{value:n});t.removePromisedPatch(e),t.updatePatches(r)}).catch(function(n){t.removePromisedPatch(e),t.updatePatches(n)})}},{key:"getMutations",value:function(e,t){return e=e||0,"number"!=typeof t&&(t=this.mutations.length),this.mutations.slice(e,t)}},{key:"getCurrentMutations",value:function(){return this.getMutationsForPlugin(this.getCurrentPlugin())}},{key:"getMutationsForPlugin",value:function(e){var t=this.getPluginMutationIndex(e);return this.getMutations(t+1)}},{key:"getCurrentPlugin",value:function(){return this.currentPlugin}},{key:"getPatchesOfType",value:function(e,t){return e.filter(t)}},{key:"getLib",value:function(){return this.libMethods}},{key:"_get",value:function(e){return _e.getIn(this.state,e)}},{key:"_getContext",value:function(e){return this.contextTree.get(e)}},{key:"setContext",value:function(e,t){return this.contextTree.set(e,t)}},{key:"_hasRun",value:function(e){return this.getPluginRunCount(this.getCurrentPlugin())>(e||0)}},{key:"_clone",value:function(e){return JSON.parse(T()(e))}},{key:"dispatch",value:function(){var e=this,t=this,n=this.nextPlugin();if(!n){var r=this.nextPromisedPatch();if(r)return r.then(function(){return e.dispatch()}).catch(function(){return e.dispatch()});var o={spec:this.state,errors:this.errors};return this.showDebug&&(o.patches=this.allPatches),Q.a.resolve(o)}if(t.pluginCount=t.pluginCount||{},t.pluginCount[n]=(t.pluginCount[n]||0)+1,t.pluginCount[n]>100)return Q.a.resolve({spec:t.state,errors:t.errors.concat(new Error("We've reached a hard limit of ".concat(100," plugin runs")))});if(n!==this.currentPlugin&&this.promisedPatches.length){var i=this.promisedPatches.map(function(e){return e.value});return Q.a.all(i.map(function(e){return e.then(Function,Function)})).then(function(){return e.dispatch()})}return function(){t.currentPlugin=n;var e=t.getCurrentMutations(),r=t.mutations.length-1;try{if(n.isGenerator){var o=!0,i=!1,s=void 0;try{for(var u,c=te()(n(e,t.getLib()));!(o=(u=c.next()).done);o=!0){var l=u.value;a(l)}}catch(e){i=!0,s=e}finally{try{o||null==c.return||c.return()}finally{if(i)throw s}}}else{var p=n(e,t.getLib());a(p)}}catch(e){console.error(e),a([ie()(re()(e),{plugin:n})])}finally{t.updatePluginHistory(n,{mutationIndex:r})}return t.dispatch()}();function a(e){e&&(e=_e.fullyNormalizeArray(e),t.updatePatches(e,n))}}}]),e}();var Et={refs:rt,allOf:mt,parameters:vt,properties:gt},St=n(29),Ct=n.n(St),kt=function(e){return String.prototype.toLowerCase.call(e)},Ot=function(e){return e.replace(/[^\w]/gi,"_")};function At(e){var t=e.openapi;return!!t&&w()(t,"3")}function Tt(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",r=(arguments.length>3&&void 0!==arguments[3]?arguments[3]:{}).v2OperationIdCompatibilityMode;return e&&"object"===P()(e)?(e.operationId||"").replace(/\s/g,"").length?Ot(e.operationId):function(e,t){if((arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).v2OperationIdCompatibilityMode){var n="".concat(t.toLowerCase(),"_").concat(e).replace(/[\s!@#$%^&*()_+=[{\]};:<>|.\/?,\\'""-]/g,"_");return(n=n||"".concat(e.substring(1),"_").concat(t)).replace(/((_){2,})/g,"_").replace(/^(_)*/g,"").replace(/([_])*$/g,"")}return"".concat(kt(t)).concat(Ot(e))}(t,n,{v2OperationIdCompatibilityMode:r}):null}function jt(e,t){return"".concat(kt(t),"-").concat(e)}function Pt(e,t){return e&&e.paths?function(e,t){return It(e,t,!0)||null}(e,function(e){var n=e.pathName,r=e.method,o=e.operation;if(!o||"object"!==P()(o))return!1;var i=o.operationId;return[Tt(o,n,r),jt(n,r),i].some(function(e){return e&&e===t})}):null}function It(e,t,n){if(!e||"object"!==P()(e)||!e.paths||"object"!==P()(e.paths))return null;var r=e.paths;for(var o in r)for(var i in r[o])if("PARAMETERS"!==i.toUpperCase()){var a=r[o][i];if(a&&"object"===P()(a)){var s={spec:e,pathName:o,method:i.toUpperCase(),operation:a},u=t(s);if(n&&u)return s}}}function Mt(e){var t=e.spec,n=t.paths,r={};if(!n||t.$$normalized)return e;for(var o in n){var i=n[o];if(Ct()(i)){var a=i.parameters,s=function(e){var n=i[e];if(!Ct()(n))return"continue";var s=Tt(n,o,e);if(s){r[s]?r[s].push(n):r[s]=[n];var u=r[s];if(u.length>1)u.forEach(function(e,t){e.__originalOperationId=e.__originalOperationId||e.operationId,e.operationId="".concat(s).concat(t+1)});else if(void 0!==n.operationId){var c=u[0];c.__originalOperationId=c.__originalOperationId||n.operationId,c.operationId=s}}if("parameters"!==e){var l=[],p={};for(var f in t)"produces"!==f&&"consumes"!==f&&"security"!==f||(p[f]=t[f],l.push(p));if(a&&(p.parameters=a,l.push(p)),l.length)for(var h=0,d=l;h1&&void 0!==arguments[1]?arguments[1]:{},n=t.requestInterceptor,r=t.responseInterceptor,o=e.withCredentials?"include":"same-origin";return function(t){return e({url:t,loadSpec:!0,requestInterceptor:n,responseInterceptor:r,headers:{Accept:"application/json"},credentials:o}).then(function(e){return e.body})}}function Rt(e){var t=e.fetch,n=e.spec,r=e.url,o=e.mode,i=e.allowMetaPatches,a=void 0===i||i,s=e.pathDiscriminator,u=e.modelPropertyMacro,c=e.parameterMacro,l=e.requestInterceptor,p=e.responseInterceptor,f=e.skipNormalization,h=e.useCircularStructures,d=e.http,m=e.baseDoc;return m=m||r,d=t||d||V,n?v(n):Nt(d,{requestInterceptor:l,responseInterceptor:p})(m).then(v);function v(e){m&&(Et.refs.docCache[m]=e),Et.refs.fetchJSON=Nt(d,{requestInterceptor:l,responseInterceptor:p});var t,n=[Et.refs];return"function"==typeof c&&n.push(Et.parameters),"function"==typeof u&&n.push(Et.properties),"strict"!==o&&n.push(Et.allOf),(t={spec:e,context:{baseDoc:m},plugins:n,allowMetaPatches:a,pathDiscriminator:s,parameterMacro:c,modelPropertyMacro:u,useCircularStructures:h},new xt(t).dispatch()).then(f?function(){var e=R()(C.a.mark(function e(t){return C.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",t);case 1:case"end":return e.stop()}},e)}));return function(t){return e.apply(this,arguments)}}():Mt)}}var Dt=n(16),Lt=n.n(Dt);function Ut(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function qt(e){for(var t=1;t2&&void 0!==m[2]?m[2]:{},o=r.returnEntireTree,i=r.baseDoc,a=r.requestInterceptor,s=r.responseInterceptor,u=r.parameterMacro,c=r.modelPropertyMacro,l=r.useCircularStructures,p={pathDiscriminator:n,baseDoc:i,requestInterceptor:a,responseInterceptor:s,parameterMacro:u,modelPropertyMacro:c,useCircularStructures:l},f=Mt({spec:t}),h=f.spec,e.next=6,Rt(qt({},p,{spec:h,allowMetaPatches:!0,skipNormalization:!0}));case 6:return d=e.sent,!o&&M()(n)&&n.length&&(d.spec=Lt()(d.spec,n)||null),e.abrupt("return",d);case 9:case"end":return e.stop()}},e)}))).apply(this,arguments)}var zt=n(38),Bt=n.n(zt);function Vt(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function Ht(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:{};return function(t){var n=t.pathName,r=t.method,o=t.operationId;return function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.execute(Ht({spec:e.spec},Bt()(e,"requestInterceptor","responseInterceptor","userFetch"),{pathName:n,method:r,parameters:t,operationId:o},i))}}}};var Kt=n(39),Gt=n.n(Kt),$t=n(40),Zt=n.n($t),Xt=n(41),Qt=n.n(Xt),en=n(19),tn=n.n(en),nn=n(42),rn=n.n(nn),on={body:function(e){var t=e.req,n=e.value;t.body=n},header:function(e){var t=e.req,n=e.parameter,r=e.value;t.headers=t.headers||{},void 0!==r&&(t.headers[n.name]=r)},query:function(e){var t=e.req,n=e.value,r=e.parameter;t.query=t.query||{},!1===n&&"boolean"===r.type&&(n="false");0===n&&["number","integer"].indexOf(r.type)>-1&&(n="0");if(n)t.query[r.name]={collectionFormat:r.collectionFormat,value:n};else if(r.allowEmptyValue&&void 0!==n){var o=r.name;t.query[o]=t.query[o]||{},t.query[o].allowEmptyValue=!0}},path:function(e){var t=e.req,n=e.value,r=e.parameter;t.url=t.url.split("{".concat(r.name,"}")).join(encodeURIComponent(n))},formData:function(e){var t=e.req,n=e.value,r=e.parameter;(n||r.allowEmptyValue)&&(t.form=t.form||{},t.form[r.name]={value:n,allowEmptyValue:r.allowEmptyValue,collectionFormat:r.collectionFormat})}};n(49);var an=n(43),sn=n.n(an),un=n(44),cn=function(e){return":/?#[]@!$&'()*+,;=".indexOf(e)>-1},ln=function(e){return/^[a-z0-9\-._~]+$/i.test(e)};function pn(e){var t=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).escape,n=arguments.length>2?arguments[2]:void 0;return"number"==typeof e&&(e=e.toString()),"string"==typeof e&&e.length&&t?n?JSON.parse(e):Object(un.stringToCharArray)(e).map(function(e){return ln(e)?e:cn(e)&&"unsafe"===t?e:(sn()(e)||[]).map(function(e){return"0".concat(e.toString(16).toUpperCase()).slice(-2)}).map(function(e){return"%".concat(e)}).join("")}).join(""):e}function fn(e){var t=e.value;return M()(t)?function(e){var t=e.key,n=e.value,r=e.style,o=e.explode,i=e.escape,a=function(e){return pn(e,{escape:i})};if("simple"===r)return n.map(function(e){return a(e)}).join(",");if("label"===r)return".".concat(n.map(function(e){return a(e)}).join("."));if("matrix"===r)return n.map(function(e){return a(e)}).reduce(function(e,n){return!e||o?"".concat(e||"",";").concat(t,"=").concat(n):"".concat(e,",").concat(n)},"");if("form"===r){var s=o?"&".concat(t,"="):",";return n.map(function(e){return a(e)}).join(s)}if("spaceDelimited"===r){var u=o?"".concat(t,"="):"";return n.map(function(e){return a(e)}).join(" ".concat(u))}if("pipeDelimited"===r){var c=o?"".concat(t,"="):"";return n.map(function(e){return a(e)}).join("|".concat(c))}}(e):"object"===P()(t)?function(e){var t=e.key,n=e.value,r=e.style,o=e.explode,i=e.escape,a=function(e){return pn(e,{escape:i})},s=m()(n);if("simple"===r)return s.reduce(function(e,t){var r=a(n[t]),i=o?"=":",",s=e?"".concat(e,","):"";return"".concat(s).concat(t).concat(i).concat(r)},"");if("label"===r)return s.reduce(function(e,t){var r=a(n[t]),i=o?"=":".",s=e?"".concat(e,"."):".";return"".concat(s).concat(t).concat(i).concat(r)},"");if("matrix"===r&&o)return s.reduce(function(e,t){var r=a(n[t]),o=e?"".concat(e,";"):";";return"".concat(o).concat(t,"=").concat(r)},"");if("matrix"===r)return s.reduce(function(e,r){var o=a(n[r]),i=e?"".concat(e,","):";".concat(t,"=");return"".concat(i).concat(r,",").concat(o)},"");if("form"===r)return s.reduce(function(e,t){var r=a(n[t]),i=e?"".concat(e).concat(o?"&":","):"",s=o?"=":",";return"".concat(i).concat(t).concat(s).concat(r)},"")}(e):function(e){var t=e.key,n=e.value,r=e.style,o=e.escape,i=function(e){return pn(e,{escape:o})};if("simple"===r)return i(n);if("label"===r)return".".concat(i(n));if("matrix"===r)return";".concat(t,"=").concat(i(n));if("form"===r)return i(n);if("deepObject"===r)return i(n)}(e)}function hn(e,t){return t.includes("application/json")?"string"==typeof e?e:T()(e):e.toString()}function dn(e){var t=e.req,n=e.value,r=e.parameter,o=r.name,i=r.style,a=r.explode,s=r.content;if(s){var u=m()(s)[0];t.url=t.url.split("{".concat(o,"}")).join(pn(hn(n,u),{escape:!0}))}else{var c=fn({key:r.name,value:n,style:i||"simple",explode:a||!1,escape:!0});t.url=t.url.split("{".concat(o,"}")).join(c)}}function mn(e){var t=e.req,n=e.value,r=e.parameter;if(t.query=t.query||{},r.content){var o=m()(r.content)[0];t.query[r.name]=hn(n,o)}else if(!1===n&&(n="false"),0===n&&(n="0"),n){var i=P()(n);if("deepObject"===r.style)m()(n).forEach(function(e){var o=n[e];t.query["".concat(r.name,"[").concat(e,"]")]={value:fn({key:e,value:o,style:"deepObject",escape:r.allowReserved?"unsafe":"reserved"}),skipEncoding:!0}});else if("object"!==i||M()(n)||"form"!==r.style&&r.style||!r.explode&&void 0!==r.explode)t.query[r.name]={value:fn({key:r.name,value:n,style:r.style||"form",explode:void 0===r.explode||r.explode,escape:r.allowReserved?"unsafe":"reserved"}),skipEncoding:!0};else{m()(n).forEach(function(e){var o=n[e];t.query[e]={value:fn({key:e,value:o,style:r.style||"form",escape:r.allowReserved?"unsafe":"reserved"}),skipEncoding:!0}})}}else if(r.allowEmptyValue&&void 0!==n){var a=r.name;t.query[a]=t.query[a]||{},t.query[a].allowEmptyValue=!0}}var vn=["accept","authorization","content-type"];function gn(e){var t=e.req,n=e.parameter,r=e.value;if(t.headers=t.headers||{},!(vn.indexOf(n.name.toLowerCase())>-1))if(n.content){var o=m()(n.content)[0];t.headers[n.name]=hn(r,o)}else void 0!==r&&(t.headers[n.name]=fn({key:n.name,value:r,style:n.style||"simple",explode:void 0!==n.explode&&n.explode,escape:!1}))}function yn(e){var t=e.req,n=e.parameter,r=e.value;t.headers=t.headers||{};var o=P()(r);if(n.content){var i=m()(n.content)[0];t.headers.Cookie="".concat(n.name,"=").concat(hn(r,i))}else if("undefined"!==o){var a="object"===o&&!M()(r)&&n.explode?"":"".concat(n.name,"=");t.headers.Cookie=a+fn({key:n.name,value:r,escape:!1,style:n.style||"form",explode:void 0!==n.explode&&n.explode})}}var bn=n(30),_n=function(e,t){var n=e.operation,r=e.requestBody,o=e.securities,i=e.spec,a=e.attachContentTypeForEmptyPayload,s=e.requestContentType;t=function(e){var t=e.request,n=e.securities,r=void 0===n?{}:n,o=e.operation,i=void 0===o?{}:o,a=e.spec,s=b()({},t),u=r.authorized,c=void 0===u?{}:u,l=i.security||a.security||[],p=c&&!!m()(c).length,f=Lt()(a,["components","securitySchemes"])||{};if(s.headers=s.headers||{},s.query=s.query||{},!m()(r).length||!p||!l||M()(i.security)&&!i.security.length)return t;return l.forEach(function(e,t){for(var n in e){var r=c[n],o=f[n];if(r){var i=r.value||r,a=o.type;if(r)if("apiKey"===a)"query"===o.in&&(s.query[o.name]=i),"header"===o.in&&(s.headers[o.name]=i),"cookie"===o.in&&(s.cookies[o.name]=i);else if("http"===a){if("basic"===o.scheme){var u=i.username,l=i.password,p=tn()("".concat(u,":").concat(l));s.headers.Authorization="Basic ".concat(p)}"bearer"===o.scheme&&(s.headers.Authorization="Bearer ".concat(i))}else if("oauth2"===a){var h=r.token||{},d=h.access_token,m=h.token_type;m&&"bearer"!==m.toLowerCase()||(m="Bearer"),s.headers.Authorization="".concat(m," ").concat(d)}}}}),s}({request:t,securities:o,operation:n,spec:i});var u=n.requestBody||{},c=m()(u.content||{}),l=s&&c.indexOf(s)>-1;if(r||a){if(s&&l)t.headers["Content-Type"]=s;else if(!s){var p=c[0];p&&(t.headers["Content-Type"]=p,s=p)}}else s&&l&&(t.headers["Content-Type"]=s);return r&&(s?c.indexOf(s)>-1&&("application/x-www-form-urlencoded"===s||0===s.indexOf("multipart/")?"object"===P()(r)?(t.form={},m()(r).forEach(function(e){var n,o,i=r[e];"undefined"!=typeof File&&(o=i instanceof File),"undefined"!=typeof Blob&&(o=o||i instanceof Blob),void 0!==bn.Buffer&&(o=o||bn.Buffer.isBuffer(i)),n="object"!==P()(i)||o?i:M()(i)?i.toString():T()(i),t.form[e]={value:n}})):t.form=r:t.body=r):t.body=r),t};var wn=function(e,t){var n=e.spec,r=e.operation,o=e.securities,i=e.requestContentType,a=e.attachContentTypeForEmptyPayload;if((t=function(e){var t=e.request,n=e.securities,r=void 0===n?{}:n,o=e.operation,i=void 0===o?{}:o,a=e.spec,s=b()({},t),u=r.authorized,c=void 0===u?{}:u,l=r.specSecurity,p=void 0===l?[]:l,f=i.security||p,h=c&&!!m()(c).length,d=a.securityDefinitions;if(s.headers=s.headers||{},s.query=s.query||{},!m()(r).length||!h||!f||M()(i.security)&&!i.security.length)return t;return f.forEach(function(e,t){for(var n in e){var r=c[n];if(r){var o=r.token,i=r.value||r,a=d[n],u=a.type,l=a["x-tokenName"]||"access_token",p=o&&o[l],f=o&&o.token_type;if(r)if("apiKey"===u){var h="query"===a.in?"query":"headers";s[h]=s[h]||{},s[h][a.name]=i}else"basic"===u?i.header?s.headers.authorization=i.header:(i.base64=tn()("".concat(i.username,":").concat(i.password)),s.headers.authorization="Basic ".concat(i.base64)):"oauth2"===u&&p&&(f=f&&"bearer"!==f.toLowerCase()?f:"Bearer",s.headers.authorization="".concat(f," ").concat(p))}}}),s}({request:t,securities:o,operation:r,spec:n})).body||t.form||a)i?t.headers["Content-Type"]=i:M()(r.consumes)?t.headers["Content-Type"]=r.consumes[0]:M()(n.consumes)?t.headers["Content-Type"]=n.consumes[0]:r.parameters&&r.parameters.filter(function(e){return"file"===e.type}).length?t.headers["Content-Type"]="multipart/form-data":r.parameters&&r.parameters.filter(function(e){return"formData"===e.in}).length&&(t.headers["Content-Type"]="application/x-www-form-urlencoded");else if(i){var s=r.parameters&&r.parameters.filter(function(e){return"body"===e.in}).length>0,u=r.parameters&&r.parameters.filter(function(e){return"formData"===e.in}).length>0;(s||u)&&(t.headers["Content-Type"]=i)}return t};function xn(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function En(e){for(var t=1;t-1&&(c=o,l=u[p.indexOf(o)])}if(!c&&u&&u.length&&(c=u[0].url,l=u[0]),c.indexOf("{")>-1){var f=function(e){for(var t,n=[],r=/{([^}]+)}/g;t=r.exec(e);)n.push(t[1]);return n}(c);f.forEach(function(e){if(l.variables&&l.variables[e]){var t=l.variables[e],n=s[e]||t.default,r=new RegExp("{".concat(e,"}"),"g");c=c.replace(r,n)}})}return function(){var e,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=E.a.parse(t),o=E.a.parse(n),i=jn(r.protocol)||jn(o.protocol)||"",a=r.host||o.host,s=r.pathname||"";return"/"===(e=i&&a?"".concat(i,"://").concat(a+s):s)[e.length-1]?e.slice(0,-1):e}(c,i)}(b):function(e){var t,n=e.spec,r=e.scheme,o=e.contextUrl,i=void 0===o?"":o,a=E.a.parse(i),s=M()(n.schemes)?n.schemes[0]:null,u=r||s||jn(a.protocol)||"http",c=n.host||a.host||"",l=n.basePath||"";return"/"===(t=u&&c?"".concat(u,"://").concat(c+l):l)[t.length-1]?t.slice(0,-1):t}(b),!n)return delete g.cookies,g;g.url+=S,g.method="".concat(x).toUpperCase(),h=h||{};var C=t.paths[S]||{};o&&(g.headers.accept=o);var k=On([].concat(Sn(w.parameters)).concat(Sn(C.parameters)));k.forEach(function(e){var n,r=d[e.in];if("body"===e.in&&e.schema&&e.schema.properties&&(n=h),void 0===(n=e&&e.name&&h[e.name])?n=e&&e.name&&h["".concat(e.in,".").concat(e.name)]:kn(e.name,k).length>1&&console.warn("Parameter '".concat(e.name,"' is ambiguous because the defined spec has more than one parameter with the name: '").concat(e.name,"' and the passed-in parameter values did not define an 'in' value.")),null!==n){if(void 0!==e.default&&void 0===n&&(n=e.default),void 0===n&&e.required&&!e.allowEmptyValue)throw new Error("Required parameter ".concat(e.name," is not provided"));if(v&&e.schema&&"object"===e.schema.type&&"string"==typeof n)try{n=JSON.parse(n)}catch(e){throw new Error("Could not parse object parameter value string as JSON")}r&&r({req:g,parameter:e,value:n,operation:w,spec:t})}});var O=En({},e,{operation:w});if((g=v?_n(O,g):wn(O,g)).cookies&&m()(g.cookies).length){var A=m()(g.cookies).reduce(function(e,t){var n=g.cookies[t];return e+(e?"&":"")+rn.a.serialize(t,n)},"");g.headers.Cookie=A}return g.cookies&&delete g.cookies,Z(g),g}var jn=function(e){return e?e.replace(/\W/g,""):null};function Pn(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function In(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("string"==typeof e?n.url=e:n=e,!(this instanceof In))return new In(n);b()(this,n);var r=this.resolve().then(function(){return t.disableInterfaces||b()(t,In.makeApisTagOperation(t)),t});return r.client=this,r}In.http=V,In.makeHttp=function(e,t,n){return n=n||function(e){return e},t=t||function(e){return e},function(r){return"string"==typeof r&&(r={url:r}),B.mergeInQueryOrForm(r),r=t(r),n(e(r))}}.bind(null,In.http),In.resolve=Rt,In.resolveSubtree=function(e,t){return Ft.apply(this,arguments)},In.execute=function(e){var t=e.http,n=e.fetch,r=e.spec,o=e.operationId,i=e.pathName,a=e.method,s=e.parameters,u=e.securities,c=Gt()(e,["http","fetch","spec","operationId","pathName","method","parameters","securities"]),l=t||n||V;i&&a&&!o&&(o=jt(i,a));var p=An.buildRequest(En({spec:r,operationId:o,parameters:s,securities:u,http:l},c));return p.body&&(Zt()(p.body)||Qt()(p.body))&&(p.body=T()(p.body)),l(p)},In.serializeRes=J,In.serializeHeaders=Y,In.clearCache=function(){Et.refs.clearCache()},In.makeApisTagOperation=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=Yt.makeExecute(e);return{apis:Yt.mapTagOperations({v2OperationIdCompatibilityMode:e.v2OperationIdCompatibilityMode,spec:e.spec,cb:t})}},In.buildRequest=Tn,In.helpers={opId:Tt},In.prototype={http:V,execute:function(e){return this.applyDefaults(),In.execute(function(e){for(var t=1;t + * @license MIT + */ +var r=n(558),o=n(559),i=n(350);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return z(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return B(e).length;default:if(r)return z(e).length;t=(""+t).toLowerCase(),r=!0}}function m(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return j(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return A(this,t,n);case"latin1":case"binary":return T(this,t,n);case"base64":return C(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return P(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function v(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function g(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:y(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var p=!0,f=0;fo&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function C(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+p<=n)switch(p){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,p=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=p}return function(e){var t=e.length;if(t<=O)return String.fromCharCode.apply(String,e);var n="",r=0;for(;r0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),p=0;po)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return _(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return x(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var O=4096;function A(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function N(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function R(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function D(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function L(e,t,n,r,i){return i||D(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||D(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||I(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||I(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||I(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||I(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||I(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||I(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||I(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||I(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||I(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||I(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||I(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||I(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||I(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||I(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||I(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||I(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):N(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):R(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):N(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):R(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return L(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return L(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function B(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(q,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function V(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(41))},function(e,t,n){"use strict";e.exports={current:null}},function(e,t){e.exports=function(e){return null!=e&&"object"==typeof e}},function(e,t,n){"use strict";var r=n(25),o=n(88),i=n(54),a=(n(23),["dispatchConfig","_targetInst","nativeEvent","isDefaultPrevented","isPropagationStopped","_dispatchListeners","_dispatchInstances"]),s={type:null,target:null,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};function u(e,t,n,r){this.dispatchConfig=e,this._targetInst=t,this.nativeEvent=n;var o=this.constructor.Interface;for(var a in o)if(o.hasOwnProperty(a)){0;var s=o[a];s?this[a]=s(n):"target"===a?this.target=r:this[a]=n[a]}var u=null!=n.defaultPrevented?n.defaultPrevented:!1===n.returnValue;return this.isDefaultPrevented=u?i.thatReturnsTrue:i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse,this}r(u.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=i.thatReturnsTrue)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=i.thatReturnsTrue)},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var e=this.constructor.Interface;for(var t in e)this[t]=null;for(var n=0;n0&&"/"!==t[0]});function oe(e,t,n){return t=t||[],te.apply(void 0,[e].concat(u()(t))).get("parameters",Object(p.List)()).reduce(function(e,t){var r=n&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set(Object(l.z)(t,{allowHashes:!1}),r)},Object(p.fromJS)({}))}function ie(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(p.List.isList(e))return e.some(function(e){return p.Map.isMap(e)&&e.get("in")===t})}function ae(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(p.List.isList(e))return e.some(function(e){return p.Map.isMap(e)&&e.get("type")===t})}function se(e,t){t=t||[];var n=x(e).getIn(["paths"].concat(u()(t)),Object(p.fromJS)({})),r=e.getIn(["meta","paths"].concat(u()(t)),Object(p.fromJS)({})),o=ue(e,t),i=n.get("parameters")||new p.List,a=r.get("consumes_value")?r.get("consumes_value"):ae(i,"file")?"multipart/form-data":ae(i,"formData")?"application/x-www-form-urlencoded":void 0;return Object(p.fromJS)({requestContentType:a,responseContentType:o})}function ue(e,t){t=t||[];var n=x(e).getIn(["paths"].concat(u()(t)),null);if(null!==n){var r=e.getIn(["meta","paths"].concat(u()(t),["produces_value"]),null),o=n.getIn(["produces",0],null);return r||o||"application/json"}}function ce(e,t){t=t||[];var n=x(e),r=n.getIn(["paths"].concat(u()(t)),null);if(null!==r){var o=t,i=a()(o,1)[0],s=r.get("produces",null),c=n.getIn(["paths",i,"produces"],null),l=n.getIn(["produces"],null);return s||c||l}}function le(e,t){t=t||[];var n=x(e),r=n.getIn(["paths"].concat(u()(t)),null);if(null!==r){var o=t,i=a()(o,1)[0],s=r.get("consumes",null),c=n.getIn(["paths",i,"consumes"],null),l=n.getIn(["consumes"],null);return s||c||l}}var pe=function(e,t,n){var r=e.get("url").match(/^([a-z][a-z0-9+\-.]*):/),i=o()(r)?r[1]:null;return e.getIn(["scheme",t,n])||e.getIn(["scheme","_defaultScheme"])||i||""},fe=function(e,t,n){return["http","https"].indexOf(pe(e,t,n))>-1},he=function(e,t){t=t||[];var n=e.getIn(["meta","paths"].concat(u()(t),["parameters"]),Object(p.fromJS)([])),r=!0;return n.forEach(function(e){var t=e.get("errors");t&&t.count()&&(r=!1)}),r};function de(e){return p.Map.isMap(e)?e:new p.Map}},function(e,t,n){"use strict";n.r(t),n.d(t,"SHOW_AUTH_POPUP",function(){return d}),n.d(t,"AUTHORIZE",function(){return m}),n.d(t,"LOGOUT",function(){return v}),n.d(t,"PRE_AUTHORIZE_OAUTH2",function(){return g}),n.d(t,"AUTHORIZE_OAUTH2",function(){return y}),n.d(t,"VALIDATE",function(){return b}),n.d(t,"CONFIGURE_AUTH",function(){return _}),n.d(t,"showDefinitions",function(){return w}),n.d(t,"authorize",function(){return x}),n.d(t,"logout",function(){return E}),n.d(t,"preAuthorizeImplicit",function(){return S}),n.d(t,"authorizeOauth2",function(){return C}),n.d(t,"authorizePassword",function(){return k}),n.d(t,"authorizeApplication",function(){return O}),n.d(t,"authorizeAccessCodeWithFormParams",function(){return A}),n.d(t,"authorizeAccessCodeWithBasicAuthentication",function(){return T}),n.d(t,"authorizeRequest",function(){return j}),n.d(t,"configureAuth",function(){return P});var r=n(26),o=n.n(r),i=n(16),a=n.n(i),s=n(28),u=n.n(s),c=n(93),l=n.n(c),p=n(18),f=n.n(p),h=n(3),d="show_popup",m="authorize",v="logout",g="pre_authorize_oauth2",y="authorize_oauth2",b="validate",_="configure_auth";function w(e){return{type:d,payload:e}}function x(e){return{type:m,payload:e}}function E(e){return{type:v,payload:e}}var S=function(e){return function(t){var n=t.authActions,r=t.errActions,o=e.auth,i=e.token,a=e.isValid,s=o.schema,c=o.name,l=s.get("flow");delete f.a.swaggerUIRedirectOauth2,"accessCode"===l||a||r.newAuthErr({authId:c,source:"auth",level:"warning",message:"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"}),i.error?r.newAuthErr({authId:c,source:"auth",level:"error",message:u()(i)}):n.authorizeOauth2({auth:o,token:i})}};function C(e){return{type:y,payload:e}}var k=function(e){return function(t){var n=t.authActions,r=e.schema,o=e.name,i=e.username,s=e.password,u=e.passwordType,c=e.clientId,l=e.clientSecret,p={grant_type:"password",scope:e.scopes.join(" "),username:i,password:s},f={};switch(u){case"request-body":!function(e,t,n){t&&a()(e,{client_id:t});n&&a()(e,{client_secret:n})}(p,c,l);break;case"basic":f.Authorization="Basic "+Object(h.a)(c+":"+l);break;default:console.warn("Warning: invalid passwordType ".concat(u," was passed, not including client id and secret"))}return n.authorizeRequest({body:Object(h.b)(p),url:r.get("tokenUrl"),name:o,headers:f,query:{},auth:e})}};var O=function(e){return function(t){var n=t.authActions,r=e.schema,o=e.scopes,i=e.name,a=e.clientId,s=e.clientSecret,u={Authorization:"Basic "+Object(h.a)(a+":"+s)},c={grant_type:"client_credentials",scope:o.join(" ")};return n.authorizeRequest({body:Object(h.b)(c),name:i,url:r.get("tokenUrl"),auth:e,headers:u})}},A=function(e){var t=e.auth,n=e.redirectUrl;return function(e){var r=e.authActions,o=t.schema,i=t.name,a=t.clientId,s=t.clientSecret,u={grant_type:"authorization_code",code:t.code,client_id:a,client_secret:s,redirect_uri:n};return r.authorizeRequest({body:Object(h.b)(u),name:i,url:o.get("tokenUrl"),auth:t})}},T=function(e){var t=e.auth,n=e.redirectUrl;return function(e){var r=e.authActions,o=t.schema,i=t.name,a=t.clientId,s=t.clientSecret,u={Authorization:"Basic "+Object(h.a)(a+":"+s)},c={grant_type:"authorization_code",code:t.code,client_id:a,redirect_uri:n};return r.authorizeRequest({body:Object(h.b)(c),name:i,url:o.get("tokenUrl"),auth:t,headers:u})}},j=function(e){return function(t){var n,r=t.fn,i=t.getConfigs,s=t.authActions,c=t.errActions,p=t.oas3Selectors,f=t.specSelectors,h=t.authSelectors,d=e.body,m=e.query,v=void 0===m?{}:m,g=e.headers,y=void 0===g?{}:g,b=e.name,_=e.url,w=e.auth,x=(h.getConfigs()||{}).additionalQueryStringParams;n=f.isOAS3()?l()(_,p.selectedServer(),!0):l()(_,f.url(),!0),"object"===o()(x)&&(n.query=a()({},n.query,x));var E=n.toString(),S=a()({Accept:"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"},y);r.fetch({url:E,method:"post",headers:S,query:v,body:d,requestInterceptor:i().requestInterceptor,responseInterceptor:i().responseInterceptor}).then(function(e){var t=JSON.parse(e.data),n=t&&(t.error||""),r=t&&(t.parseError||"");e.ok?n||r?c.newAuthErr({authId:b,level:"error",source:"auth",message:u()(t)}):s.authorizeOauth2({auth:w,token:t}):c.newAuthErr({authId:b,level:"error",source:"auth",message:e.statusText})}).catch(function(e){var t=new Error(e).message;if(e.response&&e.response.data){var n=e.response.data;try{var r="string"==typeof n?JSON.parse(n):n;r.error&&(t+=", error: ".concat(r.error)),r.error_description&&(t+=", description: ".concat(r.error_description))}catch(e){}}c.newAuthErr({authId:b,level:"error",source:"auth",message:t})})}};function P(e){return{type:_,payload:e}}},function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(203),o=n(202);e.exports=function(e){return r(o(e))}},function(e,t,n){var r=n(47),o=n(130);e.exports=n(45)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t){var n,r,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function s(e){if(n===setTimeout)return setTimeout(e,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(e){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(e){r=a}}();var u,c=[],l=!1,p=-1;function f(){l&&u&&(l=!1,u.length?c=u.concat(c):p=-1,c.length&&h())}function h(){if(!l){var e=s(f);l=!0;for(var t=c.length;t;){for(u=c,c=[];++p1)for(var n=1;n1&&void 0!==arguments[1])||arguments[1];return e=Object(r.u)(e),{type:s,payload:{thing:e,shown:t}}}function p(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=Object(r.u)(e),{type:a,payload:{thing:e,mode:t}}}},function(e,t,n){"use strict";(function(t){ +/*! + * @description Recursive object extending + * @author Viacheslav Lotsmanov + * @license MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2018 Viacheslav Lotsmanov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +function n(e){return e instanceof t||e instanceof Date||e instanceof RegExp}function r(e){if(e instanceof t){var n=t.alloc?t.alloc(e.length):new t(e.length);return e.copy(n),n}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e);throw new Error("Unexpected situation")}function o(e){var t=[];return e.forEach(function(e,i){"object"==typeof e&&null!==e?Array.isArray(e)?t[i]=o(e):n(e)?t[i]=r(e):t[i]=a({},e):t[i]=e}),t}function i(e,t){return"__proto__"===t?void 0:e[t]}var a=e.exports=function(){if(arguments.length<1||"object"!=typeof arguments[0])return!1;if(arguments.length<2)return arguments[0];var e,t,s=arguments[0],u=Array.prototype.slice.call(arguments,1);return u.forEach(function(u){"object"!=typeof u||null===u||Array.isArray(u)||Object.keys(u).forEach(function(c){return t=i(s,c),(e=i(u,c))===s?void 0:"object"!=typeof e||null===e?void(s[c]=e):Array.isArray(e)?void(s[c]=o(e)):n(e)?void(s[c]=r(e)):"object"!=typeof t||null===t||Array.isArray(t)?void(s[c]=a({},e)):void(s[c]=a(t,e))})}),s}}).call(this,n(61).Buffer)},function(e,t,n){var r=n(147),o=n(329);e.exports=n(122)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(96);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t){var n=e.exports={version:"2.5.5"};"number"==typeof __e&&(__e=n)},function(e,t,n){var r=n(202);e.exports=function(e){return Object(r(e))}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var r=n(102),o=n(592),i=n(593),a="[object Null]",s="[object Undefined]",u=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?s:a:u&&u in Object(e)?o(e):i(e)}},function(e,t,n){var r=n(610),o=n(613);e.exports=function(e,t){var n=o(e,t);return r(n)?n:void 0}},function(e,t,n){var r=n(375),o=n(650),i=n(103);e.exports=function(e){return i(e)?r(e):o(e)}},function(e,t,n){"use strict";var r=n(174),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=p;var i=n(134);i.inherits=n(106);var a=n(385),s=n(232);i.inherits(p,a);for(var u=o(s.prototype),c=0;c=t.length?{value:void 0,done:!0}:(e=r(t,n),this._i+=e.length,{value:e,done:!1})})},function(e,t){e.exports={}},function(e,t,n){n(550);for(var r=n(32),o=n(71),i=n(98),a=n(34)("toStringTag"),s="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),u=0;u1){for(var d=Array(h),m=0;m1){for(var g=Array(v),y=0;yb;b++)if((v=t?y(a(d=e[b])[0],d[1]):y(e[b]))===c||v===l)return v}else for(m=g.call(e);!(d=m.next()).done;)if((v=o(m,y,d.value,t))===c||v===l)return v}).BREAK=c,t.RETURN=l},function(e,t,n){"use strict";function r(e){return null==e}e.exports.isNothing=r,e.exports.isObject=function(e){return"object"==typeof e&&null!==e},e.exports.toArray=function(e){return Array.isArray(e)?e:r(e)?[]:[e]},e.exports.repeat=function(e,t){var n,r="";for(n=0;n1&&void 0!==arguments[1]?arguments[1]:{},r=Object(i.y)(t),a=r.type,s=r.example,u=r.properties,c=r.additionalProperties,l=r.items,p=n.includeReadOnly,f=n.includeWriteOnly;if(void 0!==s)return Object(i.d)(s,"$$ref",function(e){return"string"==typeof e&&e.indexOf("#")>-1});if(!a)if(u)a="object";else{if(!l)return;a="array"}if("object"===a){var d=Object(i.y)(u),m={};for(var v in d)d[v]&&d[v].deprecated||d[v]&&d[v].readOnly&&!p||d[v]&&d[v].writeOnly&&!f||(m[v]=e(d[v],n));if(!0===c)m.additionalProp1={};else if(c)for(var g=Object(i.y)(c),y=e(g,n),b=1;b<4;b++)m["additionalProp"+b]=y;return m}return"array"===a?o()(l.anyOf)?l.anyOf.map(function(t){return e(t,n)}):o()(l.oneOf)?l.oneOf.map(function(t){return e(t,n)}):[e(l,n)]:t.enum?t.default?t.default:Object(i.u)(t.enum)[0]:"file"!==a?h(t):void 0},m=function(e){return e.schema&&(e=e.schema),e.properties&&(e.type="object"),e},v=function e(t){var n,r,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=p()({},Object(i.y)(t)),u=s.type,c=s.properties,l=s.additionalProperties,f=s.items,d=s.example,m=a.includeReadOnly,v=a.includeWriteOnly,g=s.default,y={},b={},_=t.xml,w=_.name,x=_.prefix,E=_.namespace,S=s.enum;if(!u)if(c||l)u="object";else{if(!f)return;u="array"}if(n=(x?x+":":"")+(w=w||"notagname"),E){var C=x?"xmlns:"+x:"xmlns";b[C]=E}if("array"===u&&f){if(f.xml=f.xml||_||{},f.xml.name=f.xml.name||_.name,_.wrapped)return y[n]=[],o()(d)?d.forEach(function(t){f.example=t,y[n].push(e(f,a))}):o()(g)?g.forEach(function(t){f.default=t,y[n].push(e(f,a))}):y[n]=[e(f,a)],b&&y[n].push({_attr:b}),y;var k=[];return o()(d)?(d.forEach(function(t){f.example=t,k.push(e(f,a))}),k):o()(g)?(g.forEach(function(t){f.default=t,k.push(e(f,a))}),k):e(f,a)}if("object"===u){var O=Object(i.y)(c);for(var A in y[n]=[],d=d||{},O)if(O.hasOwnProperty(A)&&(!O[A].readOnly||m)&&(!O[A].writeOnly||v))if(O[A].xml=O[A].xml||{},O[A].xml.attribute){var T=o()(O[A].enum)&&O[A].enum[0],j=O[A].example,P=O[A].default;b[O[A].xml.name||A]=void 0!==j&&j||void 0!==d[A]&&d[A]||void 0!==P&&P||T||h(O[A])}else{O[A].xml.name=O[A].xml.name||A,void 0===O[A].example&&void 0!==d[A]&&(O[A].example=d[A]);var I=e(O[A]);o()(I)?y[n]=y[n].concat(I):y[n].push(I)}return!0===l?y[n].push({additionalProp:"Anything can be here"}):l&&y[n].push({additionalProp:h(l)}),b&&y[n].push({_attr:b}),y}return r=void 0!==d?d:void 0!==g?g:o()(S)?S[0]:h(t),y[n]=b?[{_attr:b},r]:r,y};function g(e,t){var n=v(e,t);if(n)return s()(n,{declaration:!0,indent:"\t"})}var y=c()(g),b=c()(d)},function(e,t,n){"use strict";n.r(t),n.d(t,"UPDATE_CONFIGS",function(){return i}),n.d(t,"TOGGLE_CONFIGS",function(){return a}),n.d(t,"update",function(){return s}),n.d(t,"toggle",function(){return u}),n.d(t,"loaded",function(){return c});var r=n(2),o=n.n(r),i="configs_update",a="configs_toggle";function s(e,t){return{type:i,payload:o()({},e,t)}}function u(e){return{type:a,payload:e}}var c=function(){return function(){}}},function(e,t,n){"use strict";n.d(t,"a",function(){return a});var r=n(1),o=n.n(r),i=o.a.Set.of("type","format","items","default","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","maxItems","minItems","uniqueItems","enum","multipleOf");function a(e){var t=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).isOAS3;if(!o.a.Map.isMap(e))return o.a.Map();if(!t)return"body"===e.get("in")?e.get("schema",o.a.Map()):e.filter(function(e,t){return i.includes(t)});if(e.get("content")){var n=e.get("content",o.a.Map({})).keySeq();return e.getIn(["content",n.first(),"schema"],o.a.Map())}return e.get("schema",o.a.Map())}},function(e,t,n){e.exports=n(766)},function(e,t,n){"use strict";n.r(t);var r=n(463),o="object"==typeof self&&self&&self.Object===Object&&self,i=(r.a||o||Function("return this")()).Symbol,a=Object.prototype,s=a.hasOwnProperty,u=a.toString,c=i?i.toStringTag:void 0;var l=function(e){var t=s.call(e,c),n=e[c];try{e[c]=void 0;var r=!0}catch(e){}var o=u.call(e);return r&&(t?e[c]=n:delete e[c]),o},p=Object.prototype.toString;var f=function(e){return p.call(e)},h="[object Null]",d="[object Undefined]",m=i?i.toStringTag:void 0;var v=function(e){return null==e?void 0===e?d:h:m&&m in Object(e)?l(e):f(e)};var g=function(e,t){return function(n){return e(t(n))}}(Object.getPrototypeOf,Object);var y=function(e){return null!=e&&"object"==typeof e},b="[object Object]",_=Function.prototype,w=Object.prototype,x=_.toString,E=w.hasOwnProperty,S=x.call(Object);var C=function(e){if(!y(e)||v(e)!=b)return!1;var t=g(e);if(null===t)return!0;var n=E.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&x.call(n)==S},k=n(322),O={INIT:"@@redux/INIT"};function A(e,t,n){var r;if("function"==typeof t&&void 0===n&&(n=t,t=void 0),void 0!==n){if("function"!=typeof n)throw new Error("Expected the enhancer to be a function.");return n(A)(e,t)}if("function"!=typeof e)throw new Error("Expected the reducer to be a function.");var o=e,i=t,a=[],s=a,u=!1;function c(){s===a&&(s=a.slice())}function l(){return i}function p(e){if("function"!=typeof e)throw new Error("Expected listener to be a function.");var t=!0;return c(),s.push(e),function(){if(t){t=!1,c();var n=s.indexOf(e);s.splice(n,1)}}}function f(e){if(!C(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if(void 0===e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(u)throw new Error("Reducers may not dispatch actions.");try{u=!0,i=o(i,e)}finally{u=!1}for(var t=a=s,n=0;n0&&void 0!==arguments[0]?arguments[0]:{},t=arguments[1];if(a)throw a;for(var r=!1,o={},s=0;s0?o(r(e),9007199254740991):0}},function(e,t,n){var r=n(343),o=n(207);e.exports=Object.keys||function(e){return r(e,o)}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t){e.exports=!0},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var r=n(47).f,o=n(69),i=n(34)("toStringTag");e.exports=function(e,t,n){e&&!o(e=n?e:e.prototype,i)&&r(e,i,{configurable:!0,value:t})}},function(e,t,n){var r=n(155)("meta"),o=n(40),i=n(69),a=n(47).f,s=0,u=Object.isExtensible||function(){return!0},c=!n(80)(function(){return u(Object.preventExtensions({}))}),l=function(e){a(e,r,{value:{i:"O"+ ++s,w:{}}})},p=e.exports={KEY:r,NEED:!1,fastKey:function(e,t){if(!o(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!i(e,r)){if(!u(e))return"F";if(!t)return"E";l(e)}return e[r].i},getWeak:function(e,t){if(!i(e,r)){if(!u(e))return!0;if(!t)return!1;l(e)}return e[r].w},onFreeze:function(e){return c&&p.NEED&&u(e)&&!i(e,r)&&l(e),e}}},function(e,t,n){"use strict";e.exports=function(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r1&&void 0!==arguments[1]?arguments[1]:[],n={arrayBehaviour:(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).arrayBehaviour||"replace"},r=t.map(function(e){return e||{}}),i=e||{},c=0;c1?t-1:0),r=1;r0?r:n)(e)}},function(e,t,n){var r=n(151);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,o){return e.call(t,n,r,o)}}return function(){return e.apply(t,arguments)}}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var r=n(491),o=n(68);e.exports=function(e){return r(o(e))}},function(e,t,n){"use strict";var r=n(76),o=n(95),i=n(123),a=n(68),s=n(33);e.exports=function(e,t,n){var u=s(e),c=n(a,u,""[e]),l=c[0],p=c[1];i(function(){var t={};return t[u]=function(){return 7},7!=""[e](t)})&&(o(String.prototype,e,l),r(RegExp.prototype,u,2==t?function(e,t){return p.call(e,this,t)}:function(e){return p.call(e,this)}))}},function(e,t,n){var r=n(204),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+r).toString(36))}},function(e,t,n){var r=n(44),o=n(345),i=n(207),a=n(205)("IE_PROTO"),s=function(){},u=function(){var e,t=n(209)("iframe"),r=i.length;for(t.style.display="none",n(346).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" + + + + + + + + + + diff --git a/src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts b/src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts new file mode 100644 index 00000000..6c6750ad --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/jestGlobalMocks.ts @@ -0,0 +1,19 @@ +const mock = () => { + let storage = {}; + return { + getItem: (key) => (key in storage ? storage[key] : null), + setItem: (key, value) => (storage[key] = value || ''), + removeItem: (key) => delete storage[key], + clear: () => (storage = {}) + }; +}; + +Object.defineProperty(window, 'localStorage', { value: mock() }); +Object.defineProperty(window, 'sessionStorage', { value: mock() }); +Object.defineProperty(window, 'getComputedStyle', { + value: () => ({ + getPropertyValue: () => { + return ''; + } + }) +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf new file mode 100644 index 00000000..28d2665b --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.cs.xlf @@ -0,0 +1,4365 @@ + + + + + Toggle navigation + Zobraz./skrýt navigaci + + + Dashboard + Přehled + + + Cluster + Klastr + + + Hosts + Stroje + + + Monitors + Monitory + + + OSDs + OSD + + + Configuration + Nastavení + + + CRUSH map + CRUSH mapa + + + Manager modules + Moduly správy + + + Logs + Záznamy událostí + + + Alerts + Výstrahy + + + Silences + Silences + + + Pools + Fondy + + + Block + Blok + + + Images + Obrazy + + + Mirroring + Zrcadlení + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + Souborové systémy + + + Object Gateway + Objektová brána + + + Daemons + Procesy služeb + + + Users + Uživatelé + + + Buckets + Nádoby + + + Retrieving data + for + + + . Please wait... + + Získávají se data + pro + + + . Čekejte… + + + + Displaying previously cached data + + for + + + . + + Zobrazují se data + z mezipaměti + pro + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Nedaří se načíst dat + pro + + + . + Zkontrolujte zdraví klastru. + + + + Back + Zpět + + + Select a Language + Vyberte jazyk + + + Loading panel data... + Načítání údajů panelu… + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Nahlédněte do + dokumentace + , kde naleznete jak + nastavit a zapnout funkci monitorování. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Grafana přehled neexistuje. Podívejte se do + dokumentace + jak + přidat přehledy do Grafany. + + + + Grafana Time Picker + Grafana Time Picker + + + Reset Settings + Resetovat nastavení + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Data se nepodařilo načíst + + + selected + vybráno + X selected + + + found + nalezeno + X found + + + total + celkem + X total + + + Edit + Upravit + + + Name + Název + + + Description + Popis + + + Long description + Podrobnější popis + + + Default + Výchozí + + + Daemon default + Výchozí pro proces služby + + + Services + Služby + + + Values + Hodnoty + + + The entered value is too high! It must not be greater than + . + + Zadaná hodnota je příliš vysoká! Nemůže být vyšší než + . + + + + The entered value is too low! It must not be lower than + . + + Zadaná hodnota je příliš nízká! Nemůže být nižší než + . + + + + Save + Uložit + + + CRUSH map viewer + prohlížeč CRUSH mapy + + + Hosts List + Seznam strojů + + + Overall Performance + Celková výkonnost + + + No entries found + Nenalezeny žádné položky + + + Cluster Logs + Záznamy událostí v klastra + + + Audit Logs + Auditní záznamy událostí + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Načítání nastavení… + + + The configuration could not be loaded. + Toto nastavení se nepodařilo načíst. + + + Edit Manager module + Upravit modul správy + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + Zadaná hodnota není platné UUID, např.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + Je třeba, aby zadaná hodnota byla platnou IP adresou. + + + This field is required. + Tuto kolonku je třeba vyplnit. + + + The entered value is too high! It must be lower or equal to + . + + The entered value is too high! It must be lower or equal to + . + + + + The entered value is too low! It must be greater or equal to + . + + The entered value is too low! It must be greater or equal to + . + + + + The entered value needs to be a number. + Je třeba, aby zadaná hodnota byla číslo. + + + The entered value needs to be a number or decimal. + Je třeba, aby zadaná hodnota byla číslo nebo desítkové. + + + Update + Aktualizovat + + + Status + Stav + + + Cluster ID + Identif. kastru + + + monmap modified + mapa monitorů změněna + + + monmap epoch + monmap epocha + + + quorum con + kvórum spojení + + + quorum mon + kvórum monitor + + + required con + vyžadováno spojení + + + required mon + vyžadováno monitorů + + + In Quorum + V kvóru + + + Not In Quorum + Není v kvóru + + + Cancel + Storno + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + Opravdu chcete označené + + ? + + + + Yes, I am sure. + Ano, opravdu to chci. + + + Cluster-wide OSD Flags + Příznaky OSD pro celý klastr + + + Submit + Odeslat + + + + + + + + + + + form title + + + Advanced... + Pokročilé… + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + Priorita obnovení OSD + + + Priority + Priorita + + + Customize priority values + Přizpůsobit hodnoty priority + + + This field is required! + Tuto kolonku je třeba vyplnit! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + Zadaná hodnota je příliš vysoká, je třeba, aby nebyla vyšší než + . + + + + The entered value is too low! It must not be lower than + . + + Zadaná hodnota je příliš nízká! Je třeba, aby byla nižší než + . + + + + Reweight OSD + Znovu vyvážit OSD + + + The value needs to be between 0 and 1. + Je třeba, aby hodnota byla mezi 0 a 1. + + + Reweight + Znovu vyvážit + + + OSDs + Scrub + + OSD + kontrola + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, vybrat, 1 {Deep } } + + + You are about to apply a + scrub to + the OSD + + + . + + Chystáte se použít kontrolu na + scrub to + OSD + + + . + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, vybrat, 1 {deep } } + + + OSDs List + Seznam OSD + + + + OSD + + will be marked + + + if you proceed. + + Pokud budete pokračovat, + OSD + + + + + bude označeno + + + + The OSD is not safe to destroy! + OSD není možné bezpečně zlikvidovat! + + + + OSD + + will be + + + if you proceed. + + Pokud budete pokračovat, + OSD + + bude + + + . + + + + Details + Podrobnosti + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Hodnota + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Zavřít + + + Delete + Smazat + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Zdraví + + + Statistics + Statistiky + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Ohledně nastavení a zapnutí funkce správy NFS Ganesha nahlédněte do + dokumentace + + + + + Clients + Klienti + + + Any client can access + Přistupovat může libovolný klient + + + Addresses + Adresy + + + Required field + Vyžadovaná kolonka + + + Must contain one or more comma-separated values + Je třeba, aby obsahovalo jednu nebo více čárkou oddělovaných hodnot + + + For example: + Například: + + + Access Type + Typ přístupu + + + Squash + Squash + + + Add clients + Přidat klienty + + + Loading... + Načítání… + + + -- No cluster available -- + -- Žádný klastr k dispozici -- + + + -- Select the cluster -- + -- Vyberte klastr -- + + + Add daemon + Přidat proces služby + + + Storage Backend + Podpůrná vrstva úložiště + + + -- No data pools available -- + -- Žádné fondy k dispozici -- + + + -- Select the storage backend -- + -- Vyberte podpůrnou vrstvu úložiště -- + + + Object Gateway User + Uživatel objektové brány + + + -- No users available -- + -- Žádní uživatelé k dispozici -- + + + -- Select the object gateway user -- + -- Vyberte uživatele brány objektů -- + + + CephFS User ID + Identif. uživatele CephFS + + + -- No clients available -- + -- Žádní klienti k dispozici -- + + + -- Select the cephx client -- + -- Vyberte cephx klienta -- + + + CephFS Name + Název CephFS + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Security Label + + + Enable security label + Enable security label + + + CephFS Path + Popis umístění CephFS + + + Path need to start with a '/' and can be followed by a word + Je třeba, aby popis umístění začínal na „/“, za kterým následuje slovo + + + New directory will be created + Bude vytvořena nová složka + + + Path + Popis umístění + + + Path can only be a single '/' or a word + Popis umístění může být pouze jediné „/“ nebo slovo + + + New bucket will be created + Bude vytvořena nová nádoba + + + NFS Protocol + NFS protokol + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + NFS štítek + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Alternativní přístup pro + NFS v3 + připojení (nemůže začínat na /). + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + + + By using different Tag options, the same Path may be exported multiple times. + By using different Tag options, the same Path may be exported multiple times. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + + + By using different Pseudo options, the same Path may be exported multiple times. + By using different Pseudo options, the same Path may be exported multiple times. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- Žádný typ přístupu k dispozici -- + + + -- Select the access type -- + -- Vyberte typ přístupu -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- No squash available -- + + + --Select what kind of user id squashing is performed -- + --Select what kind of user id squashing is performed -- + + + Transport Protocol + Transportní protokol + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Vítejte v Ceph! + The welcome message on the login page + + + Username is required + Je třeba vyplnit uživatelské jméno + + + Password is required + Je třeba vyplnit heslo + + + Login + Přihlásit + + + Sorry, the user does not exist in Ceph. + Je nám líto, uživatel v Ceph neexistuje. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Vrátit se na + Přihlašovací stránku + . Budete odhlášeni od poskytovatele identity když se pokusíte znovu přihlásit. + + + + Forbidden + Odepřeno + + + Sorry, you are not allowed to see what you were looking for. + Omlouváme se, ale nemáte oprávnění zobrazit to, po čem se poohlížíte. + + + Sorry, we could not find what you were looking for + Omlouváme se, nepodařilo se najít to, po čem se poohlížíte + + + Remove all + Odebrat vše + + + Recent Notifications + Nedávná oznámení + + + There are no background tasks. + Nejsou zde žádné úlohy na pozadí. + + + Background Tasks + Úlohy na pozadí + + + Help + Nápověda + + + Documentation + Dokumentace + + + API + Aplikační program. rozhraní + + + About + O aplikaci + + + Dashboard Settings + Nastavení přehledu + + + User management + Správa uživatelů + + + Logged in user + Přihlášený uživatel + + + Signed in as + + + + + Přihlášeni jako + + + + + + + Sign out + Odhlásit + + + Name... + Název… + + + The chosen name is already in use. + Zvolený název už je používán. + + + Description... + Popis… + + + Permissions + Oprávnění + + + Roles + Role + + + Username + Uživatelské jméno + + + Password + Heslo + + + Confirm password + Potvrzení zadání hesla + + + Password confirmation doesn't match the password. + Zadání hesla se neshodují. + + + Full name + Celé jméno + + + Email + E-mail + + + Invalid email. + Neplatný e-mail. + + + You are about to remove "user read / update" permissions from your own user. + Chystáte se odebrat oprávnění „uživatel číst/aktualizovat“ svému vlastnímu účtu. + + + If you continue, you will no longer be able to add or remove roles from any user. + Pokud budete pokračovat, nebudete nadále schopní přidávat nebo nebo odebírat role žádnému z uživatelů. + + + Are you sure you want to continue? + Opravdu chcete pokračovat? + + + Performance counters not available + Výkonnostní čítače nejsou k dispozici + + + Attributes (OSD map) + Atributy (OSD mapa) + + + Metadata not available + Metadata nejsou k dispozici + + + Metadata + Metadata + + + Performance counter + Výkonnostní čítač + + + Histogram not available: + + + Histogram není k dispozici: + + + + + Writes + Zápisy + + + Reads + Čtení + + + Histogram + Histogram + + + Performance Details + Podrobnosti o výkonnosti + + + Current values + Stávající hodnoty + + + Type + Typ + + + Min + Min + + + Max + Max + + + Flags + Příznaky + + + Source + Zdroj + + + Level + Úroveň + + + Can be updated at runtime (editable) + Je možné aktualizovat za provozu (upravitelné) + + + Tags + Štítky + + + Enum values + Vyčíslit hodnoty + + + See also + Viz také + + + Cluster Status + Stav klastru + + + Manager Daemons + Procesy služby správy + + + Object Gateways + Objektové brány + + + Metadata Servers + Metadata servery + + + iSCSI Gateways + iSCSI brány + + + Client IOPS + vst/výst. klienta + + + Client Throughput + Propustnost klienta + + + Client Read/Write + Čtení/zápis klienta + + + Recovery Throughput + Propustnost zotavení + + + Scrub + Kontrola + + + Performance + Výkonnost + + + Raw Capacity + Holá kapacita + + + Objects + Objekty + + + PGs per OSD + Skupin umístění na OSD + + + PG Status + Stav skupiny umístění + + + Capacity + Kapacita + + + + + See + Logs + for more details. + + Další podrobnosti + + naleznete v + záznamech událostí + . + + + + Ranks + Hodnocení + + + MDS performance counters + MDS performance counters + + + Clients: + + + Klienti: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Přesunout obraz do koše + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Pro přesunutí + + / + + do koše, + klikněte na + Přesunout obraz + . Volitelně je možné zvolit datum skončení platnosti. + + + + Protection expires at + Platnost ochrany skončí v + + + NOT PROTECTED + NECHRÁNĚNO + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Chybný formát data. Použijte „RRRR-MM-DD HH:mm:ss“. + + + Protection has already expired. Please pick a future date or leave it empty. + Platnost ochrany už skončila. Zvolte budoucí datum nebo nevyplňujte. + + + Move Image + Přesunout obraz + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Přehled + + + Targets + Cíle + + + Discovery Authentication + Ověřování pro objevování + + + User + Uživatele + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Uživatel pro vzájemné ověření + + + Mutual Password + Heslo pro vzájemné ověření + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Podívejte se do + dokumentace + + jak nastavit a zapnout funkci správy iSCSI cílů. + + + + Available information: + Informace k dispozici: + + + iSCSI Targets not available + iSCSI cíl není k dispozici + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + K dispozici pouze pro RBD obrazy se zapnutým + fast-diff + + + + + Pool + Fond + + + Data Pool + Datový fond + + + Created + Vytvořeno + + + Size + Velikost + + + Object size + Velikost objektu + + + Features + Funkce + + + Provisioned + Poskytováno + + + N/A + N/A + + + Total provisioned + Celkem poskytováno + + + Striping unit + Proužkovací jednotka + + + Striping count + Počet proužkování + + + Parent + Nadřazené + + + Block name prefix + Předpona názvu bloku + + + Order + Pořadí + + + Snapshots + Zachycené stavy + + + Image + Obraz + + + This setting overrides the global value + Toto nastavení přebije globální hodnotu + + + Global + Globální + + + This is the global value. No value for this option has been set for this image. + Toto je globální hodnota. Pro tento obraz nebyla u této volby nastavena žádná hodnota. + + + + from + + + from + + + + '/' and '@' are not allowed. + „/“ a „@“ nejsou dovoleny. + + + -- No rbd pools available -- + -- Žádné rbd fondy k dispozici -- + + + -- Select a pool -- + -- Vybrat fond -- + + + Use a dedicated data pool + Použít vyhrazený datový fond + + + Data pool + Datový fond + + + Dedicated pool that stores the object-data of the RBD. + Vyhrazený fond který uchovává objektová data RBD. + + + e.g., 10GiB + např. 10 GiB + + + You have to increase the size. + Je třeba zvětšit. + + + Advanced + Pokročilé + + + Striping + Proužkování + + + Stripe unit + Jednotka proužku + + + -- Select stripe unit -- + -- Vybrat jednotku proužku -- + + + This field is required because stripe count is defined! + Tuto kolonku je třeba vyplnit, protože je definován počet proužků! + + + Stripe unit is greater than object size. + Jednotka proužku je vyšší než velikost objektu. + + + Stripe count + Počet proužků + + + This field is required because stripe unit is defined! + Tuto kolonku je třeba vyplnit, protože je definována jednotka proužku! + + + Stripe count must be greater than 0. + Je třeba, aby počet proužků byl větší než nula. + + + + RBD Snapshot + + + RBD zachycený stav + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, vybrat, skutečné {Rename} ostatní {Create} } + + + + Snapshot + + + zachycený stav + + + + PROTECTED + CHRÁNĚNO + + + UNPROTECTED + NECHRÁNĚNO + + + You are about to rollback + Chystáte se vrátit zpět + + + Purge Trash + Vysypat koš + + + To purge, select one or All images and click + Pro vyčištění, vyberte jeden nebo všechny obrazy a klikněte na + + + Pool: + Fond: + + + Pool name... + Název fondu… + + + All + Vše + + + Restore Image + Obnovit obraz + + + To restore + Pro obnovení + + + type the image's new name and click + zadejte nový název pro obraz a klikněte na + + + New Name + Nový název + + + Expired at + Platnost skončila v + + + Protected until + Chráněno do + + + This image is protected until + . + + Tento obraz je chráněn do + . + + + + Trash + Koš + + + iSCSI Topology + Topologie iSCSI + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Měnit tyto parametry z jejich výchozích hodnot obvykle není potřeba. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Nastavení + + + Backstore + Backstore + + + Confirm + Potvrdit + + + Advanced Settings + Pokročilá nastavení + + + Target IQN + IQN cíle + + + IQN has wrong pattern. + IQN nemá správný formát. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + IQN má následující formu zápisu „iqn.$rok-$měsíc.$adresaObráceně:$určenýNázev' + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Například: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Další informace + + + This target has modified advanced settings. + Tento cíl má změněná pokročilá nastavení. + + + Portals + Portály + + + At least + gateways are required. + + Je třeba alespoň + bran. + + + + Add portal + Přidat portál + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Tento obraz má změněná nastavení. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Přidat obraz + + + ACL authentication + ACL ověřování + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Iniciátory + + + Initiator + Iniciátor + + + Client IQN + IQN klienta + + + Initiator IQN needs to be unique. + Je třeba, aby se IQN iniciátoru neopakovalo. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Je třeba, aby uživatelská jména měla délku 8 až 64 znaků a + mohou obsahovat pouze písmena a znaky „.“, „@“, „-“, „_“ nebo „:“. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + Iniciátor spadá do skupiny. Obrazy budou nastaveny ve skupině. + + + No items added. + Nepřidány žádné položky. + + + Add initiator + Přidat iniciátor + + + Groups + Skupiny + + + Group + Skupina + + + Add group + Přidat skupinu + + + [object Object] + [object Object] + + + RBD Configuration + Nastavení RBD + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Odebrat hodnotu místnímu nastavení. Namísto ní bude použita hodnota nadřazeného nastavení. + + + The mininum value is 0 + Minimální hodnota je 0 + + + Issues + problémy + + + Syncing + Synchronizuje se + + + Ready + Připraveno + + + Edit pool mirror mode + Upravit režim zrcadlení fondu + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Pro úpravu režimu zrcadlení pro fond  + + + , vyberte ze seznamu nový režim a klikněte na  + Aktualizovat + . + + + + Mode + Režim + + + Peer clusters must be removed prior to disabling mirror. + Před vypnutím zrcadlení je třeba odebrat klastry-protějšky. + + + + + pool mirror peer + + + + protějšek zrcadlení fondu + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Edit} other {Add} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + atributy + protějšku zrcadlení pro fond + + + a klikněte na + Odeslat + . + + + + Cluster Name + Název klastru + + + The cluster name is not valid. + Název klastru není platný + + + CephX ID + CephX identif. + + + CephX ID... + CephX identif. … + + + The CephX ID is not valid. + CephX identif. není platný. + + + Monitor Addresses + Adresy monitorů + + + Comma-delimited addresses... + Čárkou oddělované adresy… + + + The monitory address is not valid. + Adresa monitoru není platná. + + + CephX Key + CephX klíč + + + Base64-encoded key... + Klíč v base64 kódování… + + + CephX key must be base64 encoded. + Je třeba, aby CephX klíč byl v kódování base64. + + + Pools List + Seznam fondů + + + The name can only consist of alphanumeric characters, dashes and underscores. + Název může být tvořen pouze písmeny a číslicemi, dále ještě spojovníky a podtržítky. + + + The chosen erasure code profile name is already in use. + Zvolený název pro profil mazacího kódu je už používán. + + + Plugin + Zásuvný modul + + + Data chunks (k) + Shluky dat (k) + + + Must be equal to or greater than 2. + Je třeba, aby bylo 2 a více. + + + Coding chunks (m) + Shluky kódování (m) + + + Must be equal to or greater than 1. + Je třeba, aby bylo 1 a více. + + + Durability estimator (c) + Odhadování odolnosti (c) + + + Locality (l) + Umístění (l) + + + Crush failure domain + Doména selhání crush + + + Crush Locality + Lokalita crush + + + None + Žádné + + + Technique + Technika + + + Packetsize + Velikostpaketu + + + Crush root + Kořen crush + + + Crush device class + Třída crush zařízení + + + any + libovolné + + + Directory + Složka + + + The chosen Ceph pool name is already in use. + Zvolený název pro Ceph fond je už používán. + + + Pool type + Typ fondul + + + -- Select a pool type -- + -- Vybrat typ fondu -- + + + Placement groups + Skupiny umístění + + + At least one placement group is needed! + Je třeba alespoň jedné skupiny umístění! + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + Váš klastr nemůže obsloužit tolik skupin umístění. Přepočítejte potřebné množství skupin umístění. + + + Calculation help + Nápověda k výpočtu + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + + + Crush ruleset + Sada pravidel crush + + + -- Select a crush rule -- + -- Vybrat crush pravidlo -- + + + Crush rule + Crush pravidlo + + + Crush steps + Crush kroky + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + Pravidlo nemůže být uplatněno na stávající klastr protože má + příliš málo OSD aby splnil minimum OSD vyžadovaných tímto pravidlem. + + + Replicated size + Replikovaná velikost + + + Minimum: + + + Nejméně: + + + + + Maximum: + + + Nejvíce: + + + + + The size specified is out of range. A value from + to + is valid. + + Zadaná velikost je mimo rozsah. Platné hodnoty jsou od + do + . + + + + Erasure code profile + Profil mazacího kódu + + + -- No erasure code profile available -- + -- Žádný profil mazacího kódu -- + + + -- Select an erasure code profile -- + -- Vyberte profil mazacího kódu -- + + + EC Overwrites + EC přebití + + + Applications + Aplikace + + + Compression + Komprese + + + Algorithm + Algoritmus + + + -- No erasure compression algorithm available -- + -- Žádný algoritmus komprese mazání -- + + + Minimum blob size + Minimální velikost blobu + + + e.g., 128KiB + např. 128 KiB + + + Value should be greater than 0 + Hodnota by měla být vyšší než nula + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Nejvyšší velikost blobu + + + e.g., 512KiB + např. 512 KiB + + + Value should be greater than the minimum blob size + Hodnota by měla být vyšší než nejnižší velikost blobu + + + Ratio + Poměr + + + Compression ratio + Kompresní poměr + + + Value should be between 0.0 and 1.0 + Hodnota by měla být z rozmezí 0.0 až 1.0 + + + It's not possible to create an RBD pool with '/' in the name. + Není možné vytvořit RBD fond, který má v názvu „/“. + + + Please change the name or remove 'rbd' from the applications list. + Změňte název nebo ze seznamu použití odeberte „rbd“ + + + Cache Tiers Details + Podrobnosti o stupních mezipaměti + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Podívejte se do + dokumentace + + jak nastavit a zapnout funkci správy brány objektů. + + + + Daemons List + Seznam procesů služeb + + + Performance Counters + Výkonnostní čítače + + + Loading bucket data... + Načítání dat nádoby… + + + The bucket data could not be loaded. + Data nádoby se nepodařilo načíst. + + + Id + Identif. + + + The value is not valid. + Hodnota není platná. + + + Owner + Vlastník + + + -- Select a user -- + -- Vybrat uživatele -- + + + ID + Identif. + + + Index type + Typ rejstříku + + + Placement rule + Pravidlo umístění + + + Marker + Označovač + + + Maximum marker + Nejvyšší označovač + + + Version + Verze + + + Master version + Hlavní verze + + + Modification time + Okamžik úpravy + + + Zonegroup + Skupinazóny + + + Bucket quota + Kvóta nádoby + + + Enabled + Zapnuto + + + Maximum size + Nejvyšší velikost + + + Unlimited + Neomezeno + + + Maximum objects + Nejvýše objektů + + + -- Select a username -- + -- Vybrat uživatelské jméno -- + + + Auto-generate key + Automaticky vytvořit klíč + + + Access key + Přístupový klíč + + + Secret key + Tajný klíč + + + Email address + E-mailová adresa + + + Suspended + Pozastaveno + + + System + Systém + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {No} 1 {Yes} } + + + Maximum buckets + Nejvýše nádob + + + Subusers + Dílčí uživatelé + + + Capabilities + Schopnosti + + + User quota + Kvóta uživatele + + + Show + Zobrazit + + + Keys + Klíče + + + -- Select a type -- + -- Vybrat typ -- + + + Permission + Oprávnění + + + -- Select a permission -- + -- Vybrat oprávnění -- + + + Subuser + Dílčí uživatel + + + The chosen subuser ID is already in use. + Zvolený identifikátor dílčího uživatele už je používán. + + + read, write + číst, zapisovat + + + full + plné + + + Swift key + Swift klíč + + + Auto-generate secret + Automaticky vytvořit tajemství + + + Loading user data... + Načítání údajů uživatele… + + + The user data could not be loaded. + Údaje uživatele se nepodařilo načíst. + + + The chosen user ID is already in use. + Zvolený identif. uživatele už je používán. + + + This is not a valid email address. + Toto není platná e-mailová adresa. + + + The chosen email address is already in use. + Zvolená e-mailová adresa už je používána. + + + Max. buckets + Nejvýše nádob + + + The entered value must be >= 0. + Je třeba, aby zadaná hodnota byla 0 a vyšší. + + + S3 key + S3 klíč + + + There are no subusers. + Nejsou zde žádní dílčí uživatelé. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + Nejsou zde žádné klíče. + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + Nejsou zde žádné schopnosti. + + + + + + + + + + + + + Unlimited size + Neomezená velikost + + + Max. size + Nejvyšší velikost + + + Unlimited objects + Neomezené objekty + + + Max. objects + Nejvýše objektů + + + Current + Stávající + + + Updated discovery authentication + Aktualizováno ověřování pro objevování + + + There are no portals available. + Nejsou k dispozici žádné portály. + + + There are no images available. + Nejsou k dispozici žádné obrazy. + + + There are no images available. Please make sure you add an image to the target. + Nejsou k dispozici žádné obrazy. Ověřte, že jste cíli přidali obraz. + + + There are no initiators available. Please make sure you add an initiator to the target. + Nejsou k dispozici žádné iniciátory. Ověřte, že jste cíli přidali iniciátor. + + + target + target + + + Target + Cíl + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + Stav + + + # Targets + # Targets + + + Read Bytes + Bajtů čtení + + + Write Bytes + Bajtů zápis + + + Read Ops + Operací/s čtení + + + Write Ops + Operací/s zápis + + + A/O Since + A/O od + + + Instance + Instance + + + Hostname + Název stroje + + + Issue + Problém + + + Progress + Ukazatel postupu + + + Disabled + Vypnuto + + + Edit Mode + Upravit režim + + + Add Peer + Přidat protějšek + + + Edit Peer + Upravit protějšek + + + Delete Peer + Smazat protějšek + + + Leader + Vedoucí + + + # Local + Počet místních + + + # Remote + Počet vzdálených + + + mirror peer + zrcadlit protějšek + + + Key + Klíč + + + RBD + RBD + + + Deep flatten + Hluboké zploštění + + + Layering + Vrstvení + + + Exclusive lock + Výhradní zámek + + + Object map (requires exclusive-lock) + Mapa objektů (vyžaduje výhradní zámek) + + + Journaling (requires exclusive-lock) + Žurnálování (vyžaduje výhradní zámek) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Vrácení zachyceného stavu RBD zpět + + + Rollback + Vrácení zpět + + + RBD snapshot + Zachycený stav RBD + + + Deleted At + Smazáno v + + + id + identif. + + + type + typ + + + state + stav + + + version + verze + + + Host + Stroj + + + root + kořen + + + Rank + Hodnocení + + + Daemon + Proces služby + + + Activity + Aktivita + + + Dentries + Struktury složek + + + Inodes + I-uzlů + + + Usage + Využití + + + Standby daemons + Procesy služeb v pohotovosti + + + The value can be updated at runtime. + Hodnotu je možné aktualizovat za chodu. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + Procesy služeb / klienti nezískávají tuto hodnotu + z databáze nastavení monitoru. Není umožněno nastavit tuto volbu + prostřednictvím „ceph config set …'. Tato volba by měla být nastavena + z příkazového řádku. + + + Option takes effect only during daemon startup. + Volba se uplatní pouze při spouštění procesu služby. + + + Option only affects cluster creation. + Volba ovlivní pouze vytváření klastru. + + + Option only affects daemon creation. + Volba ovlivní pouze vytvoření procesu služby. + + + Updated config option + + + Aktualizována volba nastavení + + + + + Service + Služba + + + Current value + Stávající hodnota + + + Editable + Upravitelné + + + Updated options for module " + ". + + Aktualizována volba pro modul „ + “ + + + + Enable + Zapnout + + + Disable + Vypnout + + + Reconnecting, please wait ... + Opětovné připojování, čekejte… + + + Public Address + Veřejná adresa + + + Open Sessions + Otevřené relace + + + No In + Počet do + + + OSDs that were previously marked out will not be marked back in when they start + OSD které byly dříve odznačeny nebudou označeny nazpět když spustí + + + No Out + Počet ven + + + OSDs will not automatically be marked out after the configured interval + OSD nebudou automaticky odznačeny po nastaveném intervalu + + + No Up + Počet aktivních + + + OSDs are not allowed to start + OSD není dovoleno spuštění + + + No Down + Počet neaktivních + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + Hlášení o selhání OSD jsou ignorovány, jako například že monitory OSD neoznačí jako nedostupné + + + Pause + Pozastavit + + + Pauses reads and writes + Pozastavit čtení a zápisy + + + No Scrub + Žádná kontrola + + + Scrubbing is disabled + Kontrola je vypnutá + + + No Deep Scrub + Žádná hloubková kontrola + + + Deep Scrubbing is disabled + Hloubková kontrola je vypnutá + + + No Backfill + Žádné zasypávání + + + Backfilling of PGs is suspended + Zasypávání skupin umístění je pozastaveno + + + No Recover + Žádné obnovení + + + Recovery of PGs is suspended + Obnovování skupin umístění je pozastaveno + + + Bitwise Sort + Bitové třídění + + + Use bitwise sort + Třídit podle bitů + + + Purged Snapdirs + Vyčištěné složky zachycených stavů + + + OSDs have converted snapsets + OSD mají převedené sady zachycených stavů + + + Recovery Deletes + Smazáno při zotavování + + + Deletes performed during recovery instead of peering + Mazání provedená při obnovování namísto peeringu + + + PG Log Hard Limit + Nepřekročitelný limit záznamu událostí PG + + + Puts a hard limit on pg log length + Zapne nepřekročitelný limit na délku záznamu událostí v pg + + + Updated OSD Flags + Aktualizovány OSD příznaky + + + out + ven + + + in + dovnitř + + + down + nedostupné + + + Mark + Značka + + + OSD lost + OSD ztraceno + + + marked lost + označeno jako ztracené + + + Purge + Vyčistit + + + OSD + OSD + + + purged + vyčištěno + + + destroy + zlikvidovat + + + destroyed + zlikvidováno + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + skupiny umístění + + + Read bytes + Přečteno bajtů + + + Writes bytes + Zapsáno bajtů + + + Read ops + Operací/s čtení + + + Write ops + Operací/s zápis + + + Mark OSD + + + Označit OSD + + + + + Mark + + + Označit + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Max Backfills + + + Recovery Max Active + Recovery Max Active + + + Recovery Max Single Start + Recovery Max Single Start + + + Recovery Sleep + Recovery Sleep + + + Custom + Uživatelsky určené + + + Updated OSD recovery speed priority " + " + + Aktualizována rychlost zotavení OSD „ + “ + + + + + was initialized in the following OSD: + + + + bylo inicializováno v následujícím OSD: + + + + + Create silence + Create silence + + + Job + Úloha + + + Severity + Závažnost + + + Started + Zahájeno + + + URL + URL adresa + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Aktualizováno + + + Ends + Ends + + + Silence + Silence + + + Used + Použito + + + Avail. + K dispozici + + + Clean + Čisté + + + Working + Pracující + + + Warning + Varování + + + Unknown + Neznámé + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + aktivní + + + no filesystems + žádné souborové systémy + + + active + aktivní + + + standby + v pohotovosti + + + n/a + n/a + + + active daemon + aktivní proces služby + + + quorum + kvórum + + + The NFS Ganesha service is not configured. + Služba NFS Ganesha není nastavena. + + + Transport + Transport + + + CephFS User + CephFS uživatel + + + CephFS Filesystem + Souborový systém CephFS + + + (inherited from global config) + (převzato z globálního nastavení) + + + inherited from global config + převzato z globálního nastavení + + + -- Select what kind of user id squashing is performed -- + -- Select what kind of user id squashing is performed -- + + + There are no daemons available. + Nejsou k dispozici žádné procesy služeb. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Režim mezipaměti + + + Min Evict Age + Min Evict Age + + + Min Flush Age + Min Flush Age + + + Target Max Bytes + Nejvýše bajtů cíle + + + Target Max Objects + Nejvýše objektů cíle + + + No applications added + Nebyla přidána žádná aplikace + + + Applications limit reached + Dosažen limit aplikací + + + A pool can only have up to four applications definitions. + Fond může mít nejvýše čtyři definice aplikací. + + + Allowed characters '_a-zA-Z0-9' + Použitelné znaky „_a-zA-Z0-9“ + + + Maximum length is 128 characters + Nejvyšší délka je 128 znaků + + + Filter or add applications + Filtrovat nebo přidat aplikace + + + Add application + Přidat aplikaci + + + pool + pool + + + erasure code profile + profil mazacího kódu + + + Replica Size + Velikost repliky + + + Last Change + Nejnovější změna + + + Erasure Coded Profile + Mazáním kódovaný profil + + + Crush Ruleset + Sada crush pravidel + + + Write bytes + Zapsáno bajtů + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + nádoba + + + Updated Object Gateway bucket " + " + + Aktualizována nádoba objektové brány „ + “ + + + + Created Object Gateway bucket " + " + + Vytvořena nádoba objektové brány „ + “ + + + + buckets + nádoby + + + capability + capability + + + user + uživatel + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Aktualizován uživatel objektové brány „ + “ + + + + Created Object Gateway user " + " + + Vytvořen uživatel objektové brány „ + “ + + + + users + uživatelé + + + Swift Key + Swift Key + + + Scope + Rozsah + + + Read + Čtení + + + Create + Vytvořit + + + role + role + + + Created role ' + ' + + Vytvořena role „ + “ + + + + Updated role ' + ' + + Aktualizována role „ + “ + + + + System Role + Systémová role + + + Deleted role ' + ' + + Smazána role „ + “ + + + + Created user " + " + + Vytvořen uživatel „ + “ + + + + Update user + Aktualizovat uživatele + + + Continue + Pokračovat + + + You were automatically logged out because your roles have been changed. + Byli jste automaticky odhlášeni protože vaše role byly změněny. + + + Updated user " + " + + Aktualizován uživatel „ + “ + + + + Deleted user " + " + + Smazán uživatel „ + “ + + + + Failed to delete user " + " + + Nepodařilo se smazat uživatele „ + “ + + + + You are currently logged in as " + ". + + Nyní jste přihlášení jako „ + “. + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Každý objekt je rozdělen v částech shluků dat, každé uložené na jiném OSD. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Počítat kódovací shluky pro každý objekt a ukládat je na různých OSD. + Počet kódovacích shluků je také počet OSD, které mohou vypadnou, aniž dojde ke ztrátě dat. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Zásuvný modul jerasure je nejobecnější a nejpřizpůsobivější, + je také výchozí pro Ceph fondy kódované mazáním. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + Zásuvný modul isa obaluje knihovnu ISA. Funguje pouze na procesorech Intel. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + Název crush nádoby sloužící jako první krok CRUSH pravidla. + Například krok vzít výchozí. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Omezit umístění na zařízení určité třídy + (např., ssd nebo hdd), pomocí názvu crush třídy zařízení v CRUSH mapě. + + + Set the directory name from which the erasure code plugin is loaded. + Nastavit složku ze které načítat zásuvný modul mazacího kódu. + + + Allows all operations + Umožnit všechny operace + + + Allows only operations that do not modify the server + Umožnit pouze operace které neupraví server + + + Does not allow read or write operations, but allows any other operation + Neumožňuje operace čtení či zápisu, ale umožňuje ostatní + + + Does not allow read, write, or any operation that modifies file attributes or directory content + Neumožňuje čtení, zápis nebo jinou operaci která upravuje atributy souboru nebo obsah složky + + + Allows no access at all + Neumožnit vůbec žádný přístup + + + -- Select the priority -- + -- Vyberte prioritu -- + + + Low + Nízká + + + High + Vysoká + + + Last 5 minutes + Uplynulých 5 minut + + + Last 15 minutes + Uplynulých 15 minut + + + Last 30 minutes + Uplynulých 30 minut + + + Last 1 hour (Default) + Uplynulá 1 hodina (výchozí) + + + Last 3 hours + Uplynulé 3 hodiny + + + Last 6 hours + Uplynulých 6 hodin + + + Last 12 hours + Uplynulých 12 hodin + + + Last 24 hours + Uplynulých 24 hodin + + + Yesterday + Včera + + + Today + Dnes + + + Today so far + Dnes doposud + + + Day before yesterday + Včerejšek + + + Last 2 days + Uplynulé 2 dny + + + This day last week + Tento den minulý týden + + + Previous week + Předchozí týden + + + This week + Tento týden + + + This week so far + Tento týden doposud + + + Last 7 days + Uplynulých 7 dnů + + + Previous month + Předchozí měsíc + + + This month + Tento měsíc + + + This month so far + Tento měsíc doposud + + + Last 30 days + Uplynulých 30 dnů + + + Last 90 days + Uplynulých 90 dnů + + + Last 6 months + Uplynulých 6 měsíců + + + Last 1 year + Uplynulý 1 rok + + + Previous year + Předchozí rok + + + This year + Tento rok + + + This year so far + Tento rok doposud + + + Last 2 years + Uplynulé 2 roky + + + Last 5 years + Uplynulých 5 let + + + Information + Informace + + + No items selected. + Nevybrány žádné položky. + + + Deselect item to select again + Aby položku bylo možné znovu vybrat, je třeba nejprve zrušit její výběr + + + Selection limit reached + Dosažen limit výběru + + + Filter tags + Filtrovat štítky + + + Add badge + Přidat odznak + + + There are no items available. + Nejsou k dispozici žádné položky. + + + Add + Přidat + + + Remove + Remove + + + Clone + Klonovat + + + Copy + Kopírovat + + + Deep Scrub + Hloubková kontrola + + + Destroy + Zlikvidovat + + + Flatten + Zploštit + + + Mark Down + Označit + + + Mark In + Označit + + + Mark Lost + Označit ztracené + + + Mark Out + Odznačit + + + Protect + Ochránit + + + Rename + Přejmenovat + + + Restore + Obnovit + + + Move to Trash + Přesunout do koše + + + Unprotect + Zrušit ochranu + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Smazáno + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Naklonováno + + + Copied + Zkopírováno + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + Ano + + + No + Ne + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Kvalita služby + + + BPS Limit + BPS Limit + + + The desired limit of IO bytes per second. + Požadovaný limit vst./výstup. bajtů za sekundu. + + + IOPS Limit + IOPS Limit + + + The desired limit of IO operations per second. + Požadovaný limit vst./výstup. operací za sekundu. + + + Read BPS Limit + Read BPS Limit + + + The desired limit of read bytes per second. + Požadovaný limit čtení bajtů za sekundu. + + + Read IOPS Limit + Read IOPS Limit + + + The desired limit of read operations per second. + Požadovaný limit operací čtení za sekundu. + + + Write BPS Limit + Write BPS Limit + + + The desired limit of write bytes per second. + Požadovaný limit zápisu bajtů za sekundu. + + + Write IOPS Limit + Write IOPS Limit + + + The desired limit of write operations per second. + Požadovaný limit operací čtení za sekundu. + + + BPS Burst + BPS dávka + + + The desired burst limit of IO bytes. + The desired burst limit of IO bytes. + + + IOPS Burst + IOPS Burst + + + The desired burst limit of IO operations. + Požadovaný limit dávky vst./výstup. operací. + + + Read BPS Burst + Read BPS Burst + + + The desired burst limit of read bytes. + Požadovaný limit dávky bajtů čtení. + + + Read IOPS Burst + Read IOPS Burst + + + The desired burst limit of read operations. + Požadovaný limit dávky čtení bajtů. + + + Write BPS Burst + Write BPS Burst + + + The desired burst limit of write bytes. + Požadovaný limit bajtů dávky zápisu. + + + Write IOPS Burst + Write IOPS Burst + + + The desired burst limit of write operations. + Požadovaný limit dávky operace zápisu. + + + Failed to + + + + Nepodařilo se + + + + + + Executing + Vykonává se + + + execute + vykonat + + + Executed + Vykonáno + + + unknown task + neznámý úkol + + + Creating + Vytváří se + + + create + vytvořit + + + Updating + Aktualizuje se + + + update + aktualizovat + + + Deleting + Maže se + + + delete + smazat + + + RBD ' + ' + + RBD „ + “ + + + + RBD snapshot ' + ' + + RBD zachycený stav „ + “ + + + + mirror mode for pool ' + ' + + režim zrcadlení pro fond „ + “ + + + + mirror peer for pool ' + ' + + protějšek zrcadlení pro fond „ + “ + + + + all dashboards + all dashboards + + + Name is already used by + . + + Název už je používán + . + + + + Name is already used by + . + + Název už je používán + . + + + + Name is already used by + . + + Název už je používán + . + + + + + contains snapshots. + + + obsahuje zachycené stavy. + + + + Cloning + Klonuje se + + + clone + klonovat + + + Snapshot of + must be protected. + + Je třeba, aby zachycený stav + byl chráněný. + + + + Copying + Kopíruje se + + + copy + zkopírovat + + + Flattening + Zploštění + + + flatten + zploštit + + + Flattened + Zploštěno + + + Name is already used by + . + + Název už je používán pro + . + + + + Cannot unprotect + because it contains child images. + + Není možné zrušit ochranu + , protože obsahuje podřízené obrazy. + + + + Cannot delete + because it's protected. + + + není možné smazat, protože je chráněné. + + + + Rolling back + Bere se zpět + + + rollback + vzít zpět + + + Rolled back + Vzato zpět + + + Moving + Přesouvá se + + + move + přesunout + + + Moved + Přesunuto + + + image ' + ' to trash + + obraz „ + “ do koše + + + + Could not find image. + Obraz se nedaří najít. + + + Restoring + Obnovuje se + + + restore + obnovit + + + Restored + Obnoveno + + + image ' + ' into ' + ' + + obraz „ + “ do „ + “ + + + + Image name ' + ' is already in use. + + Název „ + “ už je používán pro jiný obraz. + + + + image ' + ' + + obraz „ + “ + + + + Purging + Čistí se + + + purge + vyčistit + + + Purged + Vyčištěno + + + all pools + všechny fondy + + + images from + + + obrazy z + + + + + Cannot disable mirroring because it contains a peer. + Zrcadlení nelze vypnout protože obsahuje protějšek. + + + pool ' + ' + + fond „ + “ + + + + erasure code profile ' + ' + + profil mazacího kódu „ + “ + + + + target ' + ' + + cíl „ + “ + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf new file mode 100644 index 00000000..4761eb83 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.de-DE.xlf @@ -0,0 +1,4365 @@ + + + + + Toggle navigation + Navigation umschalten + + + Dashboard + Dashboard + + + Cluster + Cluster + + + Hosts + Hosts + + + Monitors + Monitore + + + OSDs + OSDs + + + Configuration + Konfiguration + + + CRUSH map + CRUSH-Zuordnung + + + Manager modules + Manager-Module + + + Logs + Protokolle + + + Alerts + Warnungen + + + Silences + Silences + + + Pools + Pools + + + Block + Block + + + Images + Images + + + Mirroring + Spiegelung + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + Dateisysteme + + + Object Gateway + Objektgateway + + + Daemons + Daemons + + + Users + Benutzer + + + Buckets + Buckets + + + Retrieving data + for + + + . Please wait... + + Daten + für + + werden abgerufen. Bitte warten... + + + + Displaying previously cached data + + for + + + . + + Zuvor zwischengespeicherte Daten + + für + + + werden angezeigt. + + + + Could not load data + for + + + . + Please check the cluster health. + + Daten + für + + + konnten nicht geladen werden. + Prüfen Sie die Clusterintegrität. + + + + Back + Zurück + + + Select a Language + Sprache auswählen + + + Loading panel data... + Bereichsdaten werden geladen... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Lesen Sie die + Dokumentation + zum + Konfigurieren und Aktivieren der Überwachungsfunktion. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Das Grafana-Dashboard ist nicht vorhanden. In der + Dokumentation + wird beschrieben, + wie Grafana Dashboards hinzugefügt werden. + + + + Grafana Time Picker + Grafana-Zeitauswahl + + + Reset Settings + Einstellungen für Zurücksetzungen + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Daten konnten nicht geladen werden. + + + selected + ausgewählt + X selected + + + found + gefunden + X found + + + total + insgesamt + X total + + + Edit + Bearbeiten + + + Name + Name + + + Description + Beschreibung + + + Long description + Lange Beschreibung + + + Default + Standard + + + Daemon default + Daemon-Standard + + + Services + Services + + + Values + Werte + + + The entered value is too high! It must not be greater than + . + + Der eingegebene Wert ist zu groß! Er darf nicht größer als + sein. + + + + The entered value is too low! It must not be lower than + . + + Der eingegebene Wert ist zu klein! Er darf nicht kleiner als + sein. + + + + Save + Speichern + + + CRUSH map viewer + CRUSH-Zuordnungsanzeige + + + Hosts List + Liste mit Hosts + + + Overall Performance + Gesamtleistung + + + No entries found + Keine Einträge gefunden + + + Cluster Logs + Clusterprotokolle + + + Audit Logs + Revisionsprotokoll + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Konfiguration wird geladen... + + + The configuration could not be loaded. + Die Konfiguration konnte nicht geladen werden. + + + Edit Manager module + Manager-Modul bearbeiten + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + Der eingegebene Wert ist kein gültiger UUID, z. B.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + Der eingegebene Wert muss eine gültige IP-Adresse sein. + + + This field is required. + Dies ist ein Pflichtfeld. + + + The entered value is too high! It must be lower or equal to + . + + Der eingegebene Wert ist zu groß! Er muss kleiner als + sein oder diesem Wert entsprechen. + + + + The entered value is too low! It must be greater or equal to + . + + Der eingegebene Wert ist zu klein! Er muss größer als + sein oder diesem Wert entsprechen. + + + + The entered value needs to be a number. + Der eingegebene Wert muss eine Zahl sein. + + + The entered value needs to be a number or decimal. + Der eingegebene Wert muss eine Zahl oder Dezimalzahl sein. + + + Update + Aktualisieren + + + Status + Status + + + Cluster ID + Cluster-ID + + + monmap modified + Monmap geändert + + + monmap epoch + Monmap-Epoche + + + quorum con + quorum con + + + quorum mon + quorum mon + + + required con + erforderliche Verbindung + + + required mon + erforderliche Überwachung + + + In Quorum + In Quorum + + + Not In Quorum + Nicht in Quorum + + + Cancel + Abbrechen + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + Sind Sie sicher dass Sie die ausgewählten + + möchten? + + + + Yes, I am sure. + Ja, ich bin sicher. + + + Cluster-wide OSD Flags + Clusterweite OSD-Flags + + + Submit + Absenden + + + + + + + + + + + form title + + + Advanced... + Erweitert... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + OSD-Wiederherstellungspriorität + + + Priority + Priorität + + + Customize priority values + Prioritätswerte anpassen + + + This field is required! + Dies ist ein Pflichtfeld! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + Der eingegebene Wert ist zu groß! Er darf nicht größer als + sein. + + + + The entered value is too low! It must not be lower than + . + + Der eingegebene Wert ist zu klein! Er darf nicht kleiner als + sein. + + + + Reweight OSD + OSD neu gewichten + + + The value needs to be between 0 and 1. + Der Wert muss zwischen 0 und 1 liegen. + + + Reweight + Neu gewichten + + + OSDs + Scrub + + OSDs + Scrub + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {Tief } } + + + You are about to apply a + scrub to + the OSD + + + . + + Sie sind dabei, einen + Scrub auf + das OSD + + + anzuwenden. + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {tief } } + + + OSDs List + OSD-Liste + + + + OSD + + will be marked + + + if you proceed. + + + OSD + + wird markiert als + + + , wenn Sie den Vorgang fortsetzen. + + + + The OSD is not safe to destroy! + Es ist nicht sicher, das OSD zu vernichten! + + + + OSD + + will be + + + if you proceed. + + + OSD + + wird + + + , wenn Sie den Vorgang fortsetzen. + + + + Details + Details + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Wert + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Schließen + + + Delete + Löschen + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Integrität + + + Statistics + Statistiken + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Lesen Sie die + Dokumentation + zum + Konfigurieren und Aktivieren der Verwaltungsfunktion für NFS Ganesha. + + + + Clients + Clients + + + Any client can access + Jeder Client hat Zugriff + + + Addresses + Adressen + + + Required field + Pflichtfeld + + + Must contain one or more comma-separated values + Muss mindestens einen kommagetrennten Wert enthalten + + + For example: + Beispielsweise: + + + Access Type + Zugriffstyp + + + Squash + Squash + + + Add clients + Clients hinzufügen + + + Loading... + Laden... + + + -- No cluster available -- + -- Kein Cluster verfügbar -- + + + -- Select the cluster -- + -- Cluster auswählen -- + + + Add daemon + Daemon hinzufügen + + + Storage Backend + Speicher-Back-End + + + -- No data pools available -- + -- Keine Datenpools verfügbar -- + + + -- Select the storage backend -- + -- Speicher-Back-End auswählen -- + + + Object Gateway User + Objektgatewaybenutzer + + + -- No users available -- + -- Keine Benutzer verfügbar -- + + + -- Select the object gateway user -- + -- Objektgatewaybenutzer auswählen -- + + + CephFS User ID + CephFS-Benutzer-ID + + + -- No clients available -- + -- keine Clients verfügbar -- + + + -- Select the cephx client -- + -- cephx-Client auswählen -- + + + CephFS Name + CephFS-Name + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Sicherheitsbezeichnung + + + Enable security label + Sicherheitsbezeichnung aktivieren + + + CephFS Path + CephFS-Pfad + + + Path need to start with a '/' and can be followed by a word + Pfad muss mit einem '/' beginnen und kann von einem Wort gefolgt werden + + + New directory will be created + Neues Verzeichnis wird erstellt + + + Path + Pfad + + + Path can only be a single '/' or a word + Pfad darf nur ein einzelner '/' oder ein Wort sein + + + New bucket will be created + Neuer Bucket wird erstellt + + + NFS Protocol + NFS-Protokoll + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + NFS-Tag + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Alternativer Zugriff für + NFS v3 + -Mountpunkte (dürfen keinen führenden / enthalten) + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + Clients können Unterverzeichnisse möglicherweise nicht mounten (d. h. wenn das Tag = foo, kann der Client foo/baz möglicherweise nicht mounten). + + + By using different Tag options, the same Path may be exported multiple times. + Wenn unterschiedliche Tagoptionen verwendet werden, wird derselbe Pfad möglicherweise mehrfach exportiert. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + Die Position dieses + NFS v4 + -Exports + auf dem + Pseudo-Dateisystem + (muss eindeutig sein). + + + + By using different Pseudo options, the same Path may be exported multiple times. + Wenn unterschiedliche Pseudo-Optionen verwendet werden, wird derselbe Pfad möglicherweise mehrfach exportiert. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- Kein Zugriffstyp verfügbar -- + + + -- Select the access type -- + -- Zugriffstyp auswählen -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- Kein Squash verfügbar -- + + + --Select what kind of user id squashing is performed -- + -- Durchzuführende Benutzer-ID-Squashing-Art auswählen -- + + + Transport Protocol + Transportprotokoll + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Willkommen bei Ceph! + The welcome message on the login page + + + Username is required + Benutzername ist erforderlich + + + Password is required + Passwort ist erforderlich + + + Login + Anmeldung + + + Sorry, the user does not exist in Ceph. + Der Benutzer ist in Ceph leider nicht enthalten. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Kehren Sie zur + Anmeldeseite + zurück. Sie werden vom Identitätsanbieter abgemeldet, wenn Sie versuchen, sich erneut anzumelden. + + + + Forbidden + Verboten + + + Sorry, you are not allowed to see what you were looking for. + Leider sind Sie nicht berechtigt, den gewünschten Inhalt anzuzeigen. + + + Sorry, we could not find what you were looking for + Leider konnte der gewünschte Inhalt nicht gefunden werden. + + + Remove all + Alle löschen + + + Recent Notifications + Neue Benachrichtigungen + + + There are no background tasks. + Keine Hintergrundaufgaben vorhanden. + + + Background Tasks + Hintergrundaufgaben + + + Help + Hilfe + + + Documentation + Dokumentation + + + API + API + + + About + Über + + + Dashboard Settings + Dashboard-Einstellungen + + + User management + Benutzerverwaltung + + + Logged in user + Angemeldeter Benutzer + + + Signed in as + + + + + Angemeldet als + + + + + + + Sign out + Abmelden + + + Name... + Name... + + + The chosen name is already in use. + Der ausgewählte Name wird bereits verwendet. + + + Description... + Beschreibung... + + + Permissions + Berechtigungen + + + Roles + Rollen + + + Username + Benutzername + + + Password + Passwort + + + Confirm password + Passwort bestätigen + + + Password confirmation doesn't match the password. + Passwortbestätigung stimmt nicht mit dem Passwort überein. + + + Full name + Vollständiger Name + + + Email + E-Mail-Adresse + + + Invalid email. + Ungültige E-Mail-Adresse. + + + You are about to remove "user read / update" permissions from your own user. + Sie sind dabei, die Lese-/Aktualisierungsberechtigungen für Benutzer von Ihrem eigenen Benutzer zu entfernen. + + + If you continue, you will no longer be able to add or remove roles from any user. + Wenn Sie den Vorgang fortsetzen, können Sie Benutzerrollen nicht mehr hinzufügen oder entfernen. + + + Are you sure you want to continue? + Möchten Sie den Vorgang wirklich fortsetzen? + + + Performance counters not available + Leistungsindikatoren nicht verfügbar + + + Attributes (OSD map) + Attribute (OSD-Zuordnung) + + + Metadata not available + Metadaten nicht verfügbar + + + Metadata + Metadaten + + + Performance counter + Leistungsindikator + + + Histogram not available: + + + Histogramm nicht verfügbar: + + + + + Writes + Schreibvorgänge + + + Reads + Lesevorgänge + + + Histogram + Histogramm + + + Performance Details + Leistungsdetails + + + Current values + Aktuelle Werte + + + Type + Typ + + + Min + Min. + + + Max + Max. + + + Flags + Flags + + + Source + Quelle + + + Level + Ebene + + + Can be updated at runtime (editable) + Kann zur Laufzeit aktualisiert werden (bearbeitbar) + + + Tags + Tags + + + Enum values + Auflistungswerte + + + See also + Siehe auch + + + Cluster Status + Clusterstatus + + + Manager Daemons + Manager-Daemons + + + Object Gateways + Objektgateways + + + Metadata Servers + Metadatenserver + + + iSCSI Gateways + iSCSI-Gateways + + + Client IOPS + Client-IOPS + + + Client Throughput + Clientdurchsatz + + + Client Read/Write + Client-Lese-/Schreibvorgänge + + + Recovery Throughput + Wiederherstellungsdurchsatz + + + Scrub + Scrub + + + Performance + Leistung + + + Raw Capacity + Rohkapazität + + + Objects + Objekte + + + PGs per OSD + Platzierungsgruppen pro OSD + + + PG Status + Platzierungsgruppenstatus + + + Capacity + Kapazität + + + + + See + Logs + for more details. + + + + Weitere Details finden Sie in den + Protokollen + . + + + + Ranks + Ränge + + + MDS performance counters + MDS performance counters + + + Clients: + + + Clients: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Image in Papierkorb verschieben + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Um + + / + + in den Papierkorb zu verschieben, + klicken Sie auf + Image verschieben + . Optional können Sie ein Ablaufdatum auswählen. + + + + Protection expires at + Schutz läuft ab am + + + NOT PROTECTED + NICHT GESCHÜTZT + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Falsches Datumsformat. Verwenden Sie "TT.MM.JJJJ HH:mm:ss". + + + Protection has already expired. Please pick a future date or leave it empty. + Schutz ist bereits abgelaufen. Wählen Sie ein künftiges Datum aus oder lassen Sie es leer. + + + Move Image + Image verschieben + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Übersicht + + + Targets + Ziele + + + Discovery Authentication + Ermittlungsauthentifizierung + + + User + Benutzer + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Benutzernamen müssen zwischen 8 und 64 Zeichen lang sein und + dürfen nur Buchstaben, '.', '@', '-', '_' oder ':' enthalten. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Gemeinsamer Benutzer + + + Mutual Password + Gemeinsames Passwort + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Lesen Sie die + Dokumentation + zum + Konfigurieren und Aktivieren der Verwaltungsfunktion für iSCSI-Ziele. + + + + Available information: + Verfügbare Informationen: + + + iSCSI Targets not available + iSCSI-Ziele nicht verfügbar + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + Nur für RBD-Images verfügbar, bei denen + fast-diff + aktiviert ist + + + + Pool + Pool + + + Data Pool + Datenpool + + + Created + Erstellt + + + Size + Größe + + + Object size + Objektgröße + + + Features + Funktionen + + + Provisioned + Bereitgestellt + + + N/A + n. v. + + + Total provisioned + Bereitgestellt gesamt + + + Striping unit + Striping-Einheit + + + Striping count + Striping-Anzahl + + + Parent + Übergeordnet + + + Block name prefix + Präfix für Blockname + + + Order + Reihenfolge + + + Snapshots + Snapshots + + + Image + Image + + + This setting overrides the global value + Diese Einstellung überschreibt den globalen Wert + + + Global + Global + + + This is the global value. No value for this option has been set for this image. + Dies ist der globale Wert. Kein Wert für diese Option wurde für dieses Image festgelegt. + + + + from + + + from + + + + '/' and '@' are not allowed. + '/' und '@' sind nicht zulässig. + + + -- No rbd pools available -- + -- Keine rbd-Pools verfügbar -- + + + -- Select a pool -- + -- Pool auswählen -- + + + Use a dedicated data pool + Dedizierten Datenpool verwenden + + + Data pool + Datenpool + + + Dedicated pool that stores the object-data of the RBD. + Dedizierter Pool zur Speicherung von RBD-Objektdaten. + + + e.g., 10GiB + z. B. 10GiB + + + You have to increase the size. + Sie müssen die Größe erhöhen. + + + Advanced + Erweitert + + + Striping + Striping + + + Stripe unit + Stripe-Einheit + + + -- Select stripe unit -- + -- Stripe-Einheit auswählen -- + + + This field is required because stripe count is defined! + Dies ist ein Pflichtfeld, da eine Stripe-Anzahl definiert wurde! + + + Stripe unit is greater than object size. + Die Stripe-Einheit ist größer als die Objektgröße. + + + Stripe count + Stripe-Anzahl + + + This field is required because stripe unit is defined! + Dies ist ein Pflichtfeld, da eine Stripe-Einheit definiert wurde! + + + Stripe count must be greater than 0. + Die Stripe-Anzahl muss größer als 0 sein. + + + + RBD Snapshot + + + RBD-Snapshot + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Umbenennen} other {Erstellen} } + + + + Snapshot + + + Snapshot + + + + PROTECTED + GESCHÜTZT + + + UNPROTECTED + NICHT GESCHÜTZT + + + You are about to rollback + Sie sind dabei, ein Rollback durchzuführen + + + Purge Trash + Papierkorb bereinigen + + + To purge, select one or All images and click + Zum Bereinigen ein oder alle Images auswählen und klicken + + + Pool: + Pool: + + + Pool name... + Poolname... + + + All + Alle + + + Restore Image + Image wiederherstellen + + + To restore + Zum Wiederherstellen + + + type the image's new name and click + Neuen Namen des Images eingeben und klicken + + + New Name + Neuer Name + + + Expired at + Abgelaufen am + + + Protected until + Geschützt bis + + + This image is protected until + . + + Dieses Image ist geschützt bis + . + + + + Trash + Papierkorb + + + iSCSI Topology + iSCSI-Topologie + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Eine Änderung dieser Parameter von ihren Standardwerten ist in der Regel nicht erforderlich. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Einstellungen + + + Backstore + Backstore + + + Confirm + Bestätigen + + + Advanced Settings + Erweiterte Einstellungen + + + Target IQN + Ziel-IQN + + + IQN has wrong pattern. + IQN hat ein fehlerhaftes Muster. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + Eine IQN hat die folgende Notation 'iqn.$jahr-$monat.$umkehradresse:$definierterName' + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Zum Beispiel: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Weitere Informationen + + + This target has modified advanced settings. + Erweiterte Einstellungen bei diesem Ziel wurden geändert. + + + Portals + Portale + + + At least + gateways are required. + + Es sind mindestens + Gateways erforderlich. + + + + Add portal + Portal hinzufügen + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Einstellungen bei diesem Image wurden geändert. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Image hinzufügen + + + ACL authentication + ACL-Authentifizierung + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Initiatoren + + + Initiator + Initiator + + + Client IQN + Client-IQN + + + Initiator IQN needs to be unique. + Initiator-IQN muss eindeutig sein. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Benutzernamen müssen zwischen 8 und 64 Zeichen lang sein und + dürfen nur Buchstaben, '.', '@', '-', '_' oder ':' enthalten. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + Der Initiator gehört zu einer Gruppe. Images werden in der Gruppe konfiguriert. + + + No items added. + Keine Elemente hinzugefügt. + + + Add initiator + Initiator hinzufügen + + + Groups + Gruppen + + + Group + Gruppe + + + Add group + Gruppe hinzufügen + + + [object Object] + [object Object] + + + RBD Configuration + RBD-Konfiguration + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Entfernen Sie den lokalen Konfigurationswert. Stattdessen wird der übergeordnete Konfigurationswert übernommen und verwendet. + + + The mininum value is 0 + Der Mindestwert lautet 0 + + + Issues + Probleme + + + Syncing + Wird synchronisiert + + + Ready + Fertig + + + Edit pool mirror mode + Spiegelungsmodus für Pool bearbeiten + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Wählen Sie zum Bearbeiten des Spiegelungsmodus für den Pool  + + + einen neuen Modus aus der Liste aus und klicken Sie auf  + Aktualisieren + . + + + + Mode + Modus + + + Peer clusters must be removed prior to disabling mirror. + Vor dem Deaktivieren der Spiegelung müssen Peer-Cluster entfernt werden. + + + + + pool mirror peer + + + + Peer für Poolspiegelung + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Bearbeiten} other {Hinzufügen} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + Der Pool + Spiegeln Sie Peer-Attribute für Pool + + + und klicken Sie auf + Absenden + . + + + + Cluster Name + Clustername + + + The cluster name is not valid. + Der Clustername ist ungültig. + + + CephX ID + CephX-ID + + + CephX ID... + CephX-ID... + + + The CephX ID is not valid. + Die CephX ID ist ungültig. + + + Monitor Addresses + Adressen der Monitore + + + Comma-delimited addresses... + Kommagetrennte Adressen... + + + The monitory address is not valid. + Die Anrede ist ungültig. + + + CephX Key + CephX-Schlüssel + + + Base64-encoded key... + Base64-codierter Schlüssel... + + + CephX key must be base64 encoded. + CephX-Schlüssel muss base64-codiert sein. + + + Pools List + Pool-Liste + + + The name can only consist of alphanumeric characters, dashes and underscores. + Der Name darf nur alphanumerische Zeichen, Bindestriche und Unterstriche enthalten. + + + The chosen erasure code profile name is already in use. + Der ausgewählte Löschcode-Profilname wird bereits verwendet. + + + Plugin + Plugin + + + Data chunks (k) + Datenblöcke (k) + + + Must be equal to or greater than 2. + Muss größer oder gleich 2 sein. + + + Coding chunks (m) + Datenblöcke für die Codierung (m) + + + Must be equal to or greater than 1. + Muss größer oder gleich 1 sein. + + + Durability estimator (c) + Dauerhaftigkeitsschätzung (c) + + + Locality (l) + Standort (l) + + + Crush failure domain + Crush-Ausfalldomäne + + + Crush Locality + Crush-Standort + + + None + Keine + + + Technique + Technik + + + Packetsize + Paketgröße + + + Crush root + Crush-Stamm + + + Crush device class + Crush-Geräteklasse + + + any + beliebig + + + Directory + Verzeichnis + + + The chosen Ceph pool name is already in use. + Der ausgewählte Poolname wird bereits verwendet. + + + Pool type + Pooltyp + + + -- Select a pool type -- + -- Pooltyp auswählen -- + + + Placement groups + Platzierungsgruppen + + + At least one placement group is needed! + Es wird mindestens eine Platzierungsgruppe benötigt. + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + Ihr Cluster kann nicht so viele Platzierungsgruppen verarbeiten. Berechnen Sie die benötigte Anzahl an Platzierungsgruppen. + + + Calculation help + Hilfe zur Berechnung + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + Die aktuellen Einstellungen für die Platzierungsgruppen wurden für Sie berechnet. + Stellen Sie vor dem Senden sicher, dass die Werte Ihren Anforderungen entsprechen. + + + Crush ruleset + Crush-Regelsatz + + + -- Select a crush rule -- + -- Crush-Regel auswählen -- + + + Crush rule + Crush-Regel + + + Crush steps + Crush-Schritte + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + Die Regel kann im aktuellen Cluster nicht verwendet werden, + da es zu wenige OSDs enthält, um das von dieser Regel geforderte OSD-Minimum zu erfüllen. + + + Replicated size + Reproduzierte Größe + + + Minimum: + + + Minimum: + + + + + Maximum: + + + Maximum: + + + + + The size specified is out of range. A value from + to + is valid. + + Die angegebene Größe liegt außerhalb des Bereichs. Gültige Werte liegen zwischen + und + . + + + + Erasure code profile + Löschcode-Profil + + + -- No erasure code profile available -- + -- Kein Löschcode-Profil verfügbar -- + + + -- Select an erasure code profile -- + -- Löschcode-Profil auswählen -- + + + EC Overwrites + EC-Überschreibungen + + + Applications + Anwendungen + + + Compression + Komprimierung + + + Algorithm + Algorithmus + + + -- No erasure compression algorithm available -- + -- Kein Löschkomprimierungsalgorithmus verfügbar -- + + + Minimum blob size + Minimale Blobgröße + + + e.g., 128KiB + z. B. 128KiB + + + Value should be greater than 0 + Wert sollte größer als 0 sein + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Maximale Blobgröße + + + e.g., 512KiB + z. B. 512KiB + + + Value should be greater than the minimum blob size + Wert sollte größer als die minimale Blobgröße sein + + + Ratio + Verhältnis + + + Compression ratio + Komprimierungsverhältnis + + + Value should be between 0.0 and 1.0 + Wert sollte zwischen 0,0 und 1,0 liegen + + + It's not possible to create an RBD pool with '/' in the name. + Es ist nicht möglich, einen RBD-Pool mit '/' im Namen zu erstellen. + + + Please change the name or remove 'rbd' from the applications list. + Ändern Sie den Namen oder entfernen Sie 'rbd' aus der Anwendungsliste. + + + Cache Tiers Details + Details zu den Cache-Ebenen + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Lesen Sie die + Dokumentation + zum + Konfigurieren und Aktivieren der Verwaltungsfunktion für das Objektgateway. + + + + Daemons List + Liste der Daemons + + + Performance Counters + Leistungsindikatoren + + + Loading bucket data... + Bucket-Daten werden geladen... + + + The bucket data could not be loaded. + Die Bucket-Daten konnten nicht geladen werden. + + + Id + ID + + + The value is not valid. + Der Wert ist ungültig. + + + Owner + Inhaber + + + -- Select a user -- + -- Benutzer auswählen -- + + + ID + ID + + + Index type + Indextyp + + + Placement rule + Platzierungsregel + + + Marker + Marker + + + Maximum marker + Maximum für Marker + + + Version + Version + + + Master version + Masterversion + + + Modification time + Änderungszeit + + + Zonegroup + Zonengruppe + + + Bucket quota + Bucket-Quote + + + Enabled + Aktiviert + + + Maximum size + Maximale Größe + + + Unlimited + Unbegrenzt + + + Maximum objects + Maximale Objekte + + + -- Select a username -- + -- Benutzername auswählen -- + + + Auto-generate key + Schlüssel automatisch generieren + + + Access key + Zugriffsschlüssel + + + Secret key + Geheimer Schlüssel + + + Email address + E-Mail-Adresse + + + Suspended + Angehalten + + + System + System + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {Nein} 1 {Ja} } + + + Maximum buckets + Maximale Buckets + + + Subusers + Unterbenutzer + + + Capabilities + Befähigungen + + + User quota + Benutzerquote + + + Show + Anzeigen + + + Keys + Schlüssel + + + -- Select a type -- + -- Typ auswählen -- + + + Permission + Berechtigung + + + -- Select a permission -- + -- Berechtigung auswählen -- + + + Subuser + Unterbenutzer + + + The chosen subuser ID is already in use. + Die ausgewählte Unterbenutzer-ID wird bereits verwendet. + + + read, write + lesen, schreiben + + + full + voll + + + Swift key + Swift-Schlüssel + + + Auto-generate secret + Geheimnis automatisch generieren + + + Loading user data... + Benutzerdaten werden geladen... + + + The user data could not be loaded. + Die Benutzerdaten konnten nicht geladen werden. + + + The chosen user ID is already in use. + Die ausgewählte Benutzer-ID wird bereits verwendet. + + + This is not a valid email address. + Dies ist keine gültige E-Mail-Adresse. + + + The chosen email address is already in use. + Die ausgewählte E-Mail-Adresse wird bereits verwendet. + + + Max. buckets + Max. Buckets + + + The entered value must be >= 0. + Der eingegebene Wert muss >=0 sein. + + + S3 key + S3-Schlüssel + + + There are no subusers. + Keine Unterbenutzer vorhanden. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + Keine Schlüssel vorhanden. + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + Keine Befähigungen vorhanden. + + + + + + + + + + + + + Unlimited size + Unbegrenzte Größe + + + Max. size + Max. Größe + + + Unlimited objects + Unbegrenzte Objekte + + + Max. objects + Max. Objekte + + + Current + Aktuell + + + Updated discovery authentication + Ermittlungsauthentifizierung aktualisiert + + + There are no portals available. + Keine Portale verfügbar. + + + There are no images available. + Keine Images verfügbar. + + + There are no images available. Please make sure you add an image to the target. + Keine Images verfügbar. Fügen Sie dem Ziel ein Image hinzu. + + + There are no initiators available. Please make sure you add an initiator to the target. + Keine Initiatoren verfügen. Fügen Sie dem Ziel einen Initiator hinzu. + + + target + target + + + Target + Ziel + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + Zustand + + + # Targets + # Targets + + + Read Bytes + Bytes für Lesevorgang + + + Write Bytes + Bytes für Schreibvorgang + + + Read Ops + Lesevorgänge + + + Write Ops + Schreibvorgänge + + + A/O Since + A/O seit + + + Instance + Instanz + + + Hostname + Hostname + + + Issue + Problem + + + Progress + Fortschritt + + + Disabled + Deaktiviert + + + Edit Mode + Bearbeitungsmodus + + + Add Peer + Peer hinzufügen + + + Edit Peer + Peer bearbeiten + + + Delete Peer + Peer löschen + + + Leader + Leader + + + # Local + # lokal + + + # Remote + # remote + + + mirror peer + Peer spiegeln + + + Key + Schlüssel + + + RBD + RBD + + + Deep flatten + Umfassende Vereinfachung + + + Layering + Schichtung + + + Exclusive lock + Exklusive Sperre + + + Object map (requires exclusive-lock) + Objektzuordnung (erfordert exklusive Sperre) + + + Journaling (requires exclusive-lock) + Journaling (erfordert exklusive Sperre) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Rollback für RBD-Snapshot + + + Rollback + Rollback + + + RBD snapshot + RBD-Snapshot + + + Deleted At + Gelöscht am + + + id + ID + + + type + Typ + + + state + Zustand + + + version + Version + + + Host + Host + + + root + Stamm + + + Rank + Rang + + + Daemon + Daemon + + + Activity + Aktivität + + + Dentries + Dentries + + + Inodes + Inodes + + + Usage + Nutzung + + + Standby daemons + Standby-Daemons + + + The value can be updated at runtime. + Der Wert kann zur Laufzeit aktualisiert werden. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + Daemons/Clients rufen diesen Wert nicht aus der + Datenbank 'monitor config' ab. Es ist nicht zulässig, diese Option über 'ceph config + set ...' festzulegen. Diese Option sollte über 'ceph.conf' oder an der + Befehlszeile konfiguriert werden. + + + Option takes effect only during daemon startup. + Die Option wird nur während des Daemon-Starts wirksam. + + + Option only affects cluster creation. + Die Option wirkt sich nur auf die Cluster-Erstellung aus. + + + Option only affects daemon creation. + Die Option wirkt sich nur auf die Daemon-Erstellung aus. + + + Updated config option + + + Aktualisierte config-Option + + + + + Service + Service + + + Current value + Aktueller Wert + + + Editable + Bearbeitbar + + + Updated options for module " + ". + + Aktualisierte Optionen für Modul &quot; + &quot;. + + + + Enable + Aktivieren + + + Disable + Deaktivieren + + + Reconnecting, please wait ... + Verbindung wird erneut hergestellt, bitte warten... + + + Public Address + Öffentliche Adresse + + + Open Sessions + Offene Sitzungen + + + No In + Kein In-Vorgang + + + OSDs that were previously marked out will not be marked back in when they start + OSDs, die zuvor als 'out' markiert wurden, werden beim Start nicht wieder markiert + + + No Out + Kein Out-Vorgang + + + OSDs will not automatically be marked out after the configured interval + OSDs werden nach dem konfigurierten Intervall nicht automatisch als 'out' markiert + + + No Up + Kein Up-Vorgang + + + OSDs are not allowed to start + OSDs dürfen nicht gestartet werden + + + No Down + Kein Down-Vorgang + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + OSD-Fehlerberichte werden ignoriert, sodass die Monitore die OSDs nicht als ausgefallen markieren + + + Pause + Pause + + + Pauses reads and writes + Hält Lese- und Schreibvorgänge an + + + No Scrub + Kein Scrub + + + Scrubbing is disabled + Scrubbing ist deaktiviert + + + No Deep Scrub + Kein umfassender Scrub + + + Deep Scrubbing is disabled + Umfassendes Scrubbing ist deaktiviert + + + No Backfill + Kein Abgleich + + + Backfilling of PGs is suspended + Abgleich der Platzierungsgruppen ist ausgesetzt + + + No Recover + Keine Wiederherstellung + + + Recovery of PGs is suspended + Wiederherstellung der Platzierungsgruppen ist ausgesetzt + + + Bitwise Sort + Bitweise Sortierung + + + Use bitwise sort + Bitweise Sortierung verwenden + + + Purged Snapdirs + Bereinigte Snapdirs + + + OSDs have converted snapsets + OSDs besitzen konvertierte Snapsets + + + Recovery Deletes + Löschvorgänge bei Wiederherstellungen + + + Deletes performed during recovery instead of peering + Bei der Wiederherstellung anstelle des Peerings durchgeführte Löschvorgänge + + + PG Log Hard Limit + Hardlimit für Platzierungsgruppen-Protokoll + + + Puts a hard limit on pg log length + Legt ein Hardlimit für die Platzierungsgruppen-Protokolllänge fest + + + Updated OSD Flags + Aktualisierte OSD-Flags + + + out + aus + + + in + ein + + + down + ausgefallen + + + Mark + Markieren + + + OSD lost + OSD verloren + + + marked lost + markierter Verlust + + + Purge + Bereinigen + + + OSD + OSD + + + purged + bereinigt + + + destroy + vernichten + + + destroyed + vernichtet + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + Platzierungsgruppen + + + Read bytes + Bytes für Lesevorgang + + + Writes bytes + Bytes für Schreibvorgang + + + Read ops + Lesevorgänge + + + Write ops + Schreibvorgänge + + + Mark OSD + + + OSD + markieren + + + + Mark + + + + markieren + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Max. Abgleiche + + + Recovery Max Active + Wiederherstellung, max. aktiv + + + Recovery Max Single Start + Wiederherstellung, max. - einzelner Start + + + Recovery Sleep + Wiederherstellung - Inaktivität + + + Custom + Benutzerdefiniert + + + Updated OSD recovery speed priority " + " + + Aktualisierte OSD-Wiederherstellungsgeschwindigkeits-Priorität &quot; + &quot; + + + + + was initialized in the following OSD: + + + + wurde im folgenden OSD initialisiert: + + + + + Create silence + Create silence + + + Job + Auftrag + + + Severity + Schweregrad + + + Started + Gestartet + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Aktualisiert + + + Ends + Ends + + + Silence + Silence + + + Used + Verwendet + + + Avail. + Verf. + + + Clean + Bereinigen + + + Working + In Bearbeitung + + + Warning + Warnung + + + Unknown + Unbekannt + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + aktiv + + + no filesystems + keine Dateisysteme + + + active + aktiv + + + standby + Standby + + + n/a + n. v. + + + active daemon + aktiver Daemon + + + quorum + Quorum + + + The NFS Ganesha service is not configured. + Der NFS Ganesha-Dienst ist nicht konfiguriert. + + + Transport + Transport + + + CephFS User + CephFS-Benutzer + + + CephFS Filesystem + CephFS-Dateisystem + + + (inherited from global config) + (aus globaler Konfiguration übernommen) + + + inherited from global config + aus globaler Konfiguration übernommen + + + -- Select what kind of user id squashing is performed -- + -- Durchzuführende Benutzer-ID-Squashing-Art auswählen -- + + + There are no daemons available. + Keine Daemons verfügbar. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Cache-Modus + + + Min Evict Age + Min. Alter für Vertreibung + + + Min Flush Age + Min. Alter für Leerung + + + Target Max Bytes + Max. Bytes für Ziel + + + Target Max Objects + Max. Objekte für Ziel + + + No applications added + Keine Anwendungen hinzugefügt + + + Applications limit reached + Anwendungslimit erreicht + + + A pool can only have up to four applications definitions. + Ein Pool kann nur bis zu vier Anwendungsdefinitionen aufweisen. + + + Allowed characters '_a-zA-Z0-9' + Zulässige Zeichen '_a-zA-Z0-9' + + + Maximum length is 128 characters + Maximale Länge beträgt 128 Zeichen + + + Filter or add applications + Anwendungen filtern oder hinzufügen + + + Add application + Anwendung hinzufügen + + + pool + pool + + + erasure code profile + Löschcode-Profil + + + Replica Size + Größe des Replikats + + + Last Change + Letzte Änderung + + + Erasure Coded Profile + Profil mit Löschcodierung + + + Crush Ruleset + Crush-Regelsatz + + + Write bytes + Bytes für Schreibvorgang + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + Bucket + + + Updated Object Gateway bucket " + " + + Aktualisierter Objektgateway-Bucket &quot; + &quot; + + + + Created Object Gateway bucket " + " + + Erstellter Objektgateway-Bucket &quot; + &quot; + + + + buckets + Buckets + + + capability + capability + + + user + Benutzer + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Aktualisierter Objektgatewaybenutzer &quot; + &quot; + + + + Created Object Gateway user " + " + + Erstellter Objektgatewaybenutzer &quot; + &quot; + + + + users + Benutzer + + + Swift Key + Swift Key + + + Scope + Bereich + + + Read + Lesen + + + Create + Erstellen + + + role + role + + + Created role ' + ' + + Erstellte Rolle ' + ' + + + + Updated role ' + ' + + Aktualisierte Rolle ' + ' + + + + System Role + Systemrolle + + + Deleted role ' + ' + + Gelöschte Rolle ' + ' + + + + Created user " + " + + Erstellter Benutzer &quot; + &quot; + + + + Update user + Benutzer aktualisieren + + + Continue + Fortfahren + + + You were automatically logged out because your roles have been changed. + Sie wurden automatisch abgemeldet, da Ihre Rollen geändert wurden. + + + Updated user " + " + + Aktualisierter Benutzer &quot; + &quot; + + + + Deleted user " + " + + Gelöschter Benutzer &quot; + &quot; + + + + Failed to delete user " + " + + Fehler beim Löschen des Benutzers &quot; + &quot; + + + + You are currently logged in as " + ". + + Sie sind derzeit angemeldet als &quot; + &quot;. + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Jedes Objekt wird in Datenblöcke aufgeteilt und jeweils auf einem anderen OSD gespeichert. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Berechnen Sie Codierungsdatenblöcke für jedes Objekt und speichern Sie sie auf unterschiedlichen OSDs. + Die Anzahl der Codierungsdatenblöcke entspricht auch der Anzahl der OSDs, die ausfallen können, ohne dass Daten verloren gehen. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Das jerasure-Modul ist das allgemeinste und flexibelste Modul + und fungiert auch als der Standard für Ceph-Pools mit Löschcodierung. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + Die flexiblere Technik ist 'reed_sol_van :', wobei es ausreicht, k + und m festzulegen. Die Technik 'cauchy_good' kann schneller sein. Sie müssen jedoch die Paketgröße sorgfältig + auswählen. Sämtliche 'reed_sol_r6_op'-, 'liberation'-, 'blaum_roth'- und 'liber8tion'-Vorgänge sind dahingehend RAID6-Entsprechungen, + dass sie nur mit 'm=2' konfiguriert werden können. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + Die Codierung wird jeweils für Pakete auf Bytes-Größe vorgenommen. + Die Auswahl der richtigen Paketgröße ist schwierig. + In der Jerasure-Dokumentation sind ausführliche Informationen zu diesem Thema enthalten. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + Bei Verwendung des Jerasure-Moduls, wenn ein Objekt mit Löschcodierung auf mehreren OSDs gespeichert ist, + müssen alle anderen OSDs gelesen werden, um die verloren gegangenen Daten eines OSDs wiederherzustellen. + Wenn jerasure beispielsweise mit 'k=8' und 'm=4' konfiguriert ist, + müssen bei Verlust eines OSDs zum Reparieren die elf anderen gelesen werden. + + Das lrc-Löschcode-Modul erstellt lokale Paritätsdatenblöcke, um die Wiederherstellung mit weniger OSDs auszuführen. + Wenn lrc beispielsweise mit 'k=8', 'm=4' und 'l=4' konfiguriert ist, wird ein zusätzlicher Paritätsdatenblock für jeweils vier OSDs erstellt. + Geht ein einzelnes OSD verloren, kann es mit nur vier OSDs anstelle + von elf wiederhergestellt werden. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Gruppieren Sie die Codierungs- und Datenblöcke in Sätze entsprechend dem Speicherort. + Beispielsweise werden für 'k=4' und 'm=2', wenn der Speicherort '3' entspricht, zwei Dreiergruppen erstellt. + Jeder Satz kann wiederhergestellt werden, ohne dass Datenblöcke aus einem anderen Satz gelesen werden. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + Der Typ des Crush-Buckets, in dem jeder durch l definierte Satz von Datenblöcken gespeichert wird. + Wenn er beispielsweise auf 'rack' festgelegt ist, wird jede Gruppe an l-Datenblöcken in einem anderen Rack platziert. + Er wird zum Erstellen eines CRUSH-Regelschritts verwendet, beispielsweise für einen Schritt zum Auswählen des Racks. + Wenn er nicht festgelegt ist, wird keine solche Gruppierung vorgenommen. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + Das isa-Modul kapselt die ISA-Bibliothek und wird nur auf Intel-Prozessoren ausgeführt. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + Das ISA-Modul wird in zwei Reed Solomon-Formularen bereitgestellt. + Wenn 'reed_sol_van' festgelegt ist, entspricht dies Vandermonde. Ist 'cauchy' festgelegt, entspricht dies 'Cauchy'. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + Das shec-Modul kapselt die SHEC-Mehrfachbibliothek. + Dadurch kann ceph Daten effizienter wiederherstellen als Reed Solomon-Codes. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + Die Anzahl der Paritätsdatenblöcke, von denen jeder jeden Datenblock in seinem Berechnungsbereich enthält. + Die Anzahl wird als eine Dauerhaftigkeitsschätzung verwendet. Wenn beispielsweise 'c=2' vorliegt, + können 2 OSDs ausfallen, ohne dass Daten verloren gehen. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + Der Name des für den ersten Schritt der CRUSH-Regel verwendeten Crush-Buckets. + Beispielsweise 'step take default'. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Stellen Sie sicher, dass sich keine zwei Datenblöcke in einem Bucket mit derselben Ausfalldomäne befinden. + Wenn die Ausfalldomäne beispielsweise als Host fungiert, werden keine zwei Datenblöcke auf demselben Host gespeichert. + Er wird zum Erstellen eines CRUSH-Regelschritts verwendet, beispielsweise 'step chooseleaf host'. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Schränken Sie mithilfe der Klassennamen für Crush-Geräte in der CRUSH-Zuordnung die Platzierung + auf Geräte einer bestimmten Klasse (z. B. SSD oder HDD) ein. + + + Set the directory name from which the erasure code plugin is loaded. + Legen Sie den Verzeichnisnamen fest, über den das Löschcode-Modul geladen wird. + + + Allows all operations + Lässt alle Vorgänge zu + + + Allows only operations that do not modify the server + Lässt nur Vorgänge zu, die den Server nicht ändern + + + Does not allow read or write operations, but allows any other operation + Lässt weder Lese- noch Schreibvorgänge zu, jedoch alle anderen Vorgänge + + + Does not allow read, write, or any operation that modifies file attributes or directory content + Lässt Lese-/Schreibvorgänge und andere Vorgänge nicht zu, die Dateiattribute oder Verzeichnisinhalte ändern + + + Allows no access at all + Lässt überhaupt keinen Zugriff zu + + + -- Select the priority -- + -- Priorität auswählen -- + + + Low + Niedrig + + + High + Hoch + + + Last 5 minutes + Letzte 5 Minuten + + + Last 15 minutes + Letzte 15 Minuten + + + Last 30 minutes + Letzte 30 Minuten + + + Last 1 hour (Default) + Letzte Stunde (Standard) + + + Last 3 hours + Letzte 3 Stunden + + + Last 6 hours + Letzte 6 Stunden + + + Last 12 hours + Letzte 12 Stunden + + + Last 24 hours + Letzte 24 Stunden + + + Yesterday + Gestern + + + Today + Heute + + + Today so far + Heute bisher + + + Day before yesterday + Vorgestern + + + Last 2 days + Letzte 2 Tage + + + This day last week + Dieser Tag letzte Woche + + + Previous week + Vorwoche + + + This week + Diese Woche + + + This week so far + Diese Woche bisher + + + Last 7 days + Letzte 7 Tage + + + Previous month + Vormonat + + + This month + Dieser Monat + + + This month so far + Dieser Monat bisher + + + Last 30 days + Letzte 30 Tage + + + Last 90 days + Letzte 90 Tage + + + Last 6 months + Letzte 6 Monate + + + Last 1 year + Letztes Jahr + + + Previous year + Vorjahr + + + This year + Dieses Jahr + + + This year so far + Dieses Jahr bisher + + + Last 2 years + Letzte 2 Jahre + + + Last 5 years + Letzte 5 Jahre + + + Information + Informationen + + + No items selected. + Keine Elemente ausgewählt. + + + Deselect item to select again + Elementauswahl zum erneuten Auswählen aufheben + + + Selection limit reached + Auswahllimit erreicht + + + Filter tags + Tags filtern + + + Add badge + Badge hinzufügen + + + There are no items available. + Keine Elemente verfügbar. + + + Add + Hinzufügen + + + Remove + Remove + + + Clone + Klonen + + + Copy + Kopieren + + + Deep Scrub + Umfassender Scrub + + + Destroy + Vernichten + + + Flatten + Vereinfachen + + + Mark Down + Als ausgefallen markieren + + + Mark In + Mit Befehl 'In' markieren + + + Mark Lost + Als verloren markieren + + + Mark Out + Mit Befehl 'Out' markieren + + + Protect + Schützen + + + Rename + Umbenennen + + + Restore + Wiederherstellen + + + Move to Trash + In Papierkorb verschieben + + + Unprotect + Schutz aufheben + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Gelöscht + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Geklont + + + Copied + Kopiert + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + Ja + + + No + Nein + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Quality of Service + + + BPS Limit + BPS-Limit + + + The desired limit of IO bytes per second. + Das gewünschte Limit der E/A-Bytes pro Sekunde. + + + IOPS Limit + IOPS-Limit + + + The desired limit of IO operations per second. + Das gewünschte Limit der E/A-Vorgänge pro Sekunde. + + + Read BPS Limit + BPS-Limit für Lesevorgänge + + + The desired limit of read bytes per second. + Das gewünschte Limit der gelesenen Bytes pro Sekunde. + + + Read IOPS Limit + IOPS-Limit für Lesevorgänge + + + The desired limit of read operations per second. + Das gewünschte Limit für Lesevorgänge pro Sekunde. + + + Write BPS Limit + BPS-Limit für Schreibvorgänge + + + The desired limit of write bytes per second. + Das gewünschte Limit der geschriebenen Bytes pro Sekunde. + + + Write IOPS Limit + IOPS-Limit für Schreibvorgänge + + + The desired limit of write operations per second. + Das gewünschte Limit für Schreibvorgänge pro Sekunde. + + + BPS Burst + BPS-Block + + + The desired burst limit of IO bytes. + Das gewünschte Blocklimit der E/A-Bytes. + + + IOPS Burst + IOPS-Block + + + The desired burst limit of IO operations. + Das gewünschte Blocklimit der E/A-Vorgänge. + + + Read BPS Burst + BPS-Block für Lesevorgänge + + + The desired burst limit of read bytes. + Das gewünschte Blocklimit der gelesenen Bytes. + + + Read IOPS Burst + IOPS-Block für Lesevorgänge + + + The desired burst limit of read operations. + Das gewünschte Blocklimit der Lesevorgänge. + + + Write BPS Burst + BPS-Block für Schreibvorgänge + + + The desired burst limit of write bytes. + Das gewünschte Blocklimit der geschriebenen Bytes. + + + Write IOPS Burst + IOPS-Block für Schreibvorgänge + + + The desired burst limit of write operations. + Das gewünschte Blocklimit der Schreibvorgänge. + + + Failed to + + + + Fehler bei + + + + + + Executing + Wird ausgeführt + + + execute + ausführen + + + Executed + Ausgeführt + + + unknown task + Unbekannte Aufgabe + + + Creating + Wird erstellt + + + create + erstellen + + + Updating + Wird aktualisiert + + + update + aktualisieren + + + Deleting + Wird gelöscht + + + delete + löschen + + + RBD ' + ' + + RBD ' + ' + + + + RBD snapshot ' + ' + + RBD-Snapshot ' + ' + + + + mirror mode for pool ' + ' + + Spiegelungsmodus für Pool ' + ' + + + + mirror peer for pool ' + ' + + Peer für Pool ' + ' spiegeln + + + + all dashboards + all dashboards + + + Name is already used by + . + + Name wird bereits von + verwendet. + + + + Name is already used by + . + + Name wird bereits von + verwendet. + + + + Name is already used by + . + + Name wird bereits von + verwendet. + + + + + contains snapshots. + + + enthält Snapshots. + + + + Cloning + Wird geklont + + + clone + klonen + + + Snapshot of + must be protected. + + Snapshot von + muss geschützt sein. + + + + Copying + Wird kopiert + + + copy + kopieren + + + Flattening + Wird vereinfacht + + + flatten + vereinfachen + + + Flattened + Vereinfacht + + + Name is already used by + . + + Name wird bereits von + verwendet. + + + + Cannot unprotect + because it contains child images. + + Der Schutz von + kann aufgrund enthaltener untergeordneter Images nicht aufgehoben werden. + + + + Cannot delete + because it's protected. + + Kann + nicht löschen, da es geschützt ist. + + + + Rolling back + Rollback wird ausgeführt + + + rollback + Rollback + + + Rolled back + Rollback wurde ausgeführt + + + Moving + Wird verschoben + + + move + verschieben + + + Moved + Verschoben + + + image ' + ' to trash + + Image ' + ' in Papierkorb verschieben + + + + Could not find image. + Image konnte nicht gefunden werden. + + + Restoring + Wird wiederhergestellt + + + restore + wiederherstellen + + + Restored + Wiederhergestellt + + + image ' + ' into ' + ' + + Image ' + ' in ' + ' verschieben + + + + Image name ' + ' is already in use. + + Image-Name ' + ' wird bereits verwendet. + + + + image ' + ' + + Image ' + ' + + + + Purging + Wird bereinigt + + + purge + bereinigen + + + Purged + Bereinigt + + + all pools + alle Pools + + + images from + + + Images von + + + + + Cannot disable mirroring because it contains a peer. + Spiegelung kann nicht deaktiviert werden, da sie einen Peer enthält. + + + pool ' + ' + + Pool ' + ' + + + + erasure code profile ' + ' + + Löschcode-Profil ' + ' + + + + target ' + ' + + Ziel ' + ' + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf new file mode 100644 index 00000000..b3a8eb5f --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.es-ES.xlf @@ -0,0 +1,4371 @@ + + + + + Toggle navigation + Alternar navegación + + + Dashboard + Consola + + + Cluster + Clúster + + + Hosts + Hosts + + + Monitors + Monitores + + + OSDs + OSDs + + + Configuration + Configuración + + + CRUSH map + Mapa de CRUSH + + + Manager modules + Módulos de gestor + + + Logs + Registros + + + Alerts + Alertas + + + Silences + Silences + + + Pools + Repositorios + + + Block + Bloque + + + Images + Imágenes + + + Mirroring + Duplicación + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + Sistemas de archivos + + + Object Gateway + Object Gateway + + + Daemons + Daemons + + + Users + Usuarios + + + Buckets + Papeleras + + + Retrieving data + for + + + . Please wait... + + Obteniendo datos + +para + + + . Espere. + + + + Displaying previously cached data + + for + + + . + + Mostrando datos guardados previamente en caché + +para + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + No se han podido cargar los datos + para + + + . +Consulte el estado del clúster. + + + + Back + Atrás + + + Select a Language + Seleccione un idioma + + + Loading panel data... + Cargando datos del panel... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Consulte la + documentación + sobre cómo +configurar y habilitar la supervisión. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + No existe la consola de Grafana. Consulte la + documentación + sobre cómo + añadir consolas a Grafana. + + + + Grafana Time Picker + Selector de hora de Grafana + + + Reset Settings + Restablecer ajustes + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Error al cargar los datos. + + + selected + seleccionados + X selected + + + found + encontrados + X found + + + total + total + X total + + + Edit + Editar + + + Name + Nombre + + + Description + Descripción + + + Long description + Descripción larga + + + Default + Opción por defecto + + + Daemon default + Daemon por defecto + + + Services + Servicios + + + Values + Valores + + + The entered value is too high! It must not be greater than + . + + El valor introducido es demasiado alto. No debe ser mayor que + . + + + + The entered value is too low! It must not be lower than + . + + El valor introducido es demasiado bajo. No debe ser menor que + . + + + + Save + Guardar + + + CRUSH map viewer + Visor del mapa de CRUSH + + + Hosts List + Lista de hosts + + + Overall Performance + Rendimiento general + + + No entries found + No se encuentra ninguna entrada + + + Cluster Logs + Registros del clúster + + + Audit Logs + Registros de auditoría + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Cargando configuración... + + + The configuration could not be loaded. + No es posible cargar la configuración. + + + Edit Manager module + Módulo del gestor de edición + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + El valor introducido no es un UUID válido, por ejemplo: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + El valor introducido debe ser una dirección IP válida. + + + This field is required. + Este campo es obligatorio. + + + The entered value is too high! It must be lower or equal to + . + + El valor introducido es demasiado alto. Debe ser menor o igual que + . + + + + The entered value is too low! It must be greater or equal to + . + + El valor introducido es demasiado bajo. Debe ser mayor o igual que + . + + + + The entered value needs to be a number. + El valor introducido debe ser un número. + + + The entered value needs to be a number or decimal. + El valor introducido debe ser un número o un decimal. + + + Update + Actualizar + + + Status + Estado + + + Cluster ID + ID de clúster + + + monmap modified + Mapa de supervisión modificado + + + monmap epoch + Época de mapa de supervisión + + + quorum con + quórum de con + + + quorum mon + quórum de mon + + + required con + con requerido + + + required mon + mon requerido + + + In Quorum + Con quórum + + + Not In Quorum + Sin quórum + + + Cancel + Cancelar + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + ¿Seguro que quiere + el elemento + seleccionado? + + + + Yes, I am sure. + Sí, seguro. + + + Cluster-wide OSD Flags + Indicadores OSD de todo el clúster + + + Submit + Enviar + + + + + + + + + + + form title + + + Advanced... + Avanzado... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + Prioridad de recuperación de OSD + + + Priority + Prioridad + + + Customize priority values + Personalizar valores de prioridad + + + This field is required! + Este campo es obligatorio. + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + El valor introducido es demasiado alto. No debe ser mayor que + . + + + + The entered value is too low! It must not be lower than + . + + El valor introducido es demasiado bajo. No debe ser menor que + . + + + + Reweight OSD + Reequilibrar peso de OSD + + + The value needs to be between 0 and 1. + El valor debe estar entre 0 y 1. + + + Reweight + Reequilibrar peso + + + OSDs + Scrub + + + Depuración de OSDs + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {Profundo} } + + + You are about to apply a + scrub to + the OSD + + + . + + Se dispone a aplicar una + depuración + al OSD + + + . + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {profundo} } + + + OSDs List + Lista de OSD + + + + OSD + + will be marked + + + if you proceed. + + Si continúa, el + OSD + + + se marcará + + + . + + + + The OSD is not safe to destroy! + No es seguro destruir el OSD. + + + + OSD + + will be + + + if you proceed. + + Si continúa, el + OSD + + + se + + + . + + + + Details + Detalles + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Valor + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Cerrar + + + Delete + Suprimir + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Estado + + + Statistics + Estadísticas + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Consulte la + documentación + + sobre cómo configurar y habilitar la función de gestión de NFS Ganesha. + + + + Clients + Clientes + + + Any client can access + Cualquier cliente puede acceder + + + Addresses + Destinatarios + + + Required field + Campo requerido + + + Must contain one or more comma-separated values + Debe contener uno o varios valores separados por comas + + + For example: + Por ejemplo: + + + Access Type + Tipo de acceso + + + Squash + Reducir privilegios + + + Add clients + Añadir clientes + + + Loading... + Cargando... + + + -- No cluster available -- + -- No hay ningún clúster disponible -- + + + -- Select the cluster -- + -- Seleccione el clúster -- + + + Add daemon + Añadir daemon + + + Storage Backend + Motor de almacenamiento + + + -- No data pools available -- + -- No hay ningún repositorio de datos disponible -- + + + -- Select the storage backend -- + -- Seleccione el motor de almacenamiento -- + + + Object Gateway User + Usuario de Object Gateway + + + -- No users available -- + -- No hay ningún usuario disponible -- + + + -- Select the object gateway user -- + -- Seleccione el usuario de Object Gateway -- + + + CephFS User ID + ID de usuario de CephFS + + + -- No clients available -- + -- No hay ningún cliente disponible -- + + + -- Select the cephx client -- + -- Seleccione el cliente de CephX -- + + + CephFS Name + Nombre de CephFS + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Etiqueta de seguridad + + + Enable security label + Habilitar etiqueta de seguridad + + + CephFS Path + Ruta de CephFS + + + Path need to start with a '/' and can be followed by a word + La ruta debe empezar por "/" y puede ir seguida de una palabra + + + New directory will be created + Se creará un directorio nuevo + + + Path + Ruta + + + Path can only be a single '/' or a word + La ruta solo puede ser una "/" o una palabra + + + New bucket will be created + Se creará una papelera nueva + + + NFS Protocol + Protocolo NFS + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + Etiqueta NFS + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Acceso alternativo para montajes + NFS v3 + (no debe empezar con /). + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + Puede que los clientes no monten subdirectorios (es decir, si Etiqueta = foo, el cliente puede que no monte foo/baz). + + + By using different Tag options, the same Path may be exported multiple times. + Al usar distintas opciones de Etiqueta, la misma Ruta se puede exportar varias veces. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + La posición que ocupa esta exportación + NFS v4 + + en + Pseudo FS + (debe ser exclusiva). + + + + By using different Pseudo options, the same Path may be exported multiple times. + Al usar distintas opciones de Pseudo, la misma Ruta se puede exportar varias veces. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- No hay ningún tipo de acceso disponible -- + + + -- Select the access type -- + -- Seleccione el tipo de acceso -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- No hay ninguna reducción de privilegios disponible -- + + + --Select what kind of user id squashing is performed -- + -- Seleccione el tipo de reducción de privilegios de ID de usuario que se va a realizar -- + + + Transport Protocol + Protocolo de transporte + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + ¡Bienvenidos a Ceph! + The welcome message on the login page + + + Username is required + El nombre de usuario es obligatorio + + + Password is required + La contraseña es obligatoria + + + Login + Entrada + + + Sorry, the user does not exist in Ceph. + Lo sentimos. El usuario no existe en Ceph. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Vuelva a la + Página de entrada + . Saldrá del proveedor de identidad cuando vuelva a intentar entrar a la sesión. + + + + Forbidden + Prohibido + + + Sorry, you are not allowed to see what you were looking for. + Lo sentimos. No tiene permiso para ver lo que busca. + + + Sorry, we could not find what you were looking for + Lo sentimos. No se encuentra lo que busca + + + Remove all + Eliminar todo + + + Recent Notifications + Notificaciones recientes + + + There are no background tasks. + No hay tareas en segundo plano. + + + Background Tasks + Tareas en segundo plano + + + Help + Ayuda + + + Documentation + Documentación + + + API + API + + + About + Acerca de + + + Dashboard Settings + Ajustes de la consola + + + User management + Gestión del usuario + + + Logged in user + Usuario que ha entrado + + + Signed in as + + + + + Ha entrado como + + + + + + + Sign out + Salir + + + Name... + Nombre... + + + The chosen name is already in use. + El nombre que ha elegido ya está en uso. + + + Description... + Descripción... + + + Permissions + Permisos + + + Roles + Funciones + + + Username + Nombre de usuario + + + Password + Contraseña + + + Confirm password + Confirmar contraseña + + + Password confirmation doesn't match the password. + Las contraseñas no coinciden. + + + Full name + Nombre completo + + + Email + Correo electrónico + + + Invalid email. + Correo electrónico no válido. + + + You are about to remove "user read / update" permissions from your own user. + Se dispone a eliminar los permisos "lectura/actualización de usuario" de su propio usuario. + + + If you continue, you will no longer be able to add or remove roles from any user. + Si continúa, no podrá añadir ni eliminar funciones en ningún usuario. + + + Are you sure you want to continue? + ¿Seguro que desea continuar? + + + Performance counters not available + Los contadores de rendimiento no están disponibles + + + Attributes (OSD map) + Atributos (mapa de OSD) + + + Metadata not available + Los metadatos no están disponibles + + + Metadata + Metadatos + + + Performance counter + Contandor de rendimiento + + + Histogram not available: + + + El histograma no está disponible: + + + + + Writes + Escrituras + + + Reads + Lecturas + + + Histogram + Histograma + + + Performance Details + Detalles de rendimiento + + + Current values + Valores actuales + + + Type + Tipo + + + Min + Mín. + + + Max + Máx. + + + Flags + Indicadores + + + Source + Origen + + + Level + Nivel + + + Can be updated at runtime (editable) + Se puede actualizar en el tiempo de ejecución (editable) + + + Tags + Etiquetas + + + Enum values + Valores Enum + + + See also + Véase también + + + Cluster Status + Estado del clúster + + + Manager Daemons + Daemons de gestor + + + Object Gateways + Instancias de Object Gateway + + + Metadata Servers + Servidores de metadatos + + + iSCSI Gateways + Puertas de enlace iSCSI + + + Client IOPS + IOPS de cliente + + + Client Throughput + Rendimiento del cliente + + + Client Read/Write + Lectura/escritura de cliente + + + Recovery Throughput + Rendimiento de recuperación + + + Scrub + Depuración + + + Performance + Rendimiento + + + Raw Capacity + Capacidad en bruto + + + Objects + Objetos + + + PGs per OSD + Grupos de colocación por OSD + + + PG Status + Estado del grupo de colocación + + + Capacity + Capacidad + + + + + See + Logs + for more details. + + + + Consulte la sección + Registros + para obtener más datos. + + + + Ranks + Clasificaciones + + + MDS performance counters + MDS performance counters + + + Clients: + + + Clientes: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Mover una imagen a la papelera + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Para mover + + / + + a la papelera, + haga clic en + Mover imagen + . Opcionalmente, puede seleccionar una fecha de caducidad. + + + + Protection expires at + La protección caduca a las + + + NOT PROTECTED + SIN PROTECCIÓN + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Formato de fecha erróneo. Use el formato "AAAA-MM-DD HH:mm:ss". + + + Protection has already expired. Please pick a future date or leave it empty. + La protección ya ha caducado. Seleccione una fecha del futuro o deje el campo vacío. + + + Move Image + Mover imagen + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Resumen + + + Targets + Destinos + + + Discovery Authentication + Autenticación de descubrimiento + + + User + Usuario + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Los nombres de usuario deben tener entre 8 y 64 caracteres y + solo pueden incluir letras y estos caracteres: ".", "@", "-", "_" o ":". + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Usuario mutuo + + + Mutual Password + Contraseña mutua + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Consulte la + documentación + + sobre cómo configurar y habilitar la función de gestión de destinos iSCSI. + + + + Available information: + Información disponible: + + + iSCSI Targets not available + Destinos iSCSI no disponibles + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + Solo disponible para imágenes RBD con + fast-diff + habilitado + + + + Pool + Repositorio + + + Data Pool + Repositorio de datos + + + Created + Creados + + + Size + Tamaño + + + Object size + Tamaño del objeto + + + Features + Características + + + Provisioned + Aprovisionados + + + N/A + N/D + + + Total provisioned + Total aprovisionado + + + Striping unit + Unidad de repartición + + + Striping count + Recuento de repartición + + + Parent + Padre + + + Block name prefix + Prefijo de nombre de bloque + + + Order + Orden + + + Snapshots + Instantáneas + + + Image + Imagen + + + This setting overrides the global value + Este ajuste sustituye al valor global + + + Global + Global + + + This is the global value. No value for this option has been set for this image. + Este es el valor global. No se ha definido ningún valor para esta opción para esta imagen. + + + + from + + + from + + + + '/' and '@' are not allowed. + No se permiten los caracteres "/" ni "@". + + + -- No rbd pools available -- + -- No hay ningún repositorio RBD disponible -- + + + -- Select a pool -- + -- Seleccione un repositorio -- + + + Use a dedicated data pool + Usar un repositorio dedicado para datos + + + Data pool + Repositorio de datos + + + Dedicated pool that stores the object-data of the RBD. + Repositorio dedicado para almacenar los datos de objeto de RBD. + + + e.g., 10GiB + ej.: 10 GiB + + + You have to increase the size. + Debe aumentar el tamaño. + + + Advanced + Avanzado + + + Striping + Repartición + + + Stripe unit + Unidad de repartición + + + -- Select stripe unit -- + -- Seleccione la unidad de repartición -- + + + This field is required because stripe count is defined! + Este campo es obligatorio porque se ha definido el recuento de repartición. + + + Stripe unit is greater than object size. + La unidad de repartición es mayor que el tamaño del objeto. + + + Stripe count + Recuento de repartición + + + This field is required because stripe unit is defined! + Este campo es obligatorio porque se ha definido la unidad de repartición. + + + Stripe count must be greater than 0. + El recuento de repartición debe ser mayor que 0. + + + + RBD Snapshot + + + instantánea RBD + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Renombrar} other {Crear} } + + + + Snapshot + + + instantánea + + + + PROTECTED + CON PROTECCIÓN + + + UNPROTECTED + SIN PROTECCIÓN + + + You are about to rollback + Se dispone a revertir + + + Purge Trash + Vaciar papelera + + + To purge, select one or All images and click + Para limpiar, seleccione una imagen, o todas las imágenes, y haga clic en + + + Pool: + Repositorio: + + + Pool name... + Nombre del repositorio... + + + All + Todas + + + Restore Image + Restaurar imágenes + + + To restore + Para restaurar + + + type the image's new name and click + escriba el nombre nuevo de la imagen y haga clic en + + + New Name + Nombre nuevo + + + Expired at + Caducó a las + + + Protected until + Protección hasta + + + This image is protected until + . + + Esta imagen está protegida hasta el + . + + + + Trash + Papelera + + + iSCSI Topology + Topología iSCSI + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Normalmente no es necesario cambiar los valores por defecto de estos parámetros. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Ajustes + + + Backstore + Almacén + + + Confirm + Confirmar + + + Advanced Settings + Ajustes avanzados + + + Target IQN + IQN de destino + + + IQN has wrong pattern. + El IQN tiene un patrón erróneo. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + Los IQN tienen esta notación: iqn.$year-$month.$reversedAddress:$definedName + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Por ejemplo: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Más información + + + This target has modified advanced settings. + Este destino tiene ajustes avanzados modificados. + + + Portals + Portales + + + At least + gateways are required. + + Se requieren al menos + puertas de enlace. + + + + Add portal + Añadir portal + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Esta imagen tiene ajustes modificados. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Añadir imagen + + + ACL authentication + Autenticación de ACL + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Iniciadores + + + Initiator + Iniciador + + + Client IQN + IQN del cliente + + + Initiator IQN needs to be unique. + El IQN del iniciador debe ser exclusivo. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Los nombres de usuario deben tener entre 8 y 64 caracteres y + solo pueden incluir letras y estos caracteres: ".", "@", "-", "_" o ":". + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + El iniciador pertenece a un grupo. Las imágenes se configurarán en el grupo. + + + No items added. + No se ha añadido ningún elemento. + + + Add initiator + Añadir iniciador + + + Groups + Grupos + + + Group + Grupo + + + Add group + Añadir grupo + + + [object Object] + [object Object] + + + RBD Configuration + Configuración de RBD + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Elimina el valor de configuración local. Se heredará y usará en su lugar el valor de configuración padre. + + + The mininum value is 0 + El valor mínimo es 0 + + + Issues + Problemas + + + Syncing + Sincronizando + + + Ready + Listo + + + Edit pool mirror mode + Editar modo de duplicación de repositorio + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Para editar el modo de duplicación del repositorio  + + + , seleccione un modo nuevo en la lista y haga clic  + en + Actualizar + . + + + + Mode + Modo + + + Peer clusters must be removed prior to disabling mirror. + Los clústeres de par deben eliminarse antes de inhabilitar la duplicación. + + + + + pool mirror peer + + + +duplicar par de repositorio + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Editar} other {Añadir} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + los atributos del par + de duplicación del respositorio + + + y haga clic en + Enviar + . + + + + Cluster Name + Nombre del clúster + + + The cluster name is not valid. + El nombre del clúster no es válido. + + + CephX ID + ID de CephX + + + CephX ID... + ID de CephX... + + + The CephX ID is not valid. + El ID de CephX no es válido. + + + Monitor Addresses + Direcciones de monitores + + + Comma-delimited addresses... + Direcciones delimitadas por comas... + + + The monitory address is not valid. + La dirección del monitor no es válida. + + + CephX Key + Clave de CephX + + + Base64-encoded key... + Clave con cifrado base64... + + + CephX key must be base64 encoded. + La clave de CephX debe tener cifrado base64 + + + Pools List + Lista de repositorios + + + The name can only consist of alphanumeric characters, dashes and underscores. + El nombre solo puede tener caracteres alfanuméricos, guiones y guiones bajos. + + + The chosen erasure code profile name is already in use. + El nombre del perfil de código de borrado que ha elegido ya está en uso. + + + Plugin + Complemento + + + Data chunks (k) + Porciones de datos (k) + + + Must be equal to or greater than 2. + Debe ser igual o mayor que 2. + + + Coding chunks (m) + Porciones de código (m) + + + Must be equal to or greater than 1. + Debe ser igual o mayor que 1. + + + Durability estimator (c) + Estimador de durabilidad (c) + + + Locality (l) + Localización (l) + + + Crush failure domain + Dominio de error de CRUSH + + + Crush Locality + Localización de CRUSH + + + None + Ninguna + + + Technique + Técnica + + + Packetsize + Tamaño del paquete + + + Crush root + Raíz de CRUSH + + + Crush device class + Clase de dispositivo de CRUSH + + + any + cualquiera + + + Directory + Directorio + + + The chosen Ceph pool name is already in use. + El nombre del repositorio de Ceph que ha elegido ya está en uso. + + + Pool type + Tipo de repositorio + + + -- Select a pool type -- + -- Seleccione un tipo de repositorio -- + + + Placement groups + Grupos de colocación + + + At least one placement group is needed! + Se necesita al menos un grupo de colocación. + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + El clúster no puede gestionar tantos grupos de colocación. Vuelva a calcular la cantidad que necesita. + + + Calculation help + Ayuda para el cálculo + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + El número grupos de colocación actual se ha calculado +  automáticamente. Debe asegurarse de que sirve para sus necesidades antes de enviar. + + + Crush ruleset + Conjunto de reglas de CRUSH + + + -- Select a crush rule -- + -- Seleccione una regla de CRUSH -- + + + Crush rule + Regla de CRUSH + + + Crush steps + Pasos de CRUSH + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + La regla no se puede usar en el clúster actual, ya que + no tiene suficientes OSD que cumplan el mínimo requerido. + + + Replicated size + Tamaño replicado + + + Minimum: + + + Mínimo: + + + + + Maximum: + + + Máximo: + + + + + The size specified is out of range. A value from + to + is valid. + + El tamaño especificado está fuera del intervalo. Los valores válidos + son del + al + . + + + + Erasure code profile + Perfil de código de borrado + + + -- No erasure code profile available -- + -- No hay ningún perfil de código de borrado disponible -- + + + -- Select an erasure code profile -- + -- Seleccione un perfil de código de borrado -- + + + EC Overwrites + Sustituciones de códigos de borrado + + + Applications + Aplicaciones + + + Compression + Compresión + + + Algorithm + Algoritmo + + + -- No erasure compression algorithm available -- + -- No hay ningún algoritmo de compresión de borrado disponible -- + + + Minimum blob size + Tamaño de Blob mínimo + + + e.g., 128KiB + p. ej. 128 KiB + + + Value should be greater than 0 + El valor debe ser mayor que 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Tamaño de Blob máximo + + + e.g., 512KiB + p. ej. 512 KiB + + + Value should be greater than the minimum blob size + El valor debe ser mayor que el tamaño de Blob mínimo + + + Ratio + Relación + + + Compression ratio + Relación de compresión + + + Value should be between 0.0 and 1.0 + El valor debe estar entre 0,0 y 1,0 + + + It's not possible to create an RBD pool with '/' in the name. + No es posible crear un repositorio RBD con el nombre "/". + + + Please change the name or remove 'rbd' from the applications list. + Cambie el nombre o elimine "rbd" de la lista de aplicaciones. + + + Cache Tiers Details + Detalles de niveles de caché + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Consulte la + documentación + + sobre cómo configurar y habilitar la función de gestión de Object Gateway. + + + + Daemons List + Lista de daemons + + + Performance Counters + Contadores de rendimiento + + + Loading bucket data... + Cargando datos de la papelera... + + + The bucket data could not be loaded. + No es posible cargar los datos de la papelera. + + + Id + ID + + + The value is not valid. + El valor no es válido. + + + Owner + Propietario + + + -- Select a user -- + -- Seleccione un usuario -- + + + ID + ID + + + Index type + Tipo de índice + + + Placement rule + Regla de colocación + + + Marker + Marcador + + + Maximum marker + Marcador máximo + + + Version + Versión + + + Master version + Versión maestra + + + Modification time + Hora de modificación + + + Zonegroup + Grupo de zona + + + Bucket quota + Cuota de papelera + + + Enabled + Habilitado + + + Maximum size + Tamaño máximo + + + Unlimited + Sin límite + + + Maximum objects + Número máximo de objetos + + + -- Select a username -- + -- Seleccione un nombre de usuario -- + + + Auto-generate key + Autogenerar clave + + + Access key + Clave de acceso + + + Secret key + Clave secreta + + + Email address + Dirección de correo electrónico + + + Suspended + Suspendido + + + System + Sistema + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {No} 1 {Sí} } + + + Maximum buckets + Número máximo de papeleras + + + Subusers + Subusuarios + + + Capabilities + Capacidades + + + User quota + Cuota de usuario + + + Show + Mostrar + + + Keys + Claves + + + -- Select a type -- + -- Seleccione un tipo -- + + + Permission + Permiso + + + -- Select a permission -- + -- Seleccione un permiso -- + + + Subuser + Subusuario + + + The chosen subuser ID is already in use. + El ID de subusuario que ha elegido ya está en uso. + + + read, write + lectura, escritura + + + full + todos + + + Swift key + Clave Swift + + + Auto-generate secret + Autogenerar secreto + + + Loading user data... + Cargando datos del usuario... + + + The user data could not be loaded. + No es posible cargar los datos del usuario. + + + The chosen user ID is already in use. + El ID de usuario que ha elegido ya está en uso. + + + This is not a valid email address. + Esta dirección no es válida. + + + The chosen email address is already in use. + La dirección de correo electrónico que ha elegido ya está en uso. + + + Max. buckets + Máx. papeleras + + + The entered value must be >= 0. + El valor introducido debe ser mayor o igual que 0. + + + S3 key + Clave S3 + + + There are no subusers. + No hay ningún subusuario. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + No hay ninguna clave. + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + No hay ninguna capacidad + + + + + + + + + + + + + Unlimited size + Tamaño ilimitado + + + Max. size + Tamaño máx. + + + Unlimited objects + Objetos ilimitados + + + Max. objects + Objetos máx. + + + Current + Actual + + + Updated discovery authentication + Autenticación de descubrimiento actualizada + + + There are no portals available. + No hay ningún portal disponible. + + + There are no images available. + No hay ninguna imagen disponible. + + + There are no images available. Please make sure you add an image to the target. + No hay ninguna imagen disponible. Asegúrese de añadir una imagen al destino. + + + There are no initiators available. Please make sure you add an initiator to the target. + No hay ningún iniciador disponible. Asegúrese de añadir un iniciador al destino. + + + target + target + + + Target + Destino + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + Estado + + + # Targets + # Targets + + + Read Bytes + Bytes de lectura + + + Write Bytes + Bytes de escritura + + + Read Ops + Operaciones de lectura + + + Write Ops + Operaciones de escritura + + + A/O Since + A/O desde + + + Instance + Instancia + + + Hostname + Nombre de host + + + Issue + Problema + + + Progress + Progreso + + + Disabled + Inhabilitado + + + Edit Mode + Editar modo + + + Add Peer + Añadir par + + + Edit Peer + Editar par + + + Delete Peer + Suprimir par + + + Leader + Líder + + + # Local + N.º locales + + + # Remote + N.º remotos + + + mirror peer + duplicar par + + + Key + Clave + + + RBD + RBD + + + Deep flatten + Aplanamiento profundo + + + Layering + En capas + + + Exclusive lock + Bloqueo exclusivo + + + Object map (requires exclusive-lock) + Mapa de objetos (requiere bloqueo exclusivo) + + + Journaling (requires exclusive-lock) + En diario (requiere bloqueo exclusivo) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Reversión de instantánea RBD + + + Rollback + Revertir + + + RBD snapshot + Instantánea RBD + + + Deleted At + Suprimido a las + + + id + ID + + + type + tipo + + + state + estado + + + version + versión + + + Host + Host + + + root + raíz + + + Rank + Clasificación + + + Daemon + Daemon + + + Activity + Actividad + + + Dentries + Dentries + + + Inodes + Inodos + + + Usage + Uso + + + Standby daemons + Daemons de reserva + + + The value can be updated at runtime. + El valor se puede actualizar en el tiempo de ejecución. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + Los daemons/clientes no extraen este valor de la + base de datos de configuración del monitor. No se recomienda definir esta opción con "ceph config + set ...". Esta opción se debe configurar mediante ceph.conf o a través + de la línea de comandos. + + + Option takes effect only during daemon startup. + La opción solo surte efecto durante el inicio del daemon. + + + Option only affects cluster creation. + La opción solo afecta a la creación del clúster. + + + Option only affects daemon creation. + La opción solo afecta a la creación del daemon. + + + Updated config option + + + Opción de configuración actualizada + + + + + Service + Servicio + + + Current value + Valor actual + + + Editable + Editable + + + Updated options for module " + ". + + Opciones actualizadas para el módulo + . + + + + Enable + Habilitar + + + Disable + Inhabilitar + + + Reconnecting, please wait ... + Conectando de nuevo. Espere... + + + Public Address + Dirección pública + + + Open Sessions + Sesiones abiertas + + + No In + No incluir + + + OSDs that were previously marked out will not be marked back in when they start + Los OSD que se excluyeron anteriormente no se volverán a incluir cuando se inicien + + + No Out + No excluir + + + OSDs will not automatically be marked out after the configured interval + Los OSD no se excluirán automáticamente después del intervalo configurado + + + No Up + No activar + + + OSDs are not allowed to start + No se permite que los OSD se inicien + + + No Down + No desactivar + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + Se ignoran los informes de error de OSD, de forma que los monitores no desactivarán los OSD + + + Pause + Pausa + + + Pauses reads and writes + Pone en pausa las lecturas y escrituras + + + No Scrub + No depurar + + + Scrubbing is disabled + La depuración está inhabilitada + + + No Deep Scrub + No depuración profunda + + + Deep Scrubbing is disabled + La depuración profunda está inhabilitada + + + No Backfill + No reponer + + + Backfilling of PGs is suspended + La reposición de grupos de colocación se suspende + + + No Recover + No recuperar + + + Recovery of PGs is suspended + La recuperación de los grupos de colocación se suspende + + + Bitwise Sort + Orden bit a bit + + + Use bitwise sort + Usar orden bit a bit + + + Purged Snapdirs + Snapdir limpiados + + + OSDs have converted snapsets + Los OSD tienen snapset convertidos + + + Recovery Deletes + Supresiones de recuperación + + + Deletes performed during recovery instead of peering + Supresiones realizadas durante la recuperación, en lugar de emparejamientos + + + PG Log Hard Limit + Límite estricto de registro del grupo de colocación + + + Puts a hard limit on pg log length + Establece un límite estricto para la longitud del registro del grupo de colocación + + + Updated OSD Flags + Indicadores de OSD actualizados + + + out + excluir + + + in + Incluir + + + down + desactivar + + + Mark + Marcar + + + OSD lost + OSD perdido + + + marked lost + marcado como perdido + + + Purge + Limpiar + + + OSD + OSD + + + purged + limpiado + + + destroy + destruir + + + destroyed + destruido + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + Grupos de colocación + + + Read bytes + Bytes de lectura + + + Writes bytes + Bytes de escritura + + + Read ops + Operaciones de lectura + + + Write ops + Operaciones de escritura + + + Mark OSD + + + Marcar OSD + + + + + Mark + + + Marcar + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Número máximo de reposiciones + + + Recovery Max Active + Máximo de recuperaciones activas + + + Recovery Max Single Start + Máximo de recuperaciones de inicio único + + + Recovery Sleep + Reposo de recuperación + + + Custom + Personalizar + + + Updated OSD recovery speed priority " + " + + Prioridad de velocidad de recuperación de OSD actualizada + + + + + + was initialized in the following OSD: + + + + se ha inicializado en el siguiente OSD: + + + + + Create silence + Create silence + + + Job + Trabajo + + + Severity + Gravedad + + + Started + Iniciado + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Actualizado + + + Ends + Ends + + + Silence + Silence + + + Used + Usado + + + Avail. + Dispon. + + + Clean + Limpio + + + Working + En curso + + + Warning + Advertencia + + + Unknown + Desconocido + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + activo + + + no filesystems + sin sistemas de archivos + + + active + activo + + + standby + reserva + + + n/a + n/d + + + active daemon + daemon activo + + + quorum + quórum + + + The NFS Ganesha service is not configured. + El servicio NFS Ganesha no está configurado. + + + Transport + Transportar + + + CephFS User + Usuario de CephFS + + + CephFS Filesystem + Sistemas de archivos CephFS + + + (inherited from global config) + (se hereda de la configuración global) + + + inherited from global config + se hereda de la configuración global + + + -- Select what kind of user id squashing is performed -- + -- Seleccione el tipo de reducción de privilegios de ID de usuario que se va a realizar -- + + + There are no daemons available. + No hay ningún daemon disponible. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Modo de caché + + + Min Evict Age + Antigüedad mínima de expulsión + + + Min Flush Age + Antigüedad mínima de vaciado + + + Target Max Bytes + Número máximo de bytes de destino + + + Target Max Objects + Número máximo de objetos de destino + + + No applications added + No se ha añadido ninguna aplicación + + + Applications limit reached + Se ha alcanzado el límite de aplicaciones + + + A pool can only have up to four applications definitions. + Un repositorio solo puede tener hasta cuatro definiciones de aplicaciones. + + + Allowed characters '_a-zA-Z0-9' + Caracteres permitidos: _, a-z, A-Z y 0-9 + + + Maximum length is 128 characters + La longitud máxima es 128 caracteres + + + Filter or add applications + Filtrar o añadir aplicaciones + + + Add application + Añadir aplicación + + + pool + pool + + + erasure code profile + perfil de código de borrado + + + Replica Size + Tamaño de réplica + + + Last Change + Último cambio + + + Erasure Coded Profile + Perfil de código de borrado + + + Crush Ruleset + Conjunto de reglas de CRUSH + + + Write bytes + Bytes de escritura + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + papelera + + + Updated Object Gateway bucket " + " + + Papelera de Object Gateway actualizada " + " + + + + Created Object Gateway bucket " + " + + Papelera de Object Gateway creada " + " + + + + buckets + papeleras + + + capability + capability + + + user + usuario + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Usuario de Object Gateway actualizado " + " + + + + Created Object Gateway user " + " + + Usuario de Object Gateway creado " + " + + + + users + usuarios + + + Swift Key + Swift Key + + + Scope + Ámbito + + + Read + Lectura + + + Create + Crear + + + role + role + + + Created role ' + ' + + Se ha creado la función + + + + + Updated role ' + ' + + Se ha actualizado la función + + + + + System Role + Función del sistema + + + Deleted role ' + ' + + Se ha suprimido la función + + + + + Created user " + " + + Se ha creado el usuario + + + + + Update user + Actualizar usuario + + + Continue + Continuar + + + You were automatically logged out because your roles have been changed. + La sesión se ha cerrado automáticamente porque sus funciones han cambiado. + + + Updated user " + " + + Se ha actualizado el usuario + + + + + Deleted user " + " + + Se ha suprimido el usuario + + + + + Failed to delete user " + " + + Error al suprimir el usuario + + + + + You are currently logged in as " + ". + + Ha entrado a la sesión como + + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Cada objeto se divide en porciones de datos, cada una almacenada en un OSD distinto. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Calcula las porciones de código para cada objeto y las almacena en distintos OSD. + El número de porciones de código es también el número de OSD que pueden estar inactivos sin que se pierdan datos. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + El complemento jerasure es el más genérico y flexible, + y también el complemento por defecto para los repositorios de código de borrado de Ceph. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + La técnica más flexible es reed_sol_van: basta con definir k y m. + La técnica cauchy_good puede ser más rápida, pero hay que elegir con cuidado el tamaño + del paquete. reed_sol_r6_op, liberation, blaum_roth y liber8tion son todas equivalentes a RAID6 + en el sentido de que solo se pueden configurar con m=2. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + La codificación se realizará según el tamaño de los paquetes de bytes de uno en uno. + Elegir el tamaño correcto es difícil. + La documentación de jerasure incluye información completa sobre el tema. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + Con el complemento jerasure, cuando un objeto de código de borrado se almacena + en varios OSD, para recuperarse de la pérdida de un OSD es necesario leer de todos los demás. + Por ejemplo, si jerasure está configurado con k=8 y m=4, cuando se pierde un OSD es necesario leer + de los otros once para repararlo. + + El complemento de código de borrado lrc crea porciones de paridad local para poder realizar la recuperación con + menos OSDs. Por ejemplo, is lrc está configurado con k=8, m=4 y l=4, creará + una porción de paridad adicional para cada cuatro OSDs. Si se pierde un solo OSD, se puede recuperar + solo con cuatro OSD, en lugar de con once. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Agrupa las porciones de código y de datos en localizaciones de conjuntos de tamaño. Por ejemplo, + para k=4 y m=2, si locality=3, se crean dos grupos de tres. Cada conjunto + se puede recuperar sin leer porciones de otro conjunto. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + El tipo de papelera de CRUSH en el que se almacenará cada + conjunto de porciones definido por l. Por ejemplo, si se define como bastidor, cada grupo de l porciones + se colocará en un bastidor distinto. Se usa para crear un paso de regla de CRUSH, por ejemplo, "step choose + rack". Si no se define, no se realiza este tipo de agrupamiento. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + El complemento isa encapsula la biblioteca ISA. Solo funciona en procesadores Intel. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + El complemento ISA viene en dos formatos de Reed Solomon. + Si se define reed_sol_van, se trata de Vandermonde; si se define cauchy, se trata de Cauchy. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + El complemento shec encapsula las distintas bibliotecas SHEC. + Permite a Ceph recuperar datos de forma más eficiente que los códigos de Reed Solomon. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + El número de porciones de paridad. Cada uno de ellas incluye cada porción de datos + en su intervalo de cálculo. El número se usa como estimador de durabilidad. Por ejemplo, si c=2, + 2 OSD pueden estar inactivos sin que se pierdan datos. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + El nombre de la papelera de CRUSH usado para el primer paso de la regla de CRUSH. + Por ejemplo, "step take default". + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Asegúrese de que no hay dos porciones en una papelera con el mismo + dominio de error. Por ejemplo, si el dominio de error es host, no debe haber dos porciones almacenadas en el mismo + host. Se usa para crear un paso de regla de CRUSH, por ejemplo, "step chooseleaf host". + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Restringe la colocación a dispositivos de una clase concreta + (p.ej., ssd o hdd) usando los nombre de clase de dispositivo CRUSH en el mapa de CRUSH. + + + Set the directory name from which the erasure code plugin is loaded. + Define el nombre de directorio del que se cargará el complemento de código de borrado. + + + Allows all operations + Permite todas las operaciones + + + Allows only operations that do not modify the server + Permite solo las operaciones que no modifican el servidor + + + Does not allow read or write operations, but allows any other operation + No permite operaciones de lectura o escritura, pero sí cualquier otra + + + Does not allow read, write, or any operation that modifies file attributes or directory content + No permite operaciones de lectura o escritura, ni ninguna otra que modifique los atributos del archivo o el contenido del directorio + + + Allows no access at all + No permite ningún tipo de acceso + + + -- Select the priority -- + -- Seleccione la prioridad -- + + + Low + Baja + + + High + Alta + + + Last 5 minutes + Últimos 5 minutos + + + Last 15 minutes + Últimos 15 minutos + + + Last 30 minutes + Últimos 30 minutos + + + Last 1 hour (Default) + Última hora (opción por defecto) + + + Last 3 hours + Últimas 3 horas + + + Last 6 hours + Últimas 6 horas + + + Last 12 hours + Últimas 12 horas + + + Last 24 hours + Últimas 24 horas + + + Yesterday + Ayer + + + Today + Hoy + + + Today so far + Hoy hasta ahora + + + Day before yesterday + Anteayer + + + Last 2 days + Los últimos 2 días + + + This day last week + Este día la semana pasada + + + Previous week + La semana pasada + + + This week + Esta semana + + + This week so far + Esta semana hasta ahora + + + Last 7 days + Los últimos 7 días + + + Previous month + El mes pasado + + + This month + Este mes + + + This month so far + Este mes hasta ahora + + + Last 30 days + Los últimos 30 días + + + Last 90 days + Los últimos 90 días + + + Last 6 months + Los últimos 6 meses + + + Last 1 year + El último año + + + Previous year + El año pasado + + + This year + Este año + + + This year so far + Este año hasta ahora + + + Last 2 years + Los últimos 2 años + + + Last 5 years + Los últimos 5 años + + + Information + Información + + + No items selected. + No se ha seleccionado ningún elemento. + + + Deselect item to select again + Deseleccione el elemento para volver a seleccionarlo + + + Selection limit reached + Se ha alcanzado el límite de selección + + + Filter tags + Filtrar etiquetas + + + Add badge + Añadir insignia + + + There are no items available. + No hay ningún elemento disponible. + + + Add + Añadir + + + Remove + Remove + + + Clone + Clonar + + + Copy + Copiar + + + Deep Scrub + Depuración profunda + + + Destroy + Destruir + + + Flatten + Aplanar + + + Mark Down + Marcar para desactivar + + + Mark In + Marcar para incluir + + + Mark Lost + Marcar como perdido + + + Mark Out + Marcar para excluir + + + Protect + Proteger + + + Rename + Renombrar + + + Restore + Restaurar + + + Move to Trash + Mover a la papelera + + + Unprotect + Desproteger + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Suprimido + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Clonado + + + Copied + Copiado + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + + + + No + No + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Calidad del servicio + + + BPS Limit + Límite de BPS + + + The desired limit of IO bytes per second. + El límite deseado de bytes de E/S por segundo. + + + IOPS Limit + Límite de IOPS + + + The desired limit of IO operations per second. + El límite deseado de operaciones de E/S por segundo. + + + Read BPS Limit + Límite de BPS de lectura + + + The desired limit of read bytes per second. + El límite deseado de bytes de lectura por segundo. + + + Read IOPS Limit + Límite de IOPS de lectura + + + The desired limit of read operations per second. + El límite deseado de operaciones de lectura por segundo. + + + Write BPS Limit + Límite de BPS de escritura + + + The desired limit of write bytes per second. + El límite deseado de bytes de escritura por segundo. + + + Write IOPS Limit + Límite de IOPS de escritura + + + The desired limit of write operations per second. + El límite deseado de operaciones de escritura por segundo. + + + BPS Burst + Ráfaga de BPS + + + The desired burst limit of IO bytes. + El límite deseado de ráfaga de bytes de E/S. + + + IOPS Burst + Ráfaga de IOPS + + + The desired burst limit of IO operations. + El límite deseado de ráfaga de operaciones de E/S. + + + Read BPS Burst + Ráfaga de BPS de lectura + + + The desired burst limit of read bytes. + El límite deseado de ráfaga de bytes de lectura. + + + Read IOPS Burst + Ráfaga de IOPS de lectura + + + The desired burst limit of read operations. + El límite deseado de ráfaga de operaciones de lectura. + + + Write BPS Burst + Ráfaga de BPS de escritura + + + The desired burst limit of write bytes. + El límite deseado de ráfaga de bytes de escritura. + + + Write IOPS Burst + Ráfaga de IOPS de escritura + + + The desired burst limit of write operations. + El límite deseado de ráfaga de operaciones de escritura. + + + Failed to + + + + Error al + + + + + + Executing + Ejecutando + + + execute + ejecutar + + + Executed + Ejecutado + + + unknown task + tarea desconocida + + + Creating + Creando + + + create + crear + + + Updating + Actualizando + + + update + actualizar + + + Deleting + Suprimiendo + + + delete + suprimir + + + RBD ' + ' + + RBD + + + + + RBD snapshot ' + ' + + Instantánea RBD + + + + + mirror mode for pool ' + ' + + modo de duplicación para repositorio + + + + + mirror peer for pool ' + ' + + par de duplicación para repositorio + + + + + all dashboards + all dashboards + + + Name is already used by + . + + + ya está usando el nombre. + + + + Name is already used by + . + + + ya está usando el nombre. + + + + Name is already used by + . + + + ya está usando el nombre. + + + + + contains snapshots. + + + contiene instantáneas. + + + + Cloning + Clonando + + + clone + clonar + + + Snapshot of + must be protected. + + La instantánea de + debe estar protegida. + + + + Copying + Copiando + + + copy + copiar + + + Flattening + Aplanando + + + flatten + aplanar + + + Flattened + Aplanado + + + Name is already used by + . + + + ya está usando el nombre. + + + + Cannot unprotect + because it contains child images. + + No es posible desproteger + porque contiene imágenes hijas. + + + + Cannot delete + because it's protected. + + No es posible suprimir + porque está protegido. + + + + Rolling back + Revirtiendo + + + rollback + revertir + + + Rolled back + Revertido + + + Moving + Moviendo + + + move + mover + + + Moved + Movido + + + image ' + ' to trash + + la imagen + a la papelera + + + + Could not find image. + No se encuentra la imagen. + + + Restoring + Restaurando + + + restore + restaurar + + + Restored + Restaurado + + + image ' + ' into ' + ' + + la imagen + en + + + + + Image name ' + ' is already in use. + + El nombre de imagen + ya está en uso. + + + + image ' + ' + + la imagen + + + + + Purging + Limpiando + + + purge + limpiar + + + Purged + Limpiado + + + all pools + todos los repositorios + + + images from + + + imágenes de + + + + + Cannot disable mirroring because it contains a peer. + No es posible inhabilitar la duplicación porque contiene un par + + + pool ' + ' + + repositorio + + + + + erasure code profile ' + ' + + perfil de código de borrado + + + + + target ' + ' + + destino + + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf new file mode 100644 index 00000000..e94b1423 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.fr-FR.xlf @@ -0,0 +1,4367 @@ + + + + + Toggle navigation + Activer/Désactiver la navigation + + + Dashboard + Tableau de bord + + + Cluster + Grappe + + + Hosts + Serveurs + + + Monitors + Moniteurs + + + OSDs + OSD + + + Configuration + Configuration + + + CRUSH map + Carte CRUSH + + + Manager modules + Modules Manager + + + Logs + Journaux + + + Alerts + Alertes + + + Silences + Silences + + + Pools + Réserves + + + Block + Bloc + + + Images + Images + + + Mirroring + Mise en miroir + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + Systèmes de fichiers + + + Object Gateway + Object Gateway + + + Daemons + Daemons + + + Users + Utilisateurs + + + Buckets + Compartiments + + + Retrieving data + for + + + . Please wait... + + Récupération des données + pour + + + . Veuillez patienter... + + + + Displaying previously cached data + + for + + + . + + Affichage des données + précédemment mises en cache + pour + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Impossible de charger les données + pour + + + . + Veuillez vérifier l'état de santé de la grappe. + + + + Back + Retour + + + Select a Language + Sélectionner une langue + + + Loading panel data... + Chargement des données du panneau... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Veuillez consulter la + documentation + relative à + la configuration et à l'activation de la fonctionnalité de surveillance. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Le tableau de bord Grafana n'existe pas. Veuillez consulter + la + documentation + relative à + l'ajout de tableaux de bord à Grafana. + + + + Grafana Time Picker + Sélecteur d'heure Grafana + + + Reset Settings + Réinitialiser les paramètres + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Échec du chargement des données. + + + selected + sélectionné(e)(s) + X selected + + + found + trouvé(e)(s) + X found + + + total + total + X total + + + Edit + Modifier + + + Name + Nom + + + Description + Description + + + Long description + Description longue + + + Default + Valeur par défaut + + + Daemon default + Valeur par défaut du daemon + + + Services + Services + + + Values + Valeurs + + + The entered value is too high! It must not be greater than + . + + La valeur entrée est trop élevée ! Elle ne peut pas être supérieure à + . + + + + The entered value is too low! It must not be lower than + . + + La valeur entrée est trop faible ! Elle ne peut pas être inférieure à + . + + + + Save + Sauvegarder + + + CRUSH map viewer + Visionneuse de carte CRUSH + + + Hosts List + Liste d'hôtes + + + Overall Performance + Performance globale + + + No entries found + Aucune entrée trouvée + + + Cluster Logs + Journaux de grappes + + + Audit Logs + Journaux d'audit + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Chargement de la configuration... + + + The configuration could not be loaded. + La configuration n'a pas pu être chargée. + + + Edit Manager module + Modifier le module Manager + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + La valeur entrée n'est pas un UUID valide, par exemple : 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + La valeur entrée doit être une adresse IP valide. + + + This field is required. + Ce champs est requis. + + + The entered value is too high! It must be lower or equal to + . + + La valeur entrée est trop élevée ! Elle doit être inférieure ou égale à + . + + + + The entered value is too low! It must be greater or equal to + . + + La valeur entrée est trop faible ! Elle doit être supérieure ou égale à + . + + + + The entered value needs to be a number. + La valeur entrée doit être un nombre. + + + The entered value needs to be a number or decimal. + La valeur entrée doit être un nombre ou une valeur décimale. + + + Update + Mise à jour + + + Status + Statut + + + Cluster ID + ID de grappe + + + monmap modified + monmap modifié + + + monmap epoch + monmap epoch + + + quorum con + quorum con + + + quorum mon + quorum mon + + + required con + required con + + + required mon + required mon + + + In Quorum + Dans le quorum + + + Not In Quorum + Hors quorum + + + Cancel + Annuler + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + Voulez-vous vraiment + l'élément sélectionné + ? + + + + Yes, I am sure. + Oui. + + + Cluster-wide OSD Flags + Drapeaux OSD à l'échelle de la grappe + + + Submit + Soumettre + + + + + + + + + + + form title + + + Advanced... + Avancé... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + Priorité de récupération des OSD + + + Priority + Priorité + + + Customize priority values + Personnaliser les valeurs de priorité + + + This field is required! + Ce champ est obligatoire ! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + La valeur entrée est trop élevée ! Elle ne peut pas être supérieure à + . + + + + The entered value is too low! It must not be lower than + . + + La valeur entrée est trop faible ! Elle ne peut pas être inférieure à + . + + + + Reweight OSD + Réévaluer l'OSD + + + The value needs to be between 0 and 1. + La valeur doit être comprise entre 0 et 1. + + + Reweight + Réévaluer + + + OSDs + Scrub + + Nettoyage des + OSD + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {Profondeur } } + + + You are about to apply a + scrub to + the OSD + + + . + + Vous êtes sur le point d'appliquer un nettoyage + + à l'OSD + + + . + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {profondeur } } + + + OSDs List + Liste des OSD + + + + OSD + + will be marked + + + if you proceed. + + L' + OSD + + sera marqué + + + si vous continuez. + + + + The OSD is not safe to destroy! + L'OSD ne peut pas être détruit de façon sécurisée ! + + + + OSD + + will be + + + if you proceed. + + + L'OSD + + sera + + + si vous continuez. + + + + Details + Détails + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Valeur + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Fermer + + + Delete + Supprimer + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Santé + + + Statistics + Statistiques + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Veuillez consulter la + documentation + + relative à la configuration et à l'activation de la fonctionnalité de gestion du NFS Ganesha. + + + + Clients + Clients + + + Any client can access + Accès possible par tous les clients + + + Addresses + Adresses + + + Required field + Champ obligatoire + + + Must contain one or more comma-separated values + Doit contenir une ou plusieurs valeurs séparées par une virgule + + + For example: + Par exemple : + + + Access Type + Type d'accès + + + Squash + Squash + + + Add clients + Ajouter des clients + + + Loading... + Chargement... + + + -- No cluster available -- + -- Aucune grappe disponible -- + + + -- Select the cluster -- + -- Sélectionner la grappe -- + + + Add daemon + Ajouter un daemon + + + Storage Backend + Backend de stockage + + + -- No data pools available -- + -- Aucune réserve de données disponible -- + + + -- Select the storage backend -- + -- Sélectionner le backend de stockage -- + + + Object Gateway User + Utilisateur Object Gateway + + + -- No users available -- + -- Aucun utilisateur disponible -- + + + -- Select the object gateway user -- + -- Sélectionner l'utilisateur Object Gateway -- + + + CephFS User ID + ID utilisateur CephFS + + + -- No clients available -- + -- Aucun client disponible -- + + + -- Select the cephx client -- + -- Sélectionner le client cephx -- + + + CephFS Name + Nom CephFS + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Libellé de sécurité + + + Enable security label + Activer le libellé de sécurité + + + CephFS Path + Chemin CephFS + + + Path need to start with a '/' and can be followed by a word + Le chemin doit commencer par '/' et peut être suivi d'un mot + + + New directory will be created + Un nouveau répertoire sera créé + + + Path + Chemin + + + Path can only be a single '/' or a word + Le chemin peut être constitué d'un seul '/' ou d'un seul mot + + + New bucket will be created + Un compartiment sera créé + + + NFS Protocol + Protocole NFS + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + Balise NFS + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Autre chemin d'accès aux montages + NFS v3 + (doit commencer par /). + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + Les clients ne peuvent pas monter de sous-répertoires (si la balise = foo, le client ne peut pas monter foo/baz). + + + By using different Tag options, the same Path may be exported multiple times. + En utilisant différentes options de balise, il est possible d'exporter plusieurs fois le même chemin. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + Position occupée par cet export + NFS v4 + + dans le + système de fichiers Pseudo + (doit être unique). + + + + By using different Pseudo options, the same Path may be exported multiple times. + En utilisant différentes options de pseudo, il est possible d'exporter exporter plusieurs fois le même chemin. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- Aucun type d'accès disponible -- + + + -- Select the access type -- + -- Sélectionner le type d'accès -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- Aucun squash disponible -- + + + --Select what kind of user id squashing is performed -- + -- Sélectionnez le type de squash d'ID utilisateur qui est effectué -- + + + Transport Protocol + Protocole de transport + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Bienvenue dans Ceph ! + The welcome message on the login page + + + Username is required + Nom d'utilisateur requis + + + Password is required + Mot de passe requis + + + Login + Connexion + + + Sorry, the user does not exist in Ceph. + Désolé, l'utilisateur n'existe pas dans Ceph. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Retournez à la + page de connexion + . Vous serez déconnecté du fournisseur d'identité lorsque vous tenterez de vous reconnecter. + + + + Forbidden + Interdit + + + Sorry, you are not allowed to see what you were looking for. + Désolé, vous n'êtes pas autorisé à voir ce que vous cherchez. + + + Sorry, we could not find what you were looking for + Désolés, nous ne parvenons pas à trouver ce que vous cherchez. + + + Remove all + Tout supprimer + + + Recent Notifications + Notifications récentes + + + There are no background tasks. + Il n'y a aucune tâche en arrière-plan. + + + Background Tasks + Tâches en arrière-plan + + + Help + Aide + + + Documentation + Documentation + + + API + API + + + About + À propos de + + + Dashboard Settings + Paramètres du tableau de bord + + + User management + Gestion des utilisateurs + + + Logged in user + Utilisateur connecté + + + Signed in as + + + + + Connecté en tant que + + + + + + + Sign out + Se déconnecter + + + Name... + Nom... + + + The chosen name is already in use. + Le nom sélectionné est déjà en cours d'utilisation. + + + Description... + Description... + + + Permissions + Autorisations + + + Roles + Rôles + + + Username + Nom d'utilisateur + + + Password + Mot de passe + + + Confirm password + Confirmer le mot de passe + + + Password confirmation doesn't match the password. + Le mot de passe de confirmation ne correspond pas au mot de passe. + + + Full name + Nom complet + + + Email + Adresse électronique + + + Invalid email. + L'adresse électronique n'est pas valide. + + + You are about to remove "user read / update" permissions from your own user. + Vous êtes sur le point de supprimer les autorisations "lecture/mise à jour utilisateur" de votre propre utilisateur. + + + If you continue, you will no longer be able to add or remove roles from any user. + Si vous continuez, vous ne serez plus en mesure d'ajouter ni de supprimer des rôles pour n'importe quel utilisateur. + + + Are you sure you want to continue? + Voulez-vous vraiment continuer ? + + + Performance counters not available + Compteurs de performance non disponibles + + + Attributes (OSD map) + Attributs (carte OSD) + + + Metadata not available + Métadonnées non disponibles + + + Metadata + Métadonnées + + + Performance counter + Compteur de performance + + + Histogram not available: + + + Histogramme non disponible : + + + + + Writes + Écritures + + + Reads + Lectures + + + Histogram + Histogramme + + + Performance Details + Détails des performances + + + Current values + Valeurs actuelles + + + Type + Type + + + Min + Minimum + + + Max + Maximum + + + Flags + Drapeaux + + + Source + Source + + + Level + Niveau + + + Can be updated at runtime (editable) + Mise à jour possible lors de l'exécution (modifiable) + + + Tags + Balises + + + Enum values + Valeurs d'énuménation + + + See also + Voir aussi + + + Cluster Status + Statut de la grappe + + + Manager Daemons + Daemons du gestionnaire + + + Object Gateways + Passerelles d'objet + + + Metadata Servers + Serveurs de métadonnées + + + iSCSI Gateways + Passerelles iSCSI + + + Client IOPS + IOPS client + + + Client Throughput + Débit client + + + Client Read/Write + Lectures/Écritures client + + + Recovery Throughput + Débit de récupération + + + Scrub + Nettoyer + + + Performance + Performance + + + Raw Capacity + Capacité brute + + + Objects + Objets + + + PGs per OSD + Groupes de placements par OSD + + + PG Status + Statut du groupe de placements + + + Capacity + Capacité + + + + + See + Logs + for more details. + + + + Consultez les + journaux + pour plus d'informations. + + + + Ranks + Rangs + + + MDS performance counters + MDS performance counters + + + Clients: + + + Clients : + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Déplacer une image vers la corbeille. + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Pour déplacer + + / + + vers la corbeille, + cliquez sur + Déplacer une image + . Vous pouvez également sélectionner une date d'expiration. + + + + Protection expires at + La protection expire le + + + NOT PROTECTED + NON PROTÉGÉ + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Format de date incorrect. Veuillez utiliser "AAAA-MM-JJ HH:mm:ss" + + + Protection has already expired. Please pick a future date or leave it empty. + La protection a déjà expiré. Veuillez sélectionner une date ultérieure ou laisser le champ vide. + + + Move Image + Déplacer une image + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Présentation + + + Targets + Cibles + + + Discovery Authentication + Authentification de la découverte + + + User + Utilisateur + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Les noms d'utilisateur doivent comporter entre 8 et 64 caractères et + ne peuvent contenir que des lettres et les caractères '.', '@', '-', '_' ou ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Utilisateur commun + + + Mutual Password + Mot de passe commun + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Veuillez consulter la + documentation + +relative à la configuration et à l'activation de la fonctionnalité de gestion des cibles iSCSI. + + + + Available information: + Informations disponibles : + + + iSCSI Targets not available + Cibles iSCSI non disponibles + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + Disponible uniquement pour les images RBD pour lesquelles + fast-diff + est activé + + + + Pool + Réserve + + + Data Pool + Réserve de données + + + Created + Créé + + + Size + Taille + + + Object size + Taille de l'objet + + + Features + Fonctionnalités + + + Provisioned + Provisionné + + + N/A + N/A + + + Total provisioned + Provisionnement total + + + Striping unit + Unité de segmentation + + + Striping count + Nombre de segmentations + + + Parent + Parent + + + Block name prefix + Préfixe du nom de bloc + + + Order + Tri + + + Snapshots + Instantanés + + + Image + Image + + + This setting overrides the global value + Ce paramètre remplace la valeur globale + + + Global + Global + + + This is the global value. No value for this option has been set for this image. + Il s'agit de la valeur globale. Aucune valeur de cette option n'a été définie pour cette image. + + + + from + + + from + + + + '/' and '@' are not allowed. + Les caractères '/' et '@' ne sont pas autorisés. + + + -- No rbd pools available -- + -- Aucune réserve RBD disponible -- + + + -- Select a pool -- + -- Sélectionner une réserve -- + + + Use a dedicated data pool + Utiliser une réserve de données dédiée + + + Data pool + Réserve de données + + + Dedicated pool that stores the object-data of the RBD. + Réserve dédiée qui stocke les données objet du RBD. + + + e.g., 10GiB + par exemple, 10 Gio + + + You have to increase the size. + Vous devez augmenter la taille. + + + Advanced + Avancé + + + Striping + Segmentation + + + Stripe unit + Unité de segmentation + + + -- Select stripe unit -- + -- Sélectionner une unité de segmentation -- + + + This field is required because stripe count is defined! + Ce champ est obligatoire, car le nombre de segments est défini. + + + Stripe unit is greater than object size. + L'unité de segmentation est supérieure à la taille de l'objet. + + + Stripe count + Nombre de segments + + + This field is required because stripe unit is defined! + Ce champ est obligatoire, car l'unité de segmentation est définie. + + + Stripe count must be greater than 0. + Le nombre de segments doit être supérieur à 0. + + + + RBD Snapshot + + + instantané RDB + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Renommer} other {Créer} } + + + + Snapshot + + + instantané + + + + PROTECTED + PROTÉGÉ + + + UNPROTECTED + NON PROTÉGÉ + + + You are about to rollback + Vous êtes sur le point de revenir à l'état initial + + + Purge Trash + Vider la corbeille + + + To purge, select one or All images and click + Pour purger, sélectionner une image ou toutes, puis cliquez sur + + + Pool: + Réserve : + + + Pool name... + Nom de la réserve... + + + All + Tout + + + Restore Image + Restaurer l'image + + + To restore + Pour restaurer + + + type the image's new name and click + saisissez le nouveau nom de l'image, puis cliquez sur + + + New Name + Nouveau nom + + + Expired at + Expiration le + + + Protected until + Protection jusqu'au + + + This image is protected until + . + + Cette image est protégée jusqu'au + . + + + + Trash + Corbeille + + + iSCSI Topology + Topologie iSCSI + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Il n'est généralement pas nécessaire de modifier ces paramètres par défaut. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Paramètres + + + Backstore + Backstore + + + Confirm + Confirmer + + + Advanced Settings + Paramètres avancés + + + Target IQN + IQN cible + + + IQN has wrong pattern. + Modèle IQN incorrect. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + Un IQN est associé à la notation 'iqn.$year-$month.$reversedAddress:$definedName' + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Par exemple : iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Plus d'informations + + + This target has modified advanced settings. + Des paramètres avancés de cette cible ont été modifiés. + + + Portals + Portails + + + At least + gateways are required. + + Au moins + passerelles sont nécessaires. + + + + Add portal + Ajouter un portail + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Des paramètres avancés de cette image ont été modifiés. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Ajouter une image + + + ACL authentication + Authentification ACL + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Initiateurs + + + Initiator + Initiateur + + + Client IQN + IQN client + + + Initiator IQN needs to be unique. + L'IQN de l'initiateur doit être unique. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Les noms d'utilisateur doivent comporter entre 8 et 64 caractères et + ne peuvent contenir que des lettres et les caractères '.', '@', '-', '_' ou ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + L'initiateur appartient à un groupe dans lequel les images seront configurées. + + + No items added. + Aucun élément ajouté. + + + Add initiator + Ajouter un initiateur + + + Groups + Groupes + + + Group + Groupe + + + Add group + Ajouter un groupe + + + [object Object] + [object Object] + + + RBD Configuration + Configuration RBD + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Supprimez la valeur de configuration locale. La valeur de configuration parent sera héritée et utilisée à la place. + + + The mininum value is 0 + La valeur minimale est 0. + + + Issues + Problèmes + + + Syncing + Synchronisation en cours + + + Ready + Prêt + + + Edit pool mirror mode + Modifier le mode de mise en miroir de la réserve + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Pour modifier le mode de mise en miroir de la réserve  + + + , sélectionnez un nouveau mode dans la liste, puis cliquez sur + Mettre à jour + . + + + + Mode + Mode + + + Peer clusters must be removed prior to disabling mirror. + Les grappes d'homologues doivent être supprimées avant de désactiver la mise en miroir. + + + + + pool mirror peer + + + + homologue de mise en miroir de la réserve + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Modifier} other {Ajouter} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + les attributs + de mise en miroir de la réserve + + + et cliquez sur + Soumettre + . + + + + Cluster Name + Nom de grappe + + + The cluster name is not valid. + Le nom de grappe n'est pas valide. + + + CephX ID + ID CephX + + + CephX ID... + ID CephX + + + The CephX ID is not valid. + L'ID CephX n'est pas valide. + + + Monitor Addresses + Adresses du moniteur + + + Comma-delimited addresses... + Adresses séparées par une virgule... + + + The monitory address is not valid. + L'adresse du moniteur n'est pas valide. + + + CephX Key + Clef CephX + + + Base64-encoded key... + Clef Base64... + + + CephX key must be base64 encoded. + La clef CephX doit être codée en base64. + + + Pools List + Liste des réserves + + + The name can only consist of alphanumeric characters, dashes and underscores. + Le nom doit être exclusivement composé de caractères alphanumériques, de tirets et de traits de soulignement. + + + The chosen erasure code profile name is already in use. + Le nom de profil du code d'effacement sélectionné est déjà utilisé. + + + Plugin + Plug-in + + + Data chunks (k) + Blocs de données (k) + + + Must be equal to or greater than 2. + Doit être égal ou supérieur à 2. + + + Coding chunks (m) + Blocs de codage (m) + + + Must be equal to or greater than 1. + Doit être égal ou supérieur à 1. + + + Durability estimator (c) + Estimateur de durabilité (c) + + + Locality (l) + Localité (l) + + + Crush failure domain + Domaine de défaillance Crush + + + Crush Locality + Localité Crush + + + None + Aucun + + + Technique + Technique + + + Packetsize + Taille de paquet + + + Crush root + Racine Crush + + + Crush device class + Classe de périphérique Crush + + + any + tout + + + Directory + Répertoire + + + The chosen Ceph pool name is already in use. + Le nom de réserve Ceph sélectionné est déjà utilisé. + + + Pool type + Type de réserve + + + -- Select a pool type -- + -- Sélectionner un type de réserve -- + + + Placement groups + Groupes de placements + + + At least one placement group is needed! + Au moins un groupe de placements est nécessaire. + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + Votre grappe ne peut pas gérer autant de groupes de placements. Veuillez recalculer le nombre de groupes de placements nécessaires. + + + Calculation help + Aide au calcul + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + Les paramètres actuels des groupes de placements ont été calculés pour vous. +Vérifiez que les valeurs correspondent à vos besoins avant de les soumettre. + + + Crush ruleset + Jeu de règles Crush + + + -- Select a crush rule -- + -- Sélectionner une règle crush -- + + + Crush rule + Règle Crush + + + Crush steps + Étapes Crush + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + La règle ne peut pas être utilisée dans la grappe active, car celle-ci + comporte un nombre d'OSD inférieur au nombre d'OSD minimum requis par cette règle. + + + Replicated size + Taille de réplication + + + Minimum: + + + Minimum : + + + + + Maximum: + + + Maximum : + + + + + The size specified is out of range. A value from + to + is valid. + + La taille spécifiée est en dehors de la plage. Une valeur comprise entre + et + est valide. + + + + Erasure code profile + Profil de code d'effacement + + + -- No erasure code profile available -- + -- Aucun profil de code d'effacement n'est disponible -- + + + -- Select an erasure code profile -- + -- Sélectionner un profil de code d'effacement -- + + + EC Overwrites + Écrasements EC + + + Applications + Applications + + + Compression + Compression + + + Algorithm + Algorithme + + + -- No erasure compression algorithm available -- + -- Aucun algorithme de compression d'effacement n'est disponible -- + + + Minimum blob size + Taille de blob minimale + + + e.g., 128KiB + par ex. 128 Kio + + + Value should be greater than 0 + La valeur doit être supérieure à 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Taille de blob maximale + + + e.g., 512KiB + par ex., 512 Kio + + + Value should be greater than the minimum blob size + La valeur doit être supérieure à la taille de blob minimale. + + + Ratio + Rapport + + + Compression ratio + Rapport de compression + + + Value should be between 0.0 and 1.0 + La valeur doit se situer entre 0.0 et 1.0 + + + It's not possible to create an RBD pool with '/' in the name. + Il n'est pas possible de créer une réserve RBD dont le nom contient '/'. + + + Please change the name or remove 'rbd' from the applications list. + Modifiez le nom ou supprimez 'rbd' de la liste des applications. + + + Cache Tiers Details + Détails des niveaux de mise en cache + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Veuillez consulter la + documentation + + relative à la configuration et à l'activation de la fonctionnalité de gestion Object Gateway. + + + + Daemons List + Liste de daemons + + + Performance Counters + Compteurs de performance + + + Loading bucket data... + Chargement des données de compartiment... + + + The bucket data could not be loaded. + Les données du compartiment n'ont pas pu être chargées. + + + Id + ID + + + The value is not valid. + La valeur n'est pas valide. + + + Owner + Propriétaire + + + -- Select a user -- + -- Sélectionner un utilisateur -- + + + ID + ID + + + Index type + Type d'index + + + Placement rule + Règle de placement + + + Marker + Marqueur + + + Maximum marker + Marqueur maximum + + + Version + Version + + + Master version + Version principale + + + Modification time + Date de modification + + + Zonegroup + Groupe de zones + + + Bucket quota + Quota de compartiments + + + Enabled + Activé + + + Maximum size + Taille maximale + + + Unlimited + Illimité + + + Maximum objects + Nombre maximal d'objets + + + -- Select a username -- + -- Sélectionner un nom d'utilisateur -- + + + Auto-generate key + Générer automatiquement la clef + + + Access key + Clef d'accès + + + Secret key + Clef secrète + + + Email address + Adresse électronique + + + Suspended + Suspendu + + + System + Système + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {Non} 1 {Oui} } + + + Maximum buckets + Nombre maximal de compartiments + + + Subusers + Utilisateurs secondaires + + + Capabilities + Fonctionnalités + + + User quota + Quota utilisateur + + + Show + Afficher + + + Keys + Clefs + + + -- Select a type -- + -- Sélectionner un type -- + + + Permission + Autorisation + + + -- Select a permission -- + -- Sélectionner une autorisation -- + + + Subuser + Utilisateur secondaire + + + The chosen subuser ID is already in use. + L'ID d'utilisateur secondaire sélectionné est déjà utilisé. + + + read, write + lire, écrire + + + full + complet + + + Swift key + Clé Swift + + + Auto-generate secret + Générer automatiquement le secret + + + Loading user data... + Chargement des donnés utilisateur… + + + The user data could not be loaded. + Les donnés utilisateur n'ont pas pu être chargées. + + + The chosen user ID is already in use. + L'ID utilisateur spécifié est déjà utilisé. + + + This is not a valid email address. + Ceci n'est pas une adresse électronique valide. + + + The chosen email address is already in use. + L'adresse électronique spécifiée est déjà utilisée. + + + Max. buckets + Nombre max. de compartiments + + + The entered value must be >= 0. + La valeur saisie doit être >= 0. + + + S3 key + Clef S3 + + + There are no subusers. + Il n'y a aucun utilisateur secondaire. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + Il n'y a pas de clefs. + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + Il n'y a aucune fonctionnalité. + + + + + + + + + + + + + Unlimited size + Taille illimitée + + + Max. size + Taille max. + + + Unlimited objects + Objets illimités + + + Max. objects + Nombre max. d'objets + + + Current + Actuel + + + Updated discovery authentication + Authentification de la découverte mise à jour + + + There are no portals available. + Il n'y a aucun portail disponible. + + + There are no images available. + Il n'y a aucune image disponible. + + + There are no images available. Please make sure you add an image to the target. + Il n'y a aucune image disponible. Veillez à ajouter une image à la cible. + + + There are no initiators available. Please make sure you add an initiator to the target. + Il n'y a aucun initiateur disponible. Veillez à ajouter un initiateur à la cible. + + + target + target + + + Target + Cible + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + État + + + # Targets + # Targets + + + Read Bytes + Octets de lecture + + + Write Bytes + Octets d'écriture + + + Read Ops + Opérations de lecture + + + Write Ops + Opérations d'écriture + + + A/O Since + A/O depuis + + + Instance + Instance + + + Hostname + Nom d'hôte + + + Issue + Problème + + + Progress + Avancement + + + Disabled + Désactivé + + + Edit Mode + Mode d'édition + + + Add Peer + Ajouter un homologue + + + Edit Peer + Modifier un homologue + + + Delete Peer + Supprimer un homologue + + + Leader + Leader + + + # Local + nb en local + + + # Remote + nb à distance + + + mirror peer + mettre en miroir l'homologue + + + Key + Clef + + + RBD + RBD + + + Deep flatten + Aplatissement en profondeur + + + Layering + Superposition + + + Exclusive lock + Verrou exclusif + + + Object map (requires exclusive-lock) + Assignation d'objet (nécessite exclusive-lock) + + + Journaling (requires exclusive-lock) + Journalisation (nécessite exclusive-lock) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Retour à l'état initial de l'instantané RBD + + + Rollback + Revenir à l'état initial + + + RBD snapshot + Intantané RBD + + + Deleted At + Supprimé le + + + id + ID + + + type + type + + + state + état + + + version + version + + + Host + Hôte + + + root + racine + + + Rank + Rang + + + Daemon + Daemon + + + Activity + Activité + + + Dentries + Dentries + + + Inodes + Inodes + + + Usage + Utilisation + + + Standby daemons + Daemons en veille + + + The value can be updated at runtime. + La valeur peut être mise à jour au moment de l'exécution. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + Les daemons/clients ne tirent pas cette valeur de +  la base de données de configuration de Monitor. Nous n'autorisons pas le réglage de cette option via 'ceph config +  set ...'. Cette option doit être configurée via ceph.conf ou via +  la ligne de commande. + + + Option takes effect only during daemon startup. + L'option ne prend effet qu'au démarrage du daemon. + + + Option only affects cluster creation. + L'option n'affecte que la création des grappes. + + + Option only affects daemon creation. + L'option n'affecte que la création des daemons. + + + Updated config option + + + Option de configuration mise à jour + + + + + Service + Service + + + Current value + Valeur actuelle + + + Editable + Modifiable + + + Updated options for module " + ". + + Options mises à jour pour le module &quot; + &quot;. + + + + Enable + Activer + + + Disable + Désactiver + + + Reconnecting, please wait ... + Reconnexion en cours… Veuillez patienter. + + + Public Address + Adresse publique + + + Open Sessions + Sessions ouvertes + + + No In + Pas rentrés + + + OSDs that were previously marked out will not be marked back in when they start + Les OSD qui ont été marqués comme sortis ne seront pas marqués comme rentrés à leur démarrage. + + + No Out + Pas sortis + + + OSDs will not automatically be marked out after the configured interval + Les OSD ne seront pas marqués automatiquement comme sortis après l'intervalle configuré. + + + No Up + Pas démarrés + + + OSDs are not allowed to start + Les OSD ne sont pas autorisés à démarrer. + + + No Down + Pas arrêtés + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + Les rapports de défaillance des OSD sont ignorés, de sorte que les moniteurs ne marquent pas les OSD comme étant arrêtés. + + + Pause + Pause + + + Pauses reads and writes + Met en pause les lectures et écritures + + + No Scrub + Pas de nettoyage + + + Scrubbing is disabled + Nettoyage désactivé + + + No Deep Scrub + Pas de nettoyage en profondeur + + + Deep Scrubbing is disabled + Le nettoyage en profondeur est désactivé + + + No Backfill + Pas de renvoi + + + Backfilling of PGs is suspended + Le renvoi des groupes de placements est suspendu + + + No Recover + Pas de récupération + + + Recovery of PGs is suspended + La récupération des groupes de placements est suspendue + + + Bitwise Sort + Tri au niveau du bit + + + Use bitwise sort + Utiliser le tri au niveau du bit + + + Purged Snapdirs + Variables snapdir purgées + + + OSDs have converted snapsets + Les OSD ont converti les variables snapset + + + Recovery Deletes + Suppressions des récupérations + + + Deletes performed during recovery instead of peering + Suppressions effectuées pendant la restauration et non l'homologation + + + PG Log Hard Limit + Limite stricte de journalisation des groupes de placements + + + Puts a hard limit on pg log length + Impose une limite stricte à la longueur du journal des groupes de placements + + + Updated OSD Flags + Drapeaux OSD mis à jour + + + out + sorti + + + in + rentré + + + down + arrêté + + + Mark + Marquer + + + OSD lost + OSD perdu + + + marked lost + marqué comme perdu + + + Purge + Purger + + + OSD + OSD + + + purged + purgé + + + destroy + détruire + + + destroyed + détruit + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + Groupes de placements + + + Read bytes + Octets de lecture + + + Writes bytes + Octets d'écriture + + + Read ops + Opérations de lecture + + + Write ops + Opérations d'écriture + + + Mark OSD + + + Marquer l'OSD comme + + + + + Mark + + + Marquer comme + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Nbre max. de renvois + + + Recovery Max Active + Nombre maximum de récupérations actives + + + Recovery Max Single Start + Nombre maximum de démarrages uniques de récupérations + + + Recovery Sleep + Mise en veille de la récupération + + + Custom + Personnalisé + + + Updated OSD recovery speed priority " + " + + Priorité de la vitesse de récupération des OSD&quot; + &quot; mise à jour + + + + + was initialized in the following OSD: + + + + a été initialisé(e) sur l'OSD suivant : + + + + + Create silence + Create silence + + + Job + Travail + + + Severity + Gravité + + + Started + Démarré + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Mis à jour + + + Ends + Ends + + + Silence + Silence + + + Used + Utilisé + + + Avail. + Dispo. + + + Clean + Nettoyé + + + Working + En cours + + + Warning + Avertissement + + + Unknown + Inconnu + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + opérationnel + + + no filesystems + aucun système de fichiers + + + active + actif + + + standby + veille + + + n/a + n/a + + + active daemon + daemon actif + + + quorum + quorum + + + The NFS Ganesha service is not configured. + Le service NFS Ganesha n'est pas configuré. + + + Transport + Transport + + + CephFS User + Utilisateur CephFS + + + CephFS Filesystem + Système de fichiers CephFS + + + (inherited from global config) + (hérité de la configuration globale) + + + inherited from global config + hérité de la configuration globale + + + -- Select what kind of user id squashing is performed -- + -- Sélectionner le type de squashing d'ID utilisateur effectué -- + + + There are no daemons available. + Aucun daemon n'est disponible. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Mode cache + + + Min Evict Age + Âge évict min. + + + Min Flush Age + Âge vidage min. + + + Target Max Bytes + Nombre max d'octets cibles + + + Target Max Objects + Nombre max. d'objets cibles + + + No applications added + Aucune application ajoutée + + + Applications limit reached + Limite d'applications atteinte + + + A pool can only have up to four applications definitions. + Une réserve peut avoir quatre définitions d'application maximum. + + + Allowed characters '_a-zA-Z0-9' + Caractère autorisés '_a-zA-Z0-9' + + + Maximum length is 128 characters + La longueur maximale est de 128 caractères. + + + Filter or add applications + Filtrer ou ajouter des applications + + + Add application + Ajouter une application + + + pool + pool + + + erasure code profile + profil de code d'effacement + + + Replica Size + Taille de la réplique + + + Last Change + Dernier changement + + + Erasure Coded Profile + Profil de code d'effacement + + + Crush Ruleset + Jeu de règles Crush + + + Write bytes + Octets d'écriture + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + compartiment + + + Updated Object Gateway bucket " + " + + Compartiment Object Gateway &quot; + &quot; mis à jour + + + + Created Object Gateway bucket " + " + + Compartiment Object Gateway &quot; + &quot; créé + + + + buckets + compartiments + + + capability + capability + + + user + utilisateur + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Utilisateur Object Gateway &quot; + &quot; mis à jour + + + + Created Object Gateway user " + " + + Utilisateur Object Gateway &quot; + &quot; créé + + + + users + utilisateurs + + + Swift Key + Swift Key + + + Scope + Périmètre + + + Read + Lecture + + + Create + Créer + + + role + role + + + Created role ' + ' + + Rôle ' + ' créé + + + + Updated role ' + ' + + Rôle ' + ' mis à jour + + + + System Role + Rôle système + + + Deleted role ' + ' + + Rôle ' + ' supprimé + + + + Created user " + " + + Utilisateur &quot; + &quot; créé + + + + Update user + Mettre à jour l'utilisateur + + + Continue + Continuer + + + You were automatically logged out because your roles have been changed. + Vous avez été automatiquement déconnecté, car vos rôles ont changé. + + + Updated user " + " + + Utilisateur &quot; + &quot; mis à jour + + + + Deleted user " + " + + Utilisateur &quot; + &quot; supprimé + + + + Failed to delete user " + " + + Échec de la suppression de l'utilisateur &quot; + &quot; + + + + You are currently logged in as " + ". + + Vous êtes connecté en tant que &quot; + &quot;. + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Chaque objet est divisé en parties de blocs de données, chacune étant stockée sur un OSD différent. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Calculez des blocs de codage pour chaque objet et stockez-les sur différents OSD. + Le nombre de blocs de codage correspond également au nombre d'OSD qui peuvent être arrêtés sans perdre de données. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Le plugin jerasure est le plugin le plus générique et le plus flexible, +  c'est aussi la valeur par défaut des réserves codées à effacement Ceph. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + La technique la plus flexible est reed_sol_van_van : il suffit de définir k + et m. La technique cauchy_good peut être plus rapide, mais vous devez choisir la taille du paquet + avec précaution. reed_sol_r6_op, liberation, blaum_roth et liber8tion sont des équivalents RAID6 + en ce sens qu'ils ne peuvent être configurés qu'avec m=2. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + L'encodage se fera sur des paquets de taille d'octets. +  Choisir la bonne taille de paquet est difficile. +  La documentation de jerasure contient de nombreuses informations à ce sujet. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + Avec le plugin jerasure, lorsqu'un objet codé à effacement est stocké sur + plusieurs OSD, la récupération à la suite de la perte d'un OSD nécessite la lecture de tous les autres. + Par exemple, si jerasure est configuré avec k=8 et m=4, la perte d'un OSD nécessite de lire + les onze autres pour pouvoir effectuer une réparation. + + Le plugin de code d'effacement lrc crée des blocs de parité locale pour permettre la récupération avec + moins d'OSD. Par exemple, si lrc est configuré avec k=8, m=4 et l=4, + un bloc de parité supplémentaire est créé pour chaque groupe de quatre OSD. Lorsqu'un seul OSD est perdu, il peut être + récupéré avec seulement quatre OSD au lieu de onze. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Regroupez les blocs de données et de codage en ensembles de localité de taille. Par exemple, + pour k=4 et m=2, lorsque locality=3, deux groupes de trois sont créés. Chaque ensemble peut + être récupéré sans lire les blocs d'un autre jeu. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + Type de compartiment Crush dans lequel chaque ensemble de blocs défini + par I sera stocké. Par exemple, s'il est réglé sur rack, chaque groupe de blocs I sera + placé dans un rack différent. Il est utilisé pour créer une étape de la règle CRUSH telle que l'étape de choix + d'un rack. S'il n'est pas défini, aucun regroupement de ce type n'est effectué. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + Le plug-in isa encapsule la bibliothèque ISA. Il ne fonctionne qu'avec des processeurs Intel. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + Le plugin ISA se présente sous deux formes Reed Solomon. + Si reed_sol_van est défini, il équivaut à Vandermonde. Si cauchy est configuré, il équivaut à Cauchy. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + Le plug-in shec encapsule la bibliothèque SHEC multiple. + Il permet à Ceph de récupérer les données plus efficacement qu'avec les codes Reed Solomon. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + Nombre de blocs de parité, chacun incluant chaque bloc de données dans sa + plage de calcul. Ce nombre est utilisé comme estimateur de durabilité. Par exemple, si c=2, + 2 OSD peuvent être arrêtés sans perte de données. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + Nom du compartiment crush utilisé pour la première étape de la règle CRUSH. + Par exemple, l'étape de définition des valeurs par défaut. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Vérifiez qu'il n'existe pas deux blocs dans un compartiment avec le même domaine de + défaillance. Par exemple, si le domaine de défaillance est un hôte, deux blocs ne seront pas stockés sur le même + hôte. Cette option est utilisée pour créer une étape de la règle CRUSH telle que chooseleaf host. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Restreindre le placement aux périphériques d'une classe spécifique + (par exemple, ssd ou hdd), en utilisant les noms des classes de périphériques crush dans la carte CRUSH. + + + Set the directory name from which the erasure code plugin is loaded. + Définissez le nom du répertoire à partir duquel le plug-in de code d'effacement est chargé. + + + Allows all operations + Autoriser toutes les opérations + + + Allows only operations that do not modify the server + Autorise uniquement les opérations qui ne modifient pas le serveur + + + Does not allow read or write operations, but allows any other operation + N'autorise pas les opérations de lecture ou d'écriture, mais toutes les autres. + + + Does not allow read, write, or any operation that modifies file attributes or directory content + N'autorise pas la lecture, l'écriture ni aucune autre opération modifiant les attributs d'un fichier ou le contenu d'un répertoire. + + + Allows no access at all + N'autorise aucun accès + + + -- Select the priority -- + -- Sélectionner la priorité -- + + + Low + Faible + + + High + Élevée + + + Last 5 minutes + Les 5 dernières minutes + + + Last 15 minutes + Les 15 dernières minutes + + + Last 30 minutes + Les 30 dernières minutes + + + Last 1 hour (Default) + La dernière heure (par défaut) + + + Last 3 hours + Les 3 dernières heures + + + Last 6 hours + Les 6 dernières heures + + + Last 12 hours + Les 12 dernières heures + + + Last 24 hours + Les 24 dernières heures + + + Yesterday + Hier + + + Today + Aujourd'hui + + + Today so far + Depuis le début de la journée + + + Day before yesterday + Avant-hier + + + Last 2 days + Les 2 derniers jours + + + This day last week + Il y a huit jours + + + Previous week + La semaine dernière + + + This week + Cette semaine + + + This week so far + Depuis le début de la semaine + + + Last 7 days + Les 7 derniers jours + + + Previous month + Le mois dernier + + + This month + Ce mois + + + This month so far + Depuis le début du mois + + + Last 30 days + Les 30 derniers jours + + + Last 90 days + Les 90 derniers jours + + + Last 6 months + Les 6 derniers mois + + + Last 1 year + L'année écoulée + + + Previous year + L'année dernière + + + This year + Cette année + + + This year so far + Depuis le début de l'année + + + Last 2 years + Les 2 dernières années + + + Last 5 years + Les 5 dernières années + + + Information + Informations + + + No items selected. + Aucun élément sélectionné. + + + Deselect item to select again + Désélectionnez l'élément pour le sélectionner à nouveau. + + + Selection limit reached + Limite de sélection atteinte + + + Filter tags + Balises de filtre + + + Add badge + Ajouter un badge + + + There are no items available. + Aucun élément disponible. + + + Add + Ajouter + + + Remove + Remove + + + Clone + Cloner + + + Copy + Copier + + + Deep Scrub + Nettoyage en profondeur + + + Destroy + Détruire + + + Flatten + Aplatir + + + Mark Down + Marquer comme arrêté + + + Mark In + Marquer comme rentré + + + Mark Lost + Marquer comme perdu + + + Mark Out + Marquer comme sorti + + + Protect + Protéger + + + Rename + Renommer + + + Restore + Restaurer + + + Move to Trash + Déplacer vers la corbeille + + + Unprotect + Annuler la protection + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Supprimé + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Cloné + + + Copied + Copié + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + Oui + + + No + Non + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Qualité de service + + + BPS Limit + Limite de bits/s + + + The desired limit of IO bytes per second. + Limite souhaitée d'octets E/S par seconde. + + + IOPS Limit + Limite E/S par seconde + + + The desired limit of IO operations per second. + Limite souhaitée d'opérations E/S par seconde. + + + Read BPS Limit + Limite de bits/s en lecture + + + The desired limit of read bytes per second. + Limite souhaitée de lecture d'octets par seconde. + + + Read IOPS Limit + Limite E/S par seconde en lecture + + + The desired limit of read operations per second. + Limite souhaitée d'opérations de lecture par seconde. + + + Write BPS Limit + Limite de bits/s en écriture + + + The desired limit of write bytes per second. + Limite souhaitée d'écriture d'octets par seconde. + + + Write IOPS Limit + Limite E/S par seconde en écriture + + + The desired limit of write operations per second. + Limite souhaitée d'opérations d'écriture par seconde. + + + BPS Burst + Rafale de bits/s + + + The desired burst limit of IO bytes. + Limite de rafale d'octets en E/S souhaitée. + + + IOPS Burst + Rafale E/S par seconde + + + The desired burst limit of IO operations. + Limite de rafale d'opérations E/S souhaitée. + + + Read BPS Burst + Rafale E/S par seconde en lecture + + + The desired burst limit of read bytes. + Limite de rafale d'octets lus par seconde. + + + Read IOPS Burst + Rafale E/S par seconde en lecture + + + The desired burst limit of read operations. + Limite de rafale d'opérations de lecture + + + Write BPS Burst + Rafale E/S par seconde en écriture + + + The desired burst limit of write bytes. + Limite de rafale de lectures d'octets souhaitée. + + + Write IOPS Burst + Rafale d'E/S par seconde en écriture + + + The desired burst limit of write operations. + Limite de rafale d'opérations d'écriture souhaitée. + + + Failed to + + + + Impossible de + + + + + + Executing + En cours d'exécution + + + execute + exécuter + + + Executed + Exécuté + + + unknown task + tâche inconnue + + + Creating + En cours de création + + + create + créer + + + Updating + En cours de mise à jour + + + update + mettre à jour + + + Deleting + En cours de suppression + + + delete + supprimer + + + RBD ' + ' + + RBD ' + ' + + + + RBD snapshot ' + ' + + Instantané RBD ' + ' + + + + mirror mode for pool ' + ' + + mode miroir pour la réserve ' + ' + + + + mirror peer for pool ' + ' + + mettre en miroir l'homologue pour la réserve ' + ' + + + + all dashboards + all dashboards + + + Name is already used by + . + + Le nom est déjà utilisé par + . + + + + Name is already used by + . + + Le nom est déjà utilisé par + . + + + + Name is already used by + . + + Le nom est déjà utilisé par + . + + + + + contains snapshots. + + + contient des instantanés. + + + + Cloning + Clonage en cours + + + clone + cloner + + + Snapshot of + must be protected. + + L'instantané de + doit être protégé. + + + + Copying + En cours de copie + + + copy + copie + + + Flattening + Aplatissement + + + flatten + aplatir + + + Flattened + Applati + + + Name is already used by + . + + Nom déjà utilisé par + . + + + + Cannot unprotect + because it contains child images. + + Impossible d'annuler la protection de + , car cet élément contient des images enfants. + + + + Cannot delete + because it's protected. + + Impossible de supprimer + , car cet élément est protégé. + + + + Rolling back + Retour à l'état initial + + + rollback + rétablir l'état initial + + + Rolled back + Rétabli à l'état initial + + + Moving + En cours de déplacement + + + move + déplacer + + + Moved + Déplacé + + + image ' + ' to trash + + image ' + ' déplacée vers la corbeille + + + + Could not find image. + Impossible de trouver l'image. + + + Restoring + En cours de restauration. + + + restore + restaurer + + + Restored + Restauré + + + image ' + ' into ' + ' + + image ' + ' vers ' + ' + + + + Image name ' + ' is already in use. + + Le nom d'image ' + ' est déjà utilisé. + + + + image ' + ' + + image ' + ' + + + + Purging + En cours de purge + + + purge + purger + + + Purged + Purgé + + + all pools + toutes les réserves + + + images from + + + images de + + + + + Cannot disable mirroring because it contains a peer. + Impossible de désactiver la mise en miroir, car l'élément contient un homologue. + + + pool ' + ' + + réserve ' + ' + + + + erasure code profile ' + ' + + profil de code d'effacement ' + ' + + + + target ' + ' + + cible ' + ' + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf new file mode 100644 index 00000000..b66f0391 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.id-ID.xlf @@ -0,0 +1,4363 @@ + + + + + Toggle navigation + Pengalih navigasi + + + Dashboard + Dasbor + + + Cluster + Klaster + + + Hosts + Hos + + + Monitors + Monitor + + + OSDs + OSD + + + Configuration + Konfigurasi + + + CRUSH map + peta CRUSH + + + Manager modules + Modul Ceph Manajer + + + Logs + Log + + + Alerts + Peringatan + + + Silences + Silences + + + Pools + Pool + + + Block + Blok + + + Images + Image + + + Mirroring + Pencerminan + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + Sistemfile + + + Object Gateway + Gerbang Objek + + + Daemons + Daemon + + + Users + Pengguna + + + Buckets + Buket + + + Retrieving data + for + + + . Please wait... + + Menerima data + untuk + + + . Mohon tunggu... + + + + Displaying previously cached data + + for + + + . + + Menampilkan data + sebelumnya +untuk + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Gagal memuat data + untuk + + + . +Mohon periksa kesehatan klaster. + + + + Back + Kembali + + + Select a Language + Pilih bahasa + + + Loading panel data... + Memuat data panel... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Silakan merujuk ke + dokumentasi + tentang +cara mengonfigurasi dan mengaktifkan fungsi pemantauan. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Dasbor Grafana tidak ada. Mohon merujuk ke + dokumentasi + tentang cara +menambahkan dasbor ke Grafana. + + + + Grafana Time Picker + Pemilih Waktu Grafana + + + Reset Settings + Reset Pengaturan + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Gagal memuat data. + + + selected + dipilih + X selected + + + found + ditemukan + X found + + + total + total + X total + + + Edit + Edit + + + Name + Nama + + + Description + Deskripsi + + + Long description + Deskripsi lengkap + + + Default + Bawaan + + + Daemon default + Daemon bawaan + + + Services + Layanan + + + Values + Nilai + + + The entered value is too high! It must not be greater than + . + + Nilai yang dimasukkan terlalu tinggi! Tidak boleh lebih besar dari + . + + + + The entered value is too low! It must not be lower than + . + + Nilai yang dimasukkan terlalu rendah! Tidak boleh lebih rendah dari + . + + + + Save + Simpan + + + CRUSH map viewer + Penampil peta CRUSH + + + Hosts List + Daftar Hos + + + Overall Performance + Performa Keseluruhan + + + No entries found + Entri tidak ditemukan + + + Cluster Logs + Log Klaster + + + Audit Logs + Log Audit + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Memuat konfigurasi... + + + The configuration could not be loaded. + Konfigurasi tidak dapat dimuat. + + + Edit Manager module + Edit modul Ceph Manajer + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + Nilai yang dimasukkan bukan UUID yang valid, cth: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + Nilai yang dimasukkan harus alamat IP yang valid. + + + This field is required. + Isian ini tidak boleh kosong. + + + The entered value is too high! It must be lower or equal to + . + + Nilai yang dimasukkan terlalu tinggi! Harus lebih kecil atau sama dengan + . + + + + The entered value is too low! It must be greater or equal to + . + + Nilai yang dimasukkan terlalu rendah! Harus lebih besar atau sama dengan + . + + + + The entered value needs to be a number. + Nilai yang dimasukkan harus berupa angka. + + + The entered value needs to be a number or decimal. + Nilai yang dimasukkan harus berupa angka atau desimal. + + + Update + Perbarui + + + Status + Status + + + Cluster ID + ID Klaster + + + monmap modified + monmap diubah + + + monmap epoch + monmap epoch + + + quorum con + kuorum con + + + quorum mon + kuorum mon + + + required con + con yang dibutuhkan + + + required mon + mon yang dibutuhkan + + + In Quorum + Memenuhi Kuorum + + + Not In Quorum + Tidak dalam Kuorum + + + Cancel + Batal + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + Anda yakin ingin + dari + ? + + + + Yes, I am sure. + Ya, saya yakin. + + + Cluster-wide OSD Flags + Flag OSD Klaster + + + Submit + Kirim + + + + + + + + + + + form title + + + Advanced... + Tingkat lanjut... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + Prioritas pemulihan OSD + + + Priority + Prioritas + + + Customize priority values + Ubah nilai prioritas + + + This field is required! + Isian ini harus diisi! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + Nilai yang dimasukkan terlalu tinggi! Tidak boleh lebih tinggi dari + . + + + + The entered value is too low! It must not be lower than + . + + Nilai yang dimasukkan terlalu rendah! Tidak boleh lebih rendah dari + . + + + + Reweight OSD + Ubah bobot OSD + + + The value needs to be between 0 and 1. + Nilai harus antara 0 dan 1. + + + Reweight + Ubah bobot + + + OSDs + Scrub + + OSD + Scrub + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {Dalam } } + + + You are about to apply a + scrub to + the OSD + + + . + + Anda akan menerapkan + scrub pada +OSD + + + . + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {dalam } } + + + OSDs List + Daftar OSD + + + + OSD + + will be marked + + + if you proceed. + + + OSD + + akan ditandai + + + jika ingin melanjutkan. + + + + The OSD is not safe to destroy! + OSD tidak aman untuk dihancurkan! + + + + OSD + + will be + + + if you proceed. + + + OSD + + akan + + + jika ingin melanjutkan. + + + + Details + Detail + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Nilai + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Tutup + + + Delete + Hapus + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Kesehatan + + + Statistics + Statistik + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Mohon periksa + dokumentasi + +tentang cara mengonfigurasi dan aktfikan fungsi manajemen NFS Ganesha. + + + + Clients + Klien + + + Any client can access + Semua klien dapat mengakses + + + Addresses + Alamat + + + Required field + Wajib diisi + + + Must contain one or more comma-separated values + Harus mengandung satu atau lebih nilai yang dipisahkan koma + + + For example: + Contoh: + + + Access Type + Tipe Akses + + + Squash + Squash + + + Add clients + Tambah klien + + + Loading... + Memuat... + + + -- No cluster available -- + -- Klaster tidak tersedia -- + + + -- Select the cluster -- + -- Pilih klaster -- + + + Add daemon + Tambah daemon + + + Storage Backend + Backend Penyimpanan + + + -- No data pools available -- + -- Tidak ada pool data tersedia -- + + + -- Select the storage backend -- + -- Pilih backend penyimpanan -- + + + Object Gateway User + Pengguna Gerbang Objek + + + -- No users available -- + -- Pengguna tidak tersedia -- + + + -- Select the object gateway user -- + -- Pilih pengguna gerbang objek -- + + + CephFS User ID + ID Pengguna CephFS + + + -- No clients available -- + -- Klien tidak tersedia -- + + + -- Select the cephx client -- + -- Pilih klien cephx -- + + + CephFS Name + Nama CephFS + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Label Keamanan + + + Enable security label + Aktifkan label keamanan + + + CephFS Path + CephFS Path + + + Path need to start with a '/' and can be followed by a word + Lintasan atau path harus dimulai dengan '/' dan diikuti dengan kata + + + New directory will be created + Direktori baru akan dibuat + + + Path + Path + + + Path can only be a single '/' or a word + Path hanya boleh berupa '/' atau kata + + + New bucket will be created + Buket baru akan dibuat + + + NFS Protocol + Protokol NFS + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + Tag NFS + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Alternatif akses untuk mount + NFSv3 + (tidak boleh diawali /). + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + Klien mungkin tidak dapat mount subdirektori (cth. jika Tag = foo, klien mungkin tidak bisa mount foo/baz). + + + By using different Tag options, the same Path may be exported multiple times. + Dengan menggunakan opsi Tag yang berbeda, Path yang sama akan diekspor beberapa kali. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + Posisi dari + NFS v4 + yang diekspor ini menempati + Pseudo FS + (ini harus unik). + + + + By using different Pseudo options, the same Path may be exported multiple times. + Dengan menggunakan opsi Pseudo yang berbeda, Path yang sama akan diekspor beberapa kali. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- Tipe akses tidak tersedia -- + + + -- Select the access type -- + -- Pilih tipe akses -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- Squash tidak tersedia -- + + + --Select what kind of user id squashing is performed -- + -- Pilih jenis squashing id pengguna yang akan dilakukan -- + + + Transport Protocol + Protokol Transport + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Selamat datang di Ceph! + The welcome message on the login page + + + Username is required + Nama pengguna harus diisi + + + Password is required + Kata sandi harus diisi + + + Login + Masuk + + + Sorry, the user does not exist in Ceph. + Maaf, pengguna tidak terdaftar di Ceph. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Kembali ke Halaman Masuk + + . Anda akan dikeluarkan dari Penyedia Identitas saat Anda mencoba masuk. + + + + Forbidden + Terlarang + + + Sorry, you are not allowed to see what you were looking for. + Maaf, Anda tidak dizinkan melihat hal yang Anda inginkan. + + + Sorry, we could not find what you were looking for + Maaf, kami tidak dapat menemukan yang Anda cari + + + Remove all + Hapus semua + + + Recent Notifications + Notifikasi terkini + + + There are no background tasks. + Tidak ada tugas latar belakang. + + + Background Tasks + Tugas Latar Belakang + + + Help + Bantuan + + + Documentation + Dokumentasi + + + API + API + + + About + Tentang + + + Dashboard Settings + Pengaturan Dasbor + + + User management + Manajemen Pengguna + + + Logged in user + Pengguna masuk + + + Signed in as + + + + + Masuk sebagai + + + + + + + Sign out + Keluar + + + Name... + Nama... + + + The chosen name is already in use. + Nama yang dipilih sudah digunakan. + + + Description... + Deskripsi... + + + Permissions + Izin + + + Roles + Peran + + + Username + Nama pengguna + + + Password + Kata sandi + + + Confirm password + Konfirmasi kata sandi + + + Password confirmation doesn't match the password. + Konfirmasi kata sandi tidak sesuai dengan kata sandi. + + + Full name + Nama lengkap + + + Email + Email + + + Invalid email. + Email tidak valid. + + + You are about to remove "user read / update" permissions from your own user. + Anda akan menghapus izin "pengguna baca / perbarui" dari diri Anda sendiri. + + + If you continue, you will no longer be able to add or remove roles from any user. + Jika melanjutkan, Anda tidak akan lagi dapat menambahkan atau menghapus peran dari pengguna manapun. + + + Are you sure you want to continue? + Anda yakin ingin melanjutkan? + + + Performance counters not available + Penghitung kinerja tidak tersedia + + + Attributes (OSD map) + Atribut (peta OSD) + + + Metadata not available + Metadata tidak tersedia + + + Metadata + Metadata + + + Performance counter + Penghitung kinerja + + + Histogram not available: + + + Histogram tidak tersedia: + + + + + Writes + Tulis + + + Reads + Baca + + + Histogram + Histogram + + + Performance Details + Detail Performa + + + Current values + Nilai saat ini + + + Type + Tipe + + + Min + Min + + + Max + Maks + + + Flags + Flag + + + Source + Sumber + + + Level + Level + + + Can be updated at runtime (editable) + Boleh diperbarui saat dijalankan (bisa diedit) + + + Tags + Tag + + + Enum values + Nilai Enum + + + See also + Lihat juga + + + Cluster Status + Status Klaster + + + Manager Daemons + Manajer Daemon + + + Object Gateways + Gerbang Objek + + + Metadata Servers + Server Metadata + + + iSCSI Gateways + Gateway iSCSI + + + Client IOPS + IOPS klien + + + Client Throughput + Throughput Pengguna + + + Client Read/Write + Baca/Tulis Klien + + + Recovery Throughput + Throughput Pemulihan + + + Scrub + Scrub + + + Performance + Kinerja + + + Raw Capacity + Kapasitas mentah + + + Objects + Objek + + + PGs per OSD + PG per OSD + + + PG Status + Status PG + + + Capacity + Kapasitas + + + + + See + Logs + for more details. + + + + Lihat + + Log untuk detil lainnya. + + + + Ranks + Peringkat + + + MDS performance counters + MDS performance counters + + + Clients: + + + Klien: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Pindahkan image ke tempat sampah + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Untuk pindahkan + + / + + ke tempat sampah, +tekan + Pindah Image + . Anda juga dapat memilih tanggal kedaluwarsa. + + + + Protection expires at + Proteksi berakhir pada + + + NOT PROTECTED + TIDAK DIPROTEKSI + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Format tanggal salah. Mohon gunakan "TTTT-BB-HH JJ:mm:dd". + + + Protection has already expired. Please pick a future date or leave it empty. + Proteksi telah kedaluarsa. Mohon pilih tanggal masa mendatang atau kosongkan. + + + Move Image + Pindahkan Image + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Ikhtisar + + + Targets + Target + + + Discovery Authentication + Otentikasi Discovery + + + User + Pengguna + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Nama pengguna harus terdiri dari 8 hingga 64 karakter dan +hanya boleh mengandung huruf, '.', '@', '-', '_' atau ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Pengguna Bersama + + + Mutual Password + Kata sandi bersama + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Mohon cek ke + dokumentasi + +tentang cara mengonfigurasi dan mengaktifkan fungsi manajemen iSCSI Target. + + + + Available information: + Informasi tersedia: + + + iSCSI Targets not available + iSCSI Target tidak tersedia + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + Hanya tersedia untuk image RBD dengan + fast-diff + yang diaktifkan. + + + + Pool + Pool + + + Data Pool + Pool Data + + + Created + Dibuat + + + Size + Ukuran + + + Object size + Ukuran objek + + + Features + Fitur + + + Provisioned + Disiapkan + + + N/A + N/A + + + Total provisioned + Total disiapkan + + + Striping unit + Unit setrip + + + Striping count + Jumlah setrip + + + Parent + Induk + + + Block name prefix + Awalan nama blok + + + Order + Urutan + + + Snapshots + Snapshot + + + Image + Image + + + This setting overrides the global value + Pengaturan ini akan membatalkan nilai global + + + Global + Global + + + This is the global value. No value for this option has been set for this image. + Ini adalah nilai global. Tidak ada nilai yang diset untuk image ini. + + + + from + + + from + + + + '/' and '@' are not allowed. + '/' dan '@' tidak diperbolehkan. + + + -- No rbd pools available -- + -- Tidak ada pool rbd tersedia -- + + + -- Select a pool -- + -- Pilih pool -- + + + Use a dedicated data pool + Gunakan pool data terdedikasi + + + Data pool + Pool data + + + Dedicated pool that stores the object-data of the RBD. + Pool terdedikasi yang menyimpan data-objek dari RBD. + + + e.g., 10GiB + cth. 10GiB + + + You have to increase the size. + Anda harus menaikkan ukuran. + + + Advanced + Tingkat lanjut + + + Striping + Setrip + + + Stripe unit + Unit setrip + + + -- Select stripe unit -- + -- Pilih ukuran setrip -- + + + This field is required because stripe count is defined! + Isian ini harus diisi karena jumlah setrip telah ditentukan! + + + Stripe unit is greater than object size. + Unit setrip lebih besar dari ukuran objek. + + + Stripe count + Jumlah setrip + + + This field is required because stripe unit is defined! + Isian wajib diisi karena unit setrip didefinisikan! + + + Stripe count must be greater than 0. + Jumlah setrip harus lebih besar dari 0. + + + + RBD Snapshot + + + Snapshot RBD + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Ganti nama} other {Buat} } + + + + Snapshot + + + Snapshot + + + + PROTECTED + DIPROTEKSI + + + UNPROTECTED + TIDAK DIPROTEKSI + + + You are about to rollback + Anda akan mengembalikan semula + + + Purge Trash + Kosongkan Tempah Sampah + + + To purge, select one or All images and click + Untuk menghapus, pilih satu atau Semua image dan pilih + + + Pool: + Pool: + + + Pool name... + Nama Pool... + + + All + Semua + + + Restore Image + Pulihkan Image + + + To restore + Untuk memulihkan + + + type the image's new name and click + ketik nama baru image dan pilih + + + New Name + Nama Baru + + + Expired at + Kedaluwarsa pada + + + Protected until + Diproteksi hingga + + + This image is protected until + . + + Image ini diproteksi hingga + . + + + + Trash + Tempat sampah + + + iSCSI Topology + Topologi iSCSI + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Mengganti parameter ini dari nilai bawaan biasanya tidak diperlukan. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Pengaturan + + + Backstore + Backstore + + + Confirm + Konfirmasi + + + Advanced Settings + Pengaturan Lanjut + + + Target IQN + Target IQN + + + IQN has wrong pattern. + Pola IQN salah. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + Suatu IQN memiliki notasi seperti ini 'iqn.$tahun-$bulan.$reversedAddress:$definedName' + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Contoh: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Informasi lainnya + + + This target has modified advanced settings. + Pengaturan lanjutan target ini telah dimodifikasi. + + + Portals + Portal + + + At least + gateways are required. + + Dibutuhkan min + gerbang/gateway. + + + + Add portal + Tambahkan portal + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Pengaturan Image ini telah dimodifikasi. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Tambahkan image + + + ACL authentication + Otentikasi ACL + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Inisiator + + + Initiator + Inisiator + + + Client IQN + Klien IQN + + + Initiator IQN needs to be unique. + Inisiator IQN harus unik. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Nama pengguna harus terdiri atas 8 hingga 64 karakter dan +hanya boleh mengandung huruf, '.', '@', '-', '_' atau ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + Inisiator termasuk ke dalam grup. Image akan dikonfigurasi di dalam grup. + + + No items added. + Tidak ada yang ditambahkan. + + + Add initiator + Tambahkan inisiator + + + Groups + Grup + + + Group + Grup + + + Add group + Tambahkan grup + + + [object Object] + [object Object] + + + RBD Configuration + Konfigurasi RBD + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Menghapus nilai konfigurasi lokal. Nilai konfigurasi induk akan diturun dan digunakan. + + + The mininum value is 0 + Nilai minimum adalah 0 + + + Issues + Masalah + + + Syncing + Menyinkronkan + + + Ready + Siap + + + Edit pool mirror mode + Edit mode pencerminan pool + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Untuk mengubah mode pencerminan pool  + + + , pilih mode baru dari daftar dan klik  + Perbarui + . + + + + Mode + Mode + + + Peer clusters must be removed prior to disabling mirror. + Klaster mitra harus dihapus sebelum menonaktfikan pencerminan. + + + + + pool mirror peer + + + +mitra pencerminan pool + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Edit} other {Tambah} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + pool +atribut mitra pencerminan untuk pool + + + dan klik + Kirim + . + + + + Cluster Name + Nama Klaster + + + The cluster name is not valid. + Nama klaster tidak valid. + + + CephX ID + CephX ID + + + CephX ID... + CephX ID... + + + The CephX ID is not valid. + CephX ID tidak valid. + + + Monitor Addresses + Alamat Monitor + + + Comma-delimited addresses... + Alamat dengan pemisah-koma... + + + The monitory address is not valid. + Alamat monitor tidak valid. + + + CephX Key + CephX Key + + + Base64-encoded key... + Base64-encoded key... + + + CephX key must be base64 encoded. + Kunci CephX harus base64 encoded. + + + Pools List + Daftar pool + + + The name can only consist of alphanumeric characters, dashes and underscores. + Nama hanya boleh terdiri dari alfanumerik, tanda hubung, dan garis bawah. + + + The chosen erasure code profile name is already in use. + Nama profil erasure code sudah digunakan. + + + Plugin + Plugin + + + Data chunks (k) + Pecahan data (k) + + + Must be equal to or greater than 2. + Harus sama dengan atau lebih dari 2. + + + Coding chunks (m) + Pecahan Coding (m) + + + Must be equal to or greater than 1. + Harus sama dengan atau lebih dari 1. + + + Durability estimator (c) + Penduga daya tahan (c) + + + Locality (l) + Lokalitas (l) + + + Crush failure domain + Domain kegagalan Crush + + + Crush Locality + Lokalitas Crush + + + None + Tidak ada + + + Technique + Teknik + + + Packetsize + Ukuran paket + + + Crush root + Crush root + + + Crush device class + Kelas perangkat Crush + + + any + apa saja + + + Directory + Direktori + + + The chosen Ceph pool name is already in use. + Nama pool Ceph yang dipilih sudah digunakan. + + + Pool type + Jenis pool + + + -- Select a pool type -- + -- Pilih jenis pool -- + + + Placement groups + Grup penempatan + + + At least one placement group is needed! + Dibutuhkan setidaknya satu grup penempatan! + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + Klaster Anda tidak dapat menangani PG sebanyak ini. Mohon hitung ulang jumlah PG yang dibutuhkan. + + + Calculation help + Bantuan penghitungan + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + Pengaturan PG saat ini telah dihitung untuk Anda, Anda +harus memastikan nilai tersebut sesuai kebutuhan sebelum mengajukan. + + + Crush ruleset + Aturan CRUSH + + + -- Select a crush rule -- + -- Pilih aturan crush -- + + + Crush rule + Aturan crush + + + Crush steps + Crush steps + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + Aturan crush tidak dapat digunakan di klaster ini karena +jumlah OSD terlalu sedikit untuk memenuhi syarat minimal OSD untuk aturan ini. + + + Replicated size + Jumlah replikasi + + + Minimum: + + + Minimum: + + + + + Maximum: + + + Maksimum: + + + + + The size specified is out of range. A value from + to + is valid. + + Ukuran yang dimasukkan di luar jangkauan. Nilai yang valid +dari + hingga + . + + + + Erasure code profile + Profil erasure code + + + -- No erasure code profile available -- + -- Tidak ada profil erasure code -- + + + -- Select an erasure code profile -- + -- Pilih profil erasure code -- + + + EC Overwrites + EC Overwrites + + + Applications + Aplikasi + + + Compression + Kompresi + + + Algorithm + Algoritma + + + -- No erasure compression algorithm available -- + -- Tidak ada algoritma pengompresian erasure -- + + + Minimum blob size + Ukuran blob minimum + + + e.g., 128KiB + cth. 128KiB + + + Value should be greater than 0 + Nilai harus lebih besar dari 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Ukuran maksimum blob + + + e.g., 512KiB + cth. 512KiB + + + Value should be greater than the minimum blob size + Nilai harus lebih besar dari ukuran minimum blob + + + Ratio + Rasio + + + Compression ratio + Rasio kompresi + + + Value should be between 0.0 and 1.0 + Nilai harus antara 0.0 dan 1.0 + + + It's not possible to create an RBD pool with '/' in the name. + Tidak boleh membuat pool RBD dengan nama yang mengandung '/'. + + + Please change the name or remove 'rbd' from the applications list. + Mohon ganti atau hapus 'rbd' dari daftar aplikasi. + + + Cache Tiers Details + Detil Cache Bertingkat + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Silakan cek kembali + dokumentasi + +tentang cara mengonfigurasi dan mengaktifkan fungsi manajemen Gerbang Objek. + + + + Daemons List + Daftar Daemon + + + Performance Counters + Penghitung Performa + + + Loading bucket data... + Memuat data buket... + + + The bucket data could not be loaded. + Buket data tidak dapat dimuat. + + + Id + Id + + + The value is not valid. + Nilai tidak valid. + + + Owner + Pemilik + + + -- Select a user -- + -- Pilih pengguna -- + + + ID + ID + + + Index type + Jenis indeks + + + Placement rule + Aturan penempatan + + + Marker + Penanda + + + Maximum marker + Penanda maksimum + + + Version + Versi + + + Master version + Versi Master + + + Modification time + Modifikasi waktu + + + Zonegroup + Zona grup + + + Bucket quota + Kuota Buket + + + Enabled + Diaktifkan + + + Maximum size + Ukuran maksimum + + + Unlimited + Tak terbatas + + + Maximum objects + Objek maksimum + + + -- Select a username -- + -- Pilih nama pengguna -- + + + Auto-generate key + Kunci otomatis-dibuat + + + Access key + Kunci akses + + + Secret key + Kunci rahasia + + + Email address + Alamat email + + + Suspended + Dihentikan + + + System + Sistem + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {Tidak} 1 {Ya} } + + + Maximum buckets + Buket maksimum + + + Subusers + Subpengguna + + + Capabilities + Kemampuan + + + User quota + Kuota pengguna + + + Show + Tampilkan + + + Keys + Kunci + + + -- Select a type -- + -- Pilih tipe -- + + + Permission + Izin + + + -- Select a permission -- + -- Pilih izin -- + + + Subuser + Subpengguna + + + The chosen subuser ID is already in use. + ID subpengguna sudah digunakan. + + + read, write + baca, tulis + + + full + penuh + + + Swift key + Kunci Swift + + + Auto-generate secret + Sandi otomatis-dibuat + + + Loading user data... + Memuat data pengguna... + + + The user data could not be loaded. + Data pengguna tidak dapat dimuat. + + + The chosen user ID is already in use. + ID pengguna yang dipilih sudah digunakan. + + + This is not a valid email address. + Ini bukan alamat email yang valid. + + + The chosen email address is already in use. + Alamat email yang dipilih sudah digunakan. + + + Max. buckets + Maks. buket + + + The entered value must be >= 0. + Nilai yang dimasukkan harus >= 0. + + + S3 key + Kunci S3 + + + There are no subusers. + Tidak ada sub-pengguna. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + Kunci tidak ditemukan. + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + Kemampuan tidak ada. + + + + + + + + + + + + + Unlimited size + Ukuran tak terbatas + + + Max. size + Ukuran maks. + + + Unlimited objects + Objek tak terbatas + + + Max. objects + Objek maks. + + + Current + Terkini + + + Updated discovery authentication + Otentikasi penemuan telah diperbarui + + + There are no portals available. + Tidak ada portal yang tersedia. + + + There are no images available. + Tidak ada image yang tersedia. + + + There are no images available. Please make sure you add an image to the target. + Tidak ada image yang tersedia. Mohon pastikan Anda telah menambahkan image ke target. + + + There are no initiators available. Please make sure you add an initiator to the target. + Tidak ada inisiator tersedia. Mohon pastikan Anda telah menambahkan inisiator ke target. + + + target + target + + + Target + Target + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + Keadaan + + + # Targets + # Targets + + + Read Bytes + Baca Bytes + + + Write Bytes + Tulis Bytes + + + Read Ops + Ops Baca + + + Write Ops + Ops Tulis + + + A/O Since + A/O Sejak + + + Instance + Instance + + + Hostname + Nama hos + + + Issue + Isu + + + Progress + Kemajuan + + + Disabled + Dimatikan + + + Edit Mode + Mode Edit + + + Add Peer + Tambahkan Mitra + + + Edit Peer + Edit Mitra + + + Delete Peer + Hapus Mitra + + + Leader + Pemimpin + + + # Local + # Lokal + + + # Remote + # Jauh + + + mirror peer + mitra pencerminan + + + Key + Kunci + + + RBD + RBD + + + Deep flatten + Perataan mendalam + + + Layering + Lapisan + + + Exclusive lock + Kunci eksklusif + + + Object map (requires exclusive-lock) + Peta objek (butuh kunci-eksklusif) + + + Journaling (requires exclusive-lock) + Penjurnalan (membutuhkan kunci-eksklusif) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Kembalikan snapshot RBD + + + Rollback + Kembalikan + + + RBD snapshot + Snapshot RBD + + + Deleted At + Dihapus pada + + + id + id + + + type + tipe + + + state + keadaan + + + version + versi + + + Host + Hos + + + root + induk + + + Rank + Peringkat + + + Daemon + Daemon + + + Activity + Aktivitas + + + Dentries + Dentries + + + Inodes + Inode + + + Usage + Penggunaan + + + Standby daemons + Daemon siaga + + + The value can be updated at runtime. + Nilai dapat diperbarui saat runtime. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + Daemon/klien tidak dapat mengambil nilai dari +basis data konfigurasi monitor. Kami tidak mengizinkan mengubah ini dari 'ceph config +set ...'. Pilihan ini harus dikonfigurasi melalui ceph.conf atau CLI. + + + Option takes effect only during daemon startup. + Pilihan hanya dapat bekerja selama daemon dimulai. + + + Option only affects cluster creation. + Pilihan hanya berpengaruh pada pembuatan klaster. + + + Option only affects daemon creation. + Pilihan hanya berpengaruh pada pembuatan daemon. + + + Updated config option + + + Perbarui opsi konfigurasi + + + + + Service + Layanan + + + Current value + Nilai saat ini + + + Editable + Dapat diedit + + + Updated options for module " + ". + + Opsi diperbarui untuk modul &quot; + &quot;. + + + + Enable + Aktifkan + + + Disable + Nonaktifkan + + + Reconnecting, please wait ... + Menghubungkan kembali, mohon tunggu... + + + Public Address + Alamat Publik + + + Open Sessions + Buka Sesi + + + No In + Tidak boleh Masuk + + + OSDs that were previously marked out will not be marked back in when they start + OSD yang telah ditandai keluar tidak akan ditandai masuk saat mereka menyala + + + No Out + Tidak boleh Keluar + + + OSDs will not automatically be marked out after the configured interval + OSD tidak akan otomatis ditandai keluar setelah interval dikonfigurasi + + + No Up + Tidak Nyala + + + OSDs are not allowed to start + OSD tidak diizinkan menyala + + + No Down + Tidak Mati + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + Laporan kegagalan OSD sedang diabaikan sehingga monitor tidak akan menandai OSD mati + + + Pause + Jeda + + + Pauses reads and writes + Jeda baca dan tulis + + + No Scrub + Nonaktifkan Scrub + + + Scrubbing is disabled + Scrubbing dinonaktifkan + + + No Deep Scrub + Nonaktifkan Deep Scrub + + + Deep Scrubbing is disabled + Deep Scrubing dinonaktifkan + + + No Backfill + Tidak ada Penambalan + + + Backfilling of PGs is suspended + Penambalan PG dihentikan + + + No Recover + Tidak ada Pemulihan + + + Recovery of PGs is suspended + Pemulihan PG dihentikan + + + Bitwise Sort + Urutan Bitwise + + + Use bitwise sort + Gunakan urutan bitwise + + + Purged Snapdirs + Buang Snapdirs + + + OSDs have converted snapsets + OSD memiliki snapset yang dikonversi + + + Recovery Deletes + Pulihkan yang telah dihapus + + + Deletes performed during recovery instead of peering + Penghapusan dilakukan saat pemulihan bukan saat bermitra + + + PG Log Hard Limit + Batas Maks Log PG + + + Puts a hard limit on pg log length + Taruh batas maks pada panjang log pg + + + Updated OSD Flags + Flag OSD diperbarui + + + out + keluar + + + in + masuk + + + down + gugur + + + Mark + Tandai + + + OSD lost + OSD hilang + + + marked lost + ditandai hilang + + + Purge + Buang + + + OSD + OSD + + + purged + dibuang + + + destroy + hancurkan + + + destroyed + dihancurkan + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + PG + + + Read bytes + Bita baca + + + Writes bytes + Bita tulis + + + Read ops + Ops baca + + + Write ops + Ops tulis + + + Mark OSD + + + Tandai OSD + + + + + Mark + + + Tandai + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Maks Penambalan + + + Recovery Max Active + Maks Pemulihan Aktif + + + Recovery Max Single Start + Maks Menjalankan Pemulihan Tunggal + + + Recovery Sleep + Jeda Pemulihan + + + Custom + Ubahsuai + + + Updated OSD recovery speed priority " + " + + Piroritas &quot; + &quot; kecepatan pemulihan OSD diperbarui. + + + + + was initialized in the following OSD: + + + + telah diinisialisasi pada OSD berikut: + + + + + Create silence + Create silence + + + Job + Tugas + + + Severity + Keparahan + + + Started + Dimulai + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Diperbarui + + + Ends + Ends + + + Silence + Silence + + + Used + Terpakai + + + Avail. + Tersedia + + + Clean + Bersih + + + Working + Bekerja + + + Warning + Peringatan + + + Unknown + Tidak diketahui + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + nyala + + + no filesystems + tidak ada filesistem + + + active + aktif + + + standby + siaga + + + n/a + n/a + + + active daemon + daemon aktif + + + quorum + kuorum + + + The NFS Ganesha service is not configured. + Layanan NFS Ganesha belum dikonfigurasi. + + + Transport + Transport + + + CephFS User + Pengguna CephFS + + + CephFS Filesystem + Filesistem CephFS + + + (inherited from global config) + (diturunkan dari konfig global) + + + inherited from global config + diturunkan dari konfig global + + + -- Select what kind of user id squashing is performed -- + -- Pilih jenis squashing id pengguna yang akan dilakukan -- + + + There are no daemons available. + Tidak ada daemon tersedia. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Mode Cache + + + Min Evict Age + Min Waktu Usir + + + Min Flush Age + Min Waktu Buang + + + Target Max Bytes + Target Maks Bita + + + Target Max Objects + Target Maks Objek + + + No applications added + Tidak ada aplikasi ditambahkan + + + Applications limit reached + Batas aplikasi tercapai + + + A pool can only have up to four applications definitions. + Sebuah pool hanya dapat memiliki empat definisi aplikasi. + + + Allowed characters '_a-zA-Z0-9' + Karakter diperbolehkan '_a-zA-Z0-9' + + + Maximum length is 128 characters + Panjang maksimum 128 karakter + + + Filter or add applications + Saring atau tambah aplikasi + + + Add application + Tambah aplikasi + + + pool + pool + + + erasure code profile + profil erasure code + + + Replica Size + Ukuran Replikasi + + + Last Change + Perubahan Terakhir + + + Erasure Coded Profile + Profil Erasure Code + + + Crush Ruleset + Aturan Crush + + + Write bytes + Bita tulis + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + buket + + + Updated Object Gateway bucket " + " + + Buket Gerbang Objek &quot; + &quot; diperbarui + + + + Created Object Gateway bucket " + " + + Buat buket Gerbang Objek &quot; + &quot; + + + + buckets + buket + + + capability + capability + + + user + pengguna + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Perbarui pengguna Gerbang Objek &quot + ;&quot; + + + + Created Object Gateway user " + " + + Buat pengguna Gerbang Objek &quot; + &quot; + + + + users + pengguna + + + Swift Key + Swift Key + + + Scope + Cakupan + + + Read + Baca + + + Create + Buat + + + role + role + + + Created role ' + ' + + Peran ' + ' dibuat + + + + Updated role ' + ' + + Peran ' + ' diperbarui + + + + System Role + Peran Sistem + + + Deleted role ' + ' + + Peran ' + ' dihapus + + + + Created user " + " + + Pengguna &quot; + &quot; dibuat + + + + Update user + Perbarui pengguna + + + Continue + Lanjutkan + + + You were automatically logged out because your roles have been changed. + Anda dikeluarkan otomatis karena peran Anda telah berubah. + + + Updated user " + " + + Perbarui pengguna &quot; + &quot; + + + + Deleted user " + " + + Hapus pengguna &quot; + &quot; + + + + Failed to delete user " + " + + Gagal menghapus pengguna &quot; + &quot; + + + + You are currently logged in as " + ". + + Saat ini Anda masuk sebagai &quot; + &quot; + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Tiap objek dipecah dalam pecahan-data, masing-masing disimpan pada OSD yang berbeda. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Hitung pecahan coding untuk tiap objek dan simpan pada OSD yang berbeda. +Jumlah pecahan data juga menjadi jumlah OSD yang diperbolehkan mati tanpa kehilangan data. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Plugin jerasure merupakan plugin paling umum dan fleksibel, +serta merupakan plugin bawaan Ceph untuk pool erasure code. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + Teknik yang lebih fleksibel yaitu reed_sol_van : cukup mengeset k +dan m. Teknik cauchy_good bisa lebih cepat, namun Anda harus memilih ukuran paket +dengan seksama. Semua reed_sol_r6_op, liberation, blaum_roth, liber8tion setara dengan RAID6 +dalam hal mereka hanya bisa diatur dengan m=2. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + Penyandian dilakukan setiap saat pada ukuran bita paket. +Sulit untuk menentukan ukuran paket yang tepat. +Silakan cek dokumentasi jerasure untuk informasi lebih mendalam. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + Pada plugin jerasure, saat objek dengan erasure code disimpan pada +banyak OSD, pemulihan dari OSD yang hilang membutuhkan akses dari OSD lainnya. +Contoh, saat jerasure dikonfigurasi dengan k=8 dan m=4, saat satu OSD mati, maka pemulihan akan membutuhkan pembacaan dari tujuh OSD lainnya. + +Plugin lrc erasure code membuat pecahan paritas lokal agar dapat memulihkan +dengan OSD yang lebih sedikit. Contoh, jika lrc dikonfigurasi dengan k=8, m=4, dan l=4, maka lrc akan +membuat pecahan paritas tambahan tiap empat OSD. Saat satu OSD mati, maka pemulihan dapat dilakukan hanya dengan 4 OSD, alih-alih 7 OSD. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Kelompokkan pecahan data dan coding ke dalam ukuran lokalitas. Controh +untuk k=4 dan m=2, saat lokalitas=3 dua grup dari tiga akan dibuat. Setiap set akan +dipulihkan tanpa membaca pecahan dari set lainnya. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + Tipe buket crush setiap set pecahan yang didefinisikan oleh l +akan disimpan. Contoh, jika diset pada rak, tiap grup pecahan l akan +ditempatkan pada rak berbeda. Ini akan digunakan pada aturan step CRUSH yaitu +memilih tiap rak. Jika tidak diset, tidak akan ada pengelompokkan. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + Plugin isa menghimpun perpustakaan ISA. Hanya dapat berjalan pada prosesor Intel. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + Plugin ISA memiliki dua jenis Reed Solomon. +Jika reed_sol_van diset, maka menjadi Vandermonde, jika cauchy diset, maka menjadi Cauchy. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + Plugin shec mengenkapsulasi banyak pustaka SHEC. +Hal ini agar ceph dapat dipulihkan dengan lebih efisien dari kode Reed Solomon. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + Jumlah potongan paritas yang masing-masing mencakup setiap potongan data +dalam rentang perhitungannya. Nilai ini digunakan untuk perkiraan daya tahan. Contoh, jika c=2, +2 OSD dapat mati tanpa kehilangan data. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + Nama buket crush digunakan sebagai langkah pertama dari aturan CRUSH. +Contoh diambil langkah bawaan. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Memastikan tidak ada pecahan data berada pada buket dengan domain kegagalan +yang sama. Contoh, saat domain gagal adalah hos, maka tidak ada pecahan data yang akan disimpan +pada hos yang sama. Aturan CRUSH seperti step chooseleaf hos akan digunakan untuk hal tersebut. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Batasi penempatan ke perangkat dengan kelas tertentu +(cth. ssd atau hdd), menggunakan nama kelas perangkat crush pada peta CRUSH. + + + Set the directory name from which the erasure code plugin is loaded. + Set nama direktori empat plugin erasure code akan dimuat. + + + Allows all operations + Izinkan semua operasi + + + Allows only operations that do not modify the server + Izinkan hanya untuk operasi yang tidak mengubah server + + + Does not allow read or write operations, but allows any other operation + Tidak diizinkan untuk operasi baca dan tulis, namun izinkan operasi lainnya + + + Does not allow read, write, or any operation that modifies file attributes or directory content + Tidak diizinkan untuk baca, tulis, atau operasi lainnya yang mengubah atribut berkas atau konten direktori + + + Allows no access at all + Tidak diizinkan untuk semua hal + + + -- Select the priority -- + -- Pilih prioritas -- + + + Low + Rendah + + + High + Tinggi + + + Last 5 minutes + 5 menit terakhir + + + Last 15 minutes + 15 menit terakhir + + + Last 30 minutes + 30 menit terakhir + + + Last 1 hour (Default) + 1 Jam Terakhir (Bawaan) + + + Last 3 hours + 3 jam terakhir + + + Last 6 hours + 6 jam terakhir + + + Last 12 hours + 12 jam terakhir + + + Last 24 hours + 24 jam terakhir + + + Yesterday + Kemarin + + + Today + Hari ini + + + Today so far + Sejauh hari ini + + + Day before yesterday + Kemarin dulu + + + Last 2 days + 2 hari terakhir + + + This day last week + Hari ini minggu lalu + + + Previous week + Minggu lalu + + + This week + Minggu ini + + + This week so far + Sejauh minggu ini + + + Last 7 days + 7 hari terakhir + + + Previous month + Bulan lalu + + + This month + Bulan ini + + + This month so far + Sejauh bulan ini + + + Last 30 days + 30 hari terakhir + + + Last 90 days + 90 hari terakhir + + + Last 6 months + 6 bulan terakhir + + + Last 1 year + 1 tahun terakhir + + + Previous year + Tahun lalu + + + This year + Tahun ini + + + This year so far + Sejauh tahun ini + + + Last 2 years + 2 tahun terakhir + + + Last 5 years + 5 tahun terakhir + + + Information + Informasi + + + No items selected. + Tidak ada yang dipilih. + + + Deselect item to select again + Batalkan memilih untuk memilih ulang + + + Selection limit reached + Batas pemilihan tercapai + + + Filter tags + Tanda penyaringan + + + Add badge + Tambahkan lencana + + + There are no items available. + Tidak ada yang tersedia. + + + Add + Tambah + + + Remove + Remove + + + Clone + Klon + + + Copy + Salin + + + Deep Scrub + Deep Scrub + + + Destroy + Hancurkan + + + Flatten + Ratakan + + + Mark Down + Tandai Gugur + + + Mark In + Tandai Masuk + + + Mark Lost + Tandai Hilang + + + Mark Out + Tandai Keluar + + + Protect + Proteksi + + + Rename + Ubah nama + + + Restore + Pulihkan + + + Move to Trash + Pindahkan ke Tempat Sampah + + + Unprotect + Tidak diproteksi + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Dihapus + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Diklon + + + Copied + Disalin + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + Ya + + + No + Tidak + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Kualitas Layanan atau QoS + + + BPS Limit + Limit BPS + + + The desired limit of IO bytes per second. + Limit IO bytes per detik yang diinginkan. + + + IOPS Limit + Limit IOPS + + + The desired limit of IO operations per second. + Limit operasi IO per detik yang diinginkan. + + + Read BPS Limit + Limit Baca BPS + + + The desired limit of read bytes per second. + Limit byte baca per detik yang diinginkan. + + + Read IOPS Limit + Limit IOPS Baca + + + The desired limit of read operations per second. + Limit operasi baca per detik yang diinginkan. + + + Write BPS Limit + Limit Tulis BPS + + + The desired limit of write bytes per second. + Limit tulis byte per detik yang diinginkan. + + + Write IOPS Limit + Limit IOPS Tulis + + + The desired limit of write operations per second. + Limit operasi tulis per detik yang diinginkan. + + + BPS Burst + Letupan BPS + + + The desired burst limit of IO bytes. + Limit yang diinginkan untuk letupan atau burst dari IO byte. + + + IOPS Burst + Letupan IOPS + + + The desired burst limit of IO operations. + Limit yang diinginkan untuk letupan atau burst operasi IO. + + + Read BPS Burst + Letupan Baca BPS + + + The desired burst limit of read bytes. + Limit yang diinginkan untuk letupan atau burst dari baca byte. + + + Read IOPS Burst + Letupan IOPS Baca + + + The desired burst limit of read operations. + Limit yang diinginkan untuk letupan atau burst operasi baca. + + + Write BPS Burst + Letupan BPS Tulis + + + The desired burst limit of write bytes. + Limit yang diinginkan untuk letupan atau burst dari tulis byte. + + + Write IOPS Burst + Letupan IOPS Tulis + + + The desired burst limit of write operations. + Limit yang diinginkan untuk letupan atau burst dari operasi baca. + + + Failed to + + + + Gagal untuk + + + + + + Executing + Mengeksekusi + + + execute + eksekusi + + + Executed + Dieksekusi + + + unknown task + tugas tak diketahui + + + Creating + Membuat + + + create + buat + + + Updating + Memperbarui + + + update + perbarui + + + Deleting + Menghapus + + + delete + hapus + + + RBD ' + ' + + RBD ' + ' + + + + RBD snapshot ' + ' + + Snapshot RBD ' + ' + + + + mirror mode for pool ' + ' + + mode pencerminan untuk pool ' + ' + + + + mirror peer for pool ' + ' + + mitra pencerminan untuk pool ' + ' + + + + all dashboards + all dashboards + + + Name is already used by + . + + Nama telah digunakan oleh + . + + + + Name is already used by + . + + Nama telah digunakan oleh + . + + + + Name is already used by + . + + Nama telah digunakan oleh + . + + + + + contains snapshots. + + + berisi snapshot. + + + + Cloning + Pengklonan + + + clone + klon + + + Snapshot of + must be protected. + + Snapshot + harus diproteksi. + + + + Copying + Menyalin + + + copy + salin + + + Flattening + Meratakan + + + flatten + ratakan + + + Flattened + Diratakan + + + Name is already used by + . + + Nama telah digunakan oleh + . + + + + Cannot unprotect + because it contains child images. + + Tidak dapat menghapus proteksi + karena mengandung child image. + + + + Cannot delete + because it's protected. + + Tidak dapat menghapus + karena diproteksi. + + + + Rolling back + Mengembalikan + + + rollback + kembalikan + + + Rolled back + Dikembalikan + + + Moving + Memindahkan + + + move + pindah + + + Moved + dipindahkan + + + image ' + ' to trash + + image ' + ' ke tempat sampah + + + + Could not find image. + Tidak dapat menemukan image. + + + Restoring + Memulihkan + + + restore + pulihkan + + + Restored + Dipulihkan + + + image ' + ' into ' + ' + + image ' + ' ke ' + ' + + + + Image name ' + ' is already in use. + + Nama image ' + ' sudah digunakan. + + + + image ' + ' + + image ' + ' + + + + Purging + Membuang + + + purge + buang + + + Purged + Dibuang + + + all pools + semua pool + + + images from + + + image dari + + + + + Cannot disable mirroring because it contains a peer. + Gagal menonaktifkan pencerminan karena sedang bermitra. + + + pool ' + ' + + pool ' + ' + + + + erasure code profile ' + ' + + profil erasure code ' + ' + + + + target ' + ' + + target ' + ' + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf new file mode 100644 index 00000000..f8214f73 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.it-IT.xlf @@ -0,0 +1,4367 @@ + + + + + Toggle navigation + Attiva/Disattiva barra di navigazione + + + Dashboard + Dashboard + + + Cluster + Cluster + + + Hosts + Host + + + Monitors + Monitor + + + OSDs + OSD + + + Configuration + Configurazione + + + CRUSH map + Mappa CRUSH + + + Manager modules + Moduli Manager + + + Logs + Log + + + Alerts + Avvisi + + + Silences + Silences + + + Pools + Pool + + + Block + Blocco + + + Images + Immagini + + + Mirroring + Esecuzione della copia speculare + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + File system + + + Object Gateway + Object Gateway + + + Daemons + Daemon + + + Users + Utenti + + + Buckets + Compartimenti + + + Retrieving data + for + + + . Please wait... + + Recupero dati + per + + + . Attendere... + + + + Displaying previously cached data + + for + + + . + + Visualizzazione dei dati memorizzati in precedenza nella cache + + per + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Impossibile caricare i dati + per + + + . + Verificare lo stato del cluster. + + + + Back + Indietro + + + Select a Language + Selezionare una lingua + + + Loading panel data... + Caricamento pannello dati in corso... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Consultare la + documentazione + su come + configurare e abilitare la funzionalità di monitoraggio. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Il dashboard di Grafana non esiste. Consultare la + documentazione + su come + aggiungere dashboard a Grafana. + + + + Grafana Time Picker + Selezione ora di Grafana + + + Reset Settings + Impostazioni di ripristino + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Non è stato possibile caricare i dati. + + + selected + selezionato + X selected + + + found + trovato + X found + + + total + totale + X total + + + Edit + Modifica + + + Name + Nome + + + Description + Descrizione + + + Long description + Descrizione lunga + + + Default + Default + + + Daemon default + Default del daemon + + + Services + Servizi + + + Values + Valori + + + The entered value is too high! It must not be greater than + . + + Il valore immesso è troppo alto. Non deve essere maggiore di + . + + + + The entered value is too low! It must not be lower than + . + + Il valore immesso è troppo basso. Non deve essere minore di + . + + + + Save + Salva + + + CRUSH map viewer + Visualizzatore mappa CRUSH + + + Hosts List + Elenco degli host + + + Overall Performance + Prestazioni complessive + + + No entries found + Nessuna voce trovata + + + Cluster Logs + Log dei cluster + + + Audit Logs + Log delle revisioni + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Caricamento della configurazione in corso... + + + The configuration could not be loaded. + Impossibile caricare la configurazione. + + + Edit Manager module + Modifica modulo Manager + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + Il valore immesso non è un UUID valido, ad es.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + Il valore immesso deve essere un indirizzo IP valido. + + + This field is required. + Questo campo è obbligatorio. + + + The entered value is too high! It must be lower or equal to + . + + Il valore immesso è troppo alto. Deve essere minore o uguale a + . + + + + The entered value is too low! It must be greater or equal to + . + + Il valore immesso è troppo basso. Deve essere maggiore o uguale a + . + + + + The entered value needs to be a number. + Il valore immesso deve essere un numero. + + + The entered value needs to be a number or decimal. + Il valore immesso deve essere un numero o un decimale. + + + Update + Aggiorna + + + Status + Stato + + + Cluster ID + ID cluster + + + monmap modified + mappa mon modificata + + + monmap epoch + epoca mappa mon + + + quorum con + quorum con + + + quorum mon + quorum mon + + + required con + con richiesta + + + required mon + mon richiesto + + + In Quorum + Nel quorum + + + Not In Quorum + Non nel quorum + + + Cancel + Annulla + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + Si è sicuri di voler + l'elemento + selezionato? + + + + Yes, I am sure. + Sì. + + + Cluster-wide OSD Flags + Flag OSD in tutto il cluster + + + Submit + Invia + + + + + + + + + + + form title + + + Advanced... + Avanzate... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + Priorità di recupero OSD + + + Priority + Priorità + + + Customize priority values + Personalizza valori di priorità + + + This field is required! + Questo campo è obbligatorio. + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + Il valore immesso è troppo alto. Non deve essere maggiore di + . + + + + The entered value is too low! It must not be lower than + . + + Il valore immesso è troppo basso. Non deve essere minore di + . + + + + Reweight OSD + Ripesa OSD + + + The value needs to be between 0 and 1. + Il valore deve essere compreso tra 0 e 1. + + + Reweight + Ripesa + + + OSDs + Scrub + + Pulitura degli + OSD + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {Deep } } + + + You are about to apply a + scrub to + the OSD + + + . + + Si sta per eseguire una + pulitura + dell'OSD + + + . + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {deep } } + + + OSDs List + Elenco degli OSD + + + + OSD + + will be marked + + + if you proceed. + + + L'OSD + + viene contrassegnato + + + se si procede. + + + + The OSD is not safe to destroy! + Non è sicuro eliminare definitivamente l'OSD. + + + + OSD + + will be + + + if you proceed. + + + L'OSD + + viene + + + se si procede. + + + + Details + Dettagli + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Valore + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Chiudi + + + Delete + Elimina + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Stato + + + Statistics + Statistiche + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Consultare la + documentazione + + su come configurare e abilitare la funzionalità di gestione di NFS Ganesha. + + + + Clients + Client + + + Any client can access + Può accedere qualsiasi client + + + Addresses + Indirizzi + + + Required field + Campo obbligatorio + + + Must contain one or more comma-separated values + Deve contenere uno o più valori delimitati da virgole + + + For example: + Ad esempio: + + + Access Type + Tipo di accesso + + + Squash + Esegui squash + + + Add clients + Aggiungi client + + + Loading... + Caricamento in corso... + + + -- No cluster available -- + -- Nessun cluster disponibile -- + + + -- Select the cluster -- + -- Selezionare il cluster -- + + + Add daemon + Aggiungi daemon + + + Storage Backend + Backend di storage + + + -- No data pools available -- + -- Nessun pool di dati disponibile -- + + + -- Select the storage backend -- + -- Selezionare il backend di storage -- + + + Object Gateway User + Utente Object Gateway + + + -- No users available -- + -- Nessun utente disponibile -- + + + -- Select the object gateway user -- + -- Selezionare l'utente Object Gateway -- + + + CephFS User ID + ID utente CephFS + + + -- No clients available -- + -- Nessun client disponibile -- + + + -- Select the cephx client -- + -- Selezionare il client Cephx -- + + + CephFS Name + Nome CephFS + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Etichetta di sicurezza + + + Enable security label + Abilita etichetta di sicurezza + + + CephFS Path + Percorso CephFS + + + Path need to start with a '/' and can be followed by a word + Il percorso deve iniziare con una barra '/' e può essere seguito da una parola + + + New directory will be created + Viene creata la nuova directory + + + Path + Percorso + + + Path can only be a single '/' or a word + Il percorso può essere solo una singola barra '/' o parola + + + New bucket will be created + Viene creato il nuovo compartimento + + + NFS Protocol + Protocollo NFS + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + Tag NFS + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Accesso alternativo per montaggi + NFS v3 + (non deve contenere una / iniziale). + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + I client non possono montare le sottodirectory (ad es. se Tag = foo, il client non può montare foo/baz). + + + By using different Tag options, the same Path may be exported multiple times. + Utilizzando diverse opzioni Tag, è possibile esportare più volte lo stesso percorso. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + La posizione che occupa l'esportazione + NFS v4 + + nello + Pseudo FS + (deve essere univoca). + + + + By using different Pseudo options, the same Path may be exported multiple times. + Utilizzando diverse opzioni Pseudo, è possibile esportare più volte lo stesso percorso. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- Nessun tipo di accesso disponibile -- + + + -- Select the access type -- + -- Selezionare il tipo di accesso -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- Nessuno squash disponibile -- + + + --Select what kind of user id squashing is performed -- + --Selezionare il tipo di squash dell'ID utente da eseguire -- + + + Transport Protocol + Protocollo di trasporto + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Benvenuto in Ceph. + The welcome message on the login page + + + Username is required + Nome utente necessario + + + Password is required + Password richiesta + + + Login + Login + + + Sorry, the user does not exist in Ceph. + Spiacenti, l'utente non esiste in Ceph. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Tornale alla + Pagina di login + . Si viene disconnessi dal Provider di identità + quando si riprova a eseguire il login. + + + + Forbidden + Non consentito + + + Sorry, you are not allowed to see what you were looking for. + Spiacenti, non è consentito visualizzare ciò che si stava cercando. + + + Sorry, we could not find what you were looking for + Spiacenti, impossibile trovare ciò che si stava cercando + + + Remove all + Rimuovi tutto + + + Recent Notifications + Notifiche recenti + + + There are no background tasks. + Non esistono task in background. + + + Background Tasks + Task in background + + + Help + Guida + + + Documentation + Documentazione + + + API + API + + + About + Informazioni su + + + Dashboard Settings + Impostazioni del dashboard + + + User management + Gestione utenti + + + Logged in user + Utente connesso + + + Signed in as + + + + + Connesso come + + + + + + + Sign out + Disconnetti + + + Name... + Nome... + + + The chosen name is already in use. + Il nome scelto è già in uso. + + + Description... + Descrizione... + + + Permissions + Autorizzazioni + + + Roles + Ruoli + + + Username + Nome utente + + + Password + Password + + + Confirm password + Conferma password + + + Password confirmation doesn't match the password. + La password di conferma non corrisponde alla password. + + + Full name + Nome completo + + + Email + E-mail + + + Invalid email. + E-mail non valida. + + + You are about to remove "user read / update" permissions from your own user. + Si stanno per rimuovere le autorizzazioni di "lettura/aggiornamento utente" dal proprio utente. + + + If you continue, you will no longer be able to add or remove roles from any user. + Se si continua, non è più possibile aggiungere o rimuovere ruoli da qualsiasi utente. + + + Are you sure you want to continue? + Continuare? + + + Performance counters not available + Contatori delle prestazioni non disponibili + + + Attributes (OSD map) + Attributi (mappa OSD) + + + Metadata not available + Metadati non disponibili + + + Metadata + Metadati + + + Performance counter + Contatore delle prestazioni + + + Histogram not available: + + + Istogramma non disponibile: + + + + + Writes + Scritture + + + Reads + Letture + + + Histogram + Istogramma + + + Performance Details + Dettagli sulle prestazioni + + + Current values + Valori attuali + + + Type + Tipo + + + Min + Min + + + Max + Max + + + Flags + Flag + + + Source + Origine + + + Level + Livello + + + Can be updated at runtime (editable) + Può essere aggiornato al runtime (modificabile) + + + Tags + Tag + + + Enum values + Valori di enumerazione + + + See also + Vedere anche + + + Cluster Status + Stato del cluster + + + Manager Daemons + Manager Daemon + + + Object Gateways + Object Gateway + + + Metadata Servers + Server di metadati + + + iSCSI Gateways + iSCSI Gateway + + + Client IOPS + IOPS client + + + Client Throughput + Velocità effettiva client + + + Client Read/Write + Lettura/scrittura client + + + Recovery Throughput + Velocità effettiva di recupero + + + Scrub + Pulitura + + + Performance + Prestazioni + + + Raw Capacity + Capacità di base + + + Objects + Oggetti + + + PGs per OSD + Gruppi di posizionamento per OSD + + + PG Status + Stato gruppo di posizionamento + + + Capacity + Capacità + + + + + See + Logs + for more details. + + + + Vedere + Log + per ulteriori informazioni. + + + + Ranks + Classificazioni + + + MDS performance counters + MDS performance counters + + + Clients: + + + Client: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Sposta un'immagine nel cestino + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Per spostare + + / + + nel cestino, + fare clic su + Sposta immagine + . Facoltativamente, è possibile selezionare una data di scadenza. + + + + Protection expires at + La protezione scade alle + + + NOT PROTECTED + NON PROTETTO + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Formato data errato. Utilizzare "AAAA-MM-GG HH:mm:ss". + + + Protection has already expired. Please pick a future date or leave it empty. + La protezione è già scaduta. Selezionare una data futura o lasciarla vuota. + + + Move Image + Sposta immagine + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Panoramica + + + Targets + Destinazioni + + + Discovery Authentication + Autenticazione rilevazione + + + User + Utente + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + I nomi utente devono avere una lunghezza compresa tra 8 e 64 caratteri e + possono contenere solo lettere, '.', '@', '-', '_' o ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Utente reciproco + + + Mutual Password + Password reciproca + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Consultare la + documentazione + + su come configurare e abilitare la funzionalità di gestione delle destinazioni iSCSI. + + + + Available information: + Informazioni disponibili: + + + iSCSI Targets not available + Destinazioni iSCSI non disponibili + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + Disponibile solo per le immagini RDB con + fast-diff + abilitata + + + + Pool + Pool + + + Data Pool + Pool di dati + + + Created + Creato + + + Size + Dimensioni + + + Object size + Dimensioni oggetto + + + Features + Funzioni + + + Provisioned + Soggetto al provisioning + + + N/A + N/D + + + Total provisioned + Totale soggetto al provisioning + + + Striping unit + Unità di striping + + + Striping count + Conteggio di striping + + + Parent + Superiore + + + Block name prefix + Prefisso nome blocco + + + Order + Ordine + + + Snapshots + Snapshot + + + Image + Immagine + + + This setting overrides the global value + Questa impostazione sostituisce il valore globale + + + Global + Globale + + + This is the global value. No value for this option has been set for this image. + Questo è il valore globale. Nessun valore di opzione è stato impostato per questa immagine. + + + + from + + + from + + + + '/' and '@' are not allowed. + '/' e '@' non sono consentiti. + + + -- No rbd pools available -- + -- Nessun pool rbd disponibile -- + + + -- Select a pool -- + -- Selezionare un pool -- + + + Use a dedicated data pool + Utilizza un pool di dati dedicato + + + Data pool + Pool di dati + + + Dedicated pool that stores the object-data of the RBD. + Pool dedicato che archivia i dati oggetto dell'RBD. + + + e.g., 10GiB + ad es. 10 GiB + + + You have to increase the size. + È necessario aumentare le dimensioni. + + + Advanced + Avanzate + + + Striping + Striping + + + Stripe unit + Unità di striping + + + -- Select stripe unit -- + -- Selezionare l'unità di striping -- + + + This field is required because stripe count is defined! + Questo campo è obbligatorio perché è specificato il numero di striping. + + + Stripe unit is greater than object size. + L'unità di striping è maggiore delle dimensioni dell'oggetto. + + + Stripe count + Numero di striping + + + This field is required because stripe unit is defined! + Questo campo è obbligatorio perché è specificata l'unità di striping. + + + Stripe count must be greater than 0. + Il numero di striping deve essere maggiore di 0. + + + + RBD Snapshot + + + Snapshot RBD + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Rename} other {Create} } + + + + Snapshot + + + Snapshot + + + + PROTECTED + PROTETTO + + + UNPROTECTED + NON PROTETTO + + + You are about to rollback + Si sta per eseguire il rollback + + + Purge Trash + Elimina definitivamente contenuto del cestino + + + To purge, select one or All images and click + Per eliminare definitivamente, selezionare una o tutte le immagini e fare clic su + + + Pool: + Pool: + + + Pool name... + Nome pool... + + + All + Tutto + + + Restore Image + Ripristina immagine + + + To restore + Per ripristinare, + + + type the image's new name and click + digitare il nuovo nome dell'immagine e fare clic su + + + New Name + Nuovo nome + + + Expired at + Scaduto alle + + + Protected until + Protetto fino alle + + + This image is protected until + . + + Questa immagine è protetta fino alle + . + + + + Trash + Cestino + + + iSCSI Topology + Topologia iSCSI + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Di solito non è necessario modificare questi parametri rispetto ai valori di default. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Impostazioni + + + Backstore + Backstore + + + Confirm + Conferma + + + Advanced Settings + Impostazioni avanzate + + + Target IQN + IQN di destinazione + + + IQN has wrong pattern. + IQN contiene un modello errato. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + Un IQN contiene la notazione seguente 'iqn.$year-$month.$reversedAddress:$definedName' + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Ad esempio: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Ulteriori informazioni + + + This target has modified advanced settings. + Questa destinazione contiene impostazioni avanzate modificate. + + + Portals + Portali + + + At least + gateways are required. + + Gateway richiesti: almeno + . + + + + Add portal + Aggiungi portale + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Questa immagine contiene impostazioni modificate. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Aggiungi immagine + + + ACL authentication + Autenticazione ACL + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Iniziatori + + + Initiator + Iniziatore + + + Client IQN + IQN client + + + Initiator IQN needs to be unique. + L'IQN dell'iniziatore deve essere univoco. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + I nomi utente devono avere una lunghezza compresa tra 8 e 64 caratteri e + possono contenere solo lettere, '.', '@', '-', '_' o ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + L'iniziatore appartiene a un gruppo. Le immagini verranno configurate nel gruppo. + + + No items added. + Nessun elemento aggiunto. + + + Add initiator + Aggiungi iniziatore + + + Groups + Gruppi + + + Group + Gruppo + + + Add group + Aggiungi gruppo + + + [object Object] + [object Object] + + + RBD Configuration + Configurazione RBD + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Rimuovere il valore della configurazione locale. Al suo posto verrà ereditato e utilizzato il valore della configurazione superiore. + + + The mininum value is 0 + Il valore minimo è 0 + + + Issues + Problemi + + + Syncing + Sincronizzazione in corso + + + Ready + Pronto + + + Edit pool mirror mode + Modifica modalità speculare per il pool + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Per modificare la modalità speculare per il pool  + + + , selezionare una nuova modalità dall'elenco e fare clic su  + Aggiorna + . + + + + Mode + Modalità + + + Peer clusters must be removed prior to disabling mirror. + È necessario rimuovere i cluster peer prima di disabilitare la copia speculare. + + + + + pool mirror peer + + + + peer copia speculare del pool + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Edit} other {Add} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + gli attributi peer della + copia speculare per il pool + + + e fare clic su + Invia + . + + + + Cluster Name + Nome cluster + + + The cluster name is not valid. + Il nome del cluster non è valido. + + + CephX ID + ID CephX + + + CephX ID... + ID CephX... + + + The CephX ID is not valid. + L'ID CephX non è valido. + + + Monitor Addresses + Indirizzi dei monitor + + + Comma-delimited addresses... + Indirizzi con valori delimitati da virgole... + + + The monitory address is not valid. + L'indirizzo del monitor non è valido. + + + CephX Key + Chiave CephX + + + Base64-encoded key... + Chiave con codifica Base64... + + + CephX key must be base64 encoded. + La chiave CephX deve essere con codifica Base64. + + + Pools List + Elenco dei pool + + + The name can only consist of alphanumeric characters, dashes and underscores. + Il nome può contenere solo caratteri alfanumerici, trattini e caratteri di sottolineatura. + + + The chosen erasure code profile name is already in use. + Il nome del profilo del codice di cancellazione selezionato è già in uso. + + + Plugin + Plugin + + + Data chunks (k) + Porzioni di dati (k) + + + Must be equal to or greater than 2. + Deve essere uguale o maggiore di 2. + + + Coding chunks (m) + Porzioni di codice (m) + + + Must be equal to or greater than 1. + Deve essere uguale o maggiore di 1. + + + Durability estimator (c) + Stima durata (c) + + + Locality (l) + Località (l) + + + Crush failure domain + Dominio di errore Crush + + + Crush Locality + Località Crush + + + None + Nessuno + + + Technique + Tecnica + + + Packetsize + Dimensione del pacchetto + + + Crush root + Radice Crush + + + Crush device class + Classe dispositivo Crush + + + any + qualsiasi + + + Directory + Directory + + + The chosen Ceph pool name is already in use. + Il nome del pool Ceph scelto è già in uso. + + + Pool type + Tipo di pool + + + -- Select a pool type -- + -- Selezionare un tipo di pool -- + + + Placement groups + Gruppi di posizionamento + + + At least one placement group is needed! + È necessario almeno un gruppo di posizionamento. + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + Il cluster non può gestire questo numero eccessivo di gruppi di posizionamento. Ricalcolare il numero di gruppi di posizionamento necessari. + + + Calculation help + Guida per il calcolo + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + Sono state calcolate le impostazioni dei gruppi di posizionamento attuali; + prima di inviare, assicurarsi che i valori soddisfino le proprie esigenze. + + + Crush ruleset + Set di regole Crush + + + -- Select a crush rule -- + -- Selezionare una regola Crush -- + + + Crush rule + Regola Crush + + + Crush steps + Passaggi Crush + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + Non è possibile utilizzare la regola nel cluster attuale perché il numero degli + OSD che contiene è troppo basso e non soddisfa il numero minimo di OSD richiesto da questa regola. + + + Replicated size + Dimensioni replicate + + + Minimum: + + + Minime: + + + + + Maximum: + + + Massime: + + + + + The size specified is out of range. A value from + to + is valid. + + Le dimensioni specificate non sono comprese nell'intervallo. L'intervallo valido è da + a + . + + + + Erasure code profile + Profilo del codice di cancellazione + + + -- No erasure code profile available -- + -- Nessun profilo del codice di cancellazione disponibile -- + + + -- Select an erasure code profile -- + -- Selezionare un profilo del codice di cancellazione -- + + + EC Overwrites + Sovrascritture EC + + + Applications + Applicazioni + + + Compression + Compressione + + + Algorithm + Algoritmo + + + -- No erasure compression algorithm available -- + -- Nessun algoritmo di compressione della cancellazione disponibile -- + + + Minimum blob size + Dimensioni minime del blob + + + e.g., 128KiB + ad es. 128 KiB + + + Value should be greater than 0 + Il valore deve essere maggiore di 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Dimensioni massime del blob + + + e.g., 512KiB + ad es. 512 KiB + + + Value should be greater than the minimum blob size + Il valore deve essere maggiore delle dimensioni minime del blob + + + Ratio + Rapporto + + + Compression ratio + Rapporto di compressione + + + Value should be between 0.0 and 1.0 + Il valore deve essere compreso tra 0,0 e 1,0 + + + It's not possible to create an RBD pool with '/' in the name. + Non è possibile creare un pool RBD con una '/' nel nome. + + + Please change the name or remove 'rbd' from the applications list. + Modificare il nome o rimuovere 'rbd' dall'elenco delle applicazioni. + + + Cache Tiers Details + Dettagli livelli cache + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Consultare la + documentazione + + su come configurare e abilitare la funzionalità di gestione di Object Gateway. + + + + Daemons List + Elenco dei daemon + + + Performance Counters + Contatori delle prestazioni + + + Loading bucket data... + Caricamento dati compartimento in corso... + + + The bucket data could not be loaded. + Impossibile caricare i dati del compartimento. + + + Id + ID + + + The value is not valid. + Il valore non è valido. + + + Owner + Proprietario + + + -- Select a user -- + -- Selezionare un utente -- + + + ID + ID + + + Index type + Tipo di indice + + + Placement rule + Regola di posizionamento + + + Marker + Contrassegno + + + Maximum marker + Contrassegno massimo + + + Version + Versione + + + Master version + Versione master + + + Modification time + Ora di modifica + + + Zonegroup + Gruppo di zone + + + Bucket quota + Quota compartimenti + + + Enabled + Abilitato + + + Maximum size + Dimensioni massime + + + Unlimited + Illimitato + + + Maximum objects + Numero massimo di oggetti + + + -- Select a username -- + -- Selezionare un nome utente -- + + + Auto-generate key + Generazione automatica chiave + + + Access key + Chiave di accesso + + + Secret key + Chiave segreta + + + Email address + Indirizzo e-mail + + + Suspended + Sospeso + + + System + Sistema + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {No} 1 {Yes} } + + + Maximum buckets + Numero massimo di compartimenti + + + Subusers + Sottoutenti + + + Capabilities + Capacità + + + User quota + Quota utenti + + + Show + Mostra + + + Keys + Chiavi + + + -- Select a type -- + -- Selezionare un tipo -- + + + Permission + Autorizzazione + + + -- Select a permission -- + -- Selezionare un'autorizzazione -- + + + Subuser + Sottoutente + + + The chosen subuser ID is already in use. + L'ID del sottoutente scelto è già in uso. + + + read, write + lettura, scrittura + + + full + pieno + + + Swift key + Chiave Swift + + + Auto-generate secret + Generazione automatica segreto + + + Loading user data... + Caricamento dati utente in corso... + + + The user data could not be loaded. + Impossibile caricare i dati utente. + + + The chosen user ID is already in use. + L'ID utente scelto è già in uso. + + + This is not a valid email address. + Non è un indirizzo e-mail valido. + + + The chosen email address is already in use. + L'indirizzo e-mail scelto è già in uso. + + + Max. buckets + Numero max. di compartimenti + + + The entered value must be >= 0. + Il valore immesso deve essere >= a 0. + + + S3 key + Chiave S3 + + + There are no subusers. + Non esistono sottoutenti. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + Non esistono chiavi. + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + Non esistono capacità. + + + + + + + + + + + + + Unlimited size + Dimensioni illimitate + + + Max. size + Dimensione max. + + + Unlimited objects + Oggetti illimitati + + + Max. objects + Numero max. di oggetti + + + Current + Attuale + + + Updated discovery authentication + Autenticazione rilevazione aggiornata + + + There are no portals available. + Non sono disponibili pool. + + + There are no images available. + Non sono disponibili immagini. + + + There are no images available. Please make sure you add an image to the target. + Non sono disponibili immagini. Assicurarsi di aggiungere un'immagine alla destinazione. + + + There are no initiators available. Please make sure you add an initiator to the target. + Non sono disponibili iniziatori. Assicurarsi di aggiungere un iniziatore alla destinazione. + + + target + target + + + Target + Destinazione + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + Stato + + + # Targets + # Targets + + + Read Bytes + Byte letti + + + Write Bytes + Byte scritti + + + Read Ops + Operazioni di lettura + + + Write Ops + Operazioni di scrittura + + + A/O Since + A/O da + + + Instance + Istanza + + + Hostname + Nome host + + + Issue + Problema + + + Progress + Avanzamento + + + Disabled + Disabilitato + + + Edit Mode + Modalità di modifica + + + Add Peer + Aggiungi peer + + + Edit Peer + Modifica peer + + + Delete Peer + Elimina peer + + + Leader + Sequenza iniziale + + + # Local + # Locale + + + # Remote + # Remoto + + + mirror peer + peer copia speculare + + + Key + Chiave + + + RBD + RBD + + + Deep flatten + Appiattimento profondo + + + Layering + Su strati + + + Exclusive lock + Blocco esclusivo + + + Object map (requires exclusive-lock) + Mappa oggetti (richiede il blocco escluso) + + + Journaling (requires exclusive-lock) + Journaling (richiede il blocco esclusivo) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Rollback snapshot RBD + + + Rollback + Esegui rollback + + + RBD snapshot + Snapshot RBD + + + Deleted At + Eliminato alle + + + id + ID + + + type + tipo + + + state + stato + + + version + versione + + + Host + Host + + + root + root + + + Rank + Classificazione + + + Daemon + Daemon + + + Activity + Task + + + Dentries + Dentry + + + Inodes + Inode + + + Usage + Utilizzo + + + Standby daemons + Daemon in standby + + + The value can be updated at runtime. + È possibile aggiornare il valore al runtime. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + I daemon/client non estraggono questo valore dal + database della configurazione di monitoraggio. Non è consentito impostare questa opzione tramite 'ceph config + set ...'. È necessario configurare questa opzione tramite ceph.conf o dalla + riga di comando. + + + Option takes effect only during daemon startup. + L'opzione diventa attiva solo all'avvio del daemon. + + + Option only affects cluster creation. + L'opzione interessa solo la creazione del cluster. + + + Option only affects daemon creation. + L'opzione interessa solo la creazione del daemon. + + + Updated config option + + + Aggiornata opzione di configurazione + + + + + Service + Servizio + + + Current value + Valore attuale + + + Editable + Modificabile + + + Updated options for module " + ". + + Opzioni aggiornate per il modulo &quot; + &quot;. + + + + Enable + Abilita + + + Disable + Disabilita + + + Reconnecting, please wait ... + Riconnessione in corso. Attendere. + + + Public Address + Indirizzo pubblico + + + Open Sessions + Sessioni aperte + + + No In + Nessuno in entrata + + + OSDs that were previously marked out will not be marked back in when they start + Gli OSD che sono stati contrassegnati come disattivi in precedenza non verranno contrassegnati nuovamente come attivi all'avvio + + + No Out + Nessuno in uscita + + + OSDs will not automatically be marked out after the configured interval + Gli OSD non verranno disattivati automaticamente dopo l'intervallo configurato + + + No Up + Nessuno attivo + + + OSDs are not allowed to start + Non è consentito l'avvio degli OSD + + + No Down + Nessuno disattivo + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + I rapporti di errore degli OSD vengono ignorati in modo che i monitor non disattivino gli OSD + + + Pause + Sospendi + + + Pauses reads and writes + Sospende le operazioni di lettura e scrittura + + + No Scrub + Nessuna pulitura + + + Scrubbing is disabled + Pulitura disabilitata + + + No Deep Scrub + Nessun pulitura approfondita + + + Deep Scrubbing is disabled + Pulitura approfondita disabilitata + + + No Backfill + Nessuna operazione di recupero + + + Backfilling of PGs is suspended + Recupero dei gruppi di posizionamento sospeso + + + No Recover + Nessun recupero + + + Recovery of PGs is suspended + Recupero dei gruppi di posizionamento sospeso + + + Bitwise Sort + Ordinamento bitwise + + + Use bitwise sort + Usa ordinamento bitwise + + + Purged Snapdirs + Snapdir eliminate definitivamente + + + OSDs have converted snapsets + Gli OSD contengono set di snap convertiti + + + Recovery Deletes + Eliminazioni recuperi + + + Deletes performed during recovery instead of peering + Eliminazioni eseguite durante il recupero invece del peering + + + PG Log Hard Limit + Limite rigido log gruppo di posizionamento + + + Puts a hard limit on pg log length + Inserisce un limite rigido alla lunghezza del log del gruppo di posizionamento + + + Updated OSD Flags + Flag OSD aggiornati + + + out + esterno + + + in + interno + + + down + in basso + + + Mark + Contrassegna + + + OSD lost + OSD perso + + + marked lost + contrassegnato come perso + + + Purge + Elimina definitivamente + + + OSD + OSD + + + purged + eliminato definitivamente + + + destroy + elimina definitivamente + + + destroyed + eliminato definitivamente + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + Gruppi di posizionamento + + + Read bytes + Byte letti + + + Writes bytes + Byte scritti + + + Read ops + Operazioni di lettura + + + Write ops + Operazioni di scrittura + + + Mark OSD + + + Contrassegna OSD + + + + + Mark + + + Contrassegna + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Numero max di recuperi informazioni + + + Recovery Max Active + Numero max di recuperi attivi + + + Recovery Max Single Start + Avvio singolo numero max di recuperi + + + Recovery Sleep + Sospensione recupero + + + Custom + Personalizzato + + + Updated OSD recovery speed priority " + " + + Aggiornata la priorità della velocità di recupero dell'OSD &quot; + &quot; + + + + + was initialized in the following OSD: + + + + è stato inizializzato dall'OSD seguente: + + + + + Create silence + Create silence + + + Job + Lavoro + + + Severity + Gravità + + + Started + Avviato + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Aggiornato + + + Ends + Ends + + + Silence + Silence + + + Used + Utilizzato + + + Avail. + Dispon. + + + Clean + Pulisci + + + Working + In funzione + + + Warning + Avviso + + + Unknown + Sconosciuto + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + su + + + no filesystems + nessun file system + + + active + attivo + + + standby + standby + + + n/a + n/d + + + active daemon + daemon attivo + + + quorum + quorum + + + The NFS Ganesha service is not configured. + Il servizio NFS Ganesha non è configurato. + + + Transport + Trasporto + + + CephFS User + Utente CephFS + + + CephFS Filesystem + File system CephFS + + + (inherited from global config) + (ereditato dalla configurazione globale) + + + inherited from global config + importato dalla configurazione globale + + + -- Select what kind of user id squashing is performed -- + -- Selezionare il tipo di squash dell'ID utente che viene eseguito -- + + + There are no daemons available. + Non vi sono daemon disponibili. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Modalità cache + + + Min Evict Age + Numero minimo di giorni per la rimozione + + + Min Flush Age + Numero minimo di giorni per la cancellazione + + + Target Max Bytes + Numero max di byte di destinazione + + + Target Max Objects + Numero max di oggetti di destinazione + + + No applications added + Non sono state aggiunte applicazioni. + + + Applications limit reached + Raggiunto il limite di applicazioni + + + A pool can only have up to four applications definitions. + Un pool può contenere solo fino a quattro definizioni delle applicazioni. + + + Allowed characters '_a-zA-Z0-9' + Caratteri consentiti '_a-zA-Z0-9' + + + Maximum length is 128 characters + La lunghezza massima è di 128 caratteri + + + Filter or add applications + Filtra o aggiungi applicazioni + + + Add application + Aggiungi applicazione + + + pool + pool + + + erasure code profile + profilo del codice di cancellazione + + + Replica Size + Dimensioni della replica + + + Last Change + Ultima modifica + + + Erasure Coded Profile + Profilo con codice di cancellazione + + + Crush Ruleset + Set di regole Crush + + + Write bytes + Byte scritti + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + compartimento + + + Updated Object Gateway bucket " + " + + Aggiornato compartimento Object Gateway &quot; + &quot; + + + + Created Object Gateway bucket " + " + + Creato compartimento Object Gateway &quot; + &quot; + + + + buckets + compartimenti + + + capability + capability + + + user + utente + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Aggiornato utente Object Gateway &quot; + &quot; + + + + Created Object Gateway user " + " + + Creato utente Object Gateway &quot; + &quot; + + + + users + utenti + + + Swift Key + Swift Key + + + Scope + Ambito + + + Read + Lettura + + + Create + Crea + + + role + role + + + Created role ' + ' + + Creato ruolo ' + ' + + + + Updated role ' + ' + + Aggiornato ruolo ' + ' + + + + System Role + Ruolo di sistema + + + Deleted role ' + ' + + Eliminato ruolo ' + ' + + + + Created user " + " + + Creato utente &quot; + &quot; + + + + Update user + Aggiorna utente + + + Continue + Continua + + + You were automatically logged out because your roles have been changed. + Si è stati automaticamente disconnessi perché i ruoli sono stati modificati. + + + Updated user " + " + + Aggiornato utente &quot; + &quot; + + + + Deleted user " + " + + Eliminato utente &quot; + &quot; + + + + Failed to delete user " + " + + Impossibile eliminare l'utente &quot; + &quot; + + + + You are currently logged in as " + ". + + Si è attualmente connessi come &quot; + &quot;. + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Ogni oggetto è suddiviso in porzioni di dati, ciascuna delle quali è memorizzata su un diverso OSD. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Calcola le porzioni di codice relative a ciascun oggetto e le memorizza su diversi OSD. + Il numero di porzioni di codice è anche il numero degli OSD che è possibile disattivare senza perdere i dati. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Il plugin jerasure è il plugin più generico e flessibile, + ed è anche il plugin di default dei pool con codice di cancellazione di Ceph. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + La tecnica più flessibile è reed_sol_van: è sufficiente impostare k + ed m. La tecnica cauchy_good può essere più rapida ma occorre selezionare attentamente la dimensione del + pacchetto. reed_sol_r6_op, liberation, blaum_roth, liber8tion sono tutti equivalenti a RAID6, + nel senso che è possibile configurarli solo con m=2. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + La codifica viene eseguita su pacchetti di dimensioni in byte, uno alla volta. + È difficile scegliere la dimensione del pacchetto corretta. + La documentazione su jerasure fornisce informazioni esaustive su questo argomento. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + Con il plugin di jerasure, quando un oggetto con codice di cancellazione viene memorizzato su + più OSD, il recupero della perdita di un OSD richiede la lettura di tutti gli altri. + Ad esempio, se jerasure è configurato con k=8 e m=4, la perdita di un OSD richiede la lettura + degli altri undici per il ripristino. + + Il plugin del codice di cancellazione lrc crea porzioni di parità locali che è possibile recuperare utilizzando un + minor numero di OSD. Ad esempio, se lrc è configurato con k=8, m=4 e l=4, crea + una porzione di parità aggiuntiva ogni quattro OSD. Quando si perde un singolo OSD, è possibile + recuperarlo solo con quattro OSD invece che con undici. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Raggruppa le porzioni di codice e dati in set di località dimensione. Ad esempio, + per k=4 e m=2, se località=3 vengono creati due gruppi su tre. È possibile recuperare ciascun set + senza leggere le porzioni di un altro set. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + Il tipo di compartimento Crush in cui viene memorizzato ciascun set di porzioni definito + dall'utente. Ad esempio, se è impostato su rack, ciascun gruppo di porzioni viene + posizionato in un diverso rack. Viene utilizzato per creare un passaggio della regola CRUSH come il passaggio choose + rack. Se non è impostato, il raggruppamento non viene eseguito. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + Il plugin ISA incapsula la libreria ISA. Viene eseguito solo su processori Intel. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + Il plugin ISA è disponibile in due formati Reed Solomon. + Se è impostato reed_sol_van, il formato è Vandermonde, se è impostato cauchy, il formato è Cauchy. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + Il plugin shec incapsula la libreria SHEC multipla. + Consente a Ceph di recuperare i dati in modo più efficiente rispetto ai codici Reed Solomon. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + Il numero di compartimenti di parità, ciascuno dei quali include i singoli compartimenti di dati + nell'intervallo di calcolo. Il numero viene utilizzato come strumento di stima della durabilità. Ad esempio, se c=2, + è possibile disattivare 2 OSD senza perdere i dati. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + Il nome del compartimento Crush utilizzato per il primo passaggio della regola CRUSH. + Ad esempio il passaggio take default. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Assicurarsi che non esistano due porzioni in un compartimento con lo stesso dominio + di errore. Ad esempio, se il dominio di errore è l'host, non verranno memorizzate due porzioni sullo stesso + host. Viene utilizzato per creare un passaggio della regola CRUSH come passaggio chooseleaf host. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Limitare il posizionamento ai dispositivi di una classe specifica + (ad es. ssd o hdd) usando i nomi delle classi di dispositivi Crush nella mappa CRUSH. + + + Set the directory name from which the erasure code plugin is loaded. + Impostare il nome della directory da cui viene caricato il plugin del codice di cancellazione. + + + Allows all operations + Consente tutte le operazioni + + + Allows only operations that do not modify the server + Consente solo le operazioni che non modificano il server + + + Does not allow read or write operations, but allows any other operation + Non consente operazioni di lettura o scrittura, ma consente qualsiasi altra operazione + + + Does not allow read, write, or any operation that modifies file attributes or directory content + Non consente operazioni di lettura o scrittura o qualsiasi operazione che modifichi gli attributi dei file o il contenuto della directory + + + Allows no access at all + Non consente alcun accesso + + + -- Select the priority -- + -- Selezionare la priorità -- + + + Low + Bassa + + + High + Alta + + + Last 5 minutes + Ultimi 5 minuti + + + Last 15 minutes + Ultimi 15 minuti + + + Last 30 minutes + Ultimi 30 minuti + + + Last 1 hour (Default) + Ultima ora (Default) + + + Last 3 hours + Ultime 3 ore + + + Last 6 hours + Ultime 6 ore + + + Last 12 hours + Ultime 12 ore + + + Last 24 hours + Ultime 24 ore + + + Yesterday + Ieri + + + Today + Oggi + + + Today so far + Fino a oggi + + + Day before yesterday + Giorno prima di ieri + + + Last 2 days + Ultimi 2 giorni + + + This day last week + Questo giorno della scorsa settimana + + + Previous week + Settimana precedente + + + This week + Questa settimana + + + This week so far + Fino a questa settimana + + + Last 7 days + Ultimi 7 giorni + + + Previous month + Mese precedente + + + This month + Questo mese + + + This month so far + Fino a questo mese + + + Last 30 days + Ultimi 30 giorni + + + Last 90 days + Ultimi 90 giorni + + + Last 6 months + Ultimi 6 mesi + + + Last 1 year + Ultimo anno + + + Previous year + Anno precedente + + + This year + Quest'anno + + + This year so far + Fino a quest'anno + + + Last 2 years + Ultimi 2 anni + + + Last 5 years + Ultimi 5 anni + + + Information + Informazioni + + + No items selected. + Nessun elemento selezionato. + + + Deselect item to select again + Deselezionare l'elemento per selezionare di nuovo + + + Selection limit reached + Raggiunto il limite per la selezione + + + Filter tags + Filtra tag + + + Add badge + Aggiungi badge + + + There are no items available. + Non vi sono elementi disponibili. + + + Add + Aggiungi + + + Remove + Remove + + + Clone + Clona + + + Copy + Copia + + + Deep Scrub + Pulitura approfondita + + + Destroy + Eliminazione definitiva + + + Flatten + Appiattisci + + + Mark Down + Declassa + + + Mark In + Attiva + + + Mark Lost + Contrassegna come perso + + + Mark Out + Disattiva + + + Protect + Proteggi + + + Rename + Rinomina + + + Restore + Ripristina + + + Move to Trash + Sposta nel cestino + + + Unprotect + Rimuovi protezione + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Eliminato + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Clonato + + + Copied + Copiato + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + + + + No + No + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Qualità di servizio + + + BPS Limit + Limite di BPS + + + The desired limit of IO bytes per second. + Il limite desiderato di byte I/O al secondo. + + + IOPS Limit + Limite di IOPS + + + The desired limit of IO operations per second. + Il limite desiderato di operazioni I/O al secondo. + + + Read BPS Limit + Limite BPS in lettura + + + The desired limit of read bytes per second. + Il limite desiderato dei byte letti al secondo. + + + Read IOPS Limit + Limite di IOPS in lettura + + + The desired limit of read operations per second. + Il limite desiderato di operazioni di lettura al secondo. + + + Write BPS Limit + Limite di BPS in scrittura + + + The desired limit of write bytes per second. + Il limite desiderato di byte scritti al secondo. + + + Write IOPS Limit + Limite di IOPS in scrittura + + + The desired limit of write operations per second. + Il limite desiderato di operazioni di scrittura al secondo. + + + BPS Burst + Burst BPS + + + The desired burst limit of IO bytes. + Il limite di burst desiderato dei byte di I/O. + + + IOPS Burst + Burst IOPS + + + The desired burst limit of IO operations. + Il limite di burst desiderato delle operazioni di I/O. + + + Read BPS Burst + Burst BPS in lettura + + + The desired burst limit of read bytes. + Il limite di burst desiderato dei byte letti. + + + Read IOPS Burst + Burst IOPS in lettura + + + The desired burst limit of read operations. + Il limite di burst desiderato delle operazioni di lettura. + + + Write BPS Burst + Burst BPS in scrittura + + + The desired burst limit of write bytes. + Il limite di burst desiderato dei byte scritti. + + + Write IOPS Burst + Burst di IOPS in scrittura + + + The desired burst limit of write operations. + Il limite di burst desiderato delle operazioni di scrittura. + + + Failed to + + + + Non è stato possibile + + + + + + Executing + In esecuzione + + + execute + esegui + + + Executed + Eseguito + + + unknown task + task sconosciuto + + + Creating + Creazione in corso + + + create + crea + + + Updating + Aggiornamento in corso + + + update + aggiorna + + + Deleting + Eliminazione in corso + + + delete + elimina + + + RBD ' + ' + + RBD ' + ' + + + + RBD snapshot ' + ' + + Snapshot RBD ' + ' + + + + mirror mode for pool ' + ' + + modalità speculare per il pool ' + ' + + + + mirror peer for pool ' + ' + + peer della copia speculare per il pool ' + ' + + + + all dashboards + all dashboards + + + Name is already used by + . + + Il nome è già utilizzato da + . + + + + Name is already used by + . + + Il nome è già utilizzato da + . + + + + Name is already used by + . + + Il nome è già utilizzato da + . + + + + + contains snapshots. + + + contiene snapshot. + + + + Cloning + Clonazione in corso + + + clone + clona + + + Snapshot of + must be protected. + + La snapshot di + deve essere protetta. + + + + Copying + Copia in corso + + + copy + copia + + + Flattening + Appiattimento + + + flatten + appiattisci + + + Flattened + Appiattito + + + Name is already used by + . + + Il nome è già utilizzato da + . + + + + Cannot unprotect + because it contains child images. + + Impossibile rimuovere la protezione da + perché contiene immagini figlio. + + + + Cannot delete + because it's protected. + + Impossibile eliminare + perché è protetto. + + + + Rolling back + Rollback in corso + + + rollback + rollback + + + Rolled back + Rollback eseguito + + + Moving + Spostamento in corso + + + move + sposta + + + Moved + Spostato + + + image ' + ' to trash + + immagine ' + ' nel cestino + + + + Could not find image. + Impossibile trovare l'immagine. + + + Restoring + Ripristino in corso + + + restore + ripristina + + + Restored + Ripristinato + + + image ' + ' into ' + ' + + immagine ' + ' in ' + ' + + + + Image name ' + ' is already in use. + + Il nome dell'immagine ' + ' è già in uso. + + + + image ' + ' + + immagine ' + ' + + + + Purging + Eliminazione in corso + + + purge + elimina definitivamente + + + Purged + Eliminato definitivamente + + + all pools + tutti i pool + + + images from + + + Immagini da + + + + + Cannot disable mirroring because it contains a peer. + Impossibile disabilitare l'esecuzione della copia speculare perché contiene un peer. + + + pool ' + ' + + pool ' + ' + + + + erasure code profile ' + ' + + profilo del codice di cancellazione ' + ' + + + + target ' + ' + + destinazione ' + ' + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf new file mode 100644 index 00000000..dc39c6cd --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ja-JP.xlf @@ -0,0 +1,4368 @@ + + + + + Toggle navigation + ナビゲーションの切り替え + + + Dashboard + ダッシュボード + + + Cluster + クラスタ + + + Hosts + ホスト + + + Monitors + モニター + + + OSDs + OSD + + + Configuration + 設定 + + + CRUSH map + CRUSHマップ + + + Manager modules + マネージャモジュール + + + Logs + ログ + + + Alerts + アラート + + + Silences + Silences + + + Pools + プール + + + Block + ブロック + + + Images + イメージ + + + Mirroring + ミラーリング + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + ファイルシステム + + + Object Gateway + オブジェクトゲートウェイ + + + Daemons + デーモン + + + Users + ユーザ + + + Buckets + バケット + + + Retrieving data + for + + + . Please wait... + + Retrieving data + for + + + . Please wait... + + + + Displaying previously cached data + + for + + + . + + Displaying previously cached data + + for + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Could not load data + for + + + . + Please check the cluster health. + + + + Back + 戻る + + + Select a Language + 言語の選択 + + + Loading panel data... + パネルデータを読み込んでいます... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + 監視機能を設定および有効化 +する方法に関する + ドキュメント + を +参照してください。 + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Grafanaダッシュボードが存在していません。 +Grafanaにダッシュボードを追加する方法に関する + ドキュメント + を参照してください。 + + + + Grafana Time Picker + Grafana Time Picker + + + Reset Settings + 設定のリセット + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + データを読み込めませんでした。 + + + selected + 選択済み + X selected + + + found + 検出済み + X found + + + total + 合計 + X total + + + Edit + 編集 + + + Name + 名前 + + + Description + 説明 + + + Long description + 長い説明 + + + Default + デフォルト + + + Daemon default + デーモンのデフォルト + + + Services + サービス + + + Values + + + + The entered value is too high! It must not be greater than + . + + 入力された値は大きすぎます。 + より大きい値を入力することはできません。 + + + + The entered value is too low! It must not be lower than + . + + 入力された値は小さすぎます。 + より小さい値を入力することはできません。 + + + + Save + 保存 + + + CRUSH map viewer + CRUSHマップビューア + + + Hosts List + ホストリスト + + + Overall Performance + 全体的なパフォーマンス + + + No entries found + エントリが見つかりません + + + Cluster Logs + クラスタログ + + + Audit Logs + 監査ログ + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + 設定を読み込んでいます... + + + The configuration could not be loaded. + 設定を読み込めませんでした。 + + + Edit Manager module + マネージャモジュールの編集 + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + 入力された値は有効なUUIDではありません(有効なUUIDの例: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8)。 + + + The entered value needs to be a valid IP address. + 有効なIPアドレスを入力する必要があります。 + + + This field is required. + このフィールドは必須です。 + + + The entered value is too high! It must be lower or equal to + . + + 入力された値は大きすぎます。 + 以下の値を入力する必要があります。 + + + + The entered value is too low! It must be greater or equal to + . + + 入力された値は小さすぎます。 + 以上の値を入力する必要があります。 + + + + The entered value needs to be a number. + 数字を入力する必要があります。 + + + The entered value needs to be a number or decimal. + 数字または小数を入力する必要があります。 + + + Update + 更新 + + + Status + ステータス + + + Cluster ID + クラスタID + + + monmap modified + monmapが変更されました + + + monmap epoch + monmapエポック + + + quorum con + 定数con + + + quorum mon + 定数mon + + + required con + 必須のcon + + + required mon + 必須のmon + + + In Quorum + 定数内 + + + Not In Quorum + 非定数内 + + + Cancel + キャンセル + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + 選択された + を + してもよろしいですか? + + + + Yes, I am sure. + はい。 + + + Cluster-wide OSD Flags + クラスタ全体のOSDフラグ + + + Submit + 送信 + + + + + + + + + + + form title + + + Advanced... + 詳細... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + OSD回復優先度 + + + Priority + 優先度 + + + Customize priority values + 優先度値のカスタマイズ + + + This field is required! + このフィールドは必須です。 + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + 入力された値は大きすぎます。 + より大きい値を入力することはできません。 + + + + The entered value is too low! It must not be lower than + . + + 入力された値は小さすぎます。 + より小さい値を入力することはできません。 + + + + Reweight OSD + 再重みづけOSD + + + The value needs to be between 0 and 1. + 値は0と1の間である必要があります。 + + + Reweight + 再重みづけ + + + OSDs + Scrub + + OSD + スクラブ + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {Deep } } + + + You are about to apply a + scrub to + the OSD + + + . + + + スクラブをOSD + + + に +適用しようとしています。 + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {deep } } + + + OSDs List + OSDリスト + + + + OSD + + will be marked + + + if you proceed. + + 続行した場合は、 + OSD + + は + + + とマークされます。 + + + + The OSD is not safe to destroy! + このOSDを安全に破棄することはできません。 + + + + OSD + + will be + + + if you proceed. + + 続行した場合は、 + OSD + + は + + + されます。 + + + + Details + 詳細 + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + 閉じる + + + Delete + 削除 + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + ヘルス + + + Statistics + 統計情報 + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + NFS Ganeshaの管理機能を設定および有効化 +する方法に関する + ドキュメント + を参照してください。 + + + + Clients + クライアント + + + Any client can access + 任意のクライアントからアクセスできます + + + Addresses + アドレス + + + Required field + 必須フィールド + + + Must contain one or more comma-separated values + 1つ以上のカンマ区切り値を含んでいる必要があります + + + For example: + 例: + + + Access Type + アクセスタイプ + + + Squash + スカッシュ + + + Add clients + クライアントの追加 + + + Loading... + 読み込んでいます... + + + -- No cluster available -- + -- 使用可能なクラスタがありません -- + + + -- Select the cluster -- + -- クラスタを選択してください -- + + + Add daemon + デーモンの追加 + + + Storage Backend + ストレージバックエンド + + + -- No data pools available -- + -- 使用可能なデータプールがありません -- + + + -- Select the storage backend -- + -- ストレージバックエンドを選択してください -- + + + Object Gateway User + オブジェクトゲートウェイユーザ + + + -- No users available -- + -- 使用可能なユーザがありません -- + + + -- Select the object gateway user -- + -- オブジェクトゲートウェイユーザを選択してください -- + + + CephFS User ID + CephFSユーザID + + + -- No clients available -- + -- 使用可能なクライアントがありません -- + + + -- Select the cephx client -- + -- cephxクライアントを選択してください -- + + + CephFS Name + CephFS名 + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + セキュリティラベル + + + Enable security label + セキュリティラベルの有効化 + + + CephFS Path + CephFSパス + + + Path need to start with a '/' and can be followed by a word + パスは「/」で始まる必要があり、その後ろに1つの単語を配置できます + + + New directory will be created + 新しいディレクトリが作成されます + + + Path + パス + + + Path can only be a single '/' or a word + パスは単一の「/」または1つの単語である必要があります + + + New bucket will be created + 新しいバケットが作成されます + + + NFS Protocol + NFSプロトコル + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + NFSタグ + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + + NFS v3 + マウントの代替アクセス(先頭に「/」があってはいけません)。 + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + クライアントはサブディレクトリをマウントできません(たとえば、[タグ] = fooの場合は、クライアントはfoo/bazをマウントできません)。 + + + By using different Tag options, the same Path may be exported multiple times. + 異なる[タグ]オプションを使用することで、同じパスを複数回エクスポートできます。 + + + Pseudo + 疑似 + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + この + NFS v4 + エクスポートが + 疑似FS + 内で +占有する位置(この位置は一意である必要があります)。 + + + + By using different Pseudo options, the same Path may be exported multiple times. + 異なる[疑似]オプションを使用することで、同じパスを複数回エクスポートできます。 + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- 使用可能なアクセスタイプがありません -- + + + -- Select the access type -- + -- アクセスタイプを選択してください -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- 使用可能なスカッシュがありません -- + + + --Select what kind of user id squashing is performed -- + -- 実行されるユーザIDスカッシュ操作の種類を選択してください -- + + + Transport Protocol + トランスポートプロトコル + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Cephにようこそ! + The welcome message on the login page + + + Username is required + ユーザ名は必須です + + + Password is required + パスワードは必須です + + + Login + ログイン + + + Sorry, the user does not exist in Ceph. + このユーザはCephに存在しません。 + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + + [ログイン]ページ + に戻ります。ログインを再試行すると、Identity Providerからログアウトされます。 + + + + Forbidden + 禁止 + + + Sorry, you are not allowed to see what you were looking for. + 検索していた内容を表示することは許可されていません。 + + + Sorry, we could not find what you were looking for + 検索していた内容が見つかりませんでした + + + Remove all + すべて削除 + + + Recent Notifications + 最近の通知 + + + There are no background tasks. + バックグラウンドタスクがありません。 + + + Background Tasks + バックグラウンドタスク + + + Help + ヘルプ + + + Documentation + ドキュメント + + + API + API + + + About + バージョン情報 + + + Dashboard Settings + ダッシュボード設定 + + + User management + ユーザ管理 + + + Logged in user + ログイン済みユーザ + + + Signed in as + + + + + + + + +としてサインイン済み + + + + Sign out + サインアウト + + + Name... + 名前... + + + The chosen name is already in use. + 選択された名前はすでに使用されています。 + + + Description... + 説明... + + + Permissions + 許可 + + + Roles + 役割 + + + Username + ユーザ名 + + + Password + パスワード + + + Confirm password + パスワードの確認入力 + + + Password confirmation doesn't match the password. + 確認入力されたパスワードがパスワードと一致しません。 + + + Full name + 氏名 + + + Email + 電子メール + + + Invalid email. + 無効な電子メールです。 + + + You are about to remove "user read / update" permissions from your own user. + 自身のユーザから「user read / update」という許可を削除しようとしています。 + + + If you continue, you will no longer be able to add or remove roles from any user. + 続行した場合は、どのユーザの役割も追加および削除できなくなります。 + + + Are you sure you want to continue? + 続行してもよろしいですか? + + + Performance counters not available + パフォーマンスカウンタを使用できません + + + Attributes (OSD map) + 属性(OSDマップ) + + + Metadata not available + メタデータを使用できません + + + Metadata + メタデータ + + + Performance counter + パフォーマンスカウンタ + + + Histogram not available: + + + ヒストグラムを使用できません: + + + + + Writes + 書き込み回数 + + + Reads + 読み取り回数 + + + Histogram + ヒストグラム + + + Performance Details + パフォーマンスの詳細 + + + Current values + 現行値 + + + Type + タイプ + + + Min + 最小 + + + Max + 最大 + + + Flags + フラグ + + + Source + ソース + + + Level + レベル + + + Can be updated at runtime (editable) + 実行時に更新できます(編集可能) + + + Tags + タグ + + + Enum values + 列挙値 + + + See also + 関連項目 + + + Cluster Status + クラスタのステータス + + + Manager Daemons + マネージャデーモン + + + Object Gateways + オブジェクトゲートウェイ + + + Metadata Servers + メタデータサーバ + + + iSCSI Gateways + iSCSIゲートウェイ + + + Client IOPS + クライアントのIOPS + + + Client Throughput + クライアントのスループット + + + Client Read/Write + クライアントの読み取り/書き込み + + + Recovery Throughput + 回復スループット + + + Scrub + スクラブ + + + Performance + パフォーマンス + + + Raw Capacity + 未フォーマット時の容量 + + + Objects + オブジェクト数 + + + PGs per OSD + OSDあたりの配置グループ数 + + + PG Status + 配置グループのステータス + + + Capacity + 容量 + + + + + See + Logs + for more details. + + + + 詳細については、「 + ログ + 」を参照してください。 + + + + Ranks + ランク + + + MDS performance counters + MDS performance counters + + + Clients: + + + クライアント数: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + イメージをごみ箱に移動する + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + + + / + + をごみ箱に移動するには、 + [イメージの移動] + をクリックします。希望に応じて、失効日を選択できます。 + + + + Protection expires at + 保護の失効日 + + + NOT PROTECTED + 保護されていません + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + 日付の形式が正しくありません。「YYYY-MM-DD HH:mm:ss」という形式を使用してください。 + + + Protection has already expired. Please pick a future date or leave it empty. + 保護はすでに失効しています。将来の日付を選択するか、日付を空白のままにしてください。 + + + Move Image + イメージの移動 + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + 概要 + + + Targets + ターゲット + + + Discovery Authentication + 検出認証 + + + User + ユーザ + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + ユーザ名は8~64文字の長さである必要があり、 +英字、「.」、「@」、「-」、「_」、または「:」のみで構成される必要があります。 + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + 相互ユーザ + + + Mutual Password + 相互パスワード + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + iSCSIターゲットの管理機能を設定および有効化 +する方法に関する + ドキュメント + を参照してください。 + + + + Available information: + 取得可能な情報: + + + iSCSI Targets not available + 使用可能なiSCSIターゲットがありません + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + + fast-diff + が有効になっているRBDイメージのみに使用できます + + + + Pool + プール + + + Data Pool + データプール + + + Created + 作成済み + + + Size + サイズ + + + Object size + オブジェクトサイズ + + + Features + 機能 + + + Provisioned + プロビジョニング済み + + + N/A + なし + + + Total provisioned + プロビジョニング済み合計 + + + Striping unit + ストライピング単位 + + + Striping count + ストライピング数 + + + Parent + + + + Block name prefix + ブロック名のプレフィックス + + + Order + 順番 + + + Snapshots + スナップショット + + + Image + イメージ + + + This setting overrides the global value + この設定はグローバル値よりも優先されます + + + Global + グローバル + + + This is the global value. No value for this option has been set for this image. + これはグローバル値です。このイメージについて、このオプションの値は設定されていません。 + + + + from + + + from + + + + '/' and '@' are not allowed. + 「/」と「@」は使用できません。 + + + -- No rbd pools available -- + -- 使用可能なrbdプールがありません -- + + + -- Select a pool -- + -- プールを選択してください -- + + + Use a dedicated data pool + 専用のデータプールを使用してください + + + Data pool + データプール + + + Dedicated pool that stores the object-data of the RBD. + RBDのオブジェクトデータを保管するための専用プール + + + e.g., 10GiB + 例: 10GiB + + + You have to increase the size. + サイズを大きくする必要があります。 + + + Advanced + 詳細 + + + Striping + ストライピング + + + Stripe unit + ストライプ単位 + + + -- Select stripe unit -- + -- ストライプ単位を選択してください -- + + + This field is required because stripe count is defined! + ストライプ数が定義されているため、このフィールドは必須です。 + + + Stripe unit is greater than object size. + ストライプ単位がオブジェクトサイズより大きいです。 + + + Stripe count + ストライプ数 + + + This field is required because stripe unit is defined! + ストライプ単位が定義されているため、このフィールドは必須です。 + + + Stripe count must be greater than 0. + ストライプ数は0より大きい必要があります。 + + + + RBD Snapshot + + + RBDスナップショット + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Rename} other {Create} } + + + + Snapshot + + + スナップショット + + + + PROTECTED + 保護済み + + + UNPROTECTED + 未保護 + + + You are about to rollback + ロールバックしようとしています + + + Purge Trash + ごみ箱を空にする + + + To purge, select one or All images and click + 空にするには、1つまたはすべてのイメージを選択してクリックします + + + Pool: + プール: + + + Pool name... + プール名... + + + All + すべて + + + Restore Image + イメージの復元 + + + To restore + 復元するには + + + type the image's new name and click + イメージの新しい名前を入力してクリックします + + + New Name + 新しい名前 + + + Expired at + 失効日 + + + Protected until + 保護の終了日 + + + This image is protected until + . + + このイメージは + まで保護されます。 + + + + Trash + ごみ箱 + + + iSCSI Topology + iSCSIトポロジ + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + 通常はこれらのパラメータをデフォルト値から変更する必要はありません。 + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + 設定 + + + Backstore + バックストア + + + Confirm + 確認 + + + Advanced Settings + 詳細設定 + + + Target IQN + ターゲットIQN + + + IQN has wrong pattern. + IQNのパターンが正しくありません。 + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + IQNは「iqn.$year-$month.$reversedAddress:$definedName」という形式で表記されます。 + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + 例: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + 詳細情報 + + + This target has modified advanced settings. + このターゲットの詳細設定は変更されています。 + + + Portals + ポータル + + + At least + gateways are required. + + 少なくとも + 台のゲートウェイが必要です。 + + + + Add portal + ポータルの追加 + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + このイメージの設定は変更されています。 + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + イメージの追加 + + + ACL authentication + ACL認証 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + イニシエータ + + + Initiator + イニシエータ + + + Client IQN + クライアントIQN + + + Initiator IQN needs to be unique. + イニシエータIQNは一意である必要があります。 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + ユーザ名は8~64文字の長さである必要があり、 +英字、「.」、「@」、「-」、「_」、または「:」のみで構成される必要があります。 + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + イニシエータはいずれかのグループに属します。イメージはそのグループ内で設定されます。 + + + No items added. + アイテムが追加されていません。 + + + Add initiator + イニシエータの追加 + + + Groups + グループ + + + Group + グループ + + + Add group + グループの追加 + + + [object Object] + [object Object] + + + RBD Configuration + RBD設定 + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + ローカル設定値を削除します。親設定値が継承されて代わりに使用されます。 + + + The mininum value is 0 + 最小値は0です + + + Issues + 問題 + + + Syncing + 同期中 + + + Ready + 準備完了 + + + Edit pool mirror mode + プールのミラーモードの編集 + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + プール + + + のミラーモードを編集するには、 +リストから新しいモードを選択して、 + [更新] + をクリックします。 + + + + Mode + モード + + + Peer clusters must be removed prior to disabling mirror. + ミラーを無効にする前に、ピアクラスタを削除する必要があります。 + + + + + pool mirror peer + + + +プールのミラーピア + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Edit} other {Add} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + プール + + + +のプールミラーピア属性、および + [送信] + をクリックします。 + + + + Cluster Name + クラスタ名 + + + The cluster name is not valid. + このクラスタ名は無効です。 + + + CephX ID + CephX ID + + + CephX ID... + CephX ID... + + + The CephX ID is not valid. + このCephX IDは無効です。 + + + Monitor Addresses + モニターアドレス + + + Comma-delimited addresses... + カンマ区切りアドレス... + + + The monitory address is not valid. + この警告アドレスは無効です。 + + + CephX Key + CephXキー + + + Base64-encoded key... + Base64エンコード化済みキー... + + + CephX key must be base64 encoded. + CephXキーはbase64でエンコードされている必要があります。 + + + Pools List + プールリスト + + + The name can only consist of alphanumeric characters, dashes and underscores. + 名前は英数字、ダッシュ、および下線のみで構成される必要があります。 + + + The chosen erasure code profile name is already in use. + 選択されたイレイジャコードプロファイル名はすでに使用されています。 + + + Plugin + プラグイン + + + Data chunks (k) + データチャンク(k) + + + Must be equal to or greater than 2. + 2以上である必要があります。 + + + Coding chunks (m) + コーディングチャンク(m) + + + Must be equal to or greater than 1. + 1以上である必要があります。 + + + Durability estimator (c) + 耐久性推定子(c) + + + Locality (l) + 地域(l) + + + Crush failure domain + Crush障害ドメイン + + + Crush Locality + Crush地域 + + + None + なし + + + Technique + 技法 + + + Packetsize + パケットサイズ + + + Crush root + Crushルート + + + Crush device class + Crushデバイスクラス + + + any + 任意 + + + Directory + ディレクトリ + + + The chosen Ceph pool name is already in use. + 選択されたCephプール名はすでに使用されています。 + + + Pool type + プールタイプ + + + -- Select a pool type -- + -- プールタイプを選択してください -- + + + Placement groups + 配置グループ + + + At least one placement group is needed! + 少なくとも1つの配置グループが必要です。 + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + ご使用のクラスタはこれだけ多数の配置グループを処理できません。必要な配置グループの数を再計算してください。 + + + Calculation help + 計算のヘルプ + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + 現在の配置グループ設定は自動的に計算されたため、 +送信前に、これらの値がニーズに合っていることを確認してください。 + + + Crush ruleset + Crushルールセット + + + -- Select a crush rule -- + -- Crushルールを選択してください -- + + + Crush rule + Crushルール + + + Crush steps + Crushステップ + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + 現在のクラスタ内のOSD数はこのルールで要求される最小OSD数を下回っているため、 +このルールを現在のクラスタで使用することはできません。 + + + Replicated size + 複製されたサイズ + + + Minimum: + + + 最小: + + + + + Maximum: + + + 最大: + + + + + The size specified is out of range. A value from + to + is valid. + + 指定されたサイズは範囲外です。 +有効な値の範囲は + ~ + です。 + + + + Erasure code profile + イレイジャコードプロファイル + + + -- No erasure code profile available -- + -- 使用可能なイレイジャコードプロファイルがありません -- + + + -- Select an erasure code profile -- + -- イレイジャコードプロファイルを選択してください -- + + + EC Overwrites + ECの上書き + + + Applications + アプリケーション + + + Compression + 圧縮 + + + Algorithm + アルゴリズム + + + -- No erasure compression algorithm available -- + -- 使用可能なイレイジャ圧縮アルゴリズムがありません -- + + + Minimum blob size + 最小blobサイズ + + + e.g., 128KiB + 例: 128KiB + + + Value should be greater than 0 + 値は0より大きい必要があります + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + 最大blobサイズ + + + e.g., 512KiB + 例: 512KiB + + + Value should be greater than the minimum blob size + 値は最小blobサイズより大きい必要があります + + + Ratio + + + + Compression ratio + 圧縮率 + + + Value should be between 0.0 and 1.0 + 値は0.0~1.0の間である必要があります + + + It's not possible to create an RBD pool with '/' in the name. + 名前に「/」が含まれたRBDプールを作成することはできません。 + + + Please change the name or remove 'rbd' from the applications list. + 名前を変更するか、アプリケーションリストから「rbd」を削除してください。 + + + Cache Tiers Details + キャッシュ層の詳細 + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + オブジェクトゲートウェイの管理機能を設定および有効化 +する方法に関する + ドキュメント + を参照してください。 + + + + Daemons List + デーモンリスト + + + Performance Counters + パフォーマンスカウンタ + + + Loading bucket data... + バケットデータを読み込んでいます... + + + The bucket data could not be loaded. + バケットデータを読み込めませんでした。 + + + Id + Id + + + The value is not valid. + この値は無効です。 + + + Owner + 所有者 + + + -- Select a user -- + -- ユーザを選択してください -- + + + ID + ID + + + Index type + インデックスタイプ + + + Placement rule + 配置ルール + + + Marker + マーカー + + + Maximum marker + 最大マーカー + + + Version + バージョン + + + Master version + マスタバージョン + + + Modification time + 変更時間 + + + Zonegroup + ゾーングループ + + + Bucket quota + バケットクォータ + + + Enabled + 有効化済み + + + Maximum size + 最大サイズ + + + Unlimited + 無制限 + + + Maximum objects + 最大オブジェクト数 + + + -- Select a username -- + -- ユーザ名を選択してください -- + + + Auto-generate key + キーの自動生成 + + + Access key + アクセスキー + + + Secret key + 秘密キー + + + Email address + 電子メールアドレス + + + Suspended + 中断済み + + + System + システム + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {No} 1 {Yes} } + + + Maximum buckets + 最大バケット数 + + + Subusers + サブユーザ + + + Capabilities + 機能 + + + User quota + ユーザクォータ + + + Show + 表示 + + + Keys + キー + + + -- Select a type -- + -- タイプを選択してください -- + + + Permission + 許可 + + + -- Select a permission -- + -- 許可を選択してください -- + + + Subuser + サブユーザ + + + The chosen subuser ID is already in use. + 選択されたサブユーザIDはすでに使用されています。 + + + read, write + 読み取り、書き込み + + + full + フル + + + Swift key + スウィフトキー + + + Auto-generate secret + 秘密の自動生成 + + + Loading user data... + ユーザデータを読み込んでいます... + + + The user data could not be loaded. + ユーザデータを読み込めませんでした。 + + + The chosen user ID is already in use. + 選択されたユーザIDはすでに使用されています。 + + + This is not a valid email address. + これは有効な電子メールアドレスではありません。 + + + The chosen email address is already in use. + 選択された電子メールアドレスはすでに使用されています。 + + + Max. buckets + 最大バケット数 + + + The entered value must be >= 0. + 0以上の値を入力する必要があります。 + + + S3 key + S3キー + + + There are no subusers. + サブユーザがいません。 + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + キーがありません。 + + + + + + + + + + + + + Swift + スウィフト + + + There are no capabilities. + 機能がありません。 + + + + + + + + + + + + + Unlimited size + 無制限のサイズ + + + Max. size + 最大サイズ + + + Unlimited objects + 無制限のオブジェクト数 + + + Max. objects + 最大オブジェクト数 + + + Current + 現在 + + + Updated discovery authentication + 検出認証を更新しました + + + There are no portals available. + 使用可能なポータルはありません。 + + + There are no images available. + 使用可能なイメージはありません。 + + + There are no images available. Please make sure you add an image to the target. + 使用可能なイメージはありません。ターゲットにイメージを追加したことを確認してください。 + + + There are no initiators available. Please make sure you add an initiator to the target. + 使用可能なイニシエータはありません。ターゲットにイニシエータを追加したことを確認してください。 + + + target + target + + + Target + ターゲット + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + 状態 + + + # Targets + # Targets + + + Read Bytes + 読み取りバイト数 + + + Write Bytes + 書き込みバイト数 + + + Read Ops + 読み取り操作数 + + + Write Ops + 書き込み操作数 + + + A/O Since + 次の日付以降のA/O + + + Instance + インスタンス + + + Hostname + ホスト名 + + + Issue + 問題 + + + Progress + 進捗 + + + Disabled + 無効化済み + + + Edit Mode + モードの編集 + + + Add Peer + ピアの追加 + + + Edit Peer + ピアの編集 + + + Delete Peer + ピアの削除 + + + Leader + リーダー + + + # Local + #ローカル + + + # Remote + #リモート + + + mirror peer + ミラーピア + + + Key + キー + + + RBD + RBD + + + Deep flatten + ディープフラット化 + + + Layering + 階層化 + + + Exclusive lock + 排他ロック + + + Object map (requires exclusive-lock) + オブジェクトマップ(排他ロックが必要) + + + Journaling (requires exclusive-lock) + ジャーナリング(排他ロックが必要) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + RBDスナップショットのロールバック + + + Rollback + ロールバック + + + RBD snapshot + RBDスナップショット + + + Deleted At + 削除日時 + + + id + id + + + type + タイプ + + + state + 状態 + + + version + バージョン + + + Host + ホスト + + + root + ルート + + + Rank + ランク + + + Daemon + デーモン + + + Activity + アクティビティ + + + Dentries + dエントリ + + + Inodes + iノード + + + Usage + 使用量 + + + Standby daemons + スタンバイデーモン + + + The value can be updated at runtime. + この値は実行時に更新できます。 + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + デーモン/クライアントはこの値をモニター設定データベースから取得しません。 +このオプションを「ceph config set ...」を通じて設定することは禁止されています。 +このオプションは、ceph.confまたはコマンドラインを通じて +設定する必要があります。 + + + Option takes effect only during daemon startup. + オプションはデーモン始動時のみに有効になります。 + + + Option only affects cluster creation. + オプションはクラスタの作成のみに適用されます。 + + + Option only affects daemon creation. + オプションはデーモンの作成のみに適用されます。 + + + Updated config option + + + 設定オプション + を更新しました + + + + Service + サービス + + + Current value + 現行値 + + + Editable + 編集可能 + + + Updated options for module " + ". + + モジュール「 + 」のオプションを更新しました。 + + + + Enable + 有効化 + + + Disable + 無効化 + + + Reconnecting, please wait ... + 再接続していますので、しばらくお待ちください... + + + Public Address + パブリックアドレス + + + Open Sessions + セッションの開始 + + + No In + インなし + + + OSDs that were previously marked out will not be marked back in when they start + 以前にアウトとしてマークされたOSDは、それらの始動時にインとしてマークされることはありません + + + No Out + アウトなし + + + OSDs will not automatically be marked out after the configured interval + OSDは、設定済みの間隔が経過した後に自動的にアウトとしてマークされます + + + No Up + アップなし + + + OSDs are not allowed to start + OSDを始動することは許可されていません + + + No Down + ダウンなし + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + OSDの障害レポートは無視されているため、OSDはモニターによってダウンとしてマークされません + + + Pause + 一時停止 + + + Pauses reads and writes + 読み取りと書き込みを一時停止します + + + No Scrub + スクラブなし + + + Scrubbing is disabled + スクラブ処理は無効化されています + + + No Deep Scrub + ディープスクラブなし + + + Deep Scrubbing is disabled + ディープスクラブ処理は無効化されています + + + No Backfill + バックフィルなし + + + Backfilling of PGs is suspended + 配置グループのバックフィルは中断されています + + + No Recover + 回復なし + + + Recovery of PGs is suspended + 配置グループの回復は中断されています + + + Bitwise Sort + ビット単位のソート + + + Use bitwise sort + ビット単位のソートを使用する + + + Purged Snapdirs + 消去されたスナップディレクトリ + + + OSDs have converted snapsets + OSDによってスナップセットが変換されました + + + Recovery Deletes + 回復の削除 + + + Deletes performed during recovery instead of peering + ピアリングの代わりに回復時に削除が実行されました + + + PG Log Hard Limit + 配置グループログのハード制限 + + + Puts a hard limit on pg log length + 配置グループログ長のハード制限を適用します + + + Updated OSD Flags + OSDフラグを更新しました + + + out + アウト + + + in + イン + + + down + ダウン + + + Mark + マーク + + + OSD lost + 喪失したOSD + + + marked lost + 喪失としてマーク済み + + + Purge + 消去 + + + OSD + OSD + + + purged + 消去済み + + + destroy + 破棄 + + + destroyed + 破棄済み + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + 配置グループ数 + + + Read bytes + 読み取りバイト数 + + + Writes bytes + 書き込みバイト数 + + + Read ops + 読み取り操作数 + + + Write ops + 書き込み操作数 + + + Mark OSD + + + OSD + をマーク + + + + Mark + + + + をマーク + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + 最大バックフィル数 + + + Recovery Max Active + 回復最大アクティブ + + + Recovery Max Single Start + 回復最大単一始動 + + + Recovery Sleep + 回復スリープ + + + Custom + カスタム + + + Updated OSD recovery speed priority " + " + + OSDの回復速度優先度「 + 」を更新しました + + + + + was initialized in the following OSD: + + + + は次のOSDで初期化されました: + + + + + Create silence + Create silence + + + Job + ジョブ + + + Severity + 重大度 + + + Started + 始動済み + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + 更新済み + + + Ends + Ends + + + Silence + Silence + + + Used + 使用済み + + + Avail. + 使用可能 + + + Clean + クリーン + + + Working + 動作中 + + + Warning + 警告 + + + Unknown + 不明 + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + アップ + + + no filesystems + ファイルシステムがありません + + + active + アクティブ + + + standby + スタンバイ + + + n/a + なし + + + active daemon + アクティブデーモン + + + quorum + 定数 + + + The NFS Ganesha service is not configured. + NFS Ganeshaサービスが設定されていません。 + + + Transport + トランスポート + + + CephFS User + CephFSユーザ + + + CephFS Filesystem + CephFSファイルシステム + + + (inherited from global config) + (グローバル設定から継承) + + + inherited from global config + グローバル設定から継承されました + + + -- Select what kind of user id squashing is performed -- + -- 実行されるユーザIDスカッシュ操作を選択してください -- + + + There are no daemons available. + 使用可能なデーモンがありません。 + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + キャッシュモード + + + Min Evict Age + 退去までの最小経過時間 + + + Min Flush Age + 消去までの最小経過時間 + + + Target Max Bytes + ターゲットの最大バイト数 + + + Target Max Objects + ターゲットの最大オブジェクト数 + + + No applications added + アプリケーションは追加されていません + + + Applications limit reached + アプリケーション数の上限に達しました + + + A pool can only have up to four applications definitions. + 1つのプールは最大で4つのアプリケーション定義しか保有できません。 + + + Allowed characters '_a-zA-Z0-9' + 使用可能な文字「_a-zA-Z0-9」 + + + Maximum length is 128 characters + 最大長は128文字です + + + Filter or add applications + アプリケーションのフィルタリングまたは追加 + + + Add application + アプリケーションの追加 + + + pool + pool + + + erasure code profile + イレイジャコードプロファイル + + + Replica Size + レプリカサイズ + + + Last Change + 最後の変更 + + + Erasure Coded Profile + イレイジャコード化済みプロファイル + + + Crush Ruleset + Crushルールセット + + + Write bytes + 書き込みバイト数 + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + バケット + + + Updated Object Gateway bucket " + " + + オブジェクトゲートウェイバケット「 + 」を更新しました + + + + Created Object Gateway bucket " + " + + オブジェクトゲートウェイバケット「 + 」を作成しました + + + + buckets + バケット数 + + + capability + capability + + + user + ユーザ + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + オブジェクトゲートウェイユーザ「 + 」を更新しました + + + + Created Object Gateway user " + " + + オブジェクトゲートウェイユーザ「 + 」を作成しました + + + + users + ユーザ数 + + + Swift Key + Swift Key + + + Scope + 範囲 + + + Read + 読み取り + + + Create + 作成 + + + role + role + + + Created role ' + ' + + 役割「 + 」を作成しました + + + + Updated role ' + ' + + 役割「 + 」を更新しました + + + + System Role + システム役割 + + + Deleted role ' + ' + + 役割「 + 」を削除しました + + + + Created user " + " + + ユーザ「 + 」を作成しました + + + + Update user + ユーザの更新 + + + Continue + 続行 + + + You were automatically logged out because your roles have been changed. + このユーザの役割が変更されたため、このユーザは自動的にログアウトされました。 + + + Updated user " + " + + ユーザ「 + 」を更新しました + + + + Deleted user " + " + + ユーザ「 + 」を削除しました + + + + Failed to delete user " + " + + ユーザ「 + 」を削除できませんでした + + + + You are currently logged in as " + ". + + 現在このユーザは「 + 」としてログインしています。 + + + + Each object is split in data-chunks parts, each stored on a different OSD. + 各オブジェクトは複数のデータチャンクパートに分割されており、それぞれのパートは異なるOSDに保管されています。 + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + 各オブジェクトのコーディングチャンクを計算して、これらのチャンクを別々のOSDに保管します。 +コーディングチャンクの数は、データを失うことなくダウン状態になることができるOSDの数でもあります。 + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + jerasureプラグインは最も汎用的で柔軟性の高いプラグインです。 +このプラグインは、Cephイレイジャコード化済みプール用のデフォルトでもあります。 + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + さらに柔軟性の高い技法はreed_sol_vanです。kとmを +設定するだけで十分です。 +cauchy_good技法はより高速となり得ますが、パケットサイズを慎重に選択する必要があります。 +reed_sol_r6_op、liberation、blaum_roth、liber8tionはすべて、 +m=2を使用した設定のみが可能という意味でRAID6と同等です。 + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + エンコードはバイトサイズのパケット群に対して同時に実行されます。 +適切なパケットサイズを選択することは困難です。 +jerasureのドキュメントにはこのトピックに関する詳細な情報が記載されています。 + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + jerasureプラグインを使用すると、イレイジャコード化済みオブジェクトが複数のOSDに保管されている場合は、 +1つのOSDの喪失から回復するには、他のすべてのOSDからの読み取りが必要になります。 +たとえば、k=8およびm=4を使用してjerasureが設定されている場合は、1つのOSDが失われた場合、 +修復のためには他の11個のOSDからの読み取りが必要になります。 + +lrcイレイジャコードプラグインは、これより少ないOSDを使用した回復を可能にするために、 +ローカルパリティチャンクを作成します。たとえば、lrcがk=8、m=4、およびl=4を使用して設定されている場合は、 +lrcは、4つのOSDごとに1つの追加パリティチャンクを作成します。1つのOSDが失われた場合は、 +11個の代わりに4つのOSDのみを使用してそのOSDを回復できます。 + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + コーディングチャンクとデータチャンクをサイズ地域の複数セットにグループ分けします。 +たとえば、k=4およびm=2の場合に、[地域]=3の場合は、3つのチャンクからなるグループが2つ作成されます。 +各セットは、別のセットからチャンクを読み取ることなく回復できます。 + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + 1によって定義されたチャンクの各セットが保管されるCrushバケットのタイプ。 +たとえば、このバケットタイプがラックに設定されている場合は、1のチャンクの各グループは異なるラックに配置されます。 +このバケットタイプを使用して、「ラックの選択」ステップなどのCRUSHルールステップが作成されます。 +このバケットタイプが設定されていない場合は、このようなグループ分けは行われません。 + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + isaプラグインはISAライブラリをカプセル化します。このプラグインはIntelプロセッサ上のみで動作します。 + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + ISAプラグインは2つのリードソロモン形式で提供されています。reed_sol_vanが設定されている場合は、Vandermondeであり、cauchyが設定されている場合は、Cauchyです。 + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + shecプラグインは複数のSHECライブラリをカプセル化します。 +このプラグインを使用すると、cephはリードソロモンコードより効率的にデータを回復できます。 + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + それぞれが各データチャンクを各自の計算範囲内に含んでいるパリティチャンクの数。 +この数は、耐久性推定子として使用されます。 +たとえば、c=2の場合は、データを失うことなく2つのOSDがダウン状態になることができます。 + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + CRUSHルールの最初のステップ(「デフォルトの使用」ステップなど)用に +使用されるCrushバケットの名前。 + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + 同じ障害ドメインの単一バケット内に2つのチャンクが配置されることを防止します。 +たとえば、障害ドメインがホストである場合は、2つのチャンクが同じホストに保管されることはありません。 +これを使用して、「リーフホストの選択」ステップなどのCRUSHルールステップが作成されます。 + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + CRUSHマップ内でCrushデバイスクラス名を使用して、配置先を特定クラス(ssdやhddなど)のデバイスのみに制限します。 + + + Set the directory name from which the erasure code plugin is loaded. + イレイジャコードプラグインの読み込み元となるディレクトリ名を設定します。 + + + Allows all operations + すべての操作を許可します + + + Allows only operations that do not modify the server + サーバに変更を加えない操作のみを許可します + + + Does not allow read or write operations, but allows any other operation + 読み取り/書き込み操作を許可しませんが、他のすべての操作を許可します + + + Does not allow read, write, or any operation that modifies file attributes or directory content + 読み取り/書き込み操作、およびファイル属性やディレクトリ内容を変更するどの操作も許可しません + + + Allows no access at all + アクセスを一切許可しません + + + -- Select the priority -- + -- 優先度を選択してください -- + + + Low + + + + High + + + + Last 5 minutes + 直前の5分間 + + + Last 15 minutes + 直前の15分間 + + + Last 30 minutes + 直前の30分間 + + + Last 1 hour (Default) + 直前の1時間(デフォルト) + + + Last 3 hours + 直前の3時間 + + + Last 6 hours + 直前の6時間 + + + Last 12 hours + 直前の12時間 + + + Last 24 hours + 直前の24時間 + + + Yesterday + 昨日 + + + Today + 本日 + + + Today so far + 本日の現時点まで + + + Day before yesterday + 一昨日 + + + Last 2 days + 過去2日間 + + + This day last week + 先週の同じ曜日 + + + Previous week + 前週 + + + This week + 今週 + + + This week so far + 今週の現時点まで + + + Last 7 days + 過去7日間 + + + Previous month + 前月 + + + This month + 今月 + + + This month so far + 今月の現時点まで + + + Last 30 days + 過去30日間 + + + Last 90 days + 過去90日間 + + + Last 6 months + 過去6カ月 + + + Last 1 year + 過去1年間 + + + Previous year + 前年 + + + This year + 今年 + + + This year so far + 今年の現時点まで + + + Last 2 years + 過去2年間 + + + Last 5 years + 過去5年間 + + + Information + 情報 + + + No items selected. + アイテムが選択されていません。 + + + Deselect item to select again + アイテムを選択解除して再選択してください + + + Selection limit reached + 選択の上限に達しました + + + Filter tags + タグのフィルタリング + + + Add badge + バッジの追加 + + + There are no items available. + 使用可能なアイテムはありません。 + + + Add + 追加 + + + Remove + Remove + + + Clone + 複製 + + + Copy + コピー + + + Deep Scrub + ディープスクラブ + + + Destroy + 破棄 + + + Flatten + フラット化 + + + Mark Down + ダウンとしてマーク + + + Mark In + インとしてマーク + + + Mark Lost + 喪失としてマーク + + + Mark Out + アウトとしてマーク + + + Protect + 保護 + + + Rename + 名前の変更 + + + Restore + 復元 + + + Move to Trash + ごみ箱に移動する + + + Unprotect + 保護解除 + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + 削除済み + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + 複製済み + + + Copied + コピー済み + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + はい + + + No + いいえ + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + サービス品質 + + + BPS Limit + BPS制限 + + + The desired limit of IO bytes per second. + 希望する秒あたり入出力バイト数の上限。 + + + IOPS Limit + IOPS制限 + + + The desired limit of IO operations per second. + 希望する秒あたり入出力操作数の上限。 + + + Read BPS Limit + 読み取りBPS制限 + + + The desired limit of read bytes per second. + 希望する秒あたり読み取りバイト数の上限。 + + + Read IOPS Limit + 読み取りIOPS制限 + + + The desired limit of read operations per second. + 希望する秒あたり読み取り操作数の上限。 + + + Write BPS Limit + 書き込みBPS制限 + + + The desired limit of write bytes per second. + 希望する秒あたり書き込みバイト数の上限。 + + + Write IOPS Limit + 書き込みIOPS制限 + + + The desired limit of write operations per second. + 希望する秒あたり書き込み操作数の上限。 + + + BPS Burst + BPSバースト + + + The desired burst limit of IO bytes. + 希望する入出力バイト数のバースト上限。 + + + IOPS Burst + IOPSバースト + + + The desired burst limit of IO operations. + 希望する入出力操作数のバースト上限。 + + + Read BPS Burst + 読み取りBPSバースト + + + The desired burst limit of read bytes. + 希望する読み取りバイト数のバースト上限。 + + + Read IOPS Burst + 読み取りIOPSバースト + + + The desired burst limit of read operations. + 希望する読み取り操作数のバースト上限。 + + + Write BPS Burst + 書き込みBPSバースト + + + The desired burst limit of write bytes. + 希望する書き込みバイト数のバースト上限。 + + + Write IOPS Burst + 書き込みIOPSバースト + + + The desired burst limit of write operations. + 希望する書き込み操作数のバースト上限。 + + + Failed to + + + + + + を実行できませんでした + + + + Executing + 実行中 + + + execute + 実行 + + + Executed + 実行済み + + + unknown task + 不明なタスク + + + Creating + 作成中 + + + create + 作成 + + + Updating + 更新中 + + + update + 更新 + + + Deleting + 削除中 + + + delete + 削除 + + + RBD ' + ' + + RBD「 + 」 + + + + RBD snapshot ' + ' + + RBDスナップショット「 + 」 + + + + mirror mode for pool ' + ' + + プール「 + 」のミラーモード + + + + mirror peer for pool ' + ' + + プール「 + 」のミラーピア + + + + all dashboards + all dashboards + + + Name is already used by + . + + この名前は + によってすでに使用されています。 + + + + Name is already used by + . + + この名前は + によってすでに使用されています。 + + + + Name is already used by + . + + この名前は + によってすでに使用されています。 + + + + + contains snapshots. + + + にはスナップショットが含まれています。 + + + + Cloning + 複製中 + + + clone + 複製 + + + Snapshot of + must be protected. + + + のスナップショットは保護される必要があります。 + + + + Copying + コピー中 + + + copy + コピー + + + Flattening + フラット化中 + + + flatten + フラット化 + + + Flattened + フラット化済み + + + Name is already used by + . + + この名前は + によってすでに使用されています。 + + + + Cannot unprotect + because it contains child images. + + + は子イメージを含んでいるため保護解除できません。 + + + + Cannot delete + because it's protected. + + + は保護されているため削除できません。 + + + + Rolling back + ロールバック中 + + + rollback + ロールバック + + + Rolled back + ロールバック済み + + + Moving + 移動中 + + + move + 移動 + + + Moved + 移動済み + + + image ' + ' to trash + + イメージ「 + 」をごみ箱に + + + + Could not find image. + イメージが見つかりませんでした。 + + + Restoring + 復元中 + + + restore + 復元 + + + Restored + 復元済み + + + image ' + ' into ' + ' + + イメージ「 + 」を「 + 」に + + + + Image name ' + ' is already in use. + + イメージ名「 + 」はすでに使用されています。 + + + + image ' + ' + + イメージ「 + 」 + + + + Purging + 消去中 + + + purge + 消去 + + + Purged + 消去済み + + + all pools + すべてのプール + + + images from + + + + からのイメージ + + + + Cannot disable mirroring because it contains a peer. + ピアを含んでいるためミラーリングを無効化できません。 + + + pool ' + ' + + プール「 + 」 + + + + erasure code profile ' + ' + + イレイジャコードプロファイル「 + 」 + + + + target ' + ' + + ターゲット「 + 」 + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf new file mode 100644 index 00000000..0c3f0d85 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.ko-KR.xlf @@ -0,0 +1,4340 @@ + + + + + Toggle navigation + 네비게이션 전환 + + + Dashboard + 현황판 + + + Cluster + 클러스터 + + + Hosts + 호스트들 + + + Monitors + 모니터들 + + + OSDs + OSD들 + + + Configuration + 설정 + + + CRUSH map + 크러쉬맵 + + + Manager modules + 메니저 모듈들 + + + Logs + 로그들 + + + Alerts + 경고들 + + + Silences + Silences + + + Pools + 풀들 + + + Block + 블럭 + + + Images + 이미지들 + + + Mirroring + 미러링 + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + 파일시스템들 + + + Object Gateway + 오브젝트게이트웨이 + + + Daemons + 데몬들 + + + Users + 사용자 + + + Buckets + 버킷들 + + + Retrieving data + for + + + . Please wait... + + Retrieving data + for + + + . Please wait... + + + + Displaying previously cached data + + for + + + . + + Displaying previously cached data + + for + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Could not load data + for + + + . + Please check the cluster health. + + + + Back + 뒤로 + + + Select a Language + 언어선택 + + + Loading panel data... + 패널 데이타 로딩 중... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + + + Grafana Time Picker + 그라파나 타임 픽커 + + + Reset Settings + 설정 초기화 + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + 데이타 로딩 실폐 + + + selected + 선택된 + X selected + + + found + 발견된 + X found + + + total + 전체 + X total + + + Edit + 편집 + + + Name + 이름 + + + Description + 설명 + + + Long description + 자세한 설명 + + + Default + 기본값 + + + Daemon default + 데모 기본값 + + + Services + 서비스들 + + + Values + 값들 + + + The entered value is too high! It must not be greater than + . + + 입력값이 너무 큽니다! 그것은 + 보다 커야 합니다. + + + + The entered value is too low! It must not be lower than + . + + 입력된 값이 너무 작습니다.! 그것은 + 작아야 합니다. + + + + Save + 저장하기 + + + CRUSH map viewer + 크러쉬맵 보기 + + + Hosts List + 호스트 목록들 + + + Overall Performance + 통합 성능치 + + + No entries found + 항목들을 찾을 수 없음 + + + Cluster Logs + 클러스터 로그들 + + + Audit Logs + 감사 로그들 + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + 설정 로딩 중 + + + The configuration could not be loaded. + 설정을 로드할 수 없습니다. + + + Edit Manager module + 관리모듈 편집하기 + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + 입력된 값이 유효한 UUID가 아닙니다, 예.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + 입력된 값은 유효한 IP주소 여야 합니다. + + + This field is required. + 이 필드는 필수적입니다. + + + The entered value is too high! It must be lower or equal to + . + + 입력값이 너무 큽니다! 그것은 반드시 + 작거나 같아야 합니다. + + + + The entered value is too low! It must be greater or equal to + . + + 입력된 값이 너무 작습니다! 그것은 + 보다 크거나 같아야 합니다. + + + + The entered value needs to be a number. + 입력된 값은 적어도 하나의 숫자를 필요로 합니다. + + + The entered value needs to be a number or decimal. + 입력 된 값은 숫자 또는 십진수여야 합니다. + + + Update + 갱신 + + + Status + 상태 + + + Cluster ID + 클러스터 ID + + + monmap modified + 몬맵 변경시간 + + + monmap epoch + 몬맵 변경번호 + + + quorum con + 정족수 일치번호 + + + quorum mon + 정족수 모니터상태 + + + required con + 요구되는 일치번호 + + + required mon + 요구되는 모니터상태 + + + In Quorum + 정족수에 포함 + + + Not In Quorum + 정족수 미포함 + + + Cancel + 취소 + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + 선택된 + 로 + 을 하는 것이 확실합니까? + + + + Yes, I am sure. + 예, 확실합니다. + + + Cluster-wide OSD Flags + 클러스터-수준의 OSD 플레그들 + + + Submit + 제출 + + + + + + + + + + + form title + + + Advanced... + 자세한 옵션... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + OSD 복구 우선순위 + + + Priority + 우선순위 + + + Customize priority values + 우선 순위 값 맞춤 설정 + + + This field is required! + 이 필드는 요구됩니다! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + 입력된 값이 너무 큽니다! 그것은 + 보다 크지 않아야 합니다.. + + + + The entered value is too low! It must not be lower than + . + + 입력된 값이 너무 작습니다! 그것은 + 보다 작아야 합니다. + + + + Reweight OSD + OSD 재-조정 + + + The value needs to be between 0 and 1. + 값은 0과 1사이어야 합니다. + + + Reweight + 재-조정 + + + OSDs + Scrub + + OSD들 + 청소하기 + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, 선택, 1 {깊이 } } + + + You are about to apply a + scrub to + the OSD + + + . + + OSD + + + 을 청소하기 위해, 당신은 + 을 적용하려고 합니다. + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, 선택, 1 {깊이 } } + + + OSDs List + OSD 목록들 + + + + OSD + + will be marked + + + if you proceed. + + 계속진행하면 + OSD + + 는 + + + 로 표시됩니다. + + + + The OSD is not safe to destroy! + OSD는 파괴하기에 안전하지 않습니다! + + + + OSD + + will be + + + if you proceed. + + 계속진행하면 + OSD + + 는 + + + 가 될 것입니다. + + + + Details + 세부설명 + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + 닫기 + + + Delete + 삭제 + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + 건강상태 + + + Statistics + 통계들 + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + + + Clients + 클라이언트들 + + + Any client can access + 모든 클라이언트 접근가능 + + + Addresses + 주소들 + + + Required field + 필수 입력란 + + + Must contain one or more comma-separated values + 반드시 하나 이상의 쉼표로 구분 된 값을 포함해야 함 + + + For example: + 예를들면: + + + Access Type + 접근형태 + + + Squash + Squash + + + Add clients + 클라이언트들 추가 + + + Loading... + 로딩중... + + + -- No cluster available -- + -- 사용가능 클러스터 없음 -- + + + -- Select the cluster -- + -- 클러스터 선택 -- + + + Add daemon + 데몬 추가하기 + + + Storage Backend + 스토리지 백엔드 + + + -- No data pools available -- + -- 이용가능한 데이타풀 없음 -- + + + -- Select the storage backend -- + -- 스토리지 백엔드 선택 -- + + + Object Gateway User + 객체 게이트웨이 사용자 + + + -- No users available -- + -- 사용가능한 사용자들 없음 -- + + + -- Select the object gateway user -- + -- 객체 게이트웨이 사용자 선택 -- + + + CephFS User ID + CephFS 사용자 ID + + + -- No clients available -- + -- 사용가능한 클라이언트 없음 -- + + + -- Select the cephx client -- + -- cephx 클라이언트 선택 -- + + + CephFS Name + CephFS 이름 + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + 보안 레이블 + + + Enable security label + 보안 레이블 사용 + + + CephFS Path + CephFS 경로 + + + Path need to start with a '/' and can be followed by a word + 경로는 '/'로 시작해야하며 그 뒤에 단어가 올 수 있습니다 + + + New directory will be created + 새로운 디렉토리가 만들어 질 것입니다 + + + Path + 경로 + + + Path can only be a single '/' or a word + 경로는 하나의 '/' 또는 하나의 단어 일 수 있습니다 + + + New bucket will be created + 새로운 버킷이 만들어 질 것입니다 + + + NFS Protocol + NFS 프로토콜 + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + NFS 태크 + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + + NFS v3 + 마운트들을 위한 대체 접근 (/가 앞에 와야 함). + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + 클라이언트는 하위 디렉토리를 마운트 할 수 없습니다 (즉, Tag = foo 인 경우 클라이언트가 foo / baz를 마운트하지 못할 수 있습니다). + + + By using different Tag options, the same Path may be exported multiple times. + 다른 태그 옵션을 사용하면 같은 경로를 여러 번 내보낼 수 있습니다. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + + + By using different Pseudo options, the same Path may be exported multiple times. + 다른 Pseudo 옵션을 사용하면 동일한 경로를 여러 번 내보낼 수 있습니다. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- 사용가능한 접근형태 없음 -- + + + -- Select the access type -- + -- 접근형태 선택 -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- 사용가능한 squash 없음 -- + + + --Select what kind of user id squashing is performed -- + -- 어떤 종류의 사용자 ID 스쿼시가 수행되는지 선택하세요 -- + + + Transport Protocol + 전송프로토콜 + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Ceph 사용을 환영합니다. + The welcome message on the login page + + + Username is required + 사용자이름이 필요합니다 + + + Password is required + 암호가 필요합니다 + + + Login + 로그인 + + + Sorry, the user does not exist in Ceph. + 미안합니다. 사용자가 Ceph내에 존재하지 않습니다. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + + + Forbidden + 금지됨 + + + Sorry, you are not allowed to see what you were looking for. + 미안합니다. 당신이 요청할 것을 열람하는 것이 허락되지 않습니다. + + + Sorry, we could not find what you were looking for + 미안합니다. 당신이 요청할 것을 찾을 수 없습니다. + + + Remove all + 모든 것 제거 + + + Recent Notifications + 최근 알림들 + + + There are no background tasks. + 백그라운드 작업이 없습니다. + + + Background Tasks + 백그라운드 작업들 + + + Help + 도움말 + + + Documentation + 문서 + + + API + API + + + About + 대하여 + + + Dashboard Settings + 대쉬보드 설정 + + + User management + 사용자 관리 + + + Logged in user + 로그인된 사용자 + + + Signed in as + + + + + + + + +로써 승인됨 + + + + Sign out + 로그아웃 + + + Name... + 이름... + + + The chosen name is already in use. + 선택한 이름이 이미 사용중입니다. + + + Description... + 세부설명... + + + Permissions + 권한들 + + + Roles + 역할들 + + + Username + 사용자명 + + + Password + 암호 + + + Confirm password + 암호 확인 + + + Password confirmation doesn't match the password. + 암호 확인이 암호와 일치하지 않습니다. + + + Full name + 전체 이름 + + + Email + 전자우편 + + + Invalid email. + 유효하지않는 전자우편. + + + You are about to remove "user read / update" permissions from your own user. + 당신의 사용자로부터 "사용자 읽기 / 업데이트"권한을 제거하려고합니다. + + + If you continue, you will no longer be able to add or remove roles from any user. + 계속하면 모든 사용자에게 역할을 추가하거나 제거 할 수 없게됩니다. + + + Are you sure you want to continue? + 계속 진행하기를 원하십니까? + + + Performance counters not available + 성능 카운터들을 사용 할 수 없음 + + + Attributes (OSD map) + 속성들 (OSD 맵) + + + Metadata not available + 메타데이타 사용할 수 없음 + + + Metadata + 메타데이타 + + + Performance counter + 성능 카운터 + + + Histogram not available: + + + 히스토그램을 사용할 수 없음: + + + + + Writes + 쓰기 + + + Reads + 읽기 + + + Histogram + 히스토그램 + + + Performance Details + 성능 세부정보들 + + + Current values + 현재 값들 + + + Type + 형태 + + + Min + 최소 + + + Max + 최대 + + + Flags + 플레그들 + + + Source + 소스 + + + Level + 수준 + + + Can be updated at runtime (editable) + 수행시간에 갱신가능함(편집가능) + + + Tags + 테크들 + + + Enum values + 열거형 값들 + + + See also + 추가로 더보기 + + + Cluster Status + 클러스터 상태 + + + Manager Daemons + 관리자 데몬들 + + + Object Gateways + 오브젝트 게이트웨이들 + + + Metadata Servers + 메타데이타 서버들 + + + iSCSI Gateways + iSCSI 게이트웨이들 + + + Client IOPS + 클라이언트 IOPS + + + Client Throughput + 클라이언트 처리량 + + + Client Read/Write + 클라이언트 읽기/쓰기 + + + Recovery Throughput + 복구 처리량 + + + Scrub + 세정작업 + + + Performance + 성능 + + + Raw Capacity + 원시용량 + + + Objects + 오브젝트들 + + + PGs per OSD + OSD당 PG들 + + + PG Status + PG 상태들 + + + Capacity + 용량 + + + + + See + Logs + for more details. + + + + 더 자세한 내용을 위해 + 로그 + 보십시오. + + + + Ranks + 순위 + + + MDS performance counters + MDS performance counters + + + Clients: + + + 클라이언트들: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + 이미지를 휴지통에 이동 + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + 휴지통으로 + + / + + 옮기기 위해, + 선택, + 이미지 옮기세요. 선택적으로, 폐기날짜를 지정할 수 있습니다. + + + + Protection expires at + 보호가 만료되는 + + + NOT PROTECTED + 보호되지 않음 + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + 날짜 형식 오류. "YYYY-MM-DD HH:mm:ss" 형식으로 지정하세요. + + + Protection has already expired. Please pick a future date or leave it empty. + 보호기간이 이미 만료되었습니다. 더 미래의 날짜를 선택하거나 공란으로 남겨두세요. + + + Move Image + 이미지 옮기기 + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + 개관 + + + Targets + 타겟들 + + + Discovery Authentication + 인증 탐색 + + + User + 사용자 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + 사용자이름은 8~64자까지 길이의 문자들을 가져야 하며 그리고, 오직 , '.', '@', '-', '_', ':' 등의 특수 문자들만을 포함가능합니다. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + 공동 사용자 + + + Mutual Password + 공통 암호 + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + iSCSI 타겟들 관리 기능들을 설정하고 켜기위해서 + 문서 + 부분을 참조하시기 바랍니다. + + + + Available information: + 이용가능한 정보: + + + iSCSI Targets not available + iSCSI 타겟이 이용 불가능합니다. + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + 오직 + fast-diff + 설정된 RBD 이미지들과 함께 사용가능합니다. + + + + Pool + + + + Data Pool + 데이타 풀 + + + Created + 생성된 + + + Size + 크기 + + + Object size + 객체크기 + + + Features + 특징들 + + + Provisioned + 준비된 + + + N/A + 이용불가 + + + Total provisioned + 준비된 총계 + + + Striping unit + 스트라이핑 단위 + + + Striping count + 스트라이핑 횟수 + + + Parent + 상위 + + + Block name prefix + 블록 이름 접두사 + + + Order + 순서 + + + Snapshots + 스냅삿 + + + Image + 이미지 + + + This setting overrides the global value + 이 설정은 전역 값을 덮어씁니다. + + + Global + 글로벌 + + + This is the global value. No value for this option has been set for this image. + 이것은 전역 값입니다. 이 이미지에 대해 이 옵션의 값이 설정되지 않았습니다. + + + + from + + + from + + + + '/' and '@' are not allowed. + '/' 와 '@' 문자는 사용불가입니다. + + + -- No rbd pools available -- + -- 이용가능한 rbd풀 없음 -- + + + -- Select a pool -- + -- 풀 선택 -- + + + Use a dedicated data pool + 전용 데이타 풀들을 사용하세요 + + + Data pool + 데이타 풀 + + + Dedicated pool that stores the object-data of the RBD. + RBD의 객체-데이타를 저장하고 있는 전용 풀 + + + e.g., 10GiB + 예., 100 GiB + + + You have to increase the size. + 사이즈를 증가시켜야 합니다. + + + Advanced + 자세한 + + + Striping + 분산저장 + + + Stripe unit + 분산저장단위 + + + -- Select stripe unit -- + -- 분산저장단위 선택 -- + + + This field is required because stripe count is defined! + 분산저장 개수가 정의되어 있으므로 이 필드는 필수입니다! + + + Stripe unit is greater than object size. + 분산저장단위는 객체크기보다 커야 합니다. + + + Stripe count + 분산저장 갯수 + + + This field is required because stripe unit is defined! + 분산저장 단위가 정의되어 있으므로 이 필드는 필수입니다! + + + Stripe count must be greater than 0. + 분산저장 갯수는 반드시 0보다 커야 합니다. + + + + RBD Snapshot + + + RBD 스냅샷 + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Rename} other {Create} } + + + + Snapshot + + + 스냅샷 + + + + PROTECTED + 보호됨 + + + UNPROTECTED + 보호안됨 + + + You are about to rollback + 롤백하려고 합니다. + + + Purge Trash + 휴지통 비우기 + + + To purge, select one or All images and click + 비우기 위해, 하나 또는 모든 이미지들을 선택하고 클릭하세요. + + + Pool: + 풀: + + + Pool name... + 풀 이름: + + + All + 모든 + + + Restore Image + 이미지 복구하기 + + + To restore + 복구를 위해 + + + type the image's new name and click + 이미지들의 새로운 이름을 입력하고 클릭하세요 + + + New Name + 새로운 이름 + + + Expired at + 폐기될 + + + Protected until + 까지 보호됨 + + + This image is protected until + . + + 이 이미지는 + 까지 보호됩니다. + + + + Trash + 휴지통 + + + iSCSI Topology + iSCSI 토폴로지 + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + 기본설정 값들로 부터 인자를 변경하는 것은 일반적으로 필요하지 않습니다. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + 설정들 + + + Backstore + 백스토어 + + + Confirm + 확인 + + + Advanced Settings + 고급설정들 + + + Target IQN + 타겟 IQN + + + IQN has wrong pattern. + IQN이 잘못된 패턴을 가지고 있습니다. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + IQN은 다음과 같은 지정규칙이 있습니다. +'iqn.$년-$달.$뒤집어진주소:$정의된이름' + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Key +예를들면: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + 추가 정보 + + + This target has modified advanced settings. + 이 타겟은 고급설정들을 수정했습니다. + + + Portals + 포털 + + + At least + gateways are required. + + 적어도 + 게이트웨이들을 필요로 합니다. + + + + Add portal + 포털 추가 + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + 이 이미지는 설정들을 수정했습니다. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + 이미지 추가 + + + ACL authentication + ACL 인증 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + 개시자들 + + + Initiator + 개시자들 + + + Client IQN + 클라이언트 IQN + + + Initiator IQN needs to be unique. + 개시자 IQN은 유일해야 합니다. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + 사용자이름은 8~64자까지 길이의 문자들을 가져야 하며 그리고, 오직 , '.', '@', '-', '_', ':' 등의 특수 문자들만 포함이 가능합니다. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + 개시자는 하나의 그룹에 속해야 하고, 이미지는 그룹안에서 설정합니다. + + + No items added. + 추가된 아이템들이 없음 + + + Add initiator + 게시자 추가 + + + Groups + 그룹들 + + + Group + 그룹 + + + Add group + 그룹추가 + + + [object Object] + [object Object] + + + RBD Configuration + RBD 설정들 + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + 로컬 구성 값을 제거하십시오. 상위 구성 값은 계승되고 대신 사용됩니다. + + + The mininum value is 0 + 최소값은 0입니다. + + + Issues + 이슈들 + + + Syncing + 동기화중 + + + Ready + 준비됨 + + + Edit pool mirror mode + 풀 미러모드를 편집하기 + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + 풀을 위한 미러모드를 편집하기 위해  + + + , 그 목록으로 부터 새로운 모드를 선택하고, 클릭 + 갱신 + . + + + + Mode + 양식 + + + Peer clusters must be removed prior to disabling mirror. + 상대방 클러스터들은 미러를 단절하기 전에 반드시 제거되어야 합니다. + + + + + pool mirror peer + + + + 풀 미러 상대방 + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Edit} other {Add} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + 풀 + + + 풀을 위하여 상대방 속성 미러하고, + 선택 + 제출 + . + + + + Cluster Name + 클러스터 이름 + + + The cluster name is not valid. + 클러스터 이름이 유효하지 않습니다. + + + CephX ID + CephX 아이디 + + + CephX ID... + CephX 아이디... + + + The CephX ID is not valid. + CephX 아이디가 유효하지 않습니다. + + + Monitor Addresses + 모니터 주소들 + + + Comma-delimited addresses... + 콤마로 분리된 주소들... + + + The monitory address is not valid. + 모니터 주소가 유효하지 않습니다. + + + CephX Key + CephX 키 + + + Base64-encoded key... + Base64로 인코딩 된 키 ... + + + CephX key must be base64 encoded. + CephX 키는 반드시 base64로 인코드 되어야 합니다. + + + Pools List + 풀 목록들 + + + The name can only consist of alphanumeric characters, dashes and underscores. + 이름은 영숫자, 대시 및 밑줄로만 구성 될 수 있습니다. + + + The chosen erasure code profile name is already in use. + 선택한 Erasure Code 프로파일 이름이 이미 사용 중입니다. + + + Plugin + 플러그인 + + + Data chunks (k) + 데이터 덩어리들 (k) + + + Must be equal to or greater than 2. + 반드시 2보다 크거나 같아야합니다. + + + Coding chunks (m) + 코딩 덩어리들 (m) + + + Must be equal to or greater than 1. + 반드시 1보다 크거나 같아야합니다. + + + Durability estimator (c) + 내구성 평가(c) + + + Locality (l) + 지역 (l) + + + Crush failure domain + 크러쉬 실패 도메인 + + + Crush Locality + 크러쉬 지역 + + + None + 없음 + + + Technique + 기술 + + + Packetsize + 패킷크기 + + + Crush root + 크러쉬루트 + + + Crush device class + 크러쉬 장치 클래스 + + + any + 모든 + + + Directory + 디렉토리 + + + The chosen Ceph pool name is already in use. + 선택한 Ceph 풀이름이 이미 사용중입니다. + + + Pool type + 풀 형태 + + + -- Select a pool type -- + -- 풀 형태 선택 -- + + + Placement groups + 게재위치 그룹 + + + At least one placement group is needed! + 적어도 하나의 게재위치 그룹이 필요함! + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + 클러스터는 이 많은 PG들를 처리 할 수 없습니다. 필요한 PG 양을 다시 계산하십시오. + + + Calculation help + 계산 도움말 + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + 현재의 PG들 설정들이 당신을 위해 계산되었습니다. +당신은 제출하기 전에 당신의 요구에 적합한 값인지를 확인해야 합니다. + + + Crush ruleset + 크러쉬 룰셋 + + + -- Select a crush rule -- + -- 크러쉬 룰 선택 -- + + + Crush rule + 크러쉬 룰 + + + Crush steps + 크러쉬 단계들 + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + 이 룰에 의하여 최소로 필요로 하는 OSD보다 적은 OSD를 가지고 있기때문에 이 룰은 현재의 클러스터에서는 사용할 수 없습니다. + + + Replicated size + 복제되는 크기 + + + Minimum: + + + 최소: + + + + + Maximum: + + + 최대: + + + + + The size specified is out of range. A value from + to + is valid. + + 지정된 크기는 범위를 벗어났습니다. + 에서 + 사이의 값이 유효합니다. + + + + Erasure code profile + Erasure Code 프로파일 + + + -- No erasure code profile available -- + -- 사용가능한 Erasure Code 프로파일 없음 -- + + + -- Select an erasure code profile -- + -- 한개의 Erasure Code 프로파일 선택 -- + + + EC Overwrites + EC 덮어쓰기 + + + Applications + 응용프로그램들 + + + Compression + 압축 + + + Algorithm + 알고리즘 + + + -- No erasure compression algorithm available -- + -- 이용가능한 Erasure 압축알고리즘 없음 -- + + + Minimum blob size + 최소 blob 크기 + + + e.g., 128KiB + 예) 128KiB + + + Value should be greater than 0 + 값은 0보다 커야합니다 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + 최대 blob 크기 + + + e.g., 512KiB + 예) 512KiB + + + Value should be greater than the minimum blob size + 값은 최소 blob 크기보다 커야 합니다 + + + Ratio + 비율 + + + Compression ratio + 압축율 + + + Value should be between 0.0 and 1.0 + 값은 0.0과 1.0 사이 여야 합니다. + + + It's not possible to create an RBD pool with '/' in the name. + 이름에 '/'가 포함 된 RBD 풀을 생성 할 수 없습니다. + + + Please change the name or remove 'rbd' from the applications list. + 이름을 변경하거나 응용 프로그램 목록에서 'rbd'를 제거하십시오. + + + Cache Tiers Details + 케쉬 계층들 상세설명들 + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + 오브젝트 게이트웨이 관리기능들을 어떻게 설정하고 켜는지에 대해 +문서 + 상의 + 부분을 참조하기 바랍니다. + + + + Daemons List + 데몬 목록들 + + + Performance Counters + 성능 카운터 + + + Loading bucket data... + 버킷데이타 적재 중 + + + The bucket data could not be loaded. + 버킷 데이타를 적재할 수 없습니다. + + + Id + 아이디 + + + The value is not valid. + 값이 유효하지 않습니다. + + + Owner + 소유자 + + + -- Select a user -- + -- 사용자 선택 -- + + + ID + 아이디 + + + Index type + 색인형식 + + + Placement rule + 위치규칙 + + + Marker + 표시 + + + Maximum marker + 최대 마커 + + + Version + 버젼 + + + Master version + 마스터 버젼 + + + Modification time + 수정된 시간 + + + Zonegroup + 제로그룹 + + + Bucket quota + 버킷 할당량 + + + Enabled + 이용가능 + + + Maximum size + 최대 크기 + + + Unlimited + 무제한 + + + Maximum objects + 최대 객체들 + + + -- Select a username -- + -- 사용자명 선택 -- + + + Auto-generate key + 자동생성된 키 + + + Access key + 접근 키 + + + Secret key + 비밀 키 + + + Email address + 전자우편 주소 + + + Suspended + 유예되다. + + + System + 시스템 + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, 선택, 0 {아니오} 1 {예} } + + + Maximum buckets + 최대 버킷들 + + + Subusers + 보조사용자들 + + + Capabilities + 능력치들 + + + User quota + 사용자 할당량 + + + Show + 보기 + + + Keys + 키들 + + + -- Select a type -- + -- 형태 선택 -- + + + Permission + 권한 + + + -- Select a permission -- + -- 권한 선택 -- + + + Subuser + 보조사용자 + + + The chosen subuser ID is already in use. + 선택한 보조사용자 아이디가 이미 사용중입니다. + + + read, write + 읽기, 쓰기 + + + full + 가득찬 + + + Swift key + 스위프트 키 + + + Auto-generate secret + 자동생선된 비밀 + + + Loading user data... + 사용자 데이타 적재 중... + + + The user data could not be loaded. + 사용자 데이타를 적재할 수 없습니다. + + + The chosen user ID is already in use. + 선택된 사용자 아이디가 이미 사용 중입니다. + + + This is not a valid email address. + 이것은 유효한 전자우편 주소가 아닙니다. + + + The chosen email address is already in use. + 선택한 전자우편 주소가 이미 사용 중입니다. + + + Max. buckets + 최대 버킷들 + + + The entered value must be >= 0. + 입력된 값은 반드시 0보다 커야 합니다. + + + S3 key + S3 키 + + + There are no subusers. + 보조사용자가 없습니다. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + 키가 없습니다. + + + + + + + + + + + + + Swift + 스위프트 + + + There are no capabilities. + 능력치가 없습니다. + + + + + + + + + + + + + Unlimited size + 무제한 크기 + + + Max. size + 최대 크기 + + + Unlimited objects + 무제한 객체들 + + + Max. objects + 최대 객체들 + + + Current + 현재 + + + Updated discovery authentication + 업데이트된 검색 인증 + + + There are no portals available. + 사용가능한 포탈들이 없습니다. + + + There are no images available. + 사용가능한 이미지들이 없습니다. + + + There are no images available. Please make sure you add an image to the target. + 사용할 수있는 이미지가 없습니다. 대상에 이미지를 추가했는지 확인하십시오. + + + There are no initiators available. Please make sure you add an initiator to the target. + 사용할 수있는 개시자가 없습니다. 대상에 개시자를 추가했는지 확인하십시오. + + + target + target + + + Target + 타겟 + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + 상태 + + + # Targets + # Targets + + + Read Bytes + 읽은 바이트들 + + + Write Bytes + 쓰기 바이트들 + + + Read Ops + 읽기 Ops + + + Write Ops + 쓰기 Ops + + + A/O Since + A/O 이래로 + + + Instance + 인스탄스 + + + Hostname + 호스트이름 + + + Issue + 이슈 + + + Progress + 진행중 + + + Disabled + 설정해제됨 + + + Edit Mode + 편집모드 + + + Add Peer + 상대방 추가 + + + Edit Peer + 상대방 편집 + + + Delete Peer + 상대방 삭제 + + + Leader + 리더 + + + # Local + # 로컬 + + + # Remote + # 원격 + + + mirror peer + 상대방 미러 + + + Key + + + + RBD + RBD + + + Deep flatten + 딥 패턴 + + + Layering + 계층화 + + + Exclusive lock + 배타적인 락 + + + Object map (requires exclusive-lock) + 오프젝트-맵(배타적인-락을 요구한다) + + + Journaling (requires exclusive-lock) + 저널링(배탁적인-락을 요구합니다.) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + RBD 스냅샷 롤백 + + + Rollback + 롤백 + + + RBD snapshot + RBD 스냅샷 + + + Deleted At + 삭제될 + + + id + 아이디 + + + type + 형태 + + + state + 상태 + + + version + 버젼 + + + Host + 호스트 + + + root + 루트 + + + Rank + 순위 + + + Daemon + 데몬 + + + Activity + 활동 + + + Dentries + 덴트리들 + + + Inodes + 아이노드들 + + + Usage + 사용량 + + + Standby daemons + 대기 데몬들 + + + The value can be updated at runtime. + 이 값은 런타임에 업데이트 할 수 있습니다. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + 데몬들 / 클라이언트들은 모니터 구성 데이터베이스에서이 값을 가져 오지 않습니다. 'ceph config set ...'을 통해이 옵션을 설정하는 것은 허락되지 않습니다. 이 옵션은 ceph.conf 또는 명령 줄을 통해 구성해야합니다. + + + Option takes effect only during daemon startup. + 옵션은 데몬 시작 중에 만 적용됩니다. + + + Option only affects cluster creation. + 옵션은 클러스터 생성할 때 만 영향을 줍니다. + + + Option only affects daemon creation. + 옵션은 데몬 생성할 때만 영향을줍니다. + + + Updated config option + + + 갱신된 설정 옵션 + + + + + Service + 서비스 + + + Current value + 현재값 + + + Editable + 편집가능 + + + Updated options for module " + ". + + 모듈을 위해 갱신된 옵션들 &quot; + &quot;. + + + + Enable + 사용가능 + + + Disable + 사용불가 + + + Reconnecting, please wait ... + 재-접속 중, 기다려 주세요... + + + Public Address + 공개 주소 + + + Open Sessions + 열린 세션들 + + + No In + 들어올 수 없는 + + + OSDs that were previously marked out will not be marked back in when they start + 이전에 마크 아웃 된 OSD는 시작시 다시 표시되지 않습니다. + + + No Out + 나갈 수 없는 + + + OSDs will not automatically be marked out after the configured interval + OSD들은 구성된 간격 후에는 자동으로 표시되지 않습니다. + + + No Up + 살아나지 않는 + + + OSDs are not allowed to start + OSD는 시작할 수 없습니다. + + + No Down + 죽일 수 없는 + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + 모니터가 OSD들의 다운을 표시하지 않도록 OSD 장애 보고서가 무시되고 있습니다. + + + Pause + 멈출 + + + Pauses reads and writes + 읽기와 쓰기를 멈춤 + + + No Scrub + 스크러빙 않됨 + + + Scrubbing is disabled + 스크러빙이 비활성화되었습니다. + + + No Deep Scrub + 딥 스크럽 안됨 + + + Deep Scrubbing is disabled + 딥 스크러빙이 비활성되었습니다. + + + No Backfill + 백필 없음 + + + Backfilling of PGs is suspended + PG들의 백필이 일시중지 되었습니다. + + + No Recover + 복구 않됨 + + + Recovery of PGs is suspended + PG들의 복구가 일시중지 되었습니다. + + + Bitwise Sort + 비트단위 정렬 + + + Use bitwise sort + 비트단위 정렬을 사용하세요 + + + Purged Snapdirs + 완전삭제된 스냅디렉토리들 + + + OSDs have converted snapsets + OSD들이 변화된 스냅셋을 가지고 있습니다. + + + Recovery Deletes + 삭제된 복구들 + + + Deletes performed during recovery instead of peering + 피어링 대신 복구 중에 수행된 삭제물들 + + + PG Log Hard Limit + PG 로그 하드 한계 + + + Puts a hard limit on pg log length + pg 로그 길이에 하드 한계를 넣으세요 + + + Updated OSD Flags + 갱신된 OSD 플래그들 + + + out + 아웃 + + + in + + + + down + 다운 + + + Mark + 표시 + + + OSD lost + OSD 손실 + + + marked lost + 손실 표시 + + + Purge + 완전제거 + + + OSD + OSD + + + purged + 완전제거된 + + + destroy + 파괴됨 + + + destroyed + 파괴된 + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + 파괴됨 + + + Read bytes + 읽은 바이트들 + + + Writes bytes + 쓰기된 바이트들 + + + Read ops + 읽기 ops + + + Write ops + 쓰기 ops + + + Mark OSD + + + 표시된 OSD + + + + + Mark + + + 표시된 + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + 최대 백필들 + + + Recovery Max Active + 최대 활성화를 복구하기 + + + Recovery Max Single Start + 최대 단일 시작을 복구하기 + + + Recovery Sleep + 잠자기를 복구하기 + + + Custom + 커스텀 + + + Updated OSD recovery speed priority " + " + + 갱신된 OSD 복구 속도 우선순위 &quot; + &quot; + + + + + was initialized in the following OSD: + + + + 은 다음의 OSD들 안에 초기화됨: + + + + + Create silence + Create silence + + + Job + + + + Severity + 심각도 + + + Started + 시작된 + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + 갱신된 + + + Ends + Ends + + + Silence + Silence + + + Used + 사용된 + + + Avail. + 이용가능: + + + Clean + 깨끗한 + + + Working + 정상동작중 + + + Warning + 경고 + + + Unknown + 알려지지 않은 + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + 정상 + + + no filesystems + 파일시스템들 없음 + + + active + 활성화된 + + + standby + 대기중인 + + + n/a + 이용불가 + + + active daemon + 활성화된 데몬들 + + + quorum + 정족수 + + + The NFS Ganesha service is not configured. + NFS Ganesha 서비스가 설정되지 않음 + + + Transport + 전송 + + + CephFS User + CephFS 사용자 + + + CephFS Filesystem + CephFS 파일시스템 + + + (inherited from global config) + (전역 구성에서 상속) + + + inherited from global config + 전역 구성에서 상속 + + + -- Select what kind of user id squashing is performed -- + - 어떤 종류의 사용자 ID 스쿼시가 수행되는지 선택 - + + + There are no daemons available. + 사용가능한 데몬이 없읍니다. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + 캐쉬모드 + + + Min Evict Age + 최소 퇴거 연령 + + + Min Flush Age + 최소 플러시 연령 + + + Target Max Bytes + 목표 최대 바이트들 + + + Target Max Objects + 목표 최대 오브젝트들 + + + No applications added + 추가된 응용프로그램 없음 + + + Applications limit reached + 응용프로그램 한계에 도달함 + + + A pool can only have up to four applications definitions. + 하나의 풀은 오직 네개의 응용프로그램 정의들을 가질 수 있습니다. + + + Allowed characters '_a-zA-Z0-9' + '_a-zA-Z0-9' 문자들만 허락됨 + + + Maximum length is 128 characters + 최대 길이는 128글자이다. + + + Filter or add applications + 필터 또는 추가된 응용프로그램들 + + + Add application + 응용프로그램 추가 + + + pool + pool + + + erasure code profile + Erasure 코드 프로파일 + + + Replica Size + 복제 크기 + + + Last Change + 마지막 변경 + + + Erasure Coded Profile + Erasure 코드화된 프로파일 + + + Crush Ruleset + 크러쉬 룰셋 + + + Write bytes + 쓰여진 바이트들 + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + 버킷 + + + Updated Object Gateway bucket " + " + + 갱신된 오브젝트 게이트웨어 버킷 &quot; + &quot; + + + + Created Object Gateway bucket " + " + + 생성된 오브젝트 게이트웨이 버킷 &quot; + &quot; + + + + buckets + 버킷들 + + + capability + capability + + + user + 사용자 + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + 갱신된 오브젝트 게이트웨이 사용자 &quot; + &quot; + + + + Created Object Gateway user " + " + + 생성된 오브젝트 게이트웨이 사용자 &quot; + &quot; + + + + users + 사용자들 + + + Swift Key + Swift Key + + + Scope + 범위 + + + Read + 읽기 + + + Create + 만들기 + + + role + role + + + Created role ' + ' + + 생성된 롤 ' + ' + + + + Updated role ' + ' + + 갱신된 롤 ' + ' + + + + System Role + 시스템 롤 + + + Deleted role ' + ' + + 삭제된 롤 ' + ' + + + + Created user " + " + + 생성된 사용자 &quot; + &quot; + + + + Update user + 갱신된 사용자 + + + Continue + 계속 + + + You were automatically logged out because your roles have been changed. + 당신의 롤들이 변경되어 당신은 자동적으로 로그아웃되었습니다. + + + Updated user " + " + + 갱신된 사용자 &quot; + &quot; + + + + Deleted user " + " + + 삭제된 사용자 &quot; + &quot; + + + + Failed to delete user " + " + + 사용자 삭제가 실폐된 &quot; + &quot; + + + + You are currently logged in as " + ". + + 당신은 현재 &quot; + &quot; 로 로그인되었습니다. + + + + Each object is split in data-chunks parts, each stored on a different OSD. + 각각의 오브젝트들은 데이타-청크 부분들로 분리되어, 각기 다른 OSD에 보관됩니다. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + 각 오브젝트들에 대한 코딩 청크를 계산하고 서로 다른 OSD에 저장합니다. +코딩된 청크의 수는 데이터 손실없이 작동중지 되어 질 수있는 OSD의 숫자이기도합니다. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Jerasure 플러그인은 가장 일반적이고 유연한 플러그인으로, +또한 Ceph erasure 코드 풀의 기본값이기도합니다. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + 보다 유연한 기술은 reed_sol_van입니다 : k와 m을 설정하면 충분합니다. +cauchy_good 기술은 빠를 수 있지만 패킷크기를 주의깊게 선택해야합니다. +reed_sol_r6_op, liberation, blaum_roth, liber8tion은 모두 m = 2로만 구성 할 수 있다는 점에서 RAID-6에 해당합니다. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + 인코딩은 한번에 바이트들 크기의 패킷에 대해 수행됩니다. 올바른 패킷 크기를 선택하는 것은 어렵습니다. jerasure 문서에는이 주제에 대한 광범위한 정보가 들어 있습니다. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + jerasure 플러그인을 사용하면 삭제 된 코딩 된 객체가 여러 OSD에 저장 될 때 하나의 OSD가 손실되는 것을 복구하려면 다른 모든 OSD를 읽어야합니다. 예를 들어 jerasure가 k = 8 및 m = 4로 구성되어있는 경우 하나의 OSD를 잃어 버리면 11 명의 다른 사람들이 수리해야합니다. +lrc erasure code plugin은 적은 양의 OSD를 사용하여 복구 할 수 있도록 로컬 패리티 청크를 만듭니다. 예를 들어, lrc가 k = 8, m = 4 및 l = 4로 구성된 경우 4 개의 OSD마다 추가 패리티 덩어리가 생성됩니다. 단일 OSD가 손실되면 11 개 대신 4 개의 OSD만으로 복구 할 수 있습니다. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + 코딩 및 데이터 청크를 크기 지역 집합으로 그룹화합니다. 예를 들어, k = 4 및 m = 2에 대해, 지역성 = 3 일 때 두 개의 세 그룹이 생성됩니다. 각 세트는 다른 세트의 청크를 읽지 않고도 복구 될 수 있습니다. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + l로 정의 된 각 청크 집합이 저장되는 크러시 버킷의 유형입니다. 예를 들어 랙으로 설정하면 l 개의 청크 그룹이 각각 다른 랙에 배치됩니다. +랙 선택 단계와 같은 CRUSH 규칙 단계를 만드는 데 사용됩니다. 설정되어 있지 않으면, 그러한 그룹화가 수행되지 않습니다. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + isa 플러그인은 ISA 라이브러리를 캡슐화합니다. 인텔 프로세서에서만 실행됩니다. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + ISA 플러그인은 두 개의 리드 솔로몬 형식으로 제공됩니다. +reed_sol_van이 설정되면 Vandermonde, cauchy가 설정되면 Cauchy입니다. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + shec plugin은 다중 SHEC 라이브러리를 캡슐화합니다. +           ceph가 리드 솔로몬 코드보다 더 효율적으로 데이터를 복구 할 수 있습니다. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + 각 데이터 청크가 계산 범위에 포함되는 패리티 청크의 수입니다. 이 수치는 내구성 측정기로 사용됩니다. 예를 들어, c = 2 인 경우 2 개의 OSD가 데이터 손실없이 중단 될 수 있습니다. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + CRUSH 규칙의 첫 번째 단계에 사용 된 크러시 버킷의 이름입니다. 예를 들어 step은 기본값을 취합니다. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + 동일한 실패 도메인을 가진 양동이에 두 개의 청크가 없는지 확인하십시오. 예를 들어 실패 도메인이 호스트 인 경우 두 개의 청크가 동일한 호스트에 저장되지 않습니다. 이 단계는 리프 호스트를 선택하는 단계와 같은 CRUSH 규칙 단계를 만드는 데 사용됩니다. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + CRUSH지도에서 크래시 장치 클래스 이름을 사용하여 특정 클래스 (예 : ssd 또는 hdd)의 장치로 배치를 제한합니다. + + + Set the directory name from which the erasure code plugin is loaded. + 삭제 코드 플러그인이로드되는 디렉토리 이름을 설정하십시오. + + + Allows all operations + 모든 작업들 허용 + + + Allows only operations that do not modify the server + 오직 서버를 수정하지 않는 작업들만 가능합니다. + + + Does not allow read or write operations, but allows any other operation + 읽기와 쓰기 작업은 허용되지 않지만, 그외 모든 작업이 가능합니다. + + + Does not allow read, write, or any operation that modifies file attributes or directory content + 파일의 속성과 디렉토리 내용을 변경하는 읽기, 쓰기 또는 어떠한 작업은 허용되지 않습니다. + + + Allows no access at all + 전혀 어떠한 접근도 허용되지 않습니다. + + + -- Select the priority -- + -- 우선순위 선택 -- + + + Low + 낮음 + + + High + 높음 + + + Last 5 minutes + 마지막 5분 + + + Last 15 minutes + 지난 15분 + + + Last 30 minutes + 지난 30분 + + + Last 1 hour (Default) + 지난 1시간(기본) + + + Last 3 hours + 지난 3시간 + + + Last 6 hours + 지난 6시간 + + + Last 12 hours + 지난 12시간 + + + Last 24 hours + 지난 24시간 + + + Yesterday + 어제 + + + Today + 오늘 + + + Today so far + 오늘 지금까지 + + + Day before yesterday + 그저께 + + + Last 2 days + 지난 2일 + + + This day last week + 이번 주 마지막날 + + + Previous week + 전주 + + + This week + 이번주 + + + This week so far + 이번주 지금까지 + + + Last 7 days + 지난 7일 + + + Previous month + 지난 달 + + + This month + 이번 달 + + + This month so far + 이번 달 지금까지 + + + Last 30 days + 지난 30일 + + + Last 90 days + 지난 90일 + + + Last 6 months + 지난 6개월 + + + Last 1 year + 지난 1년 + + + Previous year + 전년도 + + + This year + 금년도 + + + This year so far + 금년 지금까지 + + + Last 2 years + 지난 2년 + + + Last 5 years + 지난 5년 + + + Information + 정보 + + + No items selected. + 선택된 아이템 없음 + + + Deselect item to select again + 다시 선택하기 위해 아이템 선택을 취소 + + + Selection limit reached + 선택 한계에 도달함 + + + Filter tags + 필터 테그들 + + + Add badge + 베찌 추가 + + + There are no items available. + 사용가능한 아이템 없음 + + + Add + 추가 + + + Remove + Remove + + + Clone + 복제 + + + Copy + 복사 + + + Deep Scrub + 딥 스크럽 + + + Destroy + 파괴됨 + + + Flatten + 단조로움 + + + Mark Down + 다운 표시 + + + Mark In + 인 표시 + + + Mark Lost + 손실 표시 + + + Mark Out + 아웃 표시 + + + Protect + 보호 + + + Rename + 이름변경 + + + Restore + 복구 + + + Move to Trash + 휴지통으로 옮기기 + + + Unprotect + 보호않됨 + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + 삭제돔 + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + 복제된 + + + Copied + 복사된 + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + + + + No + 아니오 + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + 서비스 량 + + + BPS Limit + BPS 한계 + + + The desired limit of IO bytes per second. + 원하는 초당 IO 바이트 수 제한입니다. + + + IOPS Limit + IOPS 제한 + + + The desired limit of IO operations per second. + 원하는 초당 IO 작업 제한입니다. + + + Read BPS Limit + 읽기 BPS 제한 + + + The desired limit of read bytes per second. + 원하는 초당 읽기 바이스 수 제한입니다. + + + Read IOPS Limit + 읽기 IOPS 한도 + + + The desired limit of read operations per second. + 원하는 초당 읽기 작업 제한입니다. + + + Write BPS Limit + 쓰기 BPS 한도 + + + The desired limit of write bytes per second. + 원하는 초당 쓰기 바이트 수 제한입니다. + + + Write IOPS Limit + 쓰기 IOPS 제한 + + + The desired limit of write operations per second. + 원하는 초당 쓰기 작업 제한입니다. + + + BPS Burst + BPS 버스트 + + + The desired burst limit of IO bytes. + 원하는 버스트 IO 바이트 한도 입니다. + + + IOPS Burst + IOPS 버스트 + + + The desired burst limit of IO operations. + 원하는 IO 작업의 버스트 한계입니다. + + + Read BPS Burst + 읽기 BPS 버스트 + + + The desired burst limit of read bytes. + 원하는 읽기 버스트 한계입니다. + + + Read IOPS Burst + 읽기 IOPS 버스트 + + + The desired burst limit of read operations. + 원하는 읽기 작업의 버스트 한도입니다. + + + Write BPS Burst + 쓰기 BPS 버스트 + + + The desired burst limit of write bytes. + 쓰기 바이트의 원하는 버스트 한도. + + + Write IOPS Burst + 쓰기 IOPS 버스트 + + + The desired burst limit of write operations. + 쓰기 바이트의 원하는 버스트 한도. + + + Failed to + + + + + + 의 실폐 + + + + Executing + 수행중 + + + execute + 수행 + + + Executed + 수행된 + + + unknown task + 알려지지 않는 작업 + + + Creating + 생성하는 중 + + + create + 생성 + + + Updating + 갱신 중 + + + update + 갱신 + + + Deleting + 삭제 중 + + + delete + 삭제 + + + RBD ' + ' + + RBD ' + ' + + + + RBD snapshot ' + ' + + RBD 스냅삿 ' + ' + + + + mirror mode for pool ' + ' + + 풀 ' + ' 을 위한 미러모드 + + + + mirror peer for pool ' + ' + + 풀 ' + ' 미러 상대방 + + + + all dashboards + all dashboards + + + Name is already used by + . + + 이름은 + 에 의하여 이미 사용되었습니다. + + + + Name is already used by + . + + 이름은 + 에 의하여 이미 사용중입니다. + + + + Name is already used by + . + + 이름이 + 에 의하여 이미 사용중입니다. + + + + + contains snapshots. + + + 이 포함된 스냅삿들. + + + + Cloning + 복제중 + + + clone + 복제 + + + Snapshot of + must be protected. + + 반드시 + 의 스냅삿은 보호되어야 합니다. + + + + Copying + 복사중 + + + copy + 복사 + + + Flattening + 평평하게 하는 중 + + + flatten + 평평함 + + + Flattened + 평평하게 됨 + + + Name is already used by + . + + 이름이 + 에 의하여 이미 사용 중. + + + + Cannot unprotect + because it contains child images. + + + 을 보호할 수 없습니다. 왜냐하면 그것은 자식 이미지들을 포함하고 있습니다, + + + + Cannot delete + because it's protected. + + + 을 삭제할 수 없습니다. 왜냐하면 그것은 보호되어 있습니다. + + + + Rolling back + 롤백 중 + + + rollback + 롤백 + + + Rolled back + 롤백됨 + + + Moving + 옮기는 중 + + + move + 옮기기 + + + Moved + 옮겨짐 + + + image ' + ' to trash + + 이미지 ' + ' 버리기 + + + + Could not find image. + 이미지를 찾을 수 없습니다. + + + Restoring + 복구중 + + + restore + 복구 + + + Restored + 복구됨 + + + image ' + ' into ' + ' + + 이미지 ' + ' 을 ' + ' 로 + + + + Image name ' + ' is already in use. + + 이미지 이름 ' + ' 이 이미 사용중입니다. + + + + image ' + ' + + 이미지 ' + ' + + + + Purging + 완전삭제 중 + + + purge + 완전삭제 + + + Purged + 완전삭제됨 + + + all pools + 모든 풀들 + + + images from + + + + 로 부터의 이미지들 + + + + Cannot disable mirroring because it contains a peer. + 피어가 포함되어 있기 때문에 미러링을 비활성화 할 수 없습니다. + + + pool ' + ' + + 풀 ' + ' + + + + erasure code profile ' + ' + + Erasure 코드 프로파일 ' + ' + + + + target ' + ' + + 타깃 ' + ' + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf new file mode 100644 index 00000000..b7d88262 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pl-PL.xlf @@ -0,0 +1,4360 @@ + + + + + Toggle navigation + Rozwiń + + + Dashboard + Pulpit + + + Cluster + Klaster + + + Hosts + Hosty + + + Monitors + Monitory + + + OSDs + OSD-ki + + + Configuration + Konfiguracja + + + CRUSH map + CRUSH mapa + + + Manager modules + Zarządca modułów + + + Logs + Logi + + + Alerts + Powiadomienia + + + Silences + Silences + + + Pools + Pule + + + Block + Dostęp blokowy + + + Images + Obrazy + + + Mirroring + Kopia lustrzana + + + iSCSI + iSCSI + + + NFS + Sieciowy system plików NFS + + + Filesystems + Systemy plików + + + Object Gateway + Dostęp obiektowy + + + Daemons + Demony + + + Users + Użytkownicy + + + Buckets + Wiadra + + + Retrieving data + for + + + . Please wait... + + Trwa pobieranie danych + dla + + + . Czekaj... + + + + Displaying previously cached data + + for + + + . + + Wyświetlanie wcześniej buforowanych danych + +dla + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Nie można załadować danych + dla + + + . Sprawdź proszę zdrowie klastra. + + + + Back + Wstecz + + + Select a Language + Wybierz język + + + Loading panel data... + Trwa ładowanie danych... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Sprawdź proszę + dokumentację + jak +skonfigurować i uruchomić funkcje monitoringu. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Pulpit Grafany nie istnieje. Sprawdź proszę + dokumentację + jak +dodaj pulpity do Grafany. + + + + Grafana Time Picker + Wybór czasu Grafana + + + Reset Settings + Zresetuj ustawienia + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Błąd wczytywania danych. + + + selected + Wybrane + X selected + + + found + Znaleziono + X found + + + total + Razem + X total + + + Edit + Edytuj + + + Name + Nazwa + + + Description + Opis + + + Long description + Długi opis + + + Default + Domyślna + + + Daemon default + Domyślny demon + + + Services + Usługi + + + Values + Wartości + + + The entered value is too high! It must not be greater than + . + + Podana wartość jest za wysoka. Nie może być większa niż + . + + + + The entered value is too low! It must not be lower than + . + + Podana wartość jest za mała. Nie może być mniejsza od + . + + + + Save + Zapisz + + + CRUSH map viewer + widok CRUSH mapy + + + Hosts List + Lista hostów + + + Overall Performance + Całkowita wydajność + + + No entries found + Nie znaleziono wejść + + + Cluster Logs + Logi z klastra + + + Audit Logs + Audyt logów + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Ładowanie konfiguracji. + + + The configuration could not be loaded. + Nie można załadować konfiguracji + + + Edit Manager module + Edytuj moduł zarządzania + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + Wpisana wartość nie jest poprawnym UUID, np. 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + Wpisana wartość musi być poprawnym adresem IP + + + This field is required. + Pole jest wymagane. + + + The entered value is too high! It must be lower or equal to + . + + Podana wartość jest za wysoka! Musi być mniejsza bądź równa + . + + + + The entered value is too low! It must be greater or equal to + . + + Podana wartość jest za niska! Musi być większa bądź równa + . + + + + The entered value needs to be a number. + Podana wartość musi być liczbą + + + The entered value needs to be a number or decimal. + Podana wartość musi być liczbą albo dziesiętną. + + + Update + Zaktualizuj + + + Status + Status + + + Cluster ID + Klaster ID + + + monmap modified + Zmodyfikowana monmapa + + + monmap epoch + epoka monmap + + + quorum con + kworum con + + + quorum mon + kworum mon + + + required con + wymagany con + + + required mon + Wymagane mon + + + In Quorum + W kworum + + + Not In Quorum + Nie w kworum + + + Cancel + Anuluj + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + Jesteś pewny, że chcesz +   wybrany + ? + + + + Yes, I am sure. + Tak, jestem pewny. + + + Cluster-wide OSD Flags + Flagi OSD w całym klastrze + + + Submit + Zatwierdź + + + + + + + + + + + form title + + + Advanced... + Zaawansowane... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + Priorytet odzyskiwania OSD + + + Priority + Priorytet + + + Customize priority values + Dostosuj wartości priorytetowe + + + This field is required! + To pole jest wymagane. + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + Podana wartość jest za wysoka. Nie może być większa niż + . + + + + The entered value is too low! It must not be lower than + . + + Podana wartość jest za mała! Nie może być mniejsza od + . + + + + Reweight OSD + Ponowne ważenie OSD + + + The value needs to be between 0 and 1. + Wartość powinna być pomiędzy 0 a 1. + + + Reweight + Ponowne ważenie + + + OSDs + Scrub + + Szoruj + OSD-ki + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, wybierz, 1 {Głębokość} } + + + You are about to apply a + scrub to + the OSD + + + . + + Zamierzasz zaaplikować + szorowanie na OSD + + + . + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, wybierz, 1 {głębokość} } + + + OSDs List + Lista OSD-ków + + + + OSD + + will be marked + + + if you proceed. + + Jeśli kontynuujesz + OSD + + będzie zaznaczony + + + . + + + + The OSD is not safe to destroy! + Nie można bezpiecznie zniszczyć tego OSD. + + + + OSD + + will be + + + if you proceed. + + Jeśli kontyuujesz + OSD + + będzie + + + . + + + + Details + Szczegóły + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Wartość + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Zamknij + + + Delete + Usuń + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Zdrowie + + + Statistics + Statystyki + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Sprawdź proszę + dokumentację +   +jak należy skonfigurować i uruchomić zarządzanie funkcjami NFS Ganeshy + + + + Clients + Klienci + + + Any client can access + Każdy klient ma dostęp + + + Addresses + Adresy + + + Required field + Obowiązkowe pole + + + Must contain one or more comma-separated values + Musi zawierać jedną albo więcej ,rozdzielonych przecinkiem, wartości + + + For example: + Na przykład: + + + Access Type + Typ dostępu + + + Squash + Squash + + + Add clients + Dodaj klientów + + + Loading... + Ładowanie... + + + -- No cluster available -- + -- Brak dostępnego klastra -- + + + -- Select the cluster -- + -- Wybierz klaster -- + + + Add daemon + Dodaj demona + + + Storage Backend + Pamięć Podręczna + + + -- No data pools available -- + -- Brak danych puli -- + + + -- Select the storage backend -- + -- Wybierz pamięć podręczną -- + + + Object Gateway User + Użytkownik dostępu obiektowego + + + -- No users available -- + -- Brak dostępnych użytkowników -- + + + -- Select the object gateway user -- + -- Wybierz użytkownika dostępu obiektowego -- + + + CephFS User ID + CephFS Użytkownik ID + + + -- No clients available -- + -- Brak dostępnych klientów -- + + + -- Select the cephx client -- + -- Wybierz klienta cephx -- + + + CephFS Name + Nazwa CephFS + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Etykieta bezpieczeństwa + + + Enable security label + Uruchom etykietę bezpieczeństwa + + + CephFS Path + Ścieżka CephFS + + + Path need to start with a '/' and can be followed by a word + Ścieżka powinna zaczynać się z '/' i następne może być słowo + + + New directory will be created + Nowy katalog będzie stworzony. + + + Path + Ścieżka + + + Path can only be a single '/' or a word + Ścieżką może być tylko '/' albo słowo + + + New bucket will be created + Nowe wiadro będzie stworzone + + + NFS Protocol + Protokół NFS + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + Tag NFS + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Alternatywny dostęp do + NFS v3 +  montuje ( nie musi mieć poprzedzającego '/' ) + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + Klient może nie montować podkatalogów ( np. jeśli Tag = foo, klient może nie montować foo/baz) + + + By using different Tag options, the same Path may be exported multiple times. + Używając różnych opcji Tagu, ta sama Ścieżka może być wyeksportowana kilka razy. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + Pozycja, którą + NFS v4 + eksport zajmuje +w + Pseudo FS + (musi być unikatowa). + + + + By using different Pseudo options, the same Path may be exported multiple times. + Używając różnych opcji Pseudo, ta sama Ścieżka może być wyeksportowana kilka razy. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- Brak dostępnych typów dostępu -- + + + -- Select the access type -- + -- Wybierz typ dostępu -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + - Brak squasha - + + + --Select what kind of user id squashing is performed -- + -- Wybierz, jakiego rodzaju identyfikacja użytkownika ma być przeprowadzana -- + + + Transport Protocol + Protokół Transportu + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Witamy w Cephie! + The welcome message on the login page + + + Username is required + Nazwa użytkownika jest wymagana + + + Password is required + Hasło jest wymagane. + + + Login + Zaloguj + + + Sorry, the user does not exist in Ceph. + Przepraszam, użytkownik nie istnieje w Ceph. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Powrót do + Strony Logowania + . Zostaniesz wylogowany z Dostastcy Tożsamości , kiedy spróbujesz się zalgować. + + + + Forbidden + Zakazany + + + Sorry, you are not allowed to see what you were looking for. + Przepraszam, nie masz dostępu do tego czego szukasz. + + + Sorry, we could not find what you were looking for + Przepraszam, nie możemy znaleźć tego czego szukasz. + + + Remove all + Usuń wszystko + + + Recent Notifications + Ostatnie powiadomienia + + + There are no background tasks. + Brak zadań w tle. + + + Background Tasks + Zagadnienia w tle + + + Help + Pomoc + + + Documentation + Dokumentacja + + + API + Interfejs API + + + About + O + + + Dashboard Settings + Ustawienia Pulpitu + + + User management + Zarządzanie użytkownikami + + + Logged in user + Zalogowany użytkownik + + + Signed in as + + + + + Zalogowany jako + + + + + + + Sign out + Wyloguj + + + Name... + Nazwa... + + + The chosen name is already in use. + Wybrana nazwa już jest użyta. + + + Description... + Opis... + + + Permissions + Pozwolenia + + + Roles + Role + + + Username + Nazwa użytkownika + + + Password + Hasło + + + Confirm password + Potwierdź hasło + + + Password confirmation doesn't match the password. + Potwierdzające hasło nie pokrywa się z hasłem. + + + Full name + Pełne imię + + + Email + Email + + + Invalid email. + Niepoprawny email. + + + You are about to remove "user read / update" permissions from your own user. + Zamierzasz usunąć uprawnienia „odczytu / aktualizacji użytkownika” od własnego użytkownika. + + + If you continue, you will no longer be able to add or remove roles from any user. + Jeśli kontynuujesz, nie będziesz mógł dodawać albo usuwać role od użytkowników. + + + Are you sure you want to continue? + Jesteś pewny, że chcesz kontynuować? + + + Performance counters not available + Liczniki wydajności nie są dostępne + + + Attributes (OSD map) + Atrybuty (mapa OSD-ków) + + + Metadata not available + Niedostępne metadane + + + Metadata + Metadane + + + Performance counter + Licznik wydajności + + + Histogram not available: + + + Histogram niedostępny: + + + + + Writes + Pisze + + + Reads + Czyta + + + Histogram + Histogram + + + Performance Details + Szczegóły wydajności + + + Current values + Obecne wartości + + + Type + Typ + + + Min + Min + + + Max + Max + + + Flags + Flagi + + + Source + Źródło + + + Level + Poziom + + + Can be updated at runtime (editable) + Może być aktualizowany w czasie wykonywania (edytowalny) + + + Tags + Tagi + + + Enum values + Wartości enumerowane + + + See also + Zobacz także + + + Cluster Status + Status klastra + + + Manager Daemons + Zarządzanie demonami + + + Object Gateways + Obiekty bram + + + Metadata Servers + Serwery metadanych + + + iSCSI Gateways + Bramy iSCSI + + + Client IOPS + Klient IOPS + + + Client Throughput + Przepustowość klienta + + + Client Read/Write + Odczyt/Zapis klienta + + + Recovery Throughput + Przepustowość odzyskiwania + + + Scrub + Szoruj + + + Performance + Wydajność + + + Raw Capacity + Pojemność rzędu + + + Objects + Obiekty + + + PGs per OSD + PG-y na OSD + + + PG Status + Status PG + + + Capacity + Pojemność + + + + + See + Logs + for more details. + + + + zobacz + logi + , żeby mieć więcej szczegółów. + + + + Ranks + Szeregi + + + MDS performance counters + MDS performance counters + + + Clients: + + + Klienci: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Przenieś obraz do kosza + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Żeby przenieść + + / + + do kosza, kliknij + Przenieś obraz + . Opcjonalnie, możesz wybrać datę ważności. + + + + Protection expires at + Zabezpieczenie wygasa w + + + NOT PROTECTED + NIEZABEZPIECZONY + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Zły format daty. Proszę używać "RRRR-MM-DD GG:mm:ss". + + + Protection has already expired. Please pick a future date or leave it empty. + Ochrona już wygasła. Proszę wybrać przyszłą datę lub zostawić pustą. + + + Move Image + Przenieś obraz + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Przegląd + + + Targets + Obiekty docelowe + + + Discovery Authentication + Uwierzytelnianie wykrywania + + + User + Użytkownik + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Nazwy użytkowników muszą mieć długość od 8 do 64 znaków i +mogą zawierać jedynie litery, '.', '@', '-', '_' lub ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Wspólny użytkownik + + + Mutual Password + Wspólne hasło + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Sprawdź proszę + dokumentację +   +jak skonfigurować i uruchomić zarządzanie funkcjonalnościami obiektami docelowymi iSCSI + + + + Available information: + Dostępne informacje: + + + iSCSI Targets not available + obiekty docelowe iSCSI niedostępne + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + Dostępne tylko dla obrazów RBD z + szybką różnicą + włączone + + + + Pool + Pul + + + Data Pool + Dane pula + + + Created + Utworzony + + + Size + Rozmiar + + + Object size + Rozmiar obiektu + + + Features + Funkcje + + + Provisioned + Zaopatrzony + + + N/A + Niedostępny + + + Total provisioned + Całkowite rezerwy + + + Striping unit + Jednostka maskowana + + + Striping count + Licznik maskowania + + + Parent + Rodzic + + + Block name prefix + Prefiks nazwy bloku + + + Order + Zamówienie + + + Snapshots + Migawki + + + Image + Obraz + + + This setting overrides the global value + To ustawienie zastępuję wartość globalną. + + + Global + Globalne + + + This is the global value. No value for this option has been set for this image. + To jest globalna wartość. Dla tego obrazu nie ustawiono żadnej wartości dla tej opcji. + + + + from + + + from + + + + '/' and '@' are not allowed. + '/' and '@' nie są dozwolone. + + + -- No rbd pools available -- + -- Brak dostępnych rbd puli -- + + + -- Select a pool -- + -- Wybierz pul -- + + + Use a dedicated data pool + Użyj dedykowanych danych pul + + + Data pool + Dane pul + + + Dedicated pool that stores the object-data of the RBD. + Dedykowany pul, który przechowuje dane obiektowe z RBD + + + e.g., 10GiB + np. 10 GiB + + + You have to increase the size. + Musisz zwiększyć rozmiar. + + + Advanced + Zaawansowane + + + Striping + Maskowanie + + + Stripe unit + Jednostka pasków + + + -- Select stripe unit -- + -- Wybierz jednostkę pasków -- + + + This field is required because stripe count is defined! + Pole jest wymagane, ponieważ licznik pasków jest zdefiniowany. + + + Stripe unit is greater than object size. + Jednostka pasków jest większa niż rozmiar obiektu. + + + Stripe count + Licznik pasków + + + This field is required because stripe unit is defined! + Pole jest wymagane, ponieważ jednostka pasków jest zdefiniowana! + + + Stripe count must be greater than 0. + Licznik pasków musi być większy od 0. + + + + RBD Snapshot + + + migawka RBD + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, wybierz, prawda {Zmień nazwe} inaczej{Utwórz} } + + + + Snapshot + + + Migawka + + + + PROTECTED + ZABEZPIECZONE + + + UNPROTECTED + NIEZABEZPIECZONY + + + You are about to rollback + Zaraz się wycofasz. + + + Purge Trash + Usuń Śmieci + + + To purge, select one or All images and click + Aby usunąć, wybierz jeden albo wszystkie obrazy i kliknij + + + Pool: + Pul: + + + Pool name... + Nazwa pula + + + All + Wszystkie + + + Restore Image + Przywróć obraz + + + To restore + Przywróć + + + type the image's new name and click + Wpisz nazwe nowego obrazu i kliknij. + + + New Name + Nowa Nazwa + + + Expired at + Wygasły w + + + Protected until + Zabezpieczony do + + + This image is protected until + . + + Ten obraz jest chroniony do + .  + + + + Trash + Kosz + + + iSCSI Topology + Topologia iSCSI + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Zmiana tych parametrów z domyślnych wartości przeważnie nie jest potrzebna. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Ustawienia + + + Backstore + Tylny koniec przechowywania + + + Confirm + Potwierdź + + + Advanced Settings + Ustawienia zaawansowane + + + Target IQN + Nazwa IQN obiektu docelowego iSCSI + + + IQN has wrong pattern. + Błędna składnia nazwy IQN. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + IQN ma następującą notację „iqn. $ Rok-$ miesiąc. $ odwróconyAdres: $ zdefiniowanaNazwa” + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Na przykład: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Więcej informacji + + + This target has modified advanced settings. + Ten obiekt docelowy zmodyfikował zaawansowane ustawienia. + + + Portals + Portale + + + At least + gateways are required. + + Wymagane są przynajmniej + bramy. + + + + Add portal + Dodaj portal + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Ten obraz zmodyfikował ustawienia. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Dodaj obraz. + + + ACL authentication + Uwierzytelnianie ACL + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Inicjatory iSCSI + + + Initiator + Inicjator iSCSI + + + Client IQN + Klient IQN + + + Initiator IQN needs to be unique. + Inicjator IQN powinien być unikalny. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Nazwy użytkowników muszą mieć długość od 8 do 64 znaków i mogą zawierać jedynie litery, '.', '@', '-', '_' lub ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + Inicjator iSCSI należą do grupy. Obrazy będą skonfigurowane w grupie. + + + No items added. + Brak dodanych pozycji. + + + Add initiator + Dodaj inicjator iSCSI + + + Groups + Grupy + + + Group + Grupa + + + Add group + Dodaj grupę + + + [object Object] + [object Object] + + + RBD Configuration + Konfiguracja RBD + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Usuń wartość konfiguracji lokalnej. Wartość konfiguracji rodzica będzie odziedziczona i zostanie użyta zamiast tej. + + + The mininum value is 0 + Minimalna wartość wynosi 0. + + + Issues + Zagadnienia + + + Syncing + Synchronizacja + + + Ready + Gotowy + + + Edit pool mirror mode + Tryb edycji lustrzanego pula + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Aby edytować tryb lustrzanydla pula + + + , wybierz tryb z listy i kliknij + Zaktualizuj + . + + + + Mode + Tryb + + + Peer clusters must be removed prior to disabling mirror. + Sparowany klaster musi być usunięty przed wyłączeniem lustra. + + + + + pool mirror peer + + + sparowany pul lustrzany + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, wybierz, edytuj{Edytuj} inaczej {Dodaj} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + pul +lustra sparowanych atrybutów dla pula + + + i kliknij + Zatwierdź + . + + + + Cluster Name + Nazwa Klastra + + + The cluster name is not valid. + Nazwa klastra jest niepoprawna + + + CephX ID + CephX ID + + + CephX ID... + CephX ID... + + + The CephX ID is not valid. + ID CephX nie jest poprawne. + + + Monitor Addresses + Adres monitora + + + Comma-delimited addresses... + Adresy rozdzielane przecinkami... + + + The monitory address is not valid. + Adres monitora nie jest poprawny. + + + CephX Key + Klucz CephX + + + Base64-encoded key... + Klucz zakodowany w Base64... + + + CephX key must be base64 encoded. + Klucz CephX musi być zakodowany w Base64/ + + + Pools List + Lista puli + + + The name can only consist of alphanumeric characters, dashes and underscores. + Nazwa może składać się z alfanumerycznych znaków, kresek i podkreśleń. + + + The chosen erasure code profile name is already in use. + Wybrana nazwa profilu kodu kasowania jest już używana. + + + Plugin + Wtyczka + + + Data chunks (k) + Ramka danych (k) + + + Must be equal to or greater than 2. + Musi być większa bądź równa 2. + + + Coding chunks (m) + Kodowanie kawałka (m) + + + Must be equal to or greater than 1. + Musi być większa bądź równa 1. + + + Durability estimator (c) + Estymator trwałości (c) + + + Locality (l) + Lokalność (l) + + + Crush failure domain + Domena niepowodzenia Crush + + + Crush Locality + Lokalność Crusha + + + None + Nic + + + Technique + Technika + + + Packetsize + Rozmiar pakietu + + + Crush root + korzeń Crusha + + + Crush device class + urządzenie klasy Crush + + + any + którykolwiek + + + Directory + Katalog + + + The chosen Ceph pool name is already in use. + Wybrana nazwa Ceph pula jest już użyta. + + + Pool type + Typ pula + + + -- Select a pool type -- + -- Wybierz typ pula -- + + + Placement groups + Grupa umieszczenia + + + At least one placement group is needed! + Przynajmniej jedna grupa umieszczenia jest wymagana + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + Twój klaster nie obsługuje tylu PG. Skalkuluj proszę potrzebną ilość PG. + + + Calculation help + Pomoc obliczeniowa + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + Obecne ustawienia PG zostały policzone dla Ciebie, +powinieneś upewnić się czy te wartości Ci odpowiadają przed zatwierdzeniem. + + + Crush ruleset + zbiór zasad Crush + + + -- Select a crush rule -- + -- Wybierz zasadę Crush -- + + + Crush rule + zasada Crush + + + Crush steps + Kroki Crush + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + Zasada nie może być użyta w obecnym klastrze, gdyż ma +zbyt mało OSD-ków, żeby spełnić minimum OSD-ków wymaganych przez tę zasadę. + + + Replicated size + Replikowany rozmiar + + + Minimum: + + + Minimum: + + + + + Maximum: + + + Maximum: + + + + + The size specified is out of range. A value from + to + is valid. + + Sprecyzowany rozmiar jest poza zakresem. Wartość od + do + jest poprawna. + + + + Erasure code profile + Skasuj profil kodu. + + + -- No erasure code profile available -- + -- Brak profilu kasowania -- + + + -- Select an erasure code profile -- + -- Wybierz profil kodu wymazywania -- + + + EC Overwrites + EC Nadpisuje + + + Applications + Zastosowania + + + Compression + Kompresja + + + Algorithm + Algorytm + + + -- No erasure compression algorithm available -- + -- Brak algorytmu kompresji wymazywania -- + + + Minimum blob size + Minimalny rozmiar blob + + + e.g., 128KiB + np. 128 KB + + + Value should be greater than 0 + Wartość powinna być większa niż 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Maksymalny rozmiar blob + + + e.g., 512KiB + np. 512 KB + + + Value should be greater than the minimum blob size + Wartość powinna być większa niż minimalny rozmiar blob + + + Ratio + Stosunek + + + Compression ratio + Skompresowany stosunek + + + Value should be between 0.0 and 1.0 + Wartość powinna być pomiędzy 0.0, a 1.0 + + + It's not possible to create an RBD pool with '/' in the name. + Nie można stworzyć pula RBD z '/' w nazwie. + + + Please change the name or remove 'rbd' from the applications list. + Proszę zmienić nazwę albo usunąć 'rbd' z listy zastosowań. + + + Cache Tiers Details + Szczegóły poziomów pamięci podręcznej + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Sprawdź proszę + dokumentację +   +jak skonfigurować i i uruchomić zarządzanie funkcjami Dostępu obiektowego + + + + Daemons List + Lista demonów + + + Performance Counters + Liczniki wydajności + + + Loading bucket data... + Ładowanie wiadra danych + + + The bucket data could not be loaded. + Nie można załadować wiadra danych. + + + Id + Number ID + + + The value is not valid. + Wartość nie jest poprawna. + + + Owner + Właściciel + + + -- Select a user -- + -- Wybierz użytkownika -- + + + ID + ID + + + Index type + Typ indeksu + + + Placement rule + Zasada umieszczania + + + Marker + Znacznik + + + Maximum marker + Maksymalny znacznik + + + Version + Wersja + + + Master version + Główna wersja + + + Modification time + Czas modyfikacji + + + Zonegroup + Strefa + + + Bucket quota + kontyngent wiadra + + + Enabled + Uaktywniony + + + Maximum size + Maksymalny rozmiar + + + Unlimited + Nielimitowany + + + Maximum objects + Maksimum obiektów + + + -- Select a username -- + -- Wybierz nazwę użytkownika -- + + + Auto-generate key + Auto-generowany klucz + + + Access key + Klucz dostępu + + + Secret key + Tajny klucz + + + Email address + Adres email + + + Suspended + Zawieszony + + + System + System + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, wybierz, 0 {Nie} 1{Tak} } + + + Maximum buckets + Maksimum wiader + + + Subusers + pod-użytkownicy + + + Capabilities + Zdolności + + + User quota + Limit użytkownika + + + Show + Pokaż + + + Keys + Klucze + + + -- Select a type -- + -- wybierz typ -- + + + Permission + Pozwolenie + + + -- Select a permission -- + -- Wybierz pozwolenie -- + + + Subuser + pod-użytkownik + + + The chosen subuser ID is already in use. + Wybrane ID pod-użytkownika jest już użyte. + + + read, write + odczyt, zapis + + + full + pełny + + + Swift key + Szybki klucz + + + Auto-generate secret + Auto-generowany sekret + + + Loading user data... + Ładowanie danych użytkownika... + + + The user data could not be loaded. + Nie można załadować danych użytkownika. + + + The chosen user ID is already in use. + Wybrane ID użytkownika jest już użyte. + + + This is not a valid email address. + Ten adres email nie jest poprawny. + + + The chosen email address is already in use. + Wybrany adres email jest już użyty. + + + Max. buckets + Max. wiader + + + The entered value must be >= 0. + Podana wartość musi być >= 0 + + + S3 key + klucz S3 + + + There are no subusers. + Nie ma pod-użytkowników. + + + + + + + + + + + + + S3 + S3 (prosty serwis przechowywania) + + + There are no keys. + Nie ma kluczy. + + + + + + + + + + + + + Swift + Szybki + + + There are no capabilities. + Nie ma zdolności. + + + + + + + + + + + + + Unlimited size + Nielimitowany rozmiar + + + Max. size + Max. rozmiar + + + Unlimited objects + Nielimitowane obiekty + + + Max. objects + Max. obiektów + + + Current + Obecny + + + Updated discovery authentication + Zaktualizowane uwierzytelnianie wykrywania + + + There are no portals available. + Brak dostępnych portali. + + + There are no images available. + Nie ma dostępnych obrazów. + + + There are no images available. Please make sure you add an image to the target. + Nie ma dostępnych obrazów. Proszę się upewnić, że dodajesz obraz do obiektu docelowego. + + + There are no initiators available. Please make sure you add an initiator to the target. + Nie ma dostępnych inicjatorów iSCSI. Proszę upewnić się, że dodajesz inicjator iSCSI do obiektu docelowego. + + + target + target + + + Target + obiekt docelowy iSCSI + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + Stan + + + # Targets + # Targets + + + Read Bytes + Odczyt bajtów + + + Write Bytes + Zapis bajtów + + + Read Ops + Odczyt Ops + + + Write Ops + Zapis Ops + + + A/O Since + A/O Od + + + Instance + Instancja + + + Hostname + Nazwa hosta + + + Issue + Zagadnienie + + + Progress + Progres + + + Disabled + Wyłączony + + + Edit Mode + Tryb Edycji + + + Add Peer + Dodaj parowanie + + + Edit Peer + Edytuj parowanie + + + Delete Peer + Usuń parowanie + + + Leader + Lider + + + # Local + # Lokalny + + + # Remote + # Zdalny + + + mirror peer + lustrzane parowanie + + + Key + Klucz + + + RBD + RBD + + + Deep flatten + Głębokie spłaszczenie + + + Layering + Warstwowanie + + + Exclusive lock + Wyłączna blokada + + + Object map (requires exclusive-lock) + Mapa obiektów (wymaga wyłącznej blokady) + + + Journaling (requires exclusive-lock) + Kronikowanie (wymaga wyłącznej blokady) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Wycofywanie migawek RBD + + + Rollback + Wycofanie + + + RBD snapshot + migawka RBD + + + Deleted At + Usunięty o + + + id + id + + + type + typ + + + state + stan + + + version + wersja + + + Host + Host + + + root + administrator + + + Rank + Ranga + + + Daemon + Demon + + + Activity + Aktywność + + + Dentries + centrale + + + Inodes + i-węzły + + + Usage + Użycie + + + Standby daemons + Czuwanie demona + + + The value can be updated at runtime. + Wartość może być zaktualizowana w czasie wykonywania . + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + Demony/klienci nie pobierają tej wartości z +bazy danych skonfigurowanego monitora. Nie zezwalamy na ustawienie tej opcji przez 'konfiguracje ceph +ustaw.. '. Ta opcja powinna być skonfigurowana przez ceph.conf albo przez +terminal. + + + Option takes effect only during daemon startup. + Opcja działa tylko podczas startu demona. + + + Option only affects cluster creation. + Opcja dotyczy tylko tworzenia klastra. + + + Option only affects daemon creation. + Opcja tylko wpływa na tworzenie demona. + + + Updated config option + + + Zaktualizowana opcja konfiguracji + + + + + Service + Usługa + + + Current value + Obecna wartość + + + Editable + Edytowalny + + + Updated options for module " + ". + + Zaktualizowane opcje dla modułu &quot; + &quot;. + + + + Enable + Włączyć + + + Disable + Wyłączyć + + + Reconnecting, please wait ... + Ponowne łączenie, proszę czekać + + + Public Address + Adres publiczny + + + Open Sessions + Otwarte sesje + + + No In + Nie w + + + OSDs that were previously marked out will not be marked back in when they start + OSD-ki, które zostały oznaczone jako poza, nie będą oznaczone ponownie jako w gdy zostaną uruchomion + + + No Out + Nie poza + + + OSDs will not automatically be marked out after the configured interval + OSD-ki nie będą automatycznie oznaczone jako poza po konfiguracji interwału + + + No Up + Nie powstały + + + OSDs are not allowed to start + OSD-ki nie mogą startować + + + No Down + Nie upadły + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + Raport z niepowodzenia OSD jest ignorowany, także monitory nie oznaczą OSD jako upadłego. + + + Pause + Pauza + + + Pauses reads and writes + Pauzuje czytanie i zapisywanie + + + No Scrub + Nie szoruj + + + Scrubbing is disabled + Szorowanie jest wyłączone + + + No Deep Scrub + Nie ma głębokiego szorowania + + + Deep Scrubbing is disabled + Głębokie szorowanie jest wyłączone + + + No Backfill + Brak zasypywania + + + Backfilling of PGs is suspended + Zasypywanie PG jest zawieszone + + + No Recover + Nie przywrócono + + + Recovery of PGs is suspended + Przywrócenie PGy jest zawieszone + + + Bitwise Sort + Sortuj bitowo + + + Use bitwise sort + Użyj sortowania bitowego + + + Purged Snapdirs + Usuń snap katalogi + + + OSDs have converted snapsets + OSD-ki zmieniły snapsety + + + Recovery Deletes + Odzyskaj usunięte + + + Deletes performed during recovery instead of peering + Podczas zdrowienia zastosowano usunięcie zamiast parowania + + + PG Log Hard Limit + Twardy limit logów PG + + + Puts a hard limit on pg log length + Ustawia twardy limit na długość logów PG + + + Updated OSD Flags + Zaktualizowane flagi OSD-ków + + + out + poza + + + in + w + + + down + upadły + + + Mark + Zaznacz + + + OSD lost + Stracony OSD + + + marked lost + Zaznaczony jako stracony + + + Purge + Czyść + + + OSD + OSD-ik + + + purged + Oczyszczony + + + destroy + Zniszcz + + + destroyed + Zniszczony + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + PG-y + + + Read bytes + Czytanie bajtów + + + Writes bytes + Zapis bajtów + + + Read ops + Czytanie ops + + + Write ops + Zapis ops + + + Mark OSD + + + Zaznacz OSD + + + + + Mark + + + Zaznacz + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Max zasypywanie + + + Recovery Max Active + Max aktywność wyzdrowienia + + + Recovery Max Single Start + Max pojedynczy start wyzdrowienia + + + Recovery Sleep + Uśpienie wyzdrowienia + + + Custom + Zwyczaj + + + Updated OSD recovery speed priority " + " + + Zaktualizowano prędkość wyzdrowienia OSD priorytet &quot; + &quot; + + + + + was initialized in the following OSD: + + + + został zainicjalizowany w następującym OSD: + + + + + Create silence + Create silence + + + Job + Praca + + + Severity + surowość + + + Started + Wystartowany + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Zaktualizowany + + + Ends + Ends + + + Silence + Silence + + + Used + Użyty + + + Avail. + Dostępny + + + Clean + Czyść + + + Working + Działający + + + Warning + Ostrzeżenie + + + Unknown + Nieznany + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + Podniesiony + + + no filesystems + brak systemów plików + + + active + aktywny + + + standby + Rezerwa + + + n/a + niedostępny + + + active daemon + aktywny demon + + + quorum + kworum + + + The NFS Ganesha service is not configured. + Usługa NFS Ganesha nie jest skonfigurowana + + + Transport + Transport + + + CephFS User + Użytkownik CephFS + + + CephFS Filesystem + system plików CephFS + + + (inherited from global config) + (Odziedziczyło z globalnej konfiguracji) + + + inherited from global config + Odziedziczyło z globalnej konfiguracji + + + -- Select what kind of user id squashing is performed -- + -- Wybierz, jakiego rodzaju identyfikacja użytkownika ma być przeprowadzana -- + + + There are no daemons available. + Brak dostępnym demonów + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Tryb pamięci podręcznej + + + Min Evict Age + Min wiek eksmisji + + + Min Flush Age + Min wiek wyrównania + + + Target Max Bytes + Max bajtów obiektu docelowego + + + Target Max Objects + Max obiektów docelowych + + + No applications added + Nie dodano żadnego zastosowania + + + Applications limit reached + Osiągnięto limit zastosowań + + + A pool can only have up to four applications definitions. + Pul może mieć maksymalnie 4 definicje aplikacji. + + + Allowed characters '_a-zA-Z0-9' + Dozwolone znaki '_a-zA-Z0-9' + + + Maximum length is 128 characters + Maksymalna długość wynosi 128 znaków + + + Filter or add applications + Filtruj lub dodaj zastosowanie + + + Add application + Dodaj zastosowanie + + + pool + pool + + + erasure code profile + skasuj profil kodu + + + Replica Size + Rozmiar repliki + + + Last Change + Ostatnia zmiana + + + Erasure Coded Profile + Skasuj profil zakodowany + + + Crush Ruleset + Zbiór zasad Crush + + + Write bytes + Zapis bajtów + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + wiadro + + + Updated Object Gateway bucket " + " + + Zaktualizowano wiadro dostępu obiektowego &quot; + &quot; + + + + Created Object Gateway bucket " + " + + Stworzono wiadro dostępu obiektowego &quot; + &quot; + + + + buckets + Wiadra + + + capability + capability + + + user + użytkownik + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Zaktualizowano użytkownika dostępu obiektowego &quot; + &quot; + + + + Created Object Gateway user " + " + + Stworzono użytkownika dostępu obiektowego&quot; + &quot; + + + + users + użytkownicy + + + Swift Key + Swift Key + + + Scope + Zakres + + + Read + Czytaj + + + Create + Stwórz + + + role + role + + + Created role ' + ' + + Utwórz rolę ' + ' + + + + Updated role ' + ' + + Zaktualizuj rolę ' + ' + + + + System Role + System roli + + + Deleted role ' + ' + + Usuń rolę ' + ' + + + + Created user " + " + + Stwórz użytkownika &quot; + &quot; + + + + Update user + Zaktualizuj użytkownika + + + Continue + Kontynuuj + + + You were automatically logged out because your roles have been changed. + Zostałeś automatycznie wylogowany, ponieważ zostały zmienione twoje role. + + + Updated user " + " + + Zaktualizowano użytkownika &quot; + &quot; + + + + Deleted user " + " + + Usunięto użytkownika &quot; + &quot; + + + + Failed to delete user " + " + + Nie udało się usunąć użytkownika &quot; + &quot; + + + + You are currently logged in as " + ". + + Jesteś obecnie zalogowany jako&quot; + &quot;. + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Każdy obiekt jest podzielony na części fragmentów danych, każdy jest przechowywany na innym OSD. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Oblicz porcje kodu dla każdego obiektu i przechowuj je na różnych OSD. + Liczba fragmentów kodujących to również liczba OSD, które mogą zostać wyłączone bez utraty danych. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Wtyczka jerasure jest najbardziej uniwersalną i elastyczną wtyczką, + jest to również domyślne ustawienie dla pui kodowanych przez Ceph. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + Bardziej elastyczną techniką jest reed_sol_van: wystarczy ustawić k + oraz m. Technika cauchy_good może być szybsza, ale musisz wybrać rozmiar pakietu + ostrożnie. Wszystkie reed_sol_r6_op, liberation, blaum_roth, liber8tion są odpowiednikami RAID6 + w tym sensie, że mogą być skonfigurowane tylko z m = 2. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + Kodowanie będzie wykonywane na pakietach o rozmiarze bajtów naraz. + Wybór odpowiedniego rozmiaru pakietu jest trudny. + Dokumentacja jerasure zawiera obszerne informacje na ten temat. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + Z wtyczką jerasure, gdy obiekt zakodowany przy użyciu skasowania jest przechowywany na + wielu OSD-kach, odzyskiwanie po utracie jednego OSD wymaga odczytu ze wszystkich pozostałych. + Na przykład, jeśli konfiguracja skryptu ma wartość k = 8 ,m = 4 i l=4, utrata jednego OSD wymaga odczytu + od jedenastu innych do naprawy. + + Wtyczka kodu wymazywania lrc tworzy fragmenty o parzystości lokalnej, aby móc je odzyskać + mniej OSD. Na przykład, jeśli lrc jest skonfigurowane z k = 8, m = 4 i l = 4, zostanie utworzony + dodatkowy fragment parzystości na każde cztery OSD. Gdy jeden OSD zostanie utracone, może to być + odzyskane tylko z czterema OSD zamiast jedenastu. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Grupuj fragmenty kodu i danych w zestawy lokalizacji wielkości. Na przykład, + dla k = 4 i m = 2, gdy lokalność = 3 tworzone są dwie grupy po trzy. Każdy zestaw może + odzyskać bez czytania kawałków z innego zestawu. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + Typ wiadra CRUSH, w którym zdefiniowano każdy zestaw porcji + przez l zostaną zapisane. Na przykład, jeśli jest ustawiony na rack, każda grupa l porcji będzie + umieszczona w innym raku. Służy do utworzenia kroku reguły CRUSH, takiego jak krok wyboru + racka. Jeśli nie jest ustawiony, nie ma takiego grupowania. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + Wtyczka isa zawiera bibliotekę ISA. Działa tylko na procesorach Intel. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + Wtyczka ISA jest dostępna w dwóch formach Reed Solomon. + Jeśli ustawiono reed_sol_van, jest to Vandermonde, jeśli ustawiono cauchy, to jest to Cauchy. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + Wtyczka shec zawiera wiele bibliotek SHEC. + Pozwala ceph odzyskać dane bardziej efektywnie niż kody Reeda Solomona. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + Liczba kawałków parzystości, z których każdy zawiera każdą porcję danych w swoim zakresie obliczeń. Liczba jest używana jako estymator trwałości. Na przykład, jeśli c = 2, + 2 OSD można wyłączyć bez utraty danych. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + Nazwa wiadra crush jest użyte do pierwszego kroku reguły CRUSH. +Na przykład krok jest domyślny. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Upewnij się, że żadne dwie porcje nie znajdują się w wiadrze z tą samą awarią + domeny. Na przykład, jeśli domena awarii jest hostem, nie zostaną na niej zapisane dwie porcje + hosta. Służy do utworzenia kroku reguły CRUSH, takiego jak krok wyboru hosta. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Ogranicz umieszczanie do urządzeń określonej klasy + (np. ssd lub hdd), używając nazw klas urządzeń zgniatających na mapie CRUSH. + + + Set the directory name from which the erasure code plugin is loaded. + Ustaw nazwę katalogu, z którego ładowana jest wtyczka kodu kasowania. + + + Allows all operations + Dozwolone są wszystkie operacje + + + Allows only operations that do not modify the server + Dozwolone są operacje, które nie modyfikują serweru + + + Does not allow read or write operations, but allows any other operation + Operacje odczytu i zapisu są zakazane, wszystkie inne dozwolone + + + Does not allow read, write, or any operation that modifies file attributes or directory content + Operacje odczytu i zapisu, oraz wszystkie operacje modyfikujące atrybuty albo katalogi są zakazane  + + + Allows no access at all + Brak dostępu w ogóle + + + -- Select the priority -- + -- wybierz priorytet -- + + + Low + Niski + + + High + Wysoki + + + Last 5 minutes + Ostatnie 5 minut + + + Last 15 minutes + Ostatnie 15 minut + + + Last 30 minutes + Ostatnie 30 minut + + + Last 1 hour (Default) + Ostatnia 1 godzina (domyślnie) + + + Last 3 hours + Ostatnie 3 godziny + + + Last 6 hours + Ostatnie 6 godzin + + + Last 12 hours + Ostatnie 12 godzin + + + Last 24 hours + Ostatnie 24 godziny + + + Yesterday + Wczoraj + + + Today + Dzisiaj + + + Today so far + Do tej pory dzisiaj + + + Day before yesterday + Przedwczoraj + + + Last 2 days + Ostatnie 2 dni + + + This day last week + Tego dnia tydzień temu + + + Previous week + Poprzedni tydzień + + + This week + Ten tydzień + + + This week so far + Do tej pory w tym tygodniu + + + Last 7 days + Ostatnie 7 dni + + + Previous month + Poprzedniego miesiąca + + + This month + ten miesiąc + + + This month so far + Do tej pory w tym miesiącu + + + Last 30 days + Ostatnie 30 dni + + + Last 90 days + Ostatnie 90 dni + + + Last 6 months + Ostatnie 6 miesięcy + + + Last 1 year + Ostatni 1 rok + + + Previous year + Poprzedniego roku + + + This year + Bieżącego roku + + + This year so far + Do tej pory bieżącego roku + + + Last 2 years + Ostatnie 2 lata + + + Last 5 years + Ostatnie 5 lat + + + Information + Informacja + + + No items selected. + Nie wybrano żadnej pozycji + + + Deselect item to select again + Odznacz pozycję, żeby wybrać ponownie + + + Selection limit reached + Osiągnięto limit wyboru. + + + Filter tags + Filtr tagów. + + + Add badge + Dodaj odznakę + + + There are no items available. + Brak dostępnych pozycji. + + + Add + Dodaj + + + Remove + Remove + + + Clone + Sklonuj + + + Copy + Kopia + + + Deep Scrub + Szoruj głęboko + + + Destroy + Zniszcz + + + Flatten + Spłaszcz + + + Mark Down + zaznacz jako upadły + + + Mark In + Zaznacz jako w + + + Mark Lost + Zaznacz jako stracony + + + Mark Out + Zaznacz jako poza + + + Protect + Zabezpiecz + + + Rename + Zmień nazwę + + + Restore + Przywróć + + + Move to Trash + Przenieś do kosza + + + Unprotect + Odbezpiecz + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Usunięty + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Sklonowano + + + Copied + Skopiowano + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + Tak + + + No + Nie + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Jakość serwisu + + + BPS Limit + Limit BPS + + + The desired limit of IO bytes per second. + Pożądany limit IO bajtów na sekundę. + + + IOPS Limit + Limit IOPS + + + The desired limit of IO operations per second. + Pożądany limit operacji IO na sekundę. + + + Read BPS Limit + limit odczytu BPS + + + The desired limit of read bytes per second. + Pożądany limit odczytu bajtów na sekundę. + + + Read IOPS Limit + limit odczytu IOPS + + + The desired limit of read operations per second. + Pożądany limit operacji odczytu na sekundę. + + + Write BPS Limit + Limit zapisu BPS + + + The desired limit of write bytes per second. + Pożądany limit zapisu bajtów na sekundę. + + + Write IOPS Limit + Limit zapisu IOPS + + + The desired limit of write operations per second. + Pożądany limit operacji zapisu na sekundę. + + + BPS Burst + Wiązka BPS + + + The desired burst limit of IO bytes. + Żądana granica serii IO bajtów. + + + IOPS Burst + Wiązka IOPS + + + The desired burst limit of IO operations. + Żądana granica serii operacji IO. + + + Read BPS Burst + Odczyt wiązki BPS + + + The desired burst limit of read bytes. + Żądana granica serii odczytanych bajtów. + + + Read IOPS Burst + Odczyt wiązki IOPS + + + The desired burst limit of read operations. + Żądana granica serii operacji odczytu. + + + Write BPS Burst + Zapis wiązki BPS + + + The desired burst limit of write bytes. + Żądana granica serii bajtów zapisu. + + + Write IOPS Burst + Zapis wiązki IOPS + + + The desired burst limit of write operations. + Żądana granica serii operacji zapisu. + + + Failed to + + + + Nie powiodło się + + + + + + Executing + Wykonywanie + + + execute + Wykonaj + + + Executed + Wykonany + + + unknown task + Nieznane zadanie + + + Creating + Tworzenie + + + create + Utwórz + + + Updating + Aktualizowanie + + + update + Zaktualizuj + + + Deleting + Usuwanie + + + delete + Usuń + + + RBD ' + ' + + urządzenie blokowe Rados ' + '  + + + + RBD snapshot ' + ' + + migawka RBD ' + '  + + + + mirror mode for pool ' + ' + + tryb lustrzany dla pula ' + ' + + + + mirror peer for pool ' + ' + + Lustrzane parowanie dla pula ' + ' + + + + all dashboards + all dashboards + + + Name is already used by + . + + Nazwa jest już użyta przez + . + + + + Name is already used by + . + + Nazwa jest już używana przez + . + + + + Name is already used by + . + + Nazwa jest już używana przez + . + + + + + contains snapshots. + + + zawiera migawkę. + + + + Cloning + Klonowanie + + + clone + Sklonuj + + + Snapshot of + must be protected. + + Migawka +   musi być zabezpieczona. + + + + Copying + Kopiowanie + + + copy + Kopiuj + + + Flattening + Spłaszczanie + + + flatten + Spłaszcz + + + Flattened + Spłaszczony + + + Name is already used by + . + + Nazwa już jest używana przez + . + + + + Cannot unprotect + because it contains child images. + + Nie można zdjąć zabezpieczenia + , ponieważ zawiera pokrewne obrazy. + + + + Cannot delete + because it's protected. + + Nie można usunąć + , ponieważ jest zabezpieczony. + + + + Rolling back + Wycofywanie + + + rollback + Wycofanie + + + Rolled back + Wycofaj + + + Moving + Przenoszenie + + + move + Przenieś + + + Moved + Przeniesiono + + + image ' + ' to trash + + Obraz ' + ' przenieś do kosza + + + + Could not find image. + Nie znaleziono obrazu. + + + Restoring + Przywracanie + + + restore + Przywróć + + + Restored + Przywrócony + + + image ' + ' into ' + ' + + Obraz ' + ' w ' + ' + + + + Image name ' + ' is already in use. + + Nazwa obrazu ' + ' jest już używana. + + + + image ' + ' + + Obraz ' + '  + + + + Purging + oczyszczać + + + purge + oczyść + + + Purged + Oczyszczony + + + all pools + Wszystkie pule + + + images from + + + Obraz z + + + + + Cannot disable mirroring because it contains a peer. + Nie można wyłączyć lustrzenia ponieważ zawiera parowanie. + + + pool ' + ' + + pul ' + ' + + + + erasure code profile ' + ' + + skasuj profil kodu ' + ' + + + + target ' + ' + + docelowy ' + ' + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf new file mode 100644 index 00000000..816a0976 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.pt-BR.xlf @@ -0,0 +1,4366 @@ + + + + + Toggle navigation + Alternar navegação + + + Dashboard + Painel de controle + + + Cluster + Cluster + + + Hosts + Hosts + + + Monitors + Monitores + + + OSDs + OSDs + + + Configuration + Configuração + + + CRUSH map + Mapa CRUSH + + + Manager modules + Módulos do gerenciador + + + Logs + Registros + + + Alerts + Alertas + + + Silences + Silences + + + Pools + Pools + + + Block + Bloco + + + Images + Imagens + + + Mirroring + Espelhamento + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + Sistemas de arquivos + + + Object Gateway + Gateway de Objetos + + + Daemons + Daemons + + + Users + Usuários + + + Buckets + Compartimentos + + + Retrieving data + for + + + . Please wait... + + Recuperando dados + de + + + . Aguarde... + + + + Displaying previously cached data + + for + + + . + + Exibindo dados armazenados em cache anteriormente + + para + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Não foi possível carregar os dados + de + + + . + Verifique a saúde do cluster. + + + + Back + Voltar + + + Select a Language + Selecionar Idioma + + + Loading panel data... + Carregando dados do painel... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + Consulte a + documentação + sobre como + configurar e habilitar a funcionalidade de monitoramento. + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + O Painel de Controle do Grafana não existe. Consulte a + documentação + sobre como + adicionar painéis de controle ao Grafana. + + + + Grafana Time Picker + Seletor de Horário do Grafana + + + Reset Settings + Redefinir Configurações + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + Falha ao carregar dados. + + + selected + selecionado(s) + X selected + + + found + encontrado(s) + X found + + + total + total + X total + + + Edit + Editar + + + Name + Nome + + + Description + Descrição + + + Long description + Descrição extensa + + + Default + Padrão + + + Daemon default + Padrão do daemon + + + Services + Serviços + + + Values + Valores + + + The entered value is too high! It must not be greater than + . + + O valor inserido é muito alto! Ele não pode ser maior do que + . + + + + The entered value is too low! It must not be lower than + . + + O valor inserido é muito baixo! Ele não deve ser menor do que + . + + + + Save + Salvar + + + CRUSH map viewer + Visualizador de mapa CRUSH + + + Hosts List + Lista de Hosts + + + Overall Performance + Desempenho Geral + + + No entries found + Nenhuma entrada encontrada + + + Cluster Logs + Registros do Cluster + + + Audit Logs + Registros de Auditoria + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + Carregando configuração... + + + The configuration could not be loaded. + Não foi possível carregar a configuração. + + + Edit Manager module + Editar módulo do gerenciador + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + O valor inserido não é um UUID válido. Ex.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + O valor inserido precisa ser um endereço IP válido. + + + This field is required. + Este campo é obrigatório. + + + The entered value is too high! It must be lower or equal to + . + + O valor inserido é muito alto! Ele deve ser menor ou igual a + . + + + + The entered value is too low! It must be greater or equal to + . + + O valor inserido é muito baixo! Ele deve ser maior ou igual a + . + + + + The entered value needs to be a number. + O valor inserido precisa ser um número. + + + The entered value needs to be a number or decimal. + O valor inserido precisa ser um número ou decimal. + + + Update + Atualizar + + + Status + Status + + + Cluster ID + ID do Cluster + + + monmap modified + monmap modificado + + + monmap epoch + época de monmap + + + quorum con + quorum con + + + quorum mon + quorum mon + + + required con + con obrigatório + + + required mon + mon obrigatório + + + In Quorum + No Quorum + + + Not In Quorum + Não está no Quorum + + + Cancel + Cancelar + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + Deseja realmente + o(a) + selecionado(a)? + + + + Yes, I am sure. + Sim, desejo. + + + Cluster-wide OSD Flags + Flags OSD de todo o Cluster + + + Submit + Enviar + + + + + + + + + + + form title + + + Advanced... + Avançado... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + Prioridade de Recuperação de OSD + + + Priority + Prioridade + + + Customize priority values + Personalizar valores de prioridade + + + This field is required! + Este campo é obrigatório! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + O valor inserido é muito alto! Ele não pode ser maior do que + . + + + + The entered value is too low! It must not be lower than + . + + O valor inserido é muito baixo! Ele não deve ser menor do que + . + + + + Reweight OSD + Reponderar OSD + + + The value needs to be between 0 and 1. + O valor precisa ser entre 0 e 1. + + + Reweight + Reponderar + + + OSDs + Scrub + + Remoção de OSDs + + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {Profundo } } + + + You are about to apply a + scrub to + the OSD + + + . + + Você está prestes a aplicar uma + remoção ao + OSD + + + . + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {profundo} } + + + OSDs List + Lista de OSDs + + + + OSD + + will be marked + + + if you proceed. + + + OSD + + será marcado como + + + se você continuar. + + + + The OSD is not safe to destroy! + Não é seguro destruir o OSD! + + + + OSD + + will be + + + if you proceed. + + + OSD + + será + + + se você continuar. + + + + Details + Detalhes + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + Valor + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + Fechar + + + Delete + Excluir + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + Saúde + + + Statistics + Estatísticas + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + Consulte a + documentação + + sobre como configurar e habilitar a funcionalidade de gerenciamento do NFS Ganesha. + + + + Clients + Clientes + + + Any client can access + Qualquer cliente pode acessar + + + Addresses + Endereços + + + Required field + Campo obrigatório + + + Must contain one or more comma-separated values + Deve conter um ou mais valores separados por vírgula + + + For example: + Por exemplo: + + + Access Type + Tipo de Acesso + + + Squash + Executar Squash + + + Add clients + Adicionar clientes + + + Loading... + Carregando... + + + -- No cluster available -- + -- Não há clusters disponíveis -- + + + -- Select the cluster -- + -- Selecionar cluster -- + + + Add daemon + Adicionar daemon + + + Storage Backend + Backend de Armazenamento + + + -- No data pools available -- + -- Não há pools de dados disponíveis -- + + + -- Select the storage backend -- + -- Selecionar backend de armazenamento -- + + + Object Gateway User + Usuário do Gateway de Objetos + + + -- No users available -- + -- Não há usuários disponíveis -- + + + -- Select the object gateway user -- + -- Selecionar usuário do gateway de objetos -- + + + CephFS User ID + ID de Usuário do CephFS + + + -- No clients available -- + -- Não há clientes disponíveis -- + + + -- Select the cephx client -- + -- Selecionar cliente do cephx -- + + + CephFS Name + Nome do CephFS + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + Rótulo de Segurança + + + Enable security label + Habilitar rótulo de segurança + + + CephFS Path + Caminho do CephFS + + + Path need to start with a '/' and can be followed by a word + O caminho precisa começar com '/' e pode ser seguido de uma palavra + + + New directory will be created + Novo diretório será criado + + + Path + Caminho + + + Path can only be a single '/' or a word + O caminho pode ser apenas uma '/' ou uma palavra + + + New bucket will be created + Novo compartimento será criado + + + NFS Protocol + Protocolo NFS + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + Tag NFS + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + Acesso alternativo às montagens do + NFS v3 + (não deve ter / à esquerda). + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + Clientes não podem montar subdiretórios (ou seja, se Tag = foo, o cliente não poderá montar foo/baz). + + + By using different Tag options, the same Path may be exported multiple times. + Ao usar opções diferentes de Tag, o mesmo Caminho pode ser exportado várias vezes. + + + Pseudo + Pseudo + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + A posição que esta exportação de + NFS v4 + ocupa + no + Pseudo FS + (deve ser exclusiva). + + + + By using different Pseudo options, the same Path may be exported multiple times. + Ao usar opções diferentes de Pseudo, o mesmo Caminho pode ser exportado várias vezes. + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- Não há tipos de acesso disponíveis -- + + + -- Select the access type -- + -- Selecionar tipo de acesso -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- Não há squashes disponíveis -- + + + --Select what kind of user id squashing is performed -- + --Selecionar que tipo de squash de ID de usuário será executado -- + + + Transport Protocol + Protocolo de Transporte + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + Bem-vindo ao Ceph! + The welcome message on the login page + + + Username is required + Nome de usuário é obrigatório + + + Password is required + Senha é obrigatória + + + Login + Login + + + Sorry, the user does not exist in Ceph. + O usuário não existe no Ceph. + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + Retorne à + Página de Login + . Seu logout será efetuado do Provedor de Identidade quando você repetir o login. + + + + Forbidden + Proibido + + + Sorry, you are not allowed to see what you were looking for. + Você não tem permissão para ver o que está procurando. + + + Sorry, we could not find what you were looking for + Não foi possível localizar o que você está procurando + + + Remove all + Remover tudo + + + Recent Notifications + Notificações Recentes + + + There are no background tasks. + Não há tarefas em segundo plano. + + + Background Tasks + Tarefas em Segundo Plano + + + Help + Ajuda + + + Documentation + Documentação + + + API + API + + + About + Sobre + + + Dashboard Settings + Configurações do Painel de Controle + + + User management + Gerenciamento de usuários + + + Logged in user + Usuário que efetuou login + + + Signed in as + + + + + Efetuar login como + + + + + + + Sign out + Efetuar logout + + + Name... + Nome... + + + The chosen name is already in use. + O nome escolhido já está em uso. + + + Description... + Descrição... + + + Permissions + Permissões + + + Roles + Funções + + + Username + Nome de usuário + + + Password + Senha + + + Confirm password + Confirmar senha + + + Password confirmation doesn't match the password. + A confirmação de senha não corresponde à senha. + + + Full name + Nome completo + + + Email + E-mail + + + Invalid email. + E-mail inválido. + + + You are about to remove "user read / update" permissions from your own user. + Você está prestes a remover as permissões de "leitura/atualização de usuário" do seu próprio usuário. + + + If you continue, you will no longer be able to add or remove roles from any user. + Se você continuar, não poderá mais adicionar ou remover funções de nenhum usuário. + + + Are you sure you want to continue? + Deseja realmente continuar? + + + Performance counters not available + Contadores de desempenho não disponíveis + + + Attributes (OSD map) + Atributos (mapa OSD) + + + Metadata not available + Metadados não disponíveis + + + Metadata + Metadados + + + Performance counter + Contador de desempenho + + + Histogram not available: + + + Histograma não disponível: + + + + + Writes + Gravações + + + Reads + Leituras + + + Histogram + Histograma + + + Performance Details + Detalhes de Desempenho + + + Current values + Valores atuais + + + Type + Tipo + + + Min + Mín. + + + Max + Máx. + + + Flags + Flags + + + Source + Origem + + + Level + Nível + + + Can be updated at runtime (editable) + Pode ser atualizado em tempo de execução (editável) + + + Tags + Tags + + + Enum values + Valores de enum + + + See also + Consulte também + + + Cluster Status + Status do Cluster + + + Manager Daemons + Daemons do Gerenciador + + + Object Gateways + Gateways de Objetos + + + Metadata Servers + Servidores de Metadados + + + iSCSI Gateways + Gateways iSCSI + + + Client IOPS + IOPS do Cliente + + + Client Throughput + Throughput do Cliente + + + Client Read/Write + Leitura/Gravação do Cliente + + + Recovery Throughput + Throughput de Recuperação + + + Scrub + Remoção + + + Performance + Desempenho + + + Raw Capacity + Capacidade Bruta + + + Objects + Objetos + + + PGs per OSD + PGs por OSD + + + PG Status + Status do PG + + + Capacity + Capacidade + + + + + See + Logs + for more details. + + + + Consulte os + Registros + para obter mais detalhes. + + + + Ranks + Posições + + + MDS performance counters + MDS performance counters + + + Clients: + + + Clientes: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + Mover imagem para o lixo + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + Para mover + + / + + para o lixo, + clique em + Mover Imagem + . Se preferir, escolha uma data de vencimento. + + + + Protection expires at + Vencimento da proteção em + + + NOT PROTECTED + NÃO PROTEGIDO + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + Formato de data incorreto. Use "AAAA-MM-DD HH:mm:ss". + + + Protection has already expired. Please pick a future date or leave it empty. + A proteção já venceu. Escolha uma data no futuro ou deixe-a vazia. + + + Move Image + Mover Imagem + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + Visão geral + + + Targets + Destinos + + + Discovery Authentication + Autenticação de Descoberta + + + User + Usuário + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Os nomes de usuário devem ter entre 8 e 64 caracteres e + apenas podem conter letras, '.', '@', '-', '_' ou ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + Usuário Mútuo + + + Mutual Password + Senha Mútua + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + Consulte a + documentação + + sobre como configurar e habilitar a funcionalidade de gerenciamento de Destinos iSCSI. + + + + Available information: + Informações disponíveis: + + + iSCSI Targets not available + Destinos iSCSI não disponíveis + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + Disponível apenas para imagens RBD com + diff rápido + habilitado + + + + Pool + Pool + + + Data Pool + Pool de Dados + + + Created + Criado + + + Size + Tamanho + + + Object size + Tamanho do objeto + + + Features + Recursos + + + Provisioned + Aprovisionado + + + N/A + N/A + + + Total provisioned + Total aprovisionado + + + Striping unit + Unidade de distribuição + + + Striping count + Total de distribuições + + + Parent + Pai + + + Block name prefix + Prefixo do nome do bloco + + + Order + Ordem + + + Snapshots + Instantâneos + + + Image + Imagem + + + This setting overrides the global value + Esta configuração substitui o valor global + + + Global + Global + + + This is the global value. No value for this option has been set for this image. + Este é o valor global. Nenhum valor para esta opção foi definido para esta imagem. + + + + from + + + from + + + + '/' and '@' are not allowed. + '/' e '@' não são permitidos. + + + -- No rbd pools available -- + -- Não há pools de RBD disponíveis -- + + + -- Select a pool -- + -- Selecionar pool -- + + + Use a dedicated data pool + Usar pool de dados dedicado + + + Data pool + Pool de dados + + + Dedicated pool that stores the object-data of the RBD. + Pool dedicado que armazena os dados de objetos do RBD. + + + e.g., 10GiB + ex. 10 GiB + + + You have to increase the size. + Você precisa aumentar o tamanho. + + + Advanced + Avançado + + + Striping + Distribuição + + + Stripe unit + Unidade de distribuição + + + -- Select stripe unit -- + -- Selecionar unidade de distribuição -- + + + This field is required because stripe count is defined! + Este campo é obrigatório porque o total de distribuições foi definido! + + + Stripe unit is greater than object size. + A unidade de distribuição é maior do que o tamanho do objeto. + + + Stripe count + Total de distribuições + + + This field is required because stripe unit is defined! + Este campo é obrigatório porque a unidade de distribuição foi definida! + + + Stripe count must be greater than 0. + O total de distribuições deve ser maior do que 0. + + + + RBD Snapshot + + + Instantâneo do RBD + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {Renomear} other {Criar} } + + + + Snapshot + + + Instantâneo + + + + PROTECTED + PROTEGIDO + + + UNPROTECTED + NÃO PROTEGIDO + + + You are about to rollback + Você está prestes a fazer rollback + + + Purge Trash + Purgar Lixo + + + To purge, select one or All images and click + Para purgar, selecione uma ou Todas as imagens e clique em + + + Pool: + Pool: + + + Pool name... + Nome do pool... + + + All + Tudo + + + Restore Image + Restaurar Imagem + + + To restore + Para restaurar + + + type the image's new name and click + digite o novo nome da imagem e clique em + + + New Name + Novo Nome + + + Expired at + Venceu em + + + Protected until + Protegido até + + + This image is protected until + . + + Esta imagem está protegida até + . + + + + Trash + Lixo + + + iSCSI Topology + Topologia iSCSI + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + Não costuma ser necessário mudar o valor padrão destes parâmetros. + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + Configurações + + + Backstore + Backstore + + + Confirm + Confirmar + + + Advanced Settings + Configurações Avançadas + + + Target IQN + IQN de Destino + + + IQN has wrong pattern. + IQN tem padrão incorreto. + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + Um IQN tem a seguinte notação 'iqn.$year-$month.$reversedAddress:$definedName' + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + Por exemplo: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + Mais informações + + + This target has modified advanced settings. + Este destino tem configurações avançadas modificadas. + + + Portals + Portais + + + At least + gateways are required. + + Pelo menos + gateways são necessários. + + + + Add portal + Adicionar portal + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + Esta imagem tem configurações modificadas. + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + Adicionar imagem + + + ACL authentication + Autenticação ACL + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + Iniciadores + + + Initiator + Iniciador + + + Client IQN + IQN do Cliente + + + Initiator IQN needs to be unique. + O IQN do Iniciador precisa ser exclusivo. + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Os nomes de usuário devem ter entre 8 e 64 caracteres e + apenas podem conter letras, '.', '@', '-', '_' ou ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + O iniciador pertence a um grupo. As imagens serão configuradas no grupo. + + + No items added. + Nenhum item adicionado. + + + Add initiator + Adicionar iniciador + + + Groups + Grupos + + + Group + Grupo + + + Add group + Adicionar grupo + + + [object Object] + [object Object] + + + RBD Configuration + Configuração de RBD + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + Remova o valor de configuração local. No lugar dele, o valor de configuração pai será herdado e usado. + + + The mininum value is 0 + O valor mínimo é 0 + + + Issues + Problemas + + + Syncing + Sincronizando + + + Ready + Pronto + + + Edit pool mirror mode + Editar modo de espelho do pool + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + Para editar o modo de espelho do pool  + + + , selecione o novo modo na lista e clique em  + Atualizar + . + + + + Mode + Modo + + + Peer clusters must be removed prior to disabling mirror. + Clusters de peer devem ser removidos antes de desabilitar o espelho. + + + + + pool mirror peer + + + + peer de espelho do pool + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {Editar} other {Adicionar} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + os atributos + de peer de espelho do pool + + + e clique em + Enviar + . + + + + Cluster Name + Nome do Cluster + + + The cluster name is not valid. + O nome do cluster não é válido. + + + CephX ID + ID do CephX + + + CephX ID... + ID do CephX... + + + The CephX ID is not valid. + O ID do CephX não é válido. + + + Monitor Addresses + Endereços do Monitor + + + Comma-delimited addresses... + Endereços delimitados por vírgula... + + + The monitory address is not valid. + O endereço de monitoria não é válido. + + + CephX Key + Chave do CephX + + + Base64-encoded key... + Chave codificada com base64... + + + CephX key must be base64 encoded. + A chave do CephX deve ser codificada com base64. + + + Pools List + Lista de Pools + + + The name can only consist of alphanumeric characters, dashes and underscores. + O nome pode conter apenas caracteres alfanuméricos, traços e sublinhados. + + + The chosen erasure code profile name is already in use. + O nome do perfil de código de eliminação escolhido já está em uso. + + + Plugin + Plug-in + + + Data chunks (k) + Pacotes de dados (k) + + + Must be equal to or greater than 2. + Deve ser igual ou maior do que 2. + + + Coding chunks (m) + Pacotes de codificação (m) + + + Must be equal to or greater than 1. + Deve ser igual ou maior do que 1. + + + Durability estimator (c) + Estimador de durabilidade (c) + + + Locality (l) + Localidade (l) + + + Crush failure domain + Domínio de falha do Crush + + + Crush Locality + Localidade do Crush + + + None + Nenhum + + + Technique + Técnica + + + Packetsize + Tamanho do pacote + + + Crush root + Raiz do Crush + + + Crush device class + Classe do dispositivo do Crush + + + any + qualquer + + + Directory + Diretório + + + The chosen Ceph pool name is already in use. + O nome do pool do Ceph escolhido já está em uso. + + + Pool type + Tipo de pool + + + -- Select a pool type -- + -- Selecionar tipo de pool -- + + + Placement groups + Grupos de posicionamento + + + At least one placement group is needed! + Pelo menos um grupo de posicionamento é necessário! + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + Seu cluster não pode processar tantos PGs. Recalcule a quantidade de PG necessária. + + + Calculation help + Ajuda no cálculo + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + As configurações de PGs atuais foram calculadas para você. Verifique + se os valores atendem às suas necessidades antes de enviar. + + + Crush ruleset + Conjunto de regras do Crush + + + -- Select a crush rule -- + -- Selecionar regra de crush -- + + + Crush rule + Regra de Crush + + + Crush steps + Etapas do Crush + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + Impossível usar a regra no cluster atual porque ela tem + poucos OSDs para atender ao OSD mínimo necessário para esta regra. + + + Replicated size + Tamanho replicado + + + Minimum: + + + Mínimo: + + + + + Maximum: + + + Máximo: + + + + + The size specified is out of range. A value from + to + is valid. + + O tamanho especificado está fora da faixa. Um valor de + a + é válido. + + + + Erasure code profile + Perfil do código de eliminação + + + -- No erasure code profile available -- + -- Não há perfis de código de eliminação disponíveis -- + + + -- Select an erasure code profile -- + -- Selecionar perfil do código de eliminação -- + + + EC Overwrites + Sobregravações de EC + + + Applications + Aplicativos + + + Compression + Compactação + + + Algorithm + Algoritmo + + + -- No erasure compression algorithm available -- + -- Não há algoritmos de compactação de eliminação disponíveis -- + + + Minimum blob size + Tamanho mínimo do blob + + + e.g., 128KiB + ex. 128 KiB + + + Value should be greater than 0 + O valor deve ser maior do que 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Tamanho máximo do blob + + + e.g., 512KiB + ex. 512 KiB + + + Value should be greater than the minimum blob size + O valor deve ser maior do que o tamanho mínimo do blob + + + Ratio + Taxa + + + Compression ratio + Taxa de compactação + + + Value should be between 0.0 and 1.0 + O valor deve ser entre 0.0 e 1.0 + + + It's not possible to create an RBD pool with '/' in the name. + Impossível criar um pool de RBD com '/' no nome. + + + Please change the name or remove 'rbd' from the applications list. + Altere o nome ou remova o 'rbd' da lista de aplicativos. + + + Cache Tiers Details + Detalhes das Camadas do Cache + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + Consulte a + documentação + + sobre como configurar e habilitar a funcionalidade de gerenciamento do Gateway de Objetos. + + + + Daemons List + Lista de Daemons + + + Performance Counters + Contadores de Desempenho + + + Loading bucket data... + Carregando dados do compartimento... + + + The bucket data could not be loaded. + Não foi possível carregar os dados do compartimento. + + + Id + ID + + + The value is not valid. + O valor não é válido. + + + Owner + Proprietário + + + -- Select a user -- + -- Selecionar usuário -- + + + ID + ID + + + Index type + Tipo de índice + + + Placement rule + Regra de posicionamento + + + Marker + Marcador + + + Maximum marker + Marcador máximo + + + Version + Versão + + + Master version + Versão master + + + Modification time + Horário da modificação + + + Zonegroup + Grupo de zonas + + + Bucket quota + Cota do compartimento + + + Enabled + Habilitado + + + Maximum size + Tamanho máximo + + + Unlimited + Ilimitado + + + Maximum objects + Máximo de objetos + + + -- Select a username -- + -- Selecionar nome de usuário -- + + + Auto-generate key + Gerar chave automaticamente + + + Access key + Chave de acesso + + + Secret key + Chave secreta + + + Email address + Endereço de e-mail + + + Suspended + Suspenso + + + System + Sistema + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {Não} 1 {Sim} } + + + Maximum buckets + Máximo de compartimentos + + + Subusers + Subusuários + + + Capabilities + Recursos + + + User quota + Cota do usuário + + + Show + Mostrar + + + Keys + Chaves + + + -- Select a type -- + -- Selecionar tipo -- + + + Permission + Permissão + + + -- Select a permission -- + -- Selecionar permissão -- + + + Subuser + Subusuário + + + The chosen subuser ID is already in use. + O ID de subusuário escolhido já está em uso. + + + read, write + leitura, gravação + + + full + completo + + + Swift key + Chave Swift + + + Auto-generate secret + Gerar segredo automaticamente + + + Loading user data... + Carregando dados do usuário... + + + The user data could not be loaded. + Não foi possível carregar os dados do usuário. + + + The chosen user ID is already in use. + O ID de usuário escolhido já está em uso. + + + This is not a valid email address. + Este não é um endereço de e-mail válido. + + + The chosen email address is already in use. + O endereço de e-mail escolhido já está em uso. + + + Max. buckets + Máx. de compartimentos + + + The entered value must be >= 0. + O valor inserido deve ser >= 0. + + + S3 key + Chave S3 + + + There are no subusers. + Não há subusuários. + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + Não há chaves. + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + Não há recursos. + + + + + + + + + + + + + Unlimited size + Tamanho ilimitado + + + Max. size + Tamanho máx. + + + Unlimited objects + Objetos ilimitados + + + Max. objects + Máx. de objetos + + + Current + Atual + + + Updated discovery authentication + Autenticação de descoberta atualizada + + + There are no portals available. + Não há portais disponíveis. + + + There are no images available. + Não há imagens disponíveis. + + + There are no images available. Please make sure you add an image to the target. + Não há imagens disponíveis. Adicione uma imagem ao destino. + + + There are no initiators available. Please make sure you add an initiator to the target. + Não há iniciadores disponíveis. Adicione um iniciador ao destino. + + + target + target + + + Target + Destino + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + Estado + + + # Targets + # Targets + + + Read Bytes + Bytes de Leitura + + + Write Bytes + Bytes de Gravação + + + Read Ops + Op. de Leitura + + + Write Ops + Op. de Gravação + + + A/O Since + A/O Desde + + + Instance + Instância + + + Hostname + Nome de host + + + Issue + Problema + + + Progress + Andamento + + + Disabled + Desabilitado + + + Edit Mode + Modo de Edição + + + Add Peer + Adicionar Peer + + + Edit Peer + Editar Peer + + + Delete Peer + Excluir Peer + + + Leader + Leader + + + # Local + Nº Local + + + # Remote + Nº Remoto + + + mirror peer + espelhar peer + + + Key + Chave + + + RBD + RBD + + + Deep flatten + Nivelamento profundo + + + Layering + Disposição em camadas + + + Exclusive lock + Bloqueio exclusivo + + + Object map (requires exclusive-lock) + Mapa de objetos (requer bloqueio exclusivo) + + + Journaling (requires exclusive-lock) + Registro em diário (requer bloqueio exclusivo) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + Rollback de instantâneo do RBD + + + Rollback + Fazer Rollback + + + RBD snapshot + Instantâneo do RBD + + + Deleted At + Excluído à(s) + + + id + ID + + + type + tipo + + + state + estado + + + version + versão + + + Host + Host + + + root + raiz + + + Rank + Posição + + + Daemon + Daemon + + + Activity + Atividade + + + Dentries + Dentries + + + Inodes + Inodes + + + Usage + Uso + + + Standby daemons + Daemons de standby + + + The value can be updated at runtime. + É possível atualizar o valor em temo de execução. + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + Daemons/clientes não extraem este valor do + banco de dados de configuração do monitor. A configuração desta opção não é permitida por meio de 'ceph config + set ...'. Essa opção deve ser configurada por meio do ceph.conf ou da + linha de comando. + + + Option takes effect only during daemon startup. + A opção entra em vigor apenas durante a inicialização do daemon. + + + Option only affects cluster creation. + A opção afeta apenas a criação do cluster. + + + Option only affects daemon creation. + A opção afeta apenas a criação do daemon. + + + Updated config option + + + Opção de configuração + atualizada + + + + Service + Serviço + + + Current value + Valor atual + + + Editable + Editável + + + Updated options for module " + ". + + Opções atualizadas para o módulo &quot; + &quot;. + + + + Enable + Habilitar + + + Disable + Desabilitar + + + Reconnecting, please wait ... + Reconectando, aguarde... + + + Public Address + Endereço Público + + + Open Sessions + Sessões Abertas + + + No In + Não Entrada + + + OSDs that were previously marked out will not be marked back in when they start + Os OSDs que já foram marcados como saída não serão remarcados como entrada ao serem iniciados + + + No Out + Não Saída + + + OSDs will not automatically be marked out after the configured interval + Os OSDs não serão automaticamente marcados como saída após o intervalo configurado + + + No Up + Não Ativo + + + OSDs are not allowed to start + Os OSDs não podem ser iniciados + + + No Down + Não Inativo + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + Os relatórios de falha de OSD estão sendo ignorados, portanto, os monitores não marcarão os OSDs como inativos + + + Pause + Pausar + + + Pauses reads and writes + Pausa leituras e gravações + + + No Scrub + Sem Remoção + + + Scrubbing is disabled + Remoção desabilitada + + + No Deep Scrub + Sem Remoção Profunda + + + Deep Scrubbing is disabled + Remoção Profunda desabilitada + + + No Backfill + Sem Provisionamento + + + Backfilling of PGs is suspended + Provisionamento de PGs suspenso + + + No Recover + Sem Recuperação + + + Recovery of PGs is suspended + Recuperação de PGs suspensa + + + Bitwise Sort + Classificação Bit a Bit + + + Use bitwise sort + Usar classificação bit a bit + + + Purged Snapdirs + Snapdirs Purgados + + + OSDs have converted snapsets + OSDs converteram snapsets + + + Recovery Deletes + Exclusões de Recuperação + + + Deletes performed during recovery instead of peering + Exclusões realizadas durante a recuperação, e não o emparelhamento + + + PG Log Hard Limit + Limite Físico do Registro de PG + + + Puts a hard limit on pg log length + Atribui um limite físico ao tamanho do registro de PG + + + Updated OSD Flags + Flags OSD Atualizadas + + + out + saída + + + in + entrada + + + down + inativo + + + Mark + Marcar + + + OSD lost + OSD perdido + + + marked lost + marcado como perdido + + + Purge + Purgar + + + OSD + OSD + + + purged + purgado + + + destroy + destruir + + + destroyed + destruído + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + PGs + + + Read bytes + Bytes de leitura + + + Writes bytes + Bytes de gravação + + + Read ops + Op. de leitura + + + Write ops + Op. de gravação + + + Mark OSD + + + Marcar OSD como + + + + + Mark + + + Marcar como + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + Máx. de Provisionamentos + + + Recovery Max Active + Máx. Recuperação Ativo + + + Recovery Max Single Start + Máx. Recuperação Inicialização Única + + + Recovery Sleep + Suspensão de Recuperação + + + Custom + Personalizado + + + Updated OSD recovery speed priority " + " + + Prioridade de velocidade de recuperação de OSD &quot; + &quot atualizada; + + + + + was initialized in the following OSD: + + + + foi inicializado no seguinte OSD: + + + + + Create silence + Create silence + + + Job + Tarefa + + + Severity + Gravidade + + + Started + Iniciado + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + Atualizado + + + Ends + Ends + + + Silence + Silence + + + Used + Usado + + + Avail. + Disp. + + + Clean + Limpar + + + Working + Em funcionamento + + + Warning + Aviso + + + Unknown + Desconhecido + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + ativo + + + no filesystems + sem sistemas de arquivos + + + active + ativo + + + standby + standby + + + n/a + n/a + + + active daemon + daemon ativo + + + quorum + quorum + + + The NFS Ganesha service is not configured. + O serviço NFS Ganesha não está configurado. + + + Transport + Transporte + + + CephFS User + Usuário do CephFS + + + CephFS Filesystem + Sistema de Arquivos do CephFS + + + (inherited from global config) + (herdado da configuração global) + + + inherited from global config + herdado da configuração global + + + -- Select what kind of user id squashing is performed -- + -- Selecionar que tipo de squash de ID de usuário será executado -- + + + There are no daemons available. + Não há daemons disponíveis. + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + Modo de Cache + + + Min Evict Age + Tempo Mín. Expulsão + + + Min Flush Age + Tempo Mín. Descarregamento + + + Target Max Bytes + Máx. de Bytes de Destino + + + Target Max Objects + Máx. de Objetos de Destino + + + No applications added + Nenhum aplicativo adicionado + + + Applications limit reached + Limite de aplicativos atingido + + + A pool can only have up to four applications definitions. + Um pool apenas pode ter até quatro definições de aplicativos. + + + Allowed characters '_a-zA-Z0-9' + Caracteres permitidos: '_a-zA-Z0-9' + + + Maximum length is 128 characters + Tamanho máximo de 128 caracteres + + + Filter or add applications + Filtrar ou adicionar aplicativos + + + Add application + Adicionar aplicativo + + + pool + pool + + + erasure code profile + perfil de código de eliminação + + + Replica Size + Tamanho da Réplica + + + Last Change + Última Alteração + + + Erasure Coded Profile + Perfil Codificado para Eliminação + + + Crush Ruleset + Conjunto de Regras do Crush + + + Write bytes + Bytes de gravação + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + compartimento + + + Updated Object Gateway bucket " + " + + Compartimento do Gateway de Objetos &quot; + &quot; atualizado + + + + Created Object Gateway bucket " + " + + Compartimento do Gateway de Objetos &quot; + &quot; criado + + + + buckets + compartimentos + + + capability + capability + + + user + usuário + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + Usuário do Gateway de Objetos &quot; + &quot; atualizado + + + + Created Object Gateway user " + " + + Usuário do Gateway de Objetos &quot; + &quot; criado + + + + users + usuários + + + Swift Key + Swift Key + + + Scope + Escopo + + + Read + Leitura + + + Create + Criar + + + role + role + + + Created role ' + ' + + Função ' + ' criada + + + + Updated role ' + ' + + Função ' + ' atualizada + + + + System Role + Função do Sistema + + + Deleted role ' + ' + + Função ' + ' excluída + + + + Created user " + " + + Usuário &quot; + &quot; criado + + + + Update user + Atualizar usuário + + + Continue + Continuar + + + You were automatically logged out because your roles have been changed. + Você foi automaticamente desconectado porque suas funções foram alteradas. + + + Updated user " + " + + Usuário &quot; + &quot; atualizado + + + + Deleted user " + " + + Usuário &quot; + &quot; excluído + + + + Failed to delete user " + " + + Falha ao excluir o usuário &quot; + &quot; + + + + You are currently logged in as " + ". + + No momento, você está conectado como &quot; + &quot;. + + + + Each object is split in data-chunks parts, each stored on a different OSD. + Cada objeto é dividido em partes de pacotes de dados, cada uma armazenada em um OSD diferente. + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + Calcule os pacotes de codificação de cada objeto e armazene-os em diferentes OSDs. + O número de pacotes de codificação é também o número de OSDs que podem ficar inativos sem perda de dados. + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + O plug-in jerasure é o mais genérico e flexível, + além de ser o padrão para pools codificados para eliminação do Ceph. + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + A técnica mais flexível é reed_sol_van: ela é suficiente para definir k + e m. A técnica cauchy_good pode ser mais rápida, mas você precisa escolher o tamanho do pacote + com cuidado. Todos os reed_sol_r6_op, liberation, blaum_roth e liber8tion são equivalentes ao RAID6 + no sentido de que só podem ser configurados com m=2. + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + A codificação será feita em pacotes de tamanho de bytes um de cada vez. + A escolha do tamanho do pacote certo é difícil. + A documentação do jerasure contém informações completas sobre este tópico. + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + Com o plug-in jerasure, quando um objeto codificado para eliminação é armazenado em + vários OSDs, a recuperação após a perda de um OSD requer a leitura de todos os outros. + Por exemplo, se o jerasure for configurado com k=8 e m=4, a perda de um OSD exigirá a leitura + dos outros onze para fazer o reparo. + + O plug-in de código de eliminação lrc cria pacotes locais de paridade para conseguir recuperar usando + menos OSDs. Por exemplo, se o lrc for configurado com k=8, m=4 e l=4, ele criará + um pacote de paridade adicional para cada quatro OSDs. Quando um único OSD é perdido, ele pode ser + recuperado apenas com quatro OSDs, em vez de onze. + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + Agrupe os pacotes de codificação e dados em conjuntos de localidades com tamanho. Por exemplo, + no caso de k=4 e m=2, quando locality=3, dois grupos de três são criados. Cada conjunto pode + ser recuperado sem a leitura dos pacotes do outro conjunto. + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + O tipo do compartimento de crush em que cada conjunto de pacotes definido + por l será armazenado. Por exemplo, se isso for definido como rack, cada grupo de pacotes l será + colocado em um rack diferente. Isso é usado para criar uma etapa da regra CRUSH, como a etapa de escolha do + rack. Se isso não for definido, esse tipo de agrupamento não será feito. + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + O plug-in isa encapsula a biblioteca ISA. Ele apenas é executado em processadores Intel. + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + O plug-in ISA vem em dois formatos de Reed Solomon. + Se reed_sol_van for definido, ele será Vandermonde, se cauchy for definido, ele será Cauchy. + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + O plug-in shec encapsula a biblioteca múltipla SHEC. + Ele permite ao ceph recuperar dados com mais eficiência do que os códigos de Reed Solomon. + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + O número de pacotes de paridade, em que cada um inclui cada pacote de dados em sua + faixa de cálculo. O número é usado como estimador de durabilidade. Por exemplo, se c=2, + 2 OSDs podem ficar inativos sem perda de dados. + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + O nome do compartimento de crush usado para a primeira etapa da regra CRUSH. + Por exemplo, a etapa assumir o padrão. + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + Verifique se não há dois pacotes em um compartimento com o mesmo domínio de + falha. Por exemplo, se o domínio de falha for um host, não armazene dois pacotes no mesmo + host. Isso é usado para criar uma etapa da regra CRUSH, como a etapa de escolha do host folha. + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + Restrinja o posicionamento a dispositivos de uma classe específica + (ex. ssd ou hdd), usando nomes de classe de dispositivo crush no mapa CRUSH. + + + Set the directory name from which the erasure code plugin is loaded. + Defina o nome do diretório do qual o plug-in de código de eliminação é carregado. + + + Allows all operations + Permite todas as operações + + + Allows only operations that do not modify the server + Permite apenas as operações que não modificam o servidor + + + Does not allow read or write operations, but allows any other operation + Não permite operações de leitura ou gravação, mas permite qualquer outra operação + + + Does not allow read, write, or any operation that modifies file attributes or directory content + Não permite leitura, gravação ou qualquer operação que modifica os atributos do arquivo ou o conteúdo do diretório + + + Allows no access at all + Não permite nenhum tipo de acesso + + + -- Select the priority -- + -- Selecionar prioridade -- + + + Low + Baixa + + + High + Alta + + + Last 5 minutes + Últimos 5 minutos + + + Last 15 minutes + Últimos 15 minutos + + + Last 30 minutes + Últimos 30 minutos + + + Last 1 hour (Default) + Última 1 hora (Padrão) + + + Last 3 hours + Últimas 3 horas + + + Last 6 hours + Últimas 6 horas + + + Last 12 hours + Últimas 12 horas + + + Last 24 hours + Últimas 24 horas + + + Yesterday + Ontem + + + Today + Hoje + + + Today so far + Até agora hoje + + + Day before yesterday + Antes de ontem + + + Last 2 days + Últimos 2 dias + + + This day last week + Este dia na semana passada + + + Previous week + Semana anterior + + + This week + Esta semana + + + This week so far + Até agora nesta semana + + + Last 7 days + Últimos 7 dias + + + Previous month + Mês anterior + + + This month + Este mês + + + This month so far + Até agora neste mês + + + Last 30 days + Últimos 30 dias + + + Last 90 days + Últimos 90 dias + + + Last 6 months + Últimos 6 meses + + + Last 1 year + Último ano + + + Previous year + Ano anterior + + + This year + Este ano + + + This year so far + Até agora neste ano + + + Last 2 years + Últimos 2 anos + + + Last 5 years + Últimos 5 anos + + + Information + Informações + + + No items selected. + Nenhum item selecionado. + + + Deselect item to select again + Desmarcar item para selecionar novamente + + + Selection limit reached + Limite de seleção atingido + + + Filter tags + Tags de filtro + + + Add badge + Adicionar selo + + + There are no items available. + Não há itens disponíveis. + + + Add + Adicionar + + + Remove + Remove + + + Clone + Clonar + + + Copy + Copiar + + + Deep Scrub + Remoção Profunda + + + Destroy + Destruir + + + Flatten + Nivelar + + + Mark Down + Marcar como Inativo + + + Mark In + Marcar como Entrada + + + Mark Lost + Marcar como Perdido + + + Mark Out + Marcar como Saída + + + Protect + Proteger + + + Rename + Renomear + + + Restore + Restaurar + + + Move to Trash + Mover para Lixo + + + Unprotect + Cancelar proteção + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + Excluído + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + Clonado + + + Copied + Copiado + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + Sim + + + No + Não + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + Qualidade do Serviço + + + BPS Limit + Limite de BPS + + + The desired limit of IO bytes per second. + O limite de bytes por segundo de E/S desejado. + + + IOPS Limit + Limite de IOPS + + + The desired limit of IO operations per second. + O limite de operações por segundo de E/S desejado. + + + Read BPS Limit + Limite de BPS de Leitura + + + The desired limit of read bytes per second. + O limite de bytes por segundo de leitura desejado. + + + Read IOPS Limit + Limite de IOPS de Leitura + + + The desired limit of read operations per second. + O limite de operações por segundo de leitura desejado. + + + Write BPS Limit + Limite de BPS de Gravação + + + The desired limit of write bytes per second. + O limite de bytes por segundo de gravação desejado. + + + Write IOPS Limit + Limite de IOPS de Gravação + + + The desired limit of write operations per second. + O limite de operações por segundo de gravação desejado. + + + BPS Burst + Intermitência de BPS + + + The desired burst limit of IO bytes. + O limite de bytes de E/S de intermitência desejado. + + + IOPS Burst + Intermitência de IOPS + + + The desired burst limit of IO operations. + O limite de operações de E/S de intermitência desejado. + + + Read BPS Burst + Intermitência de BPS de Leitura + + + The desired burst limit of read bytes. + O limite de bytes de leitura de intermitência desejado. + + + Read IOPS Burst + Intermitência de IOPS de Leitura + + + The desired burst limit of read operations. + O limite de operações de leitura de intermitência desejado. + + + Write BPS Burst + Intermitência de BPS de Gravação + + + The desired burst limit of write bytes. + O limite de bytes de gravação de intermitência desejado. + + + Write IOPS Burst + Intermitência de IOPS de Gravação + + + The desired burst limit of write operations. + O limite de operações de gravação de intermitência desejado. + + + Failed to + + + + Falha ao + + + + + + Executing + Executando + + + execute + executar + + + Executed + Executado + + + unknown task + tarefa desconhecida + + + Creating + Criando + + + create + criar + + + Updating + Atualizando + + + update + atualizar + + + Deleting + Excluindo + + + delete + excluir + + + RBD ' + ' + + RBD ' + ' + + + + RBD snapshot ' + ' + + Instantâneo do RBD ' + ' + + + + mirror mode for pool ' + ' + + modo de espelho para o pool ' + ' + + + + mirror peer for pool ' + ' + + espelhar peer para o pool ' + ' + + + + all dashboards + all dashboards + + + Name is already used by + . + + Nome já foi usado por + . + + + + Name is already used by + . + + Nome já foi usado por + . + + + + Name is already used by + . + + Nome já foi usado por + . + + + + + contains snapshots. + + + contém instantâneos. + + + + Cloning + Clonando + + + clone + clonar + + + Snapshot of + must be protected. + + O instantâneo de + deve ser protegido. + + + + Copying + Copiando + + + copy + copiar + + + Flattening + Nivelando + + + flatten + nivelar + + + Flattened + Nivelado + + + Name is already used by + . + + Nome já foi usado por + . + + + + Cannot unprotect + because it contains child images. + + Impossível cancelar a proteção de + porque há imagens filho. + + + + Cannot delete + because it's protected. + + Impossível excluir + porque está protegido. + + + + Rolling back + Fazendo rollback + + + rollback + rollback + + + Rolled back + Rollback feito + + + Moving + Movendo + + + move + mover + + + Moved + Movido + + + image ' + ' to trash + + imagem ' + ' para jogar no lixo + + + + Could not find image. + Imagem não encontrada. + + + Restoring + Restaurando + + + restore + restaurar + + + Restored + Restaurado + + + image ' + ' into ' + ' + + imagem ' + ' para ' + ' + + + + Image name ' + ' is already in use. + + Nome da imagem ' + ' já está em uso. + + + + image ' + ' + + imagem ' + ' + + + + Purging + Purgando + + + purge + purgar + + + Purged + Purgado + + + all pools + todos os pools + + + images from + + + imagens de + + + + + Cannot disable mirroring because it contains a peer. + Impossível desabilitar espelhamento porque ele contém um peer. + + + pool ' + ' + + pool ' + ' + + + + erasure code profile ' + ' + + perfil de código de eliminação ' + ' + + + + target ' + ' + + destino ' + ' + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf new file mode 100644 index 00000000..1184122b --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-CN.xlf @@ -0,0 +1,4365 @@ + + + + + Toggle navigation + 切换导航 + + + Dashboard + 仪表盘 + + + Cluster + 集群 + + + Hosts + 主机 + + + Monitors + Monitor + + + OSDs + OSD + + + Configuration + 配置项 + + + CRUSH map + CRUSH 索引 + + + Manager modules + Manager 扩展模块 + + + Logs + 日志 + + + Alerts + 警告 + + + Silences + Silences + + + Pools + 存储池 + + + Block + 块设备 + + + Images + 映像 + + + Mirroring + 镜像 + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + 文件系统 + + + Object Gateway + 对象网关 + + + Daemons + 守护进程 + + + Users + 用户 + + + Buckets + 存储桶 + + + Retrieving data + for + + + . Please wait... + + 关于 + 的数据,正为 + + + 获取中,请稍候... + + + + Displaying previously cached data + + for + + + . + + 关于之前缓存的数据 + ,正为 + + + 显示。 + + + + Could not load data + for + + + . + Please check the cluster health. + + 关于数据 + ,无法为 + + + 加载。 + 请检查集群的健康状况。 + + + + Back + 返回 + + + Select a Language + 请选择语言 + + + Loading panel data... + 正在加载面板的相关数据… + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + 关于如何配置以及打开监控功能, +请参阅 + 文档 + 。 + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + 无 Grafana 仪表盘。关于如何为 Grafana 添加 +仪表盘,请参考 + 文档 + 。 + + + + Grafana Time Picker + Grafana 时间选择工具 + + + Reset Settings + 重新设置 + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + 无法加载数据。 + + + selected + 选中个数 + X selected + + + found + 命中个数 + X found + + + total + 总数 + X total + + + Edit + 编辑 + + + Name + 名称 + + + Description + 解释 + + + Long description + 更详尽的解释 + + + Default + 缺省值 + + + Daemon default + 守护进程的缺省值 + + + Services + 对应的服务 + + + Values + 可选值 + + + The entered value is too high! It must not be greater than + . + + 设置的值太大了!应低于 + 。 + + + + The entered value is too low! It must not be lower than + . + + 设置的值太小了!不能低于 + 。 + + + + Save + 保存 + + + CRUSH map viewer + 检查 CRUSH 索引图 + + + Hosts List + 主机列表 + + + Overall Performance + 总体性能 + + + No entries found + 无法找到相关条目 + + + Cluster Logs + 集群日志 + + + Audit Logs + 审计日志 + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + 正在加载相关配置信息... + + + The configuration could not be loaded. + 配置信息无法加载。 + + + Edit Manager module + 编辑 Manager 扩展模块 + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + 输入值不是有效的 UUID,如:67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + 输入的应该是个有效的 IP 地址。 + + + This field is required. + 请填写此栏目! + + + The entered value is too high! It must be lower or equal to + . + + 输入值过大!必须小于或等于 + 。 + + + + The entered value is too low! It must be greater or equal to + . + + 输入值过小!必须大于或等于 + 。 + + + + The entered value needs to be a number. + 输入须为数字。 + + + The entered value needs to be a number or decimal. + 输入的应该是一个浮点数或者十进制整数。 + + + Update + 更新 + + + Status + 状态 + + + Cluster ID + 集群 ID + + + monmap modified + monmap 修改时间 + + + monmap epoch + monmap epoch + + + quorum con + quorum con + + + quorum mon + quorum mon + + + required con + required con + + + required mon + required mon + + + In Quorum + 仲裁成员 + + + Not In Quorum + 非仲裁成员 + + + Cancel + 取消 + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + 您确定要 + 选中的 + 吗? + + + + Yes, I am sure. + 是的,我确定。 + + + Cluster-wide OSD Flags + 集群范围的 OSD 标志 + + + Submit + 提交 + + + + + + + + + + + form title + + + Advanced... + 高级设置… + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + OSD 恢复优先级 + + + Priority + 优先级 + + + Customize priority values + 自定义优先级 + + + This field is required! + 这个字段是必填的! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + 输入值过大!不能大于 + 。 + + + + The entered value is too low! It must not be lower than + . + + 输入值过小!不能小于 + 。 + + + + Reweight OSD + 重新设置 OSD 的权重 + + + The value needs to be between 0 and 1. + 权重值必须在 0 和 1 之间 + + + Reweight + 重设权重 + + + OSDs + Scrub + + OSD + 洗刷 + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {深度}} + + + You are about to apply a + scrub to + the OSD + + + . + + 即将对 OSD + + + 执行 + 洗刷。 + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {深度} } + + + OSDs List + OSD 列表 + + + + OSD + + will be marked + + + if you proceed. + + 如果继续, + OSD + + +将被标记为 + + + 。 + + + + The OSD is not safe to destroy! + OSD 不安全,无法销毁! + + + + OSD + + will be + + + if you proceed. + + 如果继续, + OSD + + +将被 + + + 。 + + + + Details + 详情 + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + 关闭 + + + Delete + 删除 + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + 健康状况 + + + Statistics + 统计数据 + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + 关于如何配置和启用 NFS Ganesha 管理功能, +请参考 + 文档 + 。 + + + + Clients + 客户端 + + + Any client can access + 任何客户端均可访问 + + + Addresses + 地址 + + + Required field + 必填项 + + + Must contain one or more comma-separated values + 必须包含一个或多个逗号分隔值 + + + For example: + 例如: + + + Access Type + 访问类型 + + + Squash + Squash + + + Add clients + 添加客户端 + + + Loading... + 正在加载… + + + -- No cluster available -- + -- 无可用集群 -- + + + -- Select the cluster -- + -- 请选择一个集群 -- + + + Add daemon + 添加守护进程 + + + Storage Backend + 存储后端 + + + -- No data pools available -- + -- 没有可用的数据存储池 -- + + + -- Select the storage backend -- + -- 请选择存储后端 -- + + + Object Gateway User + 对象网关用户 + + + -- No users available -- + -- 无可选用户 -- + + + -- Select the object gateway user -- + -- 请选择对象网关用户 -- + + + CephFS User ID + CephFS 用户 ID + + + -- No clients available -- + -- 无可用客户端 -- + + + -- Select the cephx client -- + -- 请选择 cephx 客户端 -- + + + CephFS Name + CephFS 名称 + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + 安全标签 + + + Enable security label + 启用安全标签 + + + CephFS Path + CephFS 路径 + + + Path need to start with a '/' and can be followed by a word + 路径需以“/”开头,后面可跟单词 + + + New directory will be created + 将创建新文件夹 + + + Path + 路径 + + + Path can only be a single '/' or a word + 路径只能是单个“/”或单词 + + + New bucket will be created + 将创建新的桶 + + + NFS Protocol + NFS 协议 + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + NFS 标签 + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + + NFS v3 + 装入的备用访问(不得包含前置 /)。 + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + 客户端不能装入子目录(即如果标记为 foo,则客户端无法装入 foo/baz)。 + + + By using different Tag options, the same Path may be exported multiple times. + 通过使用不同标记选项,可将同一路径导出多次。 + + + Pseudo + + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + 此 + NFS v4 + 导出在 + 伪文件系统 + 中 + 所占用的位置(必须唯一)。 + + + + By using different Pseudo options, the same Path may be exported multiple times. + 通过使用不同伪选项,可将同一路径导出多次。 + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- 没有可用的访问类型 -- + + + -- Select the access type -- + -- 选择访问类型 -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- 没有可用的 squash -- + + + --Select what kind of user id squashing is performed -- + -- 选择执行哪种类型的用户 ID 匿名访问 -- + + + Transport Protocol + 传输协议 + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + 欢迎使用 Ceph! + The welcome message on the login page + + + Username is required + 请输入用户名 + + + Password is required + 请输入密码 + + + Login + 登录 + + + Sorry, the user does not exist in Ceph. + 抱歉,此用户不存在。 + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + 返回 + 登录页 + 。您将在重新登录时从身份提供程序注销。 + + + + Forbidden + 禁止访问 + + + Sorry, you are not allowed to see what you were looking for. + 抱歉,您无权访问这个页面。 + + + Sorry, we could not find what you were looking for + 抱歉,我们找不到您要看的东西。 + + + Remove all + 全部已读 + + + Recent Notifications + 最新的通知 + + + There are no background tasks. + 没有后台任务正在执行。 + + + Background Tasks + 后台任务 + + + Help + 帮助 + + + Documentation + 文档 + + + API + API + + + About + 关于 + + + Dashboard Settings + 仪表盘设置 + + + User management + 用户管理 + + + Logged in user + 登录的用户 + + + Signed in as + + + + + 以用户名 + + + +进行登录 + + + + Sign out + 登出 + + + Name... + 名称… + + + The chosen name is already in use. + 所选名称已经被使用。 + + + Description... + 描述… + + + Permissions + 权限 + + + Roles + 角色 + + + Username + 用户名 + + + Password + 密码 + + + Confirm password + 确认密码 + + + Password confirmation doesn't match the password. + 密码和之前的输入不匹配。 + + + Full name + 全名 + + + Email + 邮箱 + + + Invalid email. + 邮箱地址无效。 + + + You are about to remove "user read / update" permissions from your own user. + 您即将取消您自己用户的 "user read / update" 权限。 + + + If you continue, you will no longer be able to add or remove roles from any user. + 如果您继续的话,您以后就没办法为其他用户添加或者删除角色了。 + + + Are you sure you want to continue? + 您确实要继续吗? + + + Performance counters not available + 无法读取性能计数器 + + + Attributes (OSD map) + OSD map + + + Metadata not available + 元数据不可用 + + + Metadata + 相关元数据 + + + Performance counter + 性能计数器 + + + Histogram not available: + + + 直方图不可用: + + + + + Writes + 写入请求 + + + Reads + 读取请求 + + + Histogram + 直方图 + + + Performance Details + 性能详情 + + + Current values + 当前值 + + + Type + 类型 + + + Min + 下限 + + + Max + 上限 + + + Flags + 标志 + + + Source + 来源 + + + Level + 级别 + + + Can be updated at runtime (editable) + 可在运行时更新(可编辑) + + + Tags + 标记 + + + Enum values + 可选项 + + + See also + 参见 + + + Cluster Status + 集群状态 + + + Manager Daemons + manager 守护进程 + + + Object Gateways + 对象网关 + + + Metadata Servers + metadata 服务器 + + + iSCSI Gateways + iSCSI 网关 + + + Client IOPS + 客户端 IOPS + + + Client Throughput + 客户端吞吐量 + + + Client Read/Write + 客户端读/写 + + + Recovery Throughput + 恢复吞吐量 + + + Scrub + 洗刷 + + + Performance + 性能 + + + Raw Capacity + 基本容量 + + + Objects + 对象数 + + + PGs per OSD + 每个 OSD 的 PG 数 + + + PG Status + PG 状态 + + + Capacity + 容量 + + + + + See + Logs + for more details. + + + + 查看 + 日志 + 以获得更多细节。 + + + + Ranks + 排位 + + + MDS performance counters + MDS performance counters + + + Clients: + + + 客户端: + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + 将映像移至回收站 + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + 要将 + + / + + 移至回收站, + 请点击 + 移动映像 + 。此外,可选择设置一个过期时间。 + + + + Protection expires at + 保护期一直到 + + + NOT PROTECTED + 无保护 + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + 日期格式有问题。请使用“YYYY-MM-DD HH:mm:ss”。 + + + Protection has already expired. Please pick a future date or leave it empty. + 保护期限已经过了。请设置一个将来的日期,或者清空不填。 + + + Move Image + 移动映像 + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + 概览 + + + Targets + 目标 + + + Discovery Authentication + 发现身份验证 + + + User + 用户 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + 用户名长度必须在 8 到 64 个字符之间,且只能包含 +以下字符:英文字母、“.”、“@”、“-”、“_”或“:”。 + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + 互认证用户 + + + Mutual Password + 互认证密码 + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + 关于如何配置和启用 iSCSI 目标管理功能, +请参考 + 文档 + 。 + + + + Available information: + 可用信息: + + + iSCSI Targets not available + 无可用 iSCSI 目标 + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + 只对启动了 + fast-diff + 功能的 RBD 映像可用 + + + + Pool + 存储池 + + + Data Pool + 数据存储池 + + + Created + 创建 + + + Size + 容量 + + + Object size + 对象大小 + + + Features + 特性 + + + Provisioned + 供给容量 + + + N/A + N/A + + + Total provisioned + 总供给容量 + + + Striping unit + 条带单元 + + + Striping count + 条带个数 + + + Parent + 父节点 + + + Block name prefix + 块存储名字前缀 + + + Order + order + + + Snapshots + 快照 + + + Image + 映像 + + + This setting overrides the global value + 此设置会覆盖全局值 + + + Global + 全局 + + + This is the global value. No value for this option has been set for this image. + 该值为全局值。没有为此映像设置此选项的值。 + + + + from + + + from + + + + '/' and '@' are not allowed. + 不允许使用“/”和“@”。 + + + -- No rbd pools available -- + -- 没有可用的 RBD 存储池 -- + + + -- Select a pool -- + -- 请选择存储池 -- + + + Use a dedicated data pool + 使用一个专用的数据池 + + + Data pool + 数据池 + + + Dedicated pool that stores the object-data of the RBD. + 为保存 RBD 的对象数据单独分配的存储池。 + + + e.g., 10GiB + 如 10 GiB + + + You have to increase the size. + 您需要设置大一些的容量。 + + + Advanced + 高级设置 + + + Striping + 条带 + + + Stripe unit + 条带单元大小 + + + -- Select stripe unit -- + -- 选择条带单元大小 -- + + + This field is required because stripe count is defined! + 因为设置了条带个数,所以这个字段是必选的! + + + Stripe unit is greater than object size. + 条带单元大小超过了对象大小。 + + + Stripe count + 条带个数 + + + This field is required because stripe unit is defined! + 因为设置了条带单元大小,所以这个字段是必选的! + + + Stripe count must be greater than 0. + 条带的个数必须大于 0。 + + + + RBD Snapshot + + + RBD 快照 + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {改名} other {创建} } + + + + Snapshot + + + 快照 + + + + PROTECTED + 受保护的 + + + UNPROTECTED + 无保护的 + + + You are about to rollback + 您即将进行回滚操作 + + + Purge Trash + 清空回收站 + + + To purge, select one or All images and click + 要彻底清空的话,请选择单个或所有的映像,然后点击 + + + Pool: + 存储池: + + + Pool name... + 存储池名称… + + + All + 全选 + + + Restore Image + 恢复映像 + + + To restore + 要恢复 + + + type the image's new name and click + 输入映像的新名称,并点击 + + + New Name + 新名称 + + + Expired at + 过期时间 + + + Protected until + 保护期限 + + + This image is protected until + . + + 一直到 + ,该映像都会受保护。 + + + + Trash + 回收站 + + + iSCSI Topology + iSCSI 结构图 + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + 通常无须改变这些默认参数值。 + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + 设置 + + + Backstore + 后备存储 + + + Confirm + 确认 + + + Advanced Settings + 高级设置 + + + Target IQN + 目标限定名 + + + IQN has wrong pattern. + IQN 格式错误。 + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + IQN 应由以下格式构成:“iqn.$year-$month.$reversedAddress:$definedName” + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + 例如:iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + 更多信息 + + + This target has modified advanced settings. + 此目标的高级设置项存在修改。 + + + Portals + 端口 + + + At least + gateways are required. + + 至少需要 + 个网关。 + + + + Add portal + 添加端口 + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + 此映像的设置项存在修改。 + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + 添加映像 + + + ACL authentication + ACL 身份验证 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + 授权人 + + + Initiator + 授权人 + + + Client IQN + 客户端 IQN + + + Initiator IQN needs to be unique. + 授权人 IQN 必须唯一。 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + 用户名长度必须在 8 到 64 个字符之间,且只能包含 +以下字符:英文字母、“.”、“@”、“-”、“_”或“:”。 + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + 授权人属于群组。映像须在群组中进行设置。 + + + No items added. + 无项目添加。 + + + Add initiator + 添加授权人 + + + Groups + 群组 + + + Group + 群组 + + + Add group + 添加群组 + + + [object Object] + [object Object] + + + RBD Configuration + RBD 配置 + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + 删除本地的配置项,改用更高作用域的配置值。 + + + The mininum value is 0 + 最小值为 0 + + + Issues + 问题 + + + Syncing + 正在同步 + + + Ready + 已就绪 + + + Edit pool mirror mode + 编辑存储池镜像模式 + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + 要编辑存储池 + + +   + 的镜像模式,请从列表中选择一项,并点击  + 更新 + 。 + + + + Mode + 模式 + + + Peer clusters must be removed prior to disabling mirror. + 在禁用镜像功能前必须先移除同伴集群。 + + + + + pool mirror peer + + + +存储池镜像同伴 + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {编辑} other {添加} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + 存储池 + + + + 的存储池镜像同伴属性,并点击 + 提交 + 。 + + + + Cluster Name + 集群名称 + + + The cluster name is not valid. + 集群名称无效。 + + + CephX ID + CephX ID + + + CephX ID... + CephX ID... + + + The CephX ID is not valid. + CephX ID 无效。 + + + Monitor Addresses + Monitor 地址 + + + Comma-delimited addresses... + 逗号分割的地址... + + + The monitory address is not valid. + Monitor 地址无效。 + + + CephX Key + CephX 密钥 + + + Base64-encoded key... + Base64 编码的密钥... + + + CephX key must be base64 encoded. + CephX 密钥必须是 base64 编码的。 + + + Pools List + 存储池列表 + + + The name can only consist of alphanumeric characters, dashes and underscores. + 名称只能由字母、数字、短划线和下划线组成。 + + + The chosen erasure code profile name is already in use. + 此纠删码配置名称已被使用。 + + + Plugin + 纠删码算法 + + + Data chunks (k) + 数据块 (k) + + + Must be equal to or greater than 2. + 必须大于等于 2 + + + Coding chunks (m) + 校验块 (m) + + + Must be equal to or greater than 1. + 必须大于等于 1 + + + Durability estimator (c) + 持久因子 (c) + + + Locality (l) + 局部性因子 (l) + + + Crush failure domain + CRUSH 故障域 + + + Crush Locality + CRUSH 局部性 + + + None + + + + Technique + 算法 + + + Packetsize + packetsize + + + Crush root + CRUSH 根 + + + Crush device class + CRUSH 设备类型 + + + any + 任意 + + + Directory + 目录 + + + The chosen Ceph pool name is already in use. + 此 Ceph 存储池名称已被使用。 + + + Pool type + 存储池类型 + + + -- Select a pool type -- + -- 请选择存储池的类型 -- + + + Placement groups + 归置组 (PG) + + + At least one placement group is needed! + 至少需要一个归置组! + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + 您的集群没法支持这么多的 PG。请重新计算需要的 PG 个数。 + + + Calculation help + 在线 PG 计算器 + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + 已根据当前情况为您推算出了 PG 的设置,您 +最好在提交之前确认这些设置是合适的。 + + + Crush ruleset + CRUSH 算法规则组 + + + -- Select a crush rule -- + -- 选择 CRUSH 规则 -- + + + Crush rule + CRUSH 规则 + + + Crush steps + CRUSH 步骤 + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + 当前的集群无法使用该规则,因为集群的 OSD 个数过少, + 无法满足规则所需的最低 OSD 数量。 + + + Replicated size + 副本个数 + + + Minimum: + + + 最低: + + + + + Maximum: + + + 最高: + + + + + The size specified is out of range. A value from + to + is valid. + + 设置的超过了限制。设置值应该在 + 和 + 中间为宜. + + + + Erasure code profile + 纠删码配置 + + + -- No erasure code profile available -- + -- 无纠删码配置可选 -- + + + -- Select an erasure code profile -- + -- 请选择一个纠删码配置 -- + + + EC Overwrites + EC 重写 (overwrite) + + + Applications + 应用类型 + + + Compression + 压缩 + + + Algorithm + 算法 + + + -- No erasure compression algorithm available -- + -- 无可用的纠删码压缩算法 -- + + + Minimum blob size + blob 大小下限 + + + e.g., 128KiB + 比如 128 KiB + + + Value should be greater than 0 + 取值必须大于 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + blob 大小上限 + + + e.g., 512KiB + 如 512KiB + + + Value should be greater than the minimum blob size + 取值必须大于 blob 大小下限 + + + Ratio + 比例 + + + Compression ratio + 压缩率 + + + Value should be between 0.0 and 1.0 + 取值必须在 0.0 和 1.0 之间 + + + It's not possible to create an RBD pool with '/' in the name. + 无法新建名字中有“/”的 RBD 存储池。 + + + Please change the name or remove 'rbd' from the applications list. + 请重新命名,或者把存储池的“rbd”应用标记去掉。 + + + Cache Tiers Details + 缓存层详细信息 + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + 关于如何配置和启用对象网关的功能, + 请参考 + 文档 + 。 + + + + Daemons List + 守护进程列表 + + + Performance Counters + 性能计数器 + + + Loading bucket data... + 正在加载存储桶数据… + + + The bucket data could not be loaded. + 存储桶数据无法加载。 + + + Id + ID + + + The value is not valid. + 输入值无效。 + + + Owner + 所有者 + + + -- Select a user -- + -- 请选择一个用户 -- + + + ID + ID + + + Index type + 索引类型 + + + Placement rule + 归置规则 + + + Marker + 标识 + + + Maximum marker + max marker + + + Version + 版本 + + + Master version + 主版本 + + + Modification time + 修改时间 + + + Zonegroup + zonegroup + + + Bucket quota + 存储桶配额 + + + Enabled + 开启 + + + Maximum size + 最大数目 + + + Unlimited + 无限制 + + + Maximum objects + 最大对象数目 + + + -- Select a username -- + -- 请选择用户名 -- + + + Auto-generate key + 自动生成密钥 + + + Access key + 访问密钥 + + + Secret key + 秘密密钥 + + + Email address + 邮箱 + + + Suspended + 冻结 + + + System + 系统 + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {否} 1 {是} } + + + Maximum buckets + 最大存储桶数目 + + + Subusers + 子用户 + + + Capabilities + 用户权限 + + + User quota + 用户配额 + + + Show + 显示 + + + Keys + 密钥 + + + -- Select a type -- + -- 请选择一个类型 -- + + + Permission + 权限 + + + -- Select a permission -- + -- 请选择权限类型 -- + + + Subuser + 子用户 + + + The chosen subuser ID is already in use. + 所选的子用户 ID 已被使用。 + + + read, write + 读、写 + + + full + 全部 + + + Swift key + Swift 密钥 + + + Auto-generate secret + 自动生成密钥 + + + Loading user data... + 正在加载用户数据… + + + The user data could not be loaded. + 用户数据无法加载。 + + + The chosen user ID is already in use. + 所选的用户 ID 已被使用。 + + + This is not a valid email address. + 无效的邮箱地址。 + + + The chosen email address is already in use. + 此邮箱地址已被使用。 + + + Max. buckets + 存储桶个数的上限 + + + The entered value must be >= 0. + 设置的值必须 >= 0。 + + + S3 key + S3 密钥 + + + There are no subusers. + 没有子用户。 + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + 没有任何密钥。 + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + 权限为空。 + + + + + + + + + + + + + Unlimited size + 空间无限制 + + + Max. size + 空间上限 + + + Unlimited objects + 对象个数无限制 + + + Max. objects + 对象个数上限 + + + Current + 当前 + + + Updated discovery authentication + 已更新发现身份验证 + + + There are no portals available. + 无可用端口。 + + + There are no images available. + 无可用映像。 + + + There are no images available. Please make sure you add an image to the target. + 无可用映像。请确保为目标添加一个映像。 + + + There are no initiators available. Please make sure you add an initiator to the target. + 无可用授权人。请确保为目标添加一个授权人。 + + + target + target + + + Target + 目标 + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + 状态 + + + # Targets + # Targets + + + Read Bytes + 读字节数 + + + Write Bytes + 写字节数 + + + Read Ops + 读请求数 + + + Write Ops + 写请求数 + + + A/O Since + 活动/优化自 + + + Instance + 实例 + + + Hostname + 主机名 + + + Issue + 问题 + + + Progress + 进度 + + + Disabled + 禁用 + + + Edit Mode + 编辑模式 + + + Add Peer + 添加 peer + + + Edit Peer + 编辑 peer + + + Delete Peer + 删除 peer + + + Leader + Leader + + + # Local + # 本地 + + + # Remote + # 远程 + + + mirror peer + 镜像 peer + + + Key + 密钥 + + + RBD + RBD + + + Deep flatten + 完全展开 + + + Layering + 分层 + + + Exclusive lock + 互斥锁 + + + Object map (requires exclusive-lock) + object map(要求互斥锁支持) + + + Journaling (requires exclusive-lock) + 日志(要求互斥锁支持) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + RBD 快照回滚 + + + Rollback + 回滚 + + + RBD snapshot + RBD 快照 + + + Deleted At + 定点删除 + + + id + ID + + + type + 类型 + + + state + 状态 + + + version + 版本 + + + Host + 主机 + + + root + + + + Rank + 排位 + + + Daemon + 守护进程 + + + Activity + 活跃度 + + + Dentries + dentries + + + Inodes + inodes + + + Usage + 使用率 + + + Standby daemons + 备用服务 + + + The value can be updated at runtime. + 该值可在运行时更新。 + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + 服务器或客户端不会主动从 monitor 的配置数据库读取这个配置。 + 所以不能用“ceph config set ...”设置它。但是可以通过 + ceph.conf 或者用命令行进行配置。 + + + Option takes effect only during daemon startup. + 该配置只有在服务启动的时候才会生效。 + + + Option only affects cluster creation. + 该配置只在创建集群的时候才会生效。 + + + Option only affects daemon creation. + 该配置只在服务创建的时候才会生效。 + + + Updated config option + + + 已更新配置选项 + + + + + Service + 服务 + + + Current value + 当前值 + + + Editable + 可编辑 + + + Updated options for module " + ". + + 已更新扩展模块“ + ”的选项。 + + + + Enable + 启用 + + + Disable + 禁用 + + + Reconnecting, please wait ... + 正在重新连接,请稍候… + + + Public Address + 外部地址 + + + Open Sessions + 活动会话 + + + No In + 禁止加入 + + + OSDs that were previously marked out will not be marked back in when they start + 之前被除名的 OSD 在启动之后,不会被加入集群 + + + No Out + 禁止除名 + + + OSDs will not automatically be marked out after the configured interval + 在发现 OSD 没有响应之后一段时间,该 OSD 会被踢出集群。该标志会禁止这个功能。 + + + No Up + 禁止启用 + + + OSDs are not allowed to start + 不允许 OSD 启动 + + + No Down + 禁止停用 + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + 当前不受理对 OSD 的失效报告,因而 monitor 不会停用 OSD + + + Pause + 暂停 + + + Pauses reads and writes + 暂停读写 + + + No Scrub + 禁止洗刷 + + + Scrubbing is disabled + 洗刷已禁止 + + + No Deep Scrub + 禁止深层洗刷 + + + Deep Scrubbing is disabled + 深层洗刷已禁止 + + + No Backfill + 禁止回填 + + + Backfilling of PGs is suspended + PG 回填已推迟 + + + No Recover + 禁止恢复 + + + Recovery of PGs is suspended + PG 恢复已推迟 + + + Bitwise Sort + 逐位排序 + + + Use bitwise sort + 使用逐位排序 + + + Purged Snapdirs + 老版本的快照已全部升级 + + + OSDs have converted snapsets + OSD 上的快照已全部转换完毕 + + + Recovery Deletes + 在恢复时进行删除操作 + + + Deletes performed during recovery instead of peering + 在恢复时,而非对齐阶段进行删除 + + + PG Log Hard Limit + PG 日志硬限制 + + + Puts a hard limit on pg log length + 为 pg 日志长度添加硬限制 + + + Updated OSD Flags + 已更新 OSD 标志 + + + out + 除名 + + + in + 加入 + + + down + 停用 + + + Mark + 标记 + + + OSD lost + OSD 丢失 + + + marked lost + 已标记丢失 + + + Purge + 清除 + + + OSD + OSD + + + purged + 已清除 + + + destroy + 销毁 + + + destroyed + 已销毁 + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + PG + + + Read bytes + 读字节数 + + + Writes bytes + 写字节数 + + + Read ops + 读请求数 + + + Write ops + 写请求数 + + + Mark OSD + + + 标记 OSD 为 + + + + + Mark + + + 标记为 + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + 最大回填量 + + + Recovery Max Active + 最大活跃恢复请求数 + + + Recovery Max Single Start + 最大单次恢复操作数 + + + Recovery Sleep + 恢复/回填操作间隔睡眠时间 + + + Custom + 自定义 + + + Updated OSD recovery speed priority " + " + + 已更新 OSD 恢复速度优先级“ + ” + + + + + was initialized in the following OSD: + + + 如下 OSD 已经启动了 + 操作: + + + + + Create silence + Create silence + + + Job + 任务 + + + Severity + 严重程度 + + + Started + 已启动 + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + 更新完成 + + + Ends + Ends + + + Silence + Silence + + + Used + 已使用 + + + Avail. + 空闲 + + + Clean + 正常 + + + Working + 运行中 + + + Warning + 警报 + + + Unknown + 未知 + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + 启用中 + + + no filesystems + 无文件系统 + + + active + 工作 + + + standby + 待机 + + + n/a + n/a + + + active daemon + 工作的守护进程 + + + quorum + quorum + + + The NFS Ganesha service is not configured. + NFS Ganesha 服务的配置还没有完成。 + + + Transport + 传输 + + + CephFS User + CephFS 用户 + + + CephFS Filesystem + CephFS 文件系统 + + + (inherited from global config) + (继承自全局配置) + + + inherited from global config + 继承自全局配置 + + + -- Select what kind of user id squashing is performed -- + -- 选择执行哪种类型的用户 ID 匿名访问 -- + + + There are no daemons available. + 没有可用的守护进程。 + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + 缓存模式 + + + Min Evict Age + 最少延迟赶出时间 + + + Min Flush Age + 最少延迟刷回时间 + + + Target Max Bytes + 目标器最大字节数 + + + Target Max Objects + 目标器最大对象数 + + + No applications added + 还没有任何应用标记 + + + Applications limit reached + 应用标记到了上限 + + + A pool can only have up to four applications definitions. + 一个存储池最多能有四个应用标记。 + + + Allowed characters '_a-zA-Z0-9' + 可用的字符为“_a-zA-Z0-9” + + + Maximum length is 128 characters + 长度限制为 128 个字符 + + + Filter or add applications + 添加应用标记或根据其进行筛选 + + + Add application + 添加应用标记 + + + pool + pool + + + erasure code profile + 纠删码配置 + + + Replica Size + 副本个数 + + + Last Change + 最后修改时间 + + + Erasure Coded Profile + 纠删码配置 + + + Crush Ruleset + CRUSH 规则集 + + + Write bytes + 写字节数 + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + 存储桶 + + + Updated Object Gateway bucket " + " + + 已更新对象网关存储桶“ + ” + + + + Created Object Gateway bucket " + " + + 已创建对象网关存储桶“ + ” + + + + buckets + 存储桶 + + + capability + capability + + + user + 用户 + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + 已更新对象网关用户“ + ” + + + + Created Object Gateway user " + " + + 已创建对象网关用户“ + ” + + + + users + 用户 + + + Swift Key + Swift Key + + + Scope + 作用范围 + + + Read + 读权限 + + + Create + 新建 + + + role + role + + + Created role ' + ' + + 新建角色“ + ” + + + + Updated role ' + ' + + 更新角色“ + ” + + + + System Role + 系统角色 + + + Deleted role ' + ' + + 已删除角色“ + ” + + + + Created user " + " + + 已新建用户“ + ” + + + + Update user + 更新用户 + + + Continue + 继续 + + + You were automatically logged out because your roles have been changed. + 您被自动登出,因为您的角色有了变动。 + + + Updated user " + " + + 已更新用户“ + ” + + + + Deleted user " + " + + 已删除用户“ + ” + + + + Failed to delete user " + " + + 删除用户“ + ”失败 + + + + You are currently logged in as " + ". + + 您当前在用“ + ”的身份登录。 + + + + Each object is split in data-chunks parts, each stored on a different OSD. + 各对象都被分割为数据块,分别存储于不同 OSD 。 + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + 计算各对象的编码块、并存储于不同 OSD 。 +编码块的数量等同于在不丢数据的前提下允许同时失效的 OSD 数量。 + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + jerasure 插件是最通用、最灵活的插件, +也是 Ceph 纠删码存储池的默认插件。 + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + reed_sol_van 技术更灵活:它足以设置 k 和 m 值。 +cauchy_good 技术更快,但你得谨慎地选择 packetsize 值。 +reed_sol_r6_op 、 liberation 、 blaum_roth 、 liber8tion 都是与 RAID6 等价的技术, +它们只能配置为 m=2 。 + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + 以 bytes 大小的包为单位进行编码。 +确定合适的包尺寸很难, +jerasure 文档对此有很详细的描述。 + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + 用 jerasure 插件时,纠删码编码的对象存储在多个 OSD 上, +丢失一个 OSD 的恢复过程需读取所有其他的 OSD 。 +比如 jerasure 的配置为 k=8 且 m=4 ,丢失一个 OSD 后需读取其他 11 个 OSD 才能恢复。 + +lrc 纠删码插件创建的是局部校验块,这样只需较少的 OSD 即可恢复。 +比如 lrc 的配置为 k=8 、 m=4 且 l=4 ,它将为每四个 OSD 创建额外的校验块, +当一个 OSD 丢失时,它只需四个 OSD 即可恢复,而不需要十一个。 + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + 把编码块和数据块分组为大小为 locality 的集合。 +比如, k=4 且 m=2 时,若设置 locality=3 ,将会分组为大小为三的两组, +这样各组都能自行恢复,无需从另一组读数据块。 + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + 由 l 定义的块集合将按哪种 crush 桶类型存储。 +比如,若设置为 rack ,大小为 l 块的各组将被存入不同的机架, +此值会被用于创建类似 step choose rack 的规则集。 +如果没设置,就不会这样分组。 + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + isa 插件封装了 ISA 库。它只能运行在 Intel 处理器上。 + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + ISA 插件包含两种 Reed Solomon 编码形式。 +设置为 reed_sol_van 表示用 Vandermonde 算法,设置为 cauchy 表示用 Cauchy 算法。 + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + shec 插件封装了 multiple SHEC 库。 +与 Reed Solomon 编码相比,它能使 Ceph 更高效地恢复数据。 + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + 奇偶校验块数量,它们在各自的计算范围内包含了各数据块。 +此数值被用作持久性估值。 +例如,假设 c=2 ,就是说不丟数据的情况下可损失 2 个 OSD 。 + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + 规则集第一步所指向的 CRUSH 桶之名, +如 step take default 。 + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + 确保两个编码块不会存在于同一故障域的桶里面。 +比如,假设故障域是 host ,就不会有两个编码块存储到同一主机; +此值用于在规则集中创建类似 step chooseleaf host 的步骤。 + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + 使用 CRUSH 索引中的 crush 设备类名, +将归置限制于特定类的设备(例如,ssd 或 hdd)。 + + + Set the directory name from which the erasure code plugin is loaded. + 设置纠删码插件所在目录。 + + + Allows all operations + 允许所有操作 + + + Allows only operations that do not modify the server + 只允许不修改服务器端数据的操作 + + + Does not allow read or write operations, but allows any other operation + 禁止读写,但是允许其他的操作 + + + Does not allow read, write, or any operation that modifies file attributes or directory content + 禁止读、写以及任何可能修改文件内容的操作 + + + Allows no access at all + 完全禁止访问 + + + -- Select the priority -- + -- 选择优先级 -- + + + Low + + + + High + + + + Last 5 minutes + 过去 5 分钟 + + + Last 15 minutes + 过去 15 分钟 + + + Last 30 minutes + 过去 30 分钟 + + + Last 1 hour (Default) + 过去 1 小时(默认) + + + Last 3 hours + 过去 3 小时 + + + Last 6 hours + 过去 6 小时 + + + Last 12 hours + 过去 12 小时 + + + Last 24 hours + 过去 24 小时 + + + Yesterday + 昨天 + + + Today + 今天 + + + Today so far + 今天到现在为止 + + + Day before yesterday + 前天 + + + Last 2 days + 过去 2 天 + + + This day last week + 上周的今天 + + + Previous week + 上个星期 + + + This week + 本周 + + + This week so far + 本周以来 + + + Last 7 days + 过去 7 天 + + + Previous month + 上个月 + + + This month + 当月 + + + This month so far + 本月以来 + + + Last 30 days + 过去 30 天 + + + Last 90 days + 过去 90 天 + + + Last 6 months + 过去 6 个月 + + + Last 1 year + 过去 1 年 + + + Previous year + 去年 + + + This year + 今年 + + + This year so far + 今年以来 + + + Last 2 years + 过去 2 年 + + + Last 5 years + 过去 5 年 + + + Information + 信息 + + + No items selected. + 无选中项目。 + + + Deselect item to select again + 取消选择 + + + Selection limit reached + 达到选择项数上限。 + + + Filter tags + 过滤标签 + + + Add badge + 添加 badge + + + There are no items available. + 无可选项目。 + + + Add + 添加 + + + Remove + Remove + + + Clone + 克隆 + + + Copy + 复制 + + + Deep Scrub + 深层洗刷 + + + Destroy + 销毁 + + + Flatten + 展开 + + + Mark Down + 标记为停用 + + + Mark In + 标记为加入 + + + Mark Lost + 标记为丢失 + + + Mark Out + 标记为已除名 + + + Protect + 保护 + + + Rename + 重命名 + + + Restore + 恢复 + + + Move to Trash + 移至回收站 + + + Unprotect + 解除保护 + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + 删除完成 + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + 克隆完成 + + + Copied + 复制完成 + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + + + + No + + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + 服务质量 (QoS) + + + BPS Limit + BPS 上限 + + + The desired limit of IO bytes per second. + 指定的每秒 IO 字节数上限。 + + + IOPS Limit + IOPS 上限 + + + The desired limit of IO operations per second. + 指定的每秒 IO 操作次数上限。 + + + Read BPS Limit + 读 BPS 上限 + + + The desired limit of read bytes per second. + 指定的每秒内读取的字节数上限。 + + + Read IOPS Limit + 读 IOPS 上限 + + + The desired limit of read operations per second. + 指定的每秒读操作次数上限。 + + + Write BPS Limit + 写 BPS 上限 + + + The desired limit of write bytes per second. + 指定的每秒内写入的字节数上限。 + + + Write IOPS Limit + 写 IOPS 上限 + + + The desired limit of write operations per second. + 指定的每秒写操作次数上限。 + + + BPS Burst + BPS 突发 + + + The desired burst limit of IO bytes. + 指定的 IO 字节数突发上限。 + + + IOPS Burst + IOPS 突发 + + + The desired burst limit of IO operations. + 指定的 IO 操作次数突发上限。 + + + Read BPS Burst + 读 BPS 突发 + + + The desired burst limit of read bytes. + 指定的读取的字节数突发上限。 + + + Read IOPS Burst + 读 IOPS 突发 + + + The desired burst limit of read operations. + 指定的读操作次数突发上限。 + + + Write BPS Burst + 写 BPS 突发 + + + The desired burst limit of write bytes. + 指定的写入的字节数突发上限。 + + + Write IOPS Burst + 写 IOPS 突发 + + + The desired burst limit of write operations. + 指定的写操作次数突发上限。 + + + Failed to + + + + + + 失败 + + + + Executing + 正在执行 + + + execute + 执行 + + + Executed + 执行完毕 + + + unknown task + 未知任务 + + + Creating + 正在创建 + + + create + 创建 + + + Updating + 正在更新 + + + update + 更新 + + + Deleting + 正在删除 + + + delete + 删除 + + + RBD ' + ' + + RBD“ + ” + + + + RBD snapshot ' + ' + + RBD 快照“ + ” + + + + mirror mode for pool ' + ' + + 存储池“ + ”的镜像模式 + + + + mirror peer for pool ' + ' + + 存储池“ + ”的镜像同伴 + + + + all dashboards + all dashboards + + + Name is already used by + . + + 该名称已被 + 使用。 + + + + Name is already used by + . + + 该名称已被 + 使用。 + + + + Name is already used by + . + + 该名称已被 + 使用。 + + + + + contains snapshots. + + + 包含有快照。 + + + + Cloning + 正在克隆 + + + clone + 克隆 + + + Snapshot of + must be protected. + + + 的快照必须处于受保护状态。 + + + + Copying + 正在复制 + + + copy + 复制 + + + Flattening + 正在展开 + + + flatten + 展开 + + + Flattened + 展开完成 + + + Name is already used by + . + + 该名称已被 + 使用。 + + + + Cannot unprotect + because it contains child images. + + 无法去掉 + 的保护状态,因为它有子映像。 + + + + Cannot delete + because it's protected. + + 无法删除 + ,因为它处于受保护状态。 + + + + Rolling back + 正在回滚 + + + rollback + 回滚 + + + Rolled back + 回滚完成 + + + Moving + 正在把 + + + move + + + + Moved + 已经把 + + + image ' + ' to trash + + 映像“ + ”移至回收站 + + + + Could not find image. + 无法找到映像。 + + + Restoring + 正在把 + + + restore + + + + Restored + 已经把 + + + image ' + ' into ' + ' + + 映像从“ + ”恢复到“ + ” + + + + Image name ' + ' is already in use. + + 映像名称“ + ”已被使用。 + + + + image ' + ' + + 映像“ + ” + + + + Purging + 正在清除 + + + purge + 清除 + + + Purged + 已清除 + + + all pools + 所有存储池 + + + images from + + + + 里的映像 + + + + Cannot disable mirroring because it contains a peer. + 因为包含同伴集群,无法禁用镜像功能 + + + pool ' + ' + + 存储池“ + ” + + + + erasure code profile ' + ' + + 纠删码配置“ + ” + + + + target ' + ' + + 目标器“ + ” + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf new file mode 100644 index 00000000..0134f8bc --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.zh-TW.xlf @@ -0,0 +1,4371 @@ + + + + + Toggle navigation + 切換導覽 + + + Dashboard + 儀表板 + + + Cluster + 叢集 + + + Hosts + 主機 + + + Monitors + 監控程式 + + + OSDs + OSD + + + Configuration + 組態 + + + CRUSH map + CRUSH 地圖 + + + Manager modules + 管理員模組 + + + Logs + 記錄 + + + Alerts + 警示 + + + Silences + Silences + + + Pools + + + + Block + 區塊 + + + Images + 影像 + + + Mirroring + 鏡像 + + + iSCSI + iSCSI + + + NFS + NFS + + + Filesystems + 檔案系統 + + + Object Gateway + 物件閘道 + + + Daemons + 精靈 + + + Users + 使用者 + + + Buckets + + + + Retrieving data + for + + + . Please wait... + + Retrieving data + for + + + . Please wait... + + + + Displaying previously cached data + + for + + + . + + Displaying previously cached data + + for + + + . + + + + Could not load data + for + + + . + Please check the cluster health. + + Could not load data + for + + + . + Please check the cluster health. + + + + Back + 返回 + + + Select a Language + 選取語言 + + + Loading panel data... + 正在載入面板資料... + + + Please consult the + documentation + on how to + configure and enable the monitoring functionality. + + 如需了解如何設定和啟用監控功能, + 請參閱 + 文件 + 。 + + + + Grafana Dashboard doesn't exist. Please refer to + documentation + on how to + add dashboards to Grafana. + + Grafana 儀表板不存在。如需了解 + 如何向 Grafana 新增儀表板, + 請參閱 + 文件 + 。 + + + + Grafana Time Picker + Grafana 時間選擇器 + + + Reset Settings + 重設設定 + + + Refresh + Refresh + + + Remove the custom configuration value. The default configuration will be inherited and used instead. + Remove the custom configuration value. The default configuration will be inherited and used instead. + + + The entered value is too high! It must not be greater than + . + + The entered value is too high! It must not be greater than + . + + + + The entered value is too low! It must not be lower than + . + + The entered value is too low! It must not be lower than + . + + + + Failed to load data. + 無法載入資料。 + + + selected + 選取的數目 + X selected + + + found + 找到的數目 + X found + + + total + 總計 + X total + + + Edit + 編輯 + + + Name + 名稱 + + + Description + 描述 + + + Long description + 詳細描述 + + + Default + 預設值 + + + Daemon default + 精靈預設值 + + + Services + 服務 + + + Values + + + + The entered value is too high! It must not be greater than + . + + 輸入的值太高!該值不得大於 + 。 + + + + The entered value is too low! It must not be lower than + . + + 輸入的值太低!該值不得小於 + 。 + + + + Save + 儲存 + + + CRUSH map viewer + CRUSH 地圖檢視器 + + + Hosts List + 主機清單 + + + Overall Performance + 整體效能 + + + No entries found + 找不到項目 + + + Cluster Logs + 叢集記錄 + + + Audit Logs + 稽核記錄 + + + Priority: + Priority: + + + Keyword: + Keyword: + + + Date: + Date: + + + Datepicker + Datepicker + + + Time range: + Time range: + + + Loading configuration... + 正在載入組態... + + + The configuration could not be loaded. + 無法載入組態。 + + + Edit Manager module + 編輯管理員模組 + + + The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + 輸入的值不是有效的 UUID,例如 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8 + + + The entered value needs to be a valid IP address. + 輸入的值必須是有效的 IP 位址。 + + + This field is required. + 此欄位為必填欄位。 + + + The entered value is too high! It must be lower or equal to + . + + 輸入的值太高!該值必須小於或等於 + 。 + + + + The entered value is too low! It must be greater or equal to + . + + 輸入的值太低!該值必須大於或等於 + 。 + + + + The entered value needs to be a number. + 輸入的值必須為數字。 + + + The entered value needs to be a number or decimal. + 輸入的值必須為數字或小數。 + + + Update + 更新 + + + Status + 狀態 + + + Cluster ID + 叢集 ID + + + monmap modified + monmap 修改時間 + + + monmap epoch + monmap 版本編號 + + + quorum con + quorum con + + + quorum mon + quorum mon + + + required con + required con + + + required mon + required mon + + + In Quorum + 仲裁成員 + + + Not In Quorum + 非仲裁成員 + + + Cancel + 取消 + + + Are you sure that you want to + + + + ? + + Are you sure that you want to + + + + ? + + + + Are you sure that you want to + the selected items? + + Are you sure that you want to + the selected items? + + + + Are you sure that you want to + the selected + ? + + 確定要 + 選取的 + 嗎? + + + + Yes, I am sure. + 是的,我確定。 + + + Cluster-wide OSD Flags + 叢集範圍的 OSD 旗標 + + + Submit + 提交 + + + + + + + + + + + form title + + + Advanced... + 進階... + + + Advanced configuration options + Advanced configuration options + + + + + + + + + + + form action button + + + OSD Recovery Priority + OSD 復原優先程度 + + + Priority + 優先程度 + + + Customize priority values + 自訂優先程度值 + + + This field is required! + 此欄位為必填欄位! + + + [object Object] + [object Object] + + + The entered value is too high! It must not be greater than + . + + 輸入的值太高!該值不得大於 + 。 + + + + The entered value is too low! It must not be lower than + . + + 輸入的值太低!該值不得小於 + 。 + + + + Reweight OSD + 重新設定 OSD 的權數 + + + The value needs to be between 0 and 1. + 該值必須介於 0 至 1 之間。 + + + Reweight + 重新設定權數 + + + OSDs + Scrub + + OSD + 整理 + + + + {VAR_SELECT, select, 1 {Deep } } + {VAR_SELECT, select, 1 {深層} } + + + You are about to apply a + scrub to + the OSD + + + . + + 即將對 OSD + + + + 套用 + 整理。 + + + + {VAR_SELECT, select, 1 {deep } } + {VAR_SELECT, select, 1 {深層} } + + + OSDs List + OSD 清單 + + + + OSD + + will be marked + + + if you proceed. + + 若繼續, + OSD + + + 將被標示為 + + + 。 + + + + The OSD is not safe to destroy! + OSD 不安全,無法損毀! + + + + OSD + + will be + + + if you proceed. + + 若繼續, + OSD + + + 將被 + + + 。 + + + + Details + 詳細資料 + + + Matcher + Matcher + + + -- Select an attribute to match against -- + -- Select an attribute to match against -- + + + Value + + + + Use regular expression + Use regular expression + + + {VAR_SELECT, select, 1 {Update} other {Add} } + {VAR_SELECT, select, 1 {Update} other {Add} } + + + Close + 關閉 + + + Delete + 刪除 + + + Editing a silence will expire the old silence and recreate it as a new silence + Editing a silence will expire the old silence and recreate it as a new silence + + + Creator + Creator + + + Comment + Comment + + + Start time + Start time + + + If the start time lies in the past the creation time will be used + If the start time lies in the past the creation time will be used + + + Duration + Duration + + + End time + End time + + + Matchers + * + + + Matchers + * + + + + + A silence requires at least one matcher + A silence requires at least one matcher + + + Add matcher + Add matcher + + + Health + 狀態 + + + Statistics + 統計資料 + + + Please consult the + documentation + + on how to configure and enable the NFS Ganesha management functionality. + + 如需了解如何設定和啟用 NFS Ganesha 管理功能, + 請參閱 + 文件 + 。 + + + + Clients + 用戶端 + + + Any client can access + 任何用戶端均可存取 + + + Addresses + 位址 + + + Required field + 必填欄位 + + + Must contain one or more comma-separated values + 必須包含一或多個逗號分隔值 + + + For example: + 例如︰ + + + Access Type + 存取類型 + + + Squash + Squash + + + Add clients + 新增用戶端 + + + Loading... + 正在載入... + + + -- No cluster available -- + -- 沒有可用的叢集 -- + + + -- Select the cluster -- + -- 選取叢集 -- + + + Add daemon + 新增精靈 + + + Storage Backend + 儲存後端 + + + -- No data pools available -- + -- 沒有可用的資料池 -- + + + -- Select the storage backend -- + -- 選取儲存後端 -- + + + Object Gateway User + 物件閘道使用者 + + + -- No users available -- + -- 沒有可用的使用者 -- + + + -- Select the object gateway user -- + -- 選取物件閘道使用者 -- + + + CephFS User ID + CephFS 使用者 ID + + + -- No clients available -- + -- 沒有可用的用戶端 -- + + + -- Select the cephx client -- + -- 選取 cephx 用戶端 -- + + + CephFS Name + CephFS 名稱 + + + -- No CephFS filesystem available -- + -- No CephFS filesystem available -- + + + -- Select the CephFS filesystem -- + -- Select the CephFS filesystem -- + + + Security Label + 安全標籤 + + + Enable security label + 啟用安全標籤 + + + CephFS Path + CephFS 路徑 + + + Path need to start with a '/' and can be followed by a word + 路徑必須以「/」開頭,後面可接單詞 + + + New directory will be created + 將建立新目錄 + + + Path + 路徑 + + + Path can only be a single '/' or a word + 路徑只能以單一「/」或單詞開頭 + + + New bucket will be created + 將建立新桶 + + + NFS Protocol + NFS 通訊協定 + + + NFSv3 + NFSv3 + + + NFSv4 + NFSv4 + + + NFS Tag + NFS 標記 + + + Alternative access for + NFS v3 + mounts (it must not have a leading /). + + + NFS v3 + 掛接的備用存取 (不得包含前置 /)。 + + + + Clients may not mount subdirectories (i.e. if Tag = foo, the client may not mount foo/baz). + 用戶端不能掛接子目錄 (即如果標記為 foo,則用戶端無法掛接 foo/baz)。 + + + By using different Tag options, the same Path may be exported multiple times. + 透過使用不同標記選項,可將同一路徑輸出多次。 + + + Pseudo + 虛擬 + + + The position that this + NFS v4 + export occupies + in the + Pseudo FS + (it must be unique). + + 此 + NFS v4 + 輸出在 + 虛擬檔案系統 + 中 + 所佔用的位置 (必須唯一)。 + + + + By using different Pseudo options, the same Path may be exported multiple times. + 透過使用不同虛擬選項,可將同一路徑輸出多次。 + + + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ). + + + -- No access type available -- + -- 沒有可用的存取類型 -- + + + -- Select the access type -- + -- 選取存取類型 -- + + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + The Object Gateway NFS backend has a number of + limitations which will seriously affect applications writing to + the share. Please consult the + documentation + for details before enabling write access. + + + + -- No squash available -- + -- 沒有可用的 squash -- + + + --Select what kind of user id squashing is performed -- + -- 選取執行哪種類型的使用者 ID 匿名存取 -- + + + Transport Protocol + 傳輸通訊協定 + + + UDP + UDP + + + TCP + TCP + + + CephFS + CephFS + + + Welcome to Ceph! + 歡迎使用 Ceph! + The welcome message on the login page + + + Username is required + 需要指定使用者名稱 + + + Password is required + 需要指定密碼 + + + Login + 登入 + + + Sorry, the user does not exist in Ceph. + 抱歉,該使用者不存在於 Ceph 中。 + + + Return to + Login Page + . You'll be logged out from the Identity Provider when you retry logging in. + + 返回 + 登入頁面 + 。 當您重試登入時,您將從身分提供者登出。 + + + + Forbidden + 已禁止 + + + Sorry, you are not allowed to see what you were looking for. + 抱歉,您無權查看您要尋找的內容。 + + + Sorry, we could not find what you were looking for + 抱歉,我們找不到您要尋找的內容。 + + + Remove all + 全部移除 + + + Recent Notifications + 最近的通知 + + + There are no background tasks. + 沒有背景任務。 + + + Background Tasks + 背景任務 + + + Help + 說明 + + + Documentation + 文件 + + + API + API + + + About + 關於 + + + Dashboard Settings + 儀表板設定 + + + User management + 使用者管理 + + + Logged in user + 登入的使用者 + + + Signed in as + + + + + 以 + + + + 身分登入 + + + + Sign out + 登出 + + + Name... + 名稱... + + + The chosen name is already in use. + 所選的名稱已在使用中。 + + + Description... + 描述... + + + Permissions + 許可權 + + + Roles + 角色 + + + Username + 使用者名稱 + + + Password + 密碼 + + + Confirm password + 確認密碼 + + + Password confirmation doesn't match the password. + 確認的密碼與之前輸入的密碼不符。 + + + Full name + 全名 + + + Email + 電子郵件 + + + Invalid email. + 電子郵件無效。 + + + You are about to remove "user read / update" permissions from your own user. + 您正要為您自己的使用者移除「使用者讀取/寫入」許可權。 + + + If you continue, you will no longer be able to add or remove roles from any user. + 若繼續,您將再也無法為任何使用者新增或移除角色。 + + + Are you sure you want to continue? + 確定要繼續嗎? + + + Performance counters not available + 沒有可用的效能計數器 + + + Attributes (OSD map) + 屬性 (OSD 地圖) + + + Metadata not available + 無法使用中繼資料 + + + Metadata + 中繼資料 + + + Performance counter + 效能計數器 + + + Histogram not available: + + + 無法使用長條圖︰ + + + + + Writes + 寫入 + + + Reads + 讀取 + + + Histogram + 長條圖 + + + Performance Details + 效能詳細資料 + + + Current values + 目前的值 + + + Type + 類型 + + + Min + 最小值 + + + Max + 最大值 + + + Flags + 旗標 + + + Source + 來源 + + + Level + 層級 + + + Can be updated at runtime (editable) + 可在執行時期更新 (可編輯) + + + Tags + 標記 + + + Enum values + 列舉值 + + + See also + 另請參閱 + + + Cluster Status + 叢集狀態 + + + Manager Daemons + 管理員精靈 + + + Object Gateways + 物件閘道 + + + Metadata Servers + 中繼資料伺服器 + + + iSCSI Gateways + iSCSI 閘道 + + + Client IOPS + 用戶端 IOPS + + + Client Throughput + 用戶端輸送量 + + + Client Read/Write + 用戶端讀取/寫入 + + + Recovery Throughput + 復原輸送量 + + + Scrub + 整理 + + + Performance + 效能 + + + Raw Capacity + 原始容量 + + + Objects + 物件 + + + PGs per OSD + 每個 OSD 的 PG 數 + + + PG Status + PG 狀態 + + + Capacity + 容量 + + + + + See + Logs + for more details. + + + + 如需詳細資料,請參閱 + 記錄 + 。 + + + + Ranks + 階層 + + + MDS performance counters + MDS performance counters + + + Clients: + + + 用戶端︰ + + + + + Clients ( + ) + + Clients ( + ) + + + + Move an image to trash + 將影像移至垃圾桶 + + + To move + + / + + to trash, + click + Move Image + . Optionally, you can pick an expiration date. + + 若要將 + + / + + 移至垃圾桶, + 請按一下 + 移動影像 + 。或者,您可以選取一個過期日。 + + + + Protection expires at + 保護的過期日為 + + + NOT PROTECTED + 無保護 + + + Wrong date format. Please use "YYYY-MM-DD HH:mm:ss". + 日期格式錯誤。請使用「YYYY-MM-DD HH:mm:ss」。 + + + Protection has already expired. Please pick a future date or leave it empty. + 保護已過期。請選取一個未來的日期或保留空白。 + + + Move Image + 移動影像 + + + Gateways + Gateways + + + Must be greater than or equal to + . + + Must be greater than or equal to + . + + + + Must be less than or equal to + . + + Must be less than or equal to + . + + + + Overview + 綜覽 + + + Targets + 目標 + + + Discovery Authentication + 探查驗證 + + + User + 使用者 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + 使用者名稱的長度必須介於 8 至 64 個字元之間,並且只能包含以下 + 字元︰字母、「.」、「@」、「-」、「_」或「:」。 + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Mutual User + 雙向驗證使用者 + + + Mutual Password + 雙向驗證密碼 + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Please consult the + documentation + + on how to configure and enable the iSCSI Targets management functionality. + + 如需了解如何設定和啟用 iSCSI 目標管理功能, + 請參閱 + 文件 + 。 + + + + Available information: + 可用資訊︰ + + + iSCSI Targets not available + 無法使用 iSCSI 目標 + + + Discovery authentication + Discovery authentication + + + Only available for RBD images with + fast-diff + enabled + + 僅適用於已啟用 + fast-diff + 的 RBD 影像 + + + + Pool + + + + Data Pool + 資料池 + + + Created + 已建立 + + + Size + 大小 + + + Object size + 物件大小 + + + Features + 功能 + + + Provisioned + 已佈建 + + + N/A + + + + Total provisioned + 總佈建數 + + + Striping unit + 分割單位 + + + Striping count + 分割計數 + + + Parent + + + + Block name prefix + 區塊名稱字首 + + + Order + 順序 + + + Snapshots + 快照 + + + Image + 影像 + + + This setting overrides the global value + 此設定會覆寫全域值 + + + Global + 全域 + + + This is the global value. No value for this option has been set for this image. + 此值為全域值。未為此影像設定此選項的值。 + + + + from + + + from + + + + '/' and '@' are not allowed. + 不允許使用「/」和「@」。 + + + -- No rbd pools available -- + -- 沒有可用的 RBD 池 -- + + + -- Select a pool -- + -- 選取池 -- + + + Use a dedicated data pool + 使用專屬的資料池 + + + Data pool + 資料池 + + + Dedicated pool that stores the object-data of the RBD. + 專用於儲存 RBD 的物件資料的池 + + + e.g., 10GiB + 例如 10 GiB + + + You have to increase the size. + 您必須增加大小。 + + + Advanced + 進階 + + + Striping + 分割 + + + Stripe unit + 分割單位 + + + -- Select stripe unit -- + -- 選取分割單位 -- + + + This field is required because stripe count is defined! + 由於已定義分割計數,因此必須填寫此欄位! + + + Stripe unit is greater than object size. + 分割單位大於物件大小。 + + + Stripe count + 分割計數 + + + This field is required because stripe unit is defined! + 由於已定義分割單位,因此必須填寫此欄位! + + + Stripe count must be greater than 0. + 分割計數必須大於 0。 + + + + RBD Snapshot + + + RBD 快照 + + + + {VAR_SELECT, select, true {Rename} other {Create} } + {VAR_SELECT, select, true {重新命名} other {建立} } + + + + Snapshot + + + 快照 + + + + PROTECTED + 受保護 + + + UNPROTECTED + 未受保護 + + + You are about to rollback + 您正要復原 + + + Purge Trash + 清除垃圾桶 + + + To purge, select one or All images and click + 若要清除,請選取一個或全部影像,然後按一下 + + + Pool: + 池︰ + + + Pool name... + 池名稱... + + + All + 全部 + + + Restore Image + 回存影像 + + + To restore + 若要回存 + + + type the image's new name and click + 鍵入影像的新名稱并按一下 + + + New Name + 新名稱 + + + Expired at + 過期日為 + + + Protected until + 保護過期日為 + + + This image is protected until + . + + 此影像的保護過期日為 + 。 + + + + Trash + 垃圾桶 + + + iSCSI Topology + iSCSI 拓撲 + + + Configure + Configure + + + Changing these parameters from their default values is usually not necessary. + 通常不需要變更這些參數的預設值。 + + + Identifier + Identifier + + + lun + lun + + + wwn + wwn + + + Settings + 設定 + + + Backstore + 支援儲存 + + + Confirm + 確認 + + + Advanced Settings + 進階設定 + + + Target IQN + 目標 IQN + + + IQN has wrong pattern. + IQN 模式錯誤。 + + + An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName' + IQN 模式應如下所示︰「iqn.$year-$month.$reversedAddress:$definedName」 + + + For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + 例如:iqn.2016-06.org.dashboard:storage:disk.sn-a8675309 + + + More information + 更多資訊 + + + This target has modified advanced settings. + 此目標的進階設定存在修改。 + + + Portals + 入口網站 + + + At least + gateways are required. + + 至少需要 + 個物件閘道。 + + + + Add portal + 新增入口網站 + + + Backstore: + .  + + Backstore: + .  + + + + This image has modified settings. + 此影像的設定存在修改。 + + + Duplicated LUN numbers. + Duplicated LUN numbers. + + + Duplicated WWN. + Duplicated WWN. + + + Add image + 新增影像 + + + ACL authentication + ACL 驗證 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Initiators + 啟動器 + + + Initiator + 啟動器 + + + Client IQN + 用戶端 IQN + + + Initiator IQN needs to be unique. + 啟動器 IQN 必須唯一。 + + + Usernames must have a length of 8 to 64 characters and + can only contain letters, '.', '@', '-', '_' or ':'. + 使用者名稱的長度必須介於 8 至 64 個字元之間,並且只能包含以下 + 字元︰字母、「.」、「@」、「-」、「_」或「:」。 + + + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters + and can only contain letters, '@', '-', '_' or '/'. + + + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + Passwords must have a length of 12 to 16 characters and + can only contain letters, '@', '-', '_' or '/'. + + + Initiator belongs to a group. Images will be configure in the group. + 啟動器屬於群組。影像須在群組中進行設定。 + + + No items added. + 未新增項目。 + + + Add initiator + 新增啟動器 + + + Groups + 群組 + + + Group + 群組 + + + Add group + 新增群組 + + + [object Object] + [object Object] + + + RBD Configuration + RBD 組態 + + + Remove the local configuration value. The parent configuration value will be inherited and used instead. + 移除本地組態值。將繼承並使用父組態值。 + + + The mininum value is 0 + 最小值為 0 + + + Issues + 問題 + + + Syncing + 正在同步 + + + Ready + 準備就緒 + + + Edit pool mirror mode + 編輯池鏡像模式 + + + To edit the mirror mode for pool  + + + , select a new mode from the list and click  + Update + . + + 若要編輯池 + + +   + 的鏡像模式,請從清單中選取一個新模式,然後按一下  + 更新 + 。 + + + + Mode + 模式 + + + Peer clusters must be removed prior to disabling mirror. + 在停用鏡像之前,必須先移除對等叢集。 + + + + + pool mirror peer + + + + 池鏡像對等 + + + + {VAR_SELECT, select, edit {Edit} other {Add} } + {VAR_SELECT, select, edit {編輯} other {新增} } + + + + the pool + mirror peer attributes for pool + + + and click + Submit + . + + + 池 + + + 的 + 鏡像對等屬性,然後按一下 + 提交 + 。 + + + + Cluster Name + 叢集名稱 + + + The cluster name is not valid. + 叢集名稱無效。 + + + CephX ID + CephX ID + + + CephX ID... + CephX ID... + + + The CephX ID is not valid. + CephX ID 無效。 + + + Monitor Addresses + 監控程式位址 + + + Comma-delimited addresses... + 逗號分隔的位址... + + + The monitory address is not valid. + 監控程式位址無效。 + + + CephX Key + CephX 金鑰 + + + Base64-encoded key... + Base64 編碼的金鑰... + + + CephX key must be base64 encoded. + CephX 金鑰必須為 Base64 編碼的金鑰。 + + + Pools List + 池清單 + + + The name can only consist of alphanumeric characters, dashes and underscores. + 名稱只能由英數字元、破折號和底線組成。 + + + The chosen erasure code profile name is already in use. + 所選的糾刪碼設定檔名稱已在使用中。 + + + Plugin + 外掛程式 + + + Data chunks (k) + 資料區塊 (k) + + + Must be equal to or greater than 2. + 必須大於或等於 2。 + + + Coding chunks (m) + 編碼區塊 (m) + + + Must be equal to or greater than 1. + 必須大於或等於 1。 + + + Durability estimator (c) + 持久性估值 (c) + + + Locality (l) + 本地性 (l) + + + Crush failure domain + CRUSH 故障網域 + + + Crush Locality + CRUSH 本地性 + + + None + + + + Technique + 技術 + + + Packetsize + 封包大小 + + + Crush root + CRUSH 根 + + + Crush device class + CRUSH 裝置類別 + + + any + 任何 + + + Directory + 目錄 + + + The chosen Ceph pool name is already in use. + 所選的 Ceph 池名稱已在使用中。 + + + Pool type + 池類型 + + + -- Select a pool type -- + -- 選取池類型 -- + + + Placement groups + 放置群組 + + + At least one placement group is needed! + 至少需要一個放置群組! + + + Your cluster can't handle this many PGs. Please recalculate the PG amount needed. + 您的叢集無法處理這麼多的 PG。請重新計算所需的 PG 數量。 + + + Calculation help + 計算說明 + + + The current PGs settings were calculated for you, you + should make sure the values suit your needs before submit. + 已為您計算目前的 PG 設定,您 + 應在提交前確定這些值符合您的需求。 + + + Crush ruleset + CRUSH 規則集 + + + -- Select a crush rule -- + -- 選取 CRUSH 規則 -- + + + Crush rule + CRUSH 規則 + + + Crush steps + CRUSH 步驟 + + + The rule can't be used in the current cluster as it has + to few OSDs to meet the minimum required OSD by this rule. + 無法在目前的叢集中使用此規則,因為叢集的 + OSD 數量過少,無法滿足規則所需的最低 OSD 數量。 + + + Replicated size + 複製大小 + + + Minimum: + + + 最低︰ + + + + + Maximum: + + + 最高︰ + + + + + The size specified is out of range. A value from + to + is valid. + + 指定的大小超出了範圍。介於 + 至 + 之間的值才有效。 + + + + Erasure code profile + 糾刪碼設定檔 + + + -- No erasure code profile available -- + -- 沒有可用的糾刪碼設定檔 -- + + + -- Select an erasure code profile -- + -- 選取糾刪碼設定檔 -- + + + EC Overwrites + EC 覆寫 + + + Applications + 應用程式 + + + Compression + 壓縮 + + + Algorithm + 演算法 + + + -- No erasure compression algorithm available -- + -- 沒有可用的糾刪壓縮演算法 -- + + + Minimum blob size + Blob 最小大小 + + + e.g., 128KiB + 例如 128 KiB + + + Value should be greater than 0 + 值應大於 0 + + + Value should be less than the maximum blob size + Value should be less than the maximum blob size + + + Maximum blob size + Blob 最大大小 + + + e.g., 512KiB + 例如 512 KiB + + + Value should be greater than the minimum blob size + 值應大於 blob 最小大小 + + + Ratio + 比率 + + + Compression ratio + 壓縮率 + + + Value should be between 0.0 and 1.0 + 值應介於 0.0 至 1.0 之間 + + + It's not possible to create an RBD pool with '/' in the name. + 無法建立名稱中包含「/」的 RBD 池。 + + + Please change the name or remove 'rbd' from the applications list. + 請變更名稱或將「rbd」從應用程式清單中移除。 + + + Cache Tiers Details + 快取層詳細資料 + + + Please consult the + documentation + + on how to configure and enable the Object Gateway management functionality. + + 如需了解如何設定和啟用物件閘道管理功能, + 請參閱 + 文件 + 。 + + + + Daemons List + 精靈清單 + + + Performance Counters + 效能計數器 + + + Loading bucket data... + 正在載入桶資料... + + + The bucket data could not be loaded. + 無法載入桶資料。 + + + Id + ID + + + The value is not valid. + 該值無效。 + + + Owner + 擁有者 + + + -- Select a user -- + -- 選取使用者 -- + + + ID + ID + + + Index type + 索引類型 + + + Placement rule + 放置規則 + + + Marker + 標記 + + + Maximum marker + 最大標記數 + + + Version + 版本 + + + Master version + 主版本 + + + Modification time + 修改時間 + + + Zonegroup + 區域群組 + + + Bucket quota + 桶定額 + + + Enabled + 已啟用 + + + Maximum size + 最大大小 + + + Unlimited + 無限制 + + + Maximum objects + 最大物件數 + + + -- Select a username -- + -- 選取使用者名稱 -- + + + Auto-generate key + 自動產生金鑰 + + + Access key + 存取金鑰 + + + Secret key + 機密金鑰 + + + Email address + 電子郵件地址 + + + Suspended + 已暫停 + + + System + 系統 + + + {VAR_SELECT, select, 0 {No} 1 {Yes} } + {VAR_SELECT, select, 0 {否} 1 {是} } + + + Maximum buckets + 最大桶數 + + + Subusers + 子使用者 + + + Capabilities + 功能 + + + User quota + 使用者定額 + + + Show + 顯示 + + + Keys + 金鑰 + + + -- Select a type -- + -- 選取類型 -- + + + Permission + 許可權 + + + -- Select a permission -- + -- 選取許可權 -- + + + Subuser + 子使用者 + + + The chosen subuser ID is already in use. + 所選的子使用者 ID 已在使用中。 + + + read, write + 讀取、寫入 + + + full + 完整 + + + Swift key + Swift 金鑰 + + + Auto-generate secret + 自動產生機密金鑰 + + + Loading user data... + 正在載入使用者資料... + + + The user data could not be loaded. + 無法載入使用者資料。 + + + The chosen user ID is already in use. + 所選的使用者 ID 已在使用中。 + + + This is not a valid email address. + 電子郵件地址無效。 + + + The chosen email address is already in use. + 所選的電子郵件地址已在使用中。 + + + Max. buckets + 最大桶數 + + + The entered value must be >= 0. + 輸入的值必須大於或等於 0。 + + + S3 key + S3 金鑰 + + + There are no subusers. + 沒有子使用者。 + + + + + + + + + + + + + S3 + S3 + + + There are no keys. + 沒有金鑰。 + + + + + + + + + + + + + Swift + Swift + + + There are no capabilities. + 沒有功能。 + + + + + + + + + + + + + Unlimited size + 大小不限 + + + Max. size + 最大大小 + + + Unlimited objects + 物件數不限 + + + Max. objects + 最大物件數 + + + Current + 目前 + + + Updated discovery authentication + 已更新探查驗證 + + + There are no portals available. + 沒有可用的入口網站。 + + + There are no images available. + 沒有可用的影像。 + + + There are no images available. Please make sure you add an image to the target. + 沒有可用的影像。請確定為目標新增一個影像。 + + + There are no initiators available. Please make sure you add an initiator to the target. + 沒有可用的啟動器。請確定為目標新增一個啟動器。 + + + target + target + + + Target + 目標 + + + # Sessions + # Sessions + + + iSCSI target + iSCSI target + + + State + 狀態 + + + # Targets + # Targets + + + Read Bytes + 讀取位元組數 + + + Write Bytes + 寫入位元組數 + + + Read Ops + 讀取操作數 + + + Write Ops + 寫入操作數 + + + A/O Since + 使用中/最佳化開始時間 + + + Instance + 例項 + + + Hostname + 主機名稱 + + + Issue + 問題 + + + Progress + 進度 + + + Disabled + 已停用 + + + Edit Mode + 編輯模式 + + + Add Peer + 新增對等 + + + Edit Peer + 編輯對等 + + + Delete Peer + 刪除對等 + + + Leader + Leader + + + # Local + 本地數量 + + + # Remote + 遠端數量 + + + mirror peer + 鏡像對等 + + + Key + 金鑰 + + + RBD + RBD + + + Deep flatten + 深層壓平 + + + Layering + 分層 + + + Exclusive lock + 獨佔鎖定 + + + Object map (requires exclusive-lock) + 物件對應 (需要獨佔鎖定) + + + Journaling (requires exclusive-lock) + 記錄 (需要獨佔鎖定) + + + Fast diff (interlocked with object-map) + Fast diff (interlocked with object-map) + + + RBD snapshot rollback + RBD 快照復原 + + + Rollback + 復原 + + + RBD snapshot + RBD 快照 + + + Deleted At + 刪除位置 + + + id + ID + + + type + 類型 + + + state + 狀態 + + + version + 版本 + + + Host + 主機 + + + root + + + + Rank + 階層 + + + Daemon + 精靈 + + + Activity + 活動 + + + Dentries + Dentry + + + Inodes + Inode + + + Usage + 使用率 + + + Standby daemons + 待命精靈 + + + The value can be updated at runtime. + 該值可在執行時期更新。 + + + Daemons/clients do not pull this value from the + monitor config database. We disallow setting this option via 'ceph config + set ...'. This option should be configured via ceph.conf or via the + command line. + 精靈/用戶端不會從監控程式組態資料庫 + 提取此值。我們不允許透過「ceph config set ...」 + 設定此選項。應透過 ceph.conf 或使用指令行 + 進行設定。 + + + Option takes effect only during daemon startup. + 該選項僅在精靈啟動期間生效。 + + + Option only affects cluster creation. + 該選項僅影響叢集建立。 + + + Option only affects daemon creation. + 該選項僅影響精靈建立。 + + + Updated config option + + + 已更新組態選項 + + + + + Service + 服務 + + + Current value + 目前的值 + + + Editable + 可編輯 + + + Updated options for module " + ". + + 已更新模組「 + 」的選項。 + + + + Enable + 啟用 + + + Disable + 停用 + + + Reconnecting, please wait ... + 正在重新連接,請稍候... + + + Public Address + 公用位址 + + + Open Sessions + 開啟的工作階段 + + + No In + 禁止標示為 In + + + OSDs that were previously marked out will not be marked back in when they start + 之前標示為 out 的 OSD 在啟動時將不會重新標示為 in + + + No Out + 禁止標示為 Out + + + OSDs will not automatically be marked out after the configured interval + OSD 在設定的間隔過後將不會自動標示為 out + + + No Up + 禁止標示為 Up + + + OSDs are not allowed to start + 不允許 OSD 啟動 + + + No Down + 禁止標示為 Down + + + OSD failure reports are being ignored, such that the monitors will not mark OSDs down + 將會忽略 OSD 故障報告,如此監控程式便不會將 OSD 標示為 down + + + Pause + 暫停 + + + Pauses reads and writes + 暫停讀取和寫入 + + + No Scrub + 禁止整理 + + + Scrubbing is disabled + 整理已停用 + + + No Deep Scrub + 禁止深層整理 + + + Deep Scrubbing is disabled + 深層整理已停用 + + + No Backfill + 禁止回填 + + + Backfilling of PGs is suspended + PG 回填已暫停 + + + No Recover + 禁止復原 + + + Recovery of PGs is suspended + PG 復原已暫停 + + + Bitwise Sort + 按位元排序 + + + Use bitwise sort + 使用按位元排序 + + + Purged Snapdirs + 已清除 Snapdir + + + OSDs have converted snapsets + OSD 已轉換 snapset + + + Recovery Deletes + 復原刪除 + + + Deletes performed during recovery instead of peering + 在復原期間,而非在建立互聯時執行刪除 + + + PG Log Hard Limit + PG 記錄硬限制 + + + Puts a hard limit on pg log length + 為 pg 記錄長度設定硬限制 + + + Updated OSD Flags + 已更新 OSD 旗標 + + + out + out + + + in + in + + + down + down + + + Mark + 標示 + + + OSD lost + OSD 遺失 + + + marked lost + 已標示為遺失 + + + Purge + 清除 + + + OSD + OSD + + + purged + 已清除 + + + destroy + 損毀 + + + destroyed + 已損毀 + + + Cluster-wide Flags + Cluster-wide Flags + + + Cluster-wide Recovery Priority + Cluster-wide Recovery Priority + + + PG scrub + PG scrub + + + PGs + PG + + + Read bytes + 讀取位元組數 + + + Writes bytes + 寫入位元組數 + + + Read ops + 讀取操作數 + + + Write ops + 寫入操作數 + + + Mark OSD + + + 將 OSD 標示為 + + + + + Mark + + + 標示為 + + + + + PG scrub options + PG scrub options + + + Updated PG scrub options + Updated PG scrub options + + + Max Backfills + 最大回填數 + + + Recovery Max Active + 處於使用中狀態的最大復原操作數 + + + Recovery Max Single Start + 單次啟動的最大復原操作數 + + + Recovery Sleep + 復原操作間隔睡眠時間 + + + Custom + 自訂 + + + Updated OSD recovery speed priority " + " + + 已更新 OSD 復原速度優先程度「 + 」 + + + + + was initialized in the following OSD: + + + 以下 OSD 已啟始化 + 操作︰ + + + + + Create silence + Create silence + + + Job + 工作 + + + Severity + 嚴重性 + + + Started + 已啟動 + + + URL + URL + + + silence + silence + + + Attribute name + Attribute name + + + Regular expression + Regular expression + + + Please add your Prometheus host to the dashboard configuration and refresh the page + Please add your Prometheus host to the dashboard configuration and refresh the page + + + Created by + Created by + + + Updated + 已更新 + + + Ends + Ends + + + Silence + Silence + + + Used + 已使用 + + + Avail. + 可用 + + + Clean + 乾淨 + + + Working + 工作中 + + + Warning + 警告 + + + Unknown + 未知 + + + Healthy + Healthy + + + Misplaced + Misplaced + + + Degraded + Degraded + + + Unfound + Unfound + + + replicas + replicas + + + up + 啟用中 + + + no filesystems + 無檔案系統 + + + active + 使用中 + + + standby + 待命 + + + n/a + + + + active daemon + 使用中的精靈 + + + quorum + quorum + + + The NFS Ganesha service is not configured. + 未設定 NFS Ganesha 服務。 + + + Transport + 傳輸 + + + CephFS User + CephFS 使用者 + + + CephFS Filesystem + CephFS 檔案系統 + + + (inherited from global config) + (繼承自全域組態) + + + inherited from global config + 繼承自全域組態 + + + -- Select what kind of user id squashing is performed -- + -- 選取執行哪種類型的使用者 ID 匿名存取 -- + + + There are no daemons available. + 沒有可用的精靈。 + + + NFS export + NFS export + + + EC Profile + EC Profile + + + Cache Mode + 快取模式 + + + Min Evict Age + 逐出前至少可留存的時間 + + + Min Flush Age + 衝洗前至少可留存的時間 + + + Target Max Bytes + 目標最大位元組數 + + + Target Max Objects + 目標最大物件數 + + + No applications added + 未新增應用程式 + + + Applications limit reached + 已達到應用程式上限 + + + A pool can only have up to four applications definitions. + 一個池最多只能四個應用程式定義。 + + + Allowed characters '_a-zA-Z0-9' + 允許的字元為「_a-zA-Z0-9」 + + + Maximum length is 128 characters + 最大長度為 128 個字元 + + + Filter or add applications + 過濾或新增應用程式 + + + Add application + 新增應用程式 + + + pool + pool + + + erasure code profile + 糾刪碼設定檔 + + + Replica Size + 複本大小 + + + Last Change + 上次變更時間 + + + Erasure Coded Profile + 糾刪碼設定檔 + + + Crush Ruleset + CRUSH 規則集 + + + Write bytes + 寫入位元組數 + + + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + Pool deletion is disabled by the mon_allow_pool_delete configuration setting. + + + bucket + + + + Updated Object Gateway bucket " + " + + 已更新物件閘道桶「 + 」 + + + + Created Object Gateway bucket " + " + + 已建立物件閘道桶「 + 」 + + + + buckets + + + + capability + capability + + + user + 使用者 + + + subuser + subuser + + + S3 Key + S3 Key + + + Updated Object Gateway user " + " + + 已更新物件閘道使用者「 + 」 + + + + Created Object Gateway user " + " + + 已建立物件閘道使用者「 + 」 + + + + users + 使用者 + + + Swift Key + Swift Key + + + Scope + 範圍 + + + Read + 讀取 + + + Create + 建立 + + + role + role + + + Created role ' + ' + + 已建立角色「 + 」 + + + + Updated role ' + ' + + 已更新角色「 + 」 + + + + System Role + 系統角色 + + + Deleted role ' + ' + + 已刪除角色「 + 」 + + + + Created user " + " + + 已建立使用者「 + 」 + + + + Update user + 更新使用者 + + + Continue + 繼續 + + + You were automatically logged out because your roles have been changed. + 您已被自動登出,因為您的角色發生了變更。 + + + Updated user " + " + + 已更新使用者「 + 」 + + + + Deleted user " + " + + 已刪除使用者「 + 」 + + + + Failed to delete user " + " + + 無法刪除使用者「 + 」 + + + + You are currently logged in as " + ". + + 您目前正以「 + 」身分登入。 + + + + Each object is split in data-chunks parts, each stored on a different OSD. + 各物件都被分割成資料區塊部分,分別儲存於不同的 OSD。 + + + Compute coding chunks for each object and store them on different OSDs. + The number of coding chunks is also the number of OSDs that can be down without losing data. + 運算各物件的編碼區塊并將它們儲存到不同的 OSD。 + 編碼區塊的數量等同於在不遺失資料的前提下,可停機的 OSD 數量。 + + + The jerasure plugin is the most generic and flexible plugin, + it is also the default for Ceph erasure coded pools. + Jerasure 外掛程式是最一般、最靈活的外掛程式, + 也是 Ceph 糾刪碼池的預設外掛程式。 + + + The more flexible technique is reed_sol_van : it is enough to set k + and m. The cauchy_good technique can be faster but you need to chose the packetsize + carefully. All of reed_sol_r6_op, liberation, blaum_roth, liber8tion are RAID6 equivalents + in the sense that they can only be configured with m=2. + Reed_sol_van 方法更靈活︰它足以設定 k + 和 m。Cauchy_good 方法更快,但您需要小心選取封包大小。 + 所有 reed_sol_r6_op、liberation、blaum_roth、liber8tion 都 + 等同於 RAID6,它們只能設定為 m=2。 + + + The encoding will be done on packets of bytes size at a time. + Chosing the right packet size is difficult. + The jerasure documentation contains extensive information on this topic. + 將以位元組大小的封包為單位進行編碼。 + 選取合適的封包大小很難。 + Jerasure 文件包含有關此主題的詳細資訊。 + + + With the jerasure plugin, when an erasure coded object is stored on + multiple OSDs, recovering from the loss of one OSD requires reading from all the others. + For instance if jerasure is configured with k=8 and m=4, losing one OSD requires reading + from the eleven others to repair. + + The lrc erasure code plugin creates local parity chunks to be able to recover using + less OSDs. For instance if lrc is configured with k=8, m=4 and l=4, it will create + an additional parity chunk for every four OSDs. When a single OSD is lost, it can be + recovered with only four OSDs instead of eleven. + 使用 jerasure 外掛程式時,若糾刪碼物件儲存於 + 多個 OSD 上,則復原一個遺失的 OSD 時需要讀取所有其他 OSD。 + 例如,若 jerasure 設定為 k=8 且 m=4,則遺失一個 OSD 後需讀取 + 其他十一個 OSD 才能修復。 + + lrc 糾刪碼外掛程式會建立本地同位區塊,因此只需較少的 OSD 即 + 可復原。例如,若 lrc 設定為 k=8、m=4 且 l=4,它將為每四個 OSD + 建立額外的同位區塊。這樣,當一個 OSD 遺失時,它只需四個 OSD + 即可復原,而不需要十一個。 + + + Group the coding and data chunks into sets of size locality. For instance, + for k=4 and m=2, when locality=3 two groups of three are created. Each set can + be recovered without reading chunks from another set. + 將編碼區塊和資料區塊分組為大小為 locality 的集合。例如, + k=4 且 m=2 時,若 locality=3,則會建立 2 個大小為 3 的組。這樣,各組都能 + 自行復原,而無需從另一組讀取區塊。 + + + The type of the crush bucket in which each set of chunks defined + by l will be stored. For instance, if it is set to rack, each group of l chunks will be + placed in a different rack. It is used to create a CRUSH rule step such as step choose + rack. If it is not set, no such grouping is done. + 由 l 定義的區塊集將按哪種 CRUSH 桶類型儲存。 + 例如,若設定為機架,則各組 l 區塊將會被放置到不同的 + 機架中。該值用於建立類似 step choose rack 的 CRUSH + 規則步驟。若未設定,則不會進行此類分組。 + + + The isa plugin encapsulates the ISA library. It only runs on Intel processors. + isa 外掛程式封包了 ISA 程式庫。它只能在 Intel 處理器上執行。 + + + The ISA plugin comes in two Reed Solomon forms. + If reed_sol_van is set, it is Vandermonde, if cauchy is set, it is Cauchy. + ISA 外掛程式包含兩種 Reed Solomon 格式。 + 若設定為 reed_sol_van,則為 Vandermonde。若設定為 cauchy,則為 Cauchy。 + + + The shec plugin encapsulates the multiple SHEC library. + It allows ceph to recover data more efficiently than Reed Solomon codes. + shec 外掛程式封包了多個 SHEC 程式庫。 + 與 Reed Solomon 代碼相比,它能更有效地復原資料。 + + + The number of parity chunks each of which includes each data chunk in its + calculation range. The number is used as a durability estimator. For instance, if c=2, + 2 OSDs can be down without losing data. + 同位區塊的數量,它們在各自的計算範圍內包含了 + 各資料區塊。該數值被用做持久性估值。例如,若 c=2, + 則在不遺失資料的前提下,可有 2 個 OSD 停機。 + + + The name of the crush bucket used for the first step of the CRUSH rule. + For instance step take default. + CRUSH 規則的第一步所指向的 CRUSH 桶名稱。 + 例如 step take default。 + + + Ensure that no two chunks are in a bucket with the same failure + domain. For instance, if the failure domain is host no two chunks will be stored on the same + host. It is used to create a CRUSH rule step such as step chooseleaf host. + 確定兩個區塊不會存在於同一故障網域的桶中。 + 例如,若故障網域為主機,則不會有兩個區塊儲存於同一主機中。 + 該值用於建立類似 step chooseleaf host 的 CRUSH 規則步驟。 + + + Restrict placement to devices of a specific class + (e.g., ssd or hdd), using the crush device class names in the CRUSH map. + 使用 CRUSH 地圖中的 crush 裝置類別名稱, + 將放置限制於特定類別的裝置 (例如 ssd 或 hdd)。 + + + Set the directory name from which the erasure code plugin is loaded. + 設定糾刪碼外掛程式所在目錄。 + + + Allows all operations + 允許所有操作 + + + Allows only operations that do not modify the server + 僅允許不修改伺服器的操作 + + + Does not allow read or write operations, but allows any other operation + 不允許讀取或寫入操作,但是允許任何其他操作 + + + Does not allow read, write, or any operation that modifies file attributes or directory content + 不允許讀取、寫入或任何可能修改檔案屬性或目錄內容的操作 + + + Allows no access at all + 完全禁止存取 + + + -- Select the priority -- + -- 選取優先程度 -- + + + Low + + + + High + + + + Last 5 minutes + 過去 5 分鐘 + + + Last 15 minutes + 過去 15 分鐘 + + + Last 30 minutes + 過去 30 分鐘 + + + Last 1 hour (Default) + 過去 1 小時 (預設值) + + + Last 3 hours + 過去 3 小時 + + + Last 6 hours + 過去 6 小時 + + + Last 12 hours + 過去 12 小時 + + + Last 24 hours + 過去 24 小時 + + + Yesterday + 昨天 + + + Today + 今天 + + + Today so far + 今天到目前為止 + + + Day before yesterday + 前天 + + + Last 2 days + 過去 2 天 + + + This day last week + 上週的今天 + + + Previous week + 上週 + + + This week + 本週 + + + This week so far + 本週目前為止 + + + Last 7 days + 過去 7 天 + + + Previous month + 上個月 + + + This month + 本月 + + + This month so far + 本月目前為止 + + + Last 30 days + 過去 30 天 + + + Last 90 days + 過去 90 天 + + + Last 6 months + 過去 6 個月 + + + Last 1 year + 過去 1 年 + + + Previous year + 去年 + + + This year + 今年 + + + This year so far + 今年目前為止 + + + Last 2 years + 過去 2 年 + + + Last 5 years + 過去 5 年 + + + Information + 資訊 + + + No items selected. + 未選取項目。 + + + Deselect item to select again + 取消選取項目以再次選取 + + + Selection limit reached + 已達到選取上限 + + + Filter tags + 過濾標記 + + + Add badge + 新增徽章 + + + There are no items available. + 沒有可用的項目。 + + + Add + 新增 + + + Remove + Remove + + + Clone + 克隆 + + + Copy + 複製 + + + Deep Scrub + 深層整理 + + + Destroy + 損毀 + + + Flatten + 壓平 + + + Mark Down + 標示為 Down + + + Mark In + 標示為 In + + + Mark Lost + 標示為遺失 + + + Mark Out + 標示為 Out + + + Protect + 保護 + + + Rename + 重新命名 + + + Restore + 還原 + + + Move to Trash + 移至垃圾桶 + + + Unprotect + 取消保護 + + + Recreate + Recreate + + + Expire + Expire + + + Deleted + 已刪除 + + + Added + Added + + + Removed + Removed + + + Edited + Edited + + + Canceled + Canceled + + + Cloned + 已克隆 + + + Copied + 已複製 + + + Showed + Showed + + + Moved to Trash + Moved to Trash + + + Unprotected + Unprotected + + + Recreated + Recreated + + + Expired + Expired + + + Yes + + + + No + + + + Your matcher seems to match no currently defined rule or active alert. + Your matcher seems to match no currently defined rule or active alert. + + + no active alerts + no active alerts + + + 1 active alert + 1 active alert + + + + active alerts + + + active alerts + + + + Matches 1 rule + Matches 1 rule + + + Matches + rules + + Matches + rules + + + + + with + . + + + with + . + + + + Quality of Service + 服務品質 + + + BPS Limit + BPS 上限 + + + The desired limit of IO bytes per second. + 指定的每秒 IO 位元組數上限。 + + + IOPS Limit + IOPS 上限 + + + The desired limit of IO operations per second. + 指定的每秒 IO 操作次數上限。 + + + Read BPS Limit + 讀取 BPS 上限 + + + The desired limit of read bytes per second. + 指定的每秒內讀取的位元組數上限。 + + + Read IOPS Limit + 讀取 IOPS 上限 + + + The desired limit of read operations per second. + 指定的每秒讀取操作次數上限。 + + + Write BPS Limit + 寫入 BPS 上限 + + + The desired limit of write bytes per second. + 指定的每秒內寫入的位元組數上限。 + + + Write IOPS Limit + 寫入 IOPS 上限 + + + The desired limit of write operations per second. + 指定的每秒寫入操作次數上限。 + + + BPS Burst + BPS 高載 + + + The desired burst limit of IO bytes. + 指定的 IO 位元組數高載上限。 + + + IOPS Burst + IOPS 高載 + + + The desired burst limit of IO operations. + 指定的 IO 操作次數高載上限。 + + + Read BPS Burst + 讀取 BPS 高載 + + + The desired burst limit of read bytes. + 指定的讀取的位元組數高載上限。 + + + Read IOPS Burst + 讀取 IOPS 高載 + + + The desired burst limit of read operations. + 指定的讀取操作次數高載上限。 + + + Write BPS Burst + 寫入 BPS 高載 + + + The desired burst limit of write bytes. + 指定的寫入的位元組數高載上限。 + + + Write IOPS Burst + 寫入 IOPS 高載 + + + The desired burst limit of write operations. + 指定的寫入操作次數高載上限。 + + + Failed to + + + + 無法 + + + + + + Executing + 正在執行 + + + execute + 執行 + + + Executed + 已執行 + + + unknown task + 未知任務 + + + Creating + 正在建立 + + + create + 建立 + + + Updating + 正在更新 + + + update + 更新 + + + Deleting + 正在刪除 + + + delete + 刪除 + + + RBD ' + ' + + RBD「 + 」 + + + + RBD snapshot ' + ' + + RBD 快照「 + 」 + + + + mirror mode for pool ' + ' + + 池「 + 」的鏡像模式 + + + + mirror peer for pool ' + ' + + 池「 + 」的鏡像對等 + + + + all dashboards + all dashboards + + + Name is already used by + . + + 名稱已被 + 使用。 + + + + Name is already used by + . + + 名稱已被 + 使用。 + + + + Name is already used by + . + + 名稱已被 + 使用。 + + + + + contains snapshots. + + + 包含快照。 + + + + Cloning + 正在克隆 + + + clone + 克隆 + + + Snapshot of + must be protected. + + 必須保護 + 的快照。 + + + + Copying + 正在複製 + + + copy + 複製 + + + Flattening + 正在壓平 + + + flatten + 壓平 + + + Flattened + 已壓平 + + + Name is already used by + . + + 名稱已被 + 使用。 + + + + Cannot unprotect + because it contains child images. + + 無法保護 + ,因為其包含子影像。 + + + + Cannot delete + because it's protected. + + 無法刪除 + ,因為其處於保護狀態。 + + + + Rolling back + 正在復原 + + + rollback + 復原 + + + Rolled back + 已復原 + + + Moving + 正在移動 + + + move + 移動 + + + Moved + 已移動 + + + image ' + ' to trash + + 影像「 + 」到垃圾桶 + + + + Could not find image. + 找不到影像。 + + + Restoring + 正在還原 + + + restore + 還原 + + + Restored + 已還原 + + + image ' + ' into ' + ' + + 影像「 + 」(到「 + 」) + + + + Image name ' + ' is already in use. + + 影像名稱「 + 」已在使用中。 + + + + image ' + ' + + 影像「 + 」 + + + + Purging + 正在清除 + + + purge + 清除 + + + Purged + 已清除 + + + all pools + 所有池 + + + images from + + + 影像 (從 + ) + + + + Cannot disable mirroring because it contains a peer. + 無法停用鏡像,因為其包含對等。 + + + pool ' + ' + + 池「 + 」 + + + + erasure code profile ' + ' + + 糾刪碼設定檔「 + 」 + + + + target ' + ' + + 目標「 + 」 + + + + NFS + + + NFS + + + + + + \ No newline at end of file diff --git a/src/pybind/mgr/dashboard/frontend/src/main.ts b/src/pybind/mgr/dashboard/frontend/src/main.ts new file mode 100644 index 00000000..741c9eb8 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/main.ts @@ -0,0 +1,13 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.log(err)); diff --git a/src/pybind/mgr/dashboard/frontend/src/polyfills.ts b/src/pybind/mgr/dashboard/frontend/src/polyfills.ts new file mode 100644 index 00000000..6eb2cc38 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/polyfills.ts @@ -0,0 +1,67 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +import 'core-js/es6/array'; +import 'core-js/es6/date'; +import 'core-js/es6/function'; +import 'core-js/es6/map'; +import 'core-js/es6/math'; +import 'core-js/es6/number'; +import 'core-js/es6/object'; +import 'core-js/es6/parse-float'; +import 'core-js/es6/parse-int'; +import 'core-js/es6/regexp'; +import 'core-js/es6/set'; +import 'core-js/es6/string'; +import 'core-js/es6/symbol'; +import 'core-js/es6/weak-map'; +import 'core-js/es7/object'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + +/** + * Required to support Web Animations `@angular/platform-browser/animations`. + * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/*************************************************************************************************** + * Zone JS is required by Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/** + * Date, currency, decimal and percent pipes. + * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 + */ +// import 'intl'; // Run `npm install --save intl`. +/** + * Need to import at least one locale-data with intl. + */ +// import 'intl/locale-data/jsonp/en'; diff --git a/src/pybind/mgr/dashboard/frontend/src/setupJest.ts b/src/pybind/mgr/dashboard/frontend/src/setupJest.ts new file mode 100644 index 00000000..f695767e --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/setupJest.ts @@ -0,0 +1,4 @@ +import 'jest-preset-angular'; +import 'jest-zone-patch'; + +import './jestGlobalMocks'; diff --git a/src/pybind/mgr/dashboard/frontend/src/styles.scss b/src/pybind/mgr/dashboard/frontend/src/styles.scss new file mode 100644 index 00000000..ad06737c --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/styles.scss @@ -0,0 +1,392 @@ +/* You can add global styles to this file, and also import other style files */ + +@import 'defaults'; +$fa-font-path: '../node_modules/fork-awesome/fonts'; +@import '../node_modules/fork-awesome/scss/fork-awesome'; +$font_family_1: 'ForkAwesome'; +@import 'app/ceph/dashboard/info-card/info-card-popover.scss'; + +/* Basics */ +html { + background-color: $color-app-bg; +} +html, +body { + width: 100%; + height: 100%; + font-size: 12px; +} +a { + color: $color-links; + cursor: pointer; +} +a:hover, +a:focus { + color: $color-links-focus; +} +h1 { + letter-spacing: -1px; + font-size: 2em; +} +h2 { + letter-spacing: -1px; + font-size: 1.833em; +} +h3 { + display: block; + font-size: 1.583em; + font-weight: 400; +} +h4 { + font-size: 1.5em; + line-height: normal; +} +option { + font-weight: normal; + font-style: normal; +} +/* For awesome-bootstrap-checkbox */ +.checkbox input[type='checkbox']:checked + label:after { + font-family: $font_family_1; +} +/*******/ +.full-height { + height: 100%; +} +.vertical-align { + display: flex; + align-items: center; +} +.loading { + position: absolute; + top: 50%; + left: 50%; +} +.margin-right-md { + margin-right: 15px; +} +.no-border { + border: 0px; + box-shadow: 0px 0px 0px !important; +} +.italic { + font-style: italic; +} +.bold { + font-weight: bold; +} +.text-right { + text-align: right; +} +.text-monospace { + font-family: monospace; +} + +/* Buttons */ +.btn { + &, + &:active, + &.active { + &:focus, + &.focus { + outline: 0; + } + } +} +.btn-primary { + color: $color-button-text; + background-color: $color-accent; + border-color: $color-accent; + border-radius: $button-radius; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + color: $color-button-text; + background-color: lighten($color-accent, 10); + border-color: lighten($color-accent, 10); +} +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + background-image: none; + + &:hover, + &:focus { + background-color: lighten($color-accent, 10); + border-color: lighten($color-accent, 10); + } +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: $color-accent; + border-color: $color-accent; +} +.btn-primary .badge { + color: $color-primary; + background-color: $color-button-badge; +} +.btn-primary .caret { + color: $color-button-caret; +} +.btn-default { + border-radius: $button-radius; +} +.form-group .btn-default { + border-radius: 4px; +} +.btn-group > .btn > i.fa, +button.btn.btn-label > i.fa { + /** Add space between icon and text */ + padding-right: 5px; +} + +/* Dropdown */ +.dropdown-menu { + min-width: 50px; + z-index: 999999; +} +.dropdown-menu > li > a { + color: $color-dropdown-menu; + cursor: pointer; +} +.dropdown-menu > li > a > i.fa { + /** Add space between icon and text */ + padding-right: 5px; +} +.dropdown-menu > .active > a { + color: $color-dropdown-active-text; + background-color: $color-dropdown-active-bg; + + &, + &:hover, + &:focus { + background-color: darken($color-dropdown-active-bg, 10); + } +} +.dataTables_wrapper .dropdown-menu > li.divider { + cursor: auto; +} + +/* Grid */ +.container, +.container-fluid { + padding-left: 30px; + padding-right: 30px; +} +.row { + margin-left: -30px; + margin-right: -30px; +} +.col-lg-1, +.col-lg-10, +.col-lg-11, +.col-lg-12, +.col-lg-2, +.col-lg-3, +.col-lg-4, +.col-lg-5, +.col-lg-6, +.col-lg-7, +.col-lg-8, +.col-lg-9, +.col-md-1, +.col-md-10, +.col-md-11, +.col-md-12, +.col-md-2, +.col-md-3, +.col-md-4, +.col-md-5, +.col-md-6, +.col-md-7, +.col-md-8, +.col-md-9, +.col-sm-1, +.col-sm-10, +.col-sm-11, +.col-sm-12, +.col-sm-2, +.col-sm-3, +.col-sm-4, +.col-sm-5, +.col-sm-6, +.col-sm-7, +.col-sm-8, +.col-sm-9, +.col-xs-1, +.col-xs-10, +.col-xs-11, +.col-xs-12, +.col-xs-2, +.col-xs-3, +.col-xs-4, +.col-xs-5, +.col-xs-6, +.col-xs-7, +.col-xs-8, +.col-xs-9 { + padding-left: 30px; + padding-right: 30px; +} +/* Caret */ +.caret { + color: $color-caret-text; +} +/* Progressbar */ +.progress-bar { + background-image: none !important; +} +.progress-bar-info { + background-color: $color-progress-bar-info-bg; +} +.progress-bar-freespace { + background-color: $color-progress-bar-freespace-bg; +} +.oaprogress { + position: relative; + margin-bottom: 0; +} +.oaprogress div.progress-bar { + position: static; +} +.oaprogress span { + position: absolute; + display: block; + width: 100%; + color: $color-oaprogress-text; + font-weight: normal; +} +tags-input .tags { + border-radius: 4px; + border: 1px solid $color-tags-border; + box-shadow: inset 0 1px 1px $color-tags-box-shadow; +} +uib-accordion .panel-title, +.panel .accordion-title { + font-size: 14px !important; +} +.panel-body h2:first-child { + margin-top: 0; +} +.pull-left { + float: left; +} +.disabled { + pointer-events: none; +} +.clickable { + cursor: pointer; +} +.has-error .has-error-btn, +.has-error .has-error-btn:disabled:hover { + background-color: $color-error-btn-bg; + border-color: $color-error-btn-border; +} +/* If javascript is disabled. */ +.noscript { + padding-top: 5em; +} +.noscript p { + color: $color-noscript-text; +} +.required { + color: $color-required-text; +} +/* Forms */ +.form-group > .control-label > span.required, +.form-group > .col-sm-12 > .control-label > span.required { + @extend .fa; + @extend .fa-asterisk; + @extend .required; + font-size: 6px; + padding-left: 4px; + vertical-align: text-top; +} +.form-control { + display: table-cell; + + &:focus { + border-color: rgba($color-primary, 0.8); + outline: 0; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px 2px rgba($color-primary, 0.5); + } +} +/* Panel */ +.panel-footer button.btn:not(:first-child) { + margin-left: 5px; +} +/* Modal dialog */ +.modal-footer button.btn:not(:first-child) { + margin-left: 5px; +} +.margin-right-sm { + margin-right: 10px; +} +.nav-tabs { + margin-bottom: 15px; +} +/* Icons */ +.ceph-icon { + background: url('assets/Ceph_Logo_Stacked_RGB_120411_fa_228x228.png'); +} +.prometheus-icon { + background: url('assets/prometheus_logo.svg'); +} +.custom-icon { + padding: 10px; + margin-right: 1em; + background-clip: padding-box; + background-size: contain; + background-repeat: no-repeat; +} +/* Notification icons */ +.toast-message .custom-icon { + /* Display icons in white, regardless of their origin color. */ + filter: brightness(0) invert(1); + -webkit-filter: brightness(0) invert(1); + -moz-filter: brightness(0) invert(1); + -o-filter: brightness(0) invert(1); + -ms-filter: brightness(0) invert(1); +} +/* Block UI */ +.block-ui-wrapper { + background: $color-transparent-black !important; +} + +h3.page-header { + margin-left: 1em; + margin-top: 1em; + border-color: #f0f0f0; +} + +.tooltip-wide .tooltip-inner { + width: 400px; +} + +.tooltip-inner { + background-color: white; + border: 1px solid grey; + color: #333; + font-size: 1.1em; +} + +.toast-message > ul { + padding-left: 1em; + margin: 0; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/chart-tooltip.scss b/src/pybind/mgr/dashboard/frontend/src/styles/chart-tooltip.scss new file mode 100644 index 00000000..b37e5fcc --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/styles/chart-tooltip.scss @@ -0,0 +1,64 @@ +@import '../defaults'; + +.chart-container { + position: absolute; + margin: auto; + cursor: pointer; + overflow: visible; +} + +canvas { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.chartjs-tooltip { + opacity: 0; + position: absolute; + background: $color-chart-tooltip-bg; + color: $color-chat-tooltip-text; + border-radius: 3px; + -webkit-transition: all 0.1s ease; + transition: all 0.1s ease; + pointer-events: none; + font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif !important; + + -webkit-transform: translate(-50%, 0); + transform: translate(-50%, 0); + + &.transform-left { + transform: translate(-10%, 0); + + &::after { + left: 10%; + } + } + + &.transform-right { + transform: translate(-90%, 0); + + &::after { + left: 90%; + } + } +} + +.chartjs-tooltip::after { + content: ' '; + position: absolute; + top: 100%; /* At the bottom of the tooltip */ + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: $color-chart-tooltip-border transparent transparent transparent; +} + +::ng-deep .chartjs-tooltip-key { + display: inline-block; + width: 10px; + height: 10px; + margin-right: 10px; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/popover.scss b/src/pybind/mgr/dashboard/frontend/src/styles/popover.scss new file mode 100644 index 00000000..ab747bf6 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/styles/popover.scss @@ -0,0 +1,46 @@ +@import '../defaults'; + +::ng-deep .popover-content { + padding: 0.5em; + height: auto; + max-height: 70vh; + overflow-x: hidden; +} + +::ng-deep .popover { + min-width: 276px !important; +} + +.separator { + padding: 5px 12px; + color: $color-popover-seperator-text; + background-color: $color-popover-seperator-bg; + font-size: 12px; +} + +.message { + padding: 10px 16px; + color: $color-popover-message-text; + font-size: 12px; +} + +table { + width: 252px; + margin: 5px 12px 5px 5px; + font-size: 12px; + color: $color-popover-table-text; +} + +.icon-col { + width: 50px; + font-size: 10px; +} + +.date { + color: $color-popover-date; +} + +hr { + margin-top: 0px; + margin-bottom: 0px; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts b/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts new file mode 100644 index 00000000..fafbf60b --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/testing/activated-route-stub.ts @@ -0,0 +1,23 @@ +import { ReplaySubject } from 'rxjs'; + +/** + * An ActivateRoute test double with a `params` observable. + * Use the `setParams()` method to add the next `params` value. + */ +export class ActivatedRouteStub { + // Use a ReplaySubject to share previous values with subscribers + // and pump new values into the `params` observable + private subject = new ReplaySubject(); + + constructor(initialParams?: object) { + this.setParams(initialParams); + } + + /** The mock params observable */ + readonly params = this.subject.asObservable(); + + /** Set the params observables's next value */ + setParams(params?: object) { + this.subject.next(params); + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts b/src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts new file mode 100644 index 00000000..a22c76ec --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts @@ -0,0 +1,344 @@ +import { LOCALE_ID, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { AbstractControl } from '@angular/forms'; +import { By } from '@angular/platform-browser'; + +import { I18n } from '@ngx-translate/i18n-polyfill'; +import * as _ from 'lodash'; + +import { TableActionsComponent } from '../app/shared/datatable/table-actions/table-actions.component'; +import { CdFormGroup } from '../app/shared/forms/cd-form-group'; +import { Permission } from '../app/shared/models/permissions'; +import { + AlertmanagerAlert, + AlertmanagerNotification, + AlertmanagerNotificationAlert, + PrometheusRule +} from '../app/shared/models/prometheus-alerts'; +import { _DEV_ } from '../unit-test-configuration'; + +export function configureTestBed(configuration, useOldMethod?) { + if (_DEV_ && !useOldMethod) { + const resetTestingModule = TestBed.resetTestingModule; + beforeAll((done) => + (async () => { + TestBed.resetTestingModule(); + TestBed.configureTestingModule(configuration); + // prevent Angular from resetting testing module + TestBed.resetTestingModule = () => TestBed; + })() + .then(done) + .catch(done.fail) + ); + afterAll(() => { + TestBed.resetTestingModule = resetTestingModule; + }); + } else { + beforeEach(async(() => { + TestBed.configureTestingModule(configuration); + })); + } +} + +export class PermissionHelper { + tableActions: TableActionsComponent; + permission: Permission; + getTableActionComponent: () => TableActionsComponent; + + constructor(permission: Permission, getTableActionComponent: () => TableActionsComponent) { + this.permission = permission; + this.getTableActionComponent = getTableActionComponent; + } + + setPermissionsAndGetActions( + createPerm: number | boolean, + updatePerm: number | boolean, + deletePerm: number | boolean + ): TableActionsComponent { + this.permission.create = Boolean(createPerm); + this.permission.update = Boolean(updatePerm); + this.permission.delete = Boolean(deletePerm); + this.tableActions = this.getTableActionComponent(); + return this.tableActions; + } + + // Overwrite if needed + createSelection(): object { + return {}; + } + + testScenarios({ + fn, + empty, + single, + singleExecuting, + multiple + }: { + fn: () => any; + empty: any; + single: any; + singleExecuting?: any; // uses 'single' if not defined + multiple?: any; // uses 'empty' if not defined + }) { + this.testScenario( + // 'multiple selections' + [this.createSelection(), this.createSelection()], + fn, + _.isUndefined(multiple) ? empty : multiple + ); + const executing = this.createSelection(); + executing['cdExecuting'] = 'someAction'; + this.testScenario( + // 'select executing item' + [executing], + fn, + _.isUndefined(singleExecuting) ? single : singleExecuting + ); + this.testScenario([this.createSelection()], fn, single); // 'select non-executing item' + this.testScenario([], fn, empty); // 'no selection' + } + + private testScenario(selection: object[], fn: () => any, expected: any) { + this.setSelection(selection); + expect(fn()).toBe(expected); + } + + setSelection(selection: object[]) { + this.tableActions.selection.selected = selection; + this.tableActions.selection.update(); + } +} + +export class FormHelper { + form: CdFormGroup; + + constructor(form: CdFormGroup) { + this.form = form; + } + + /** + * Changes multiple values in multiple controls + */ + setMultipleValues(values: { [controlName: string]: any }, markAsDirty?: boolean) { + Object.keys(values).forEach((key) => { + this.setValue(key, values[key], markAsDirty); + }); + } + + /** + * Changes the value of a control + */ + setValue(control: AbstractControl | string, value: any, markAsDirty?: boolean): AbstractControl { + control = this.getControl(control); + if (markAsDirty) { + control.markAsDirty(); + } + control.setValue(value); + return control; + } + + private getControl(control: AbstractControl | string): AbstractControl { + if (typeof control === 'string') { + return this.form.get(control); + } + return control; + } + + /** + * Change the value of the control and expect the control to be valid afterwards. + */ + expectValidChange(control: AbstractControl | string, value: any, markAsDirty?: boolean) { + this.expectValid(this.setValue(control, value, markAsDirty)); + } + + /** + * Expect that the given control is valid. + */ + expectValid(control: AbstractControl | string) { + // 'isValid' would be false for disabled controls + expect(this.getControl(control).errors).toBe(null); + } + + /** + * Change the value of the control and expect a specific error. + */ + expectErrorChange( + control: AbstractControl | string, + value: any, + error: string, + markAsDirty?: boolean + ) { + this.expectError(this.setValue(control, value, markAsDirty), error); + } + + /** + * Expect a specific error for the given control. + */ + expectError(control: AbstractControl | string, error: string) { + expect(this.getControl(control).hasError(error)).toBeTruthy(); + } +} + +export class FixtureHelper { + fixture: ComponentFixture; + + constructor(fixture: ComponentFixture) { + this.fixture = fixture; + } + + /** + * Expect a list of id elements to be visible or not. + */ + expectIdElementsVisible(ids: string[], visibility: boolean) { + ids.forEach((css) => { + this.expectElementVisible(`#${css}`, visibility); + }); + } + + /** + * Expect a specific element to be visible or not. + */ + expectElementVisible(css: string, visibility: boolean) { + expect(Boolean(this.getElementByCss(css))).toBe(visibility); + } + + expectFormFieldToBe(css: string, value: string) { + const props = this.getElementByCss(css).properties; + expect(props['value'] || props['checked'].toString()).toBe(value); + } + + clickElement(css: string) { + this.getElementByCss(css).triggerEventHandler('click', null); + this.fixture.detectChanges(); + } + + getText(css: string) { + const e = this.getElementByCss(css); + return e ? e.nativeElement.textContent.trim() : null; + } + + getElementByCss(css: string) { + this.fixture.detectChanges(); + return this.fixture.debugElement.query(By.css(css)); + } +} + +export class PrometheusHelper { + createSilence(id) { + return { + id: id, + createdBy: `Creator of ${id}`, + comment: `A comment for ${id}`, + startsAt: new Date('2022-02-22T22:22:00').toISOString(), + endsAt: new Date('2022-02-23T22:22:00').toISOString(), + matchers: [ + { + name: 'job', + value: 'someJob', + isRegex: true + } + ] + }; + } + + createRule(name, severity, alerts: any[]): PrometheusRule { + return { + name: name, + labels: { + severity: severity + }, + alerts: alerts + } as PrometheusRule; + } + + createAlert(name, state = 'active', timeMultiplier = 1): AlertmanagerAlert { + return { + fingerprint: name, + status: { state }, + labels: { + alertname: name, + instance: 'someInstance', + job: 'someJob', + severity: 'someSeverity' + }, + annotations: { + summary: `${name} is ${state}` + }, + generatorURL: `http://${name}`, + startsAt: new Date(new Date('2022-02-22').getTime() * timeMultiplier).toString() + } as AlertmanagerAlert; + } + + createNotificationAlert(name, status = 'firing'): AlertmanagerNotificationAlert { + return { + status: status, + labels: { + alertname: name + }, + annotations: { + summary: `${name} is ${status}` + }, + generatorURL: `http://${name}` + } as AlertmanagerNotificationAlert; + } + + createNotification(alertNumber = 1, status = 'firing'): AlertmanagerNotification { + const alerts = []; + for (let i = 0; i < alertNumber; i++) { + alerts.push(this.createNotificationAlert('alert' + i, status)); + } + return { alerts, status } as AlertmanagerNotification; + } + + createLink(url) { + return ``; + } +} + +const XLIFF = ` + + + + + + +`; + +const i18nProviders = [ + { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }, + { provide: TRANSLATIONS, useValue: XLIFF }, + { provide: LOCALE_ID, useValue: 'en' }, + I18n +]; + +export { i18nProviders }; + +export function expectItemTasks(item: any, executing: string, percentage?: number) { + if (executing) { + executing = executing + '...'; + if (percentage) { + executing = `${executing} ${percentage}%`; + } + } + expect(item.cdExecuting).toBe(executing); +} + +export class IscsiHelper { + static validateUser(formHelper: FormHelper, fieldName: string) { + formHelper.expectErrorChange(fieldName, 'short', 'pattern'); + formHelper.expectValidChange(fieldName, 'thisIsCorrect'); + formHelper.expectErrorChange(fieldName, '##?badChars?##', 'pattern'); + formHelper.expectErrorChange( + fieldName, + 'thisUsernameIsWayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyTooBig', + 'pattern' + ); + } + + static validatePassword(formHelper: FormHelper, fieldName: string) { + formHelper.expectErrorChange(fieldName, 'short', 'pattern'); + formHelper.expectValidChange(fieldName, 'thisIsCorrect'); + formHelper.expectErrorChange(fieldName, '##?badChars?##', 'pattern'); + formHelper.expectErrorChange(fieldName, 'thisPasswordIsWayTooBig', 'pattern'); + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json b/src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json new file mode 100644 index 00000000..05a9aad1 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "module": "es2015", + "types": [] + }, + "exclude": [ + "**/*.spec.ts", + "testing/*.ts" + ] +} diff --git a/src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json b/src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json new file mode 100644 index 00000000..0533feab --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/tsconfig.spec.json @@ -0,0 +1,22 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "baseUrl": "./", + "module": "commonjs", + "target": "es5", + "types": [ + "jest", + "node" + ], + "noEmit": true + }, + "files": [ + "polyfills.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts", + "testing/*.ts" + ] +} diff --git a/src/pybind/mgr/dashboard/frontend/src/typings.d.ts b/src/pybind/mgr/dashboard/frontend/src/typings.d.ts new file mode 100644 index 00000000..ef5c7bd6 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/typings.d.ts @@ -0,0 +1,5 @@ +/* SystemJS module definition */ +declare var module: NodeModule; +interface NodeModule { + id: string; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/unit-test-configuration.ts.sample b/src/pybind/mgr/dashboard/frontend/src/unit-test-configuration.ts.sample new file mode 100644 index 00000000..74dbf2c0 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/unit-test-configuration.ts.sample @@ -0,0 +1 @@ +export const _DEV_ = false; diff --git a/src/pybind/mgr/dashboard/frontend/src/vendor.overrides.scss b/src/pybind/mgr/dashboard/frontend/src/vendor.overrides.scss new file mode 100644 index 00000000..0cca9de8 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/vendor.overrides.scss @@ -0,0 +1,3 @@ +/* Vendor specific scss */ + +@import 'defaults'; diff --git a/src/pybind/mgr/dashboard/frontend/src/vendor.variables.scss b/src/pybind/mgr/dashboard/frontend/src/vendor.variables.scss new file mode 100644 index 00000000..e35fef11 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/vendor.variables.scss @@ -0,0 +1 @@ +/* Vendor specific variables */ diff --git a/src/pybind/mgr/dashboard/frontend/tsconfig.json b/src/pybind/mgr/dashboard/frontend/tsconfig.json new file mode 100644 index 00000000..557f4b43 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "importHelpers": true, + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": ["node_modules/@types"], + "lib": ["es2017", "dom"], + "allowJs": true + } +} diff --git a/src/pybind/mgr/dashboard/frontend/tslint.json b/src/pybind/mgr/dashboard/frontend/tslint.json new file mode 100644 index 00000000..f0ce66cf --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/tslint.json @@ -0,0 +1,90 @@ +{ + "rulesDirectory": ["node_modules/codelyzer"], + "rules": { + "no-consecutive-blank-lines": true, + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [true, "check-space"], + "curly": true, + "eofline": true, + "forin": true, + "import-blacklist": [true, "rxjs/Rx", "ngx-bootstrap"], + "import-spacing": true, + "indent": [true, "spaces"], + "interface-over-type-literal": true, + "label-position": true, + "member-access": false, + "member-ordering": [ + true, + { + "order": ["static-field", "instance-field", "static-method", "instance-method"] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [true, "ignore-params"], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], + "prefer-const": true, + "quotemark": [true, "single"], + "radix": true, + "semicolon": [true, "always"], + "triple-equals": [true, "allow-null-check"], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "unified-signatures": true, + "variable-name": [true, "check-format", "allow-snake-case", "allow-leading-underscore"], + "whitespace": [ + true, + "check-branch", + "check-operator", + "check-separator", + "check-type", + "check-module" + ], + "directive-selector": [true, "attribute", "cd", "camelCase"], + "component-selector": [true, "element", "cd", "kebab-case"], + "angular-whitespace": [true, "check-interpolation", "check-semicolon"], + "no-output-on-prefix": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-attribute-parameter-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true, + "no-forward-ref": true, + "no-output-named-after-standard-event": true, + "ordered-imports": true + } +} diff --git a/src/pybind/mgr/dashboard/grafana.py b/src/pybind/mgr/dashboard/grafana.py new file mode 100644 index 00000000..e1157553 --- /dev/null +++ b/src/pybind/mgr/dashboard/grafana.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json +import os +import time +import requests + +from . import logger +from .exceptions import GrafanaError +from .settings import Settings + + +class GrafanaRestClient(object): + + @staticmethod + def url_validation(method, path): + response = requests.request( + method, + path, + verify=Settings.GRAFANA_API_SSL_VERIFY) + return response.status_code + + @staticmethod + def push_dashboard(dashboard_obj): + if not Settings.GRAFANA_API_URL: + raise GrafanaError("The Grafana API URL is not set") + if not Settings.GRAFANA_API_URL.startswith('http'): + raise GrafanaError("The Grafana API URL is invalid") + if not Settings.GRAFANA_API_USERNAME: + raise GrafanaError("The Grafana API username is not set") + if not Settings.GRAFANA_API_PASSWORD: + raise GrafanaError("The Grafana API password is not set") + url = Settings.GRAFANA_API_URL.rstrip('/') + \ + '/api/dashboards/db' + headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + } + payload = { + 'dashboard': dashboard_obj, + 'overwrite': True, + } + try: + response = requests.post( + url, + headers=headers, + data=json.dumps(payload), + auth=(Settings.GRAFANA_API_USERNAME, + Settings.GRAFANA_API_PASSWORD), + verify=Settings.GRAFANA_API_SSL_VERIFY + ) + except requests.ConnectionError: + raise GrafanaError("Could not connect to Grafana server") + response.raise_for_status() + return response.status_code, response.json() + + +class Retrier(object): + def __init__(self, tries, sleep, func, *args, **kwargs): + """ + Wraps a function. An instance of this class may be called to call that + function, retrying if it raises an exception. Sleeps between retries, + eventually reraising the original exception when retries are exhausted. + Once the function returns a value, that value is returned. + + :param tries: How many times to try, before reraising the exception + :type tries: int + :param sleep: How many seconds to wait between tries + :type sleep: int|float + :param func: The function to execute + :type func: function + :param args: Any arguments to pass to the function + :type args: list + :param kwargs: Any keyword arguments to pass to the function + :type kwargs: dict + """ + assert tries >= 1 + self.tries = int(tries) + self.tried = 0 + self.sleep = sleep + self.func = func + self.args = args + self.kwargs = kwargs + + def __call__(self): + result = None + while self.tried < self.tries: + try: + result = self.func(*self.args, **self.kwargs) + except Exception: # pylint: disable=broad-except + if self.tried == self.tries - 1: + raise + else: + self.tried += 1 + time.sleep(self.sleep) + else: + return result + + +def load_local_dashboards(): + if os.environ.get('CEPH_DEV') == '1' or 'UNITTEST' in os.environ: + path = os.path.abspath(os.path.join( + os.path.dirname(__file__), + '../../../../monitoring/grafana/dashboards/' + )) + else: + path = '/etc/grafana/dashboards/ceph-dashboard' + dashboards = dict() + for item in [p for p in os.listdir(path) if p.endswith('.json')]: + db_path = os.path.join(path, item) + with open(db_path) as f: + dashboards[item] = json.loads(f.read()) + return dashboards + + +def push_local_dashboards(tries=1, sleep=0): + try: + dashboards = load_local_dashboards() + except (EnvironmentError, ValueError): + logger.exception("Failed to load local dashboard files") + raise + + def push(): + try: + grafana = GrafanaRestClient() + for body in dashboards.values(): + grafana.push_dashboard(body) + except Exception: + logger.exception("Failed to push dashboards to Grafana") + raise + retry = Retrier(tries, sleep, push) + retry() + return True diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py new file mode 100644 index 00000000..9770bd85 --- /dev/null +++ b/src/pybind/mgr/dashboard/module.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- +""" +ceph dashboard mgr plugin (based on CherryPy) +""" +from __future__ import absolute_import + +import collections +from distutils.version import StrictVersion +import errno +import os +import socket +import ssl +import sys +import tempfile +import threading +import time +from uuid import uuid4 +from OpenSSL import crypto +import _strptime # pylint: disable=unused-import +from mgr_module import MgrModule, MgrStandbyModule, Option, CLIWriteCommand +from mgr_util import get_default_addr, ServerConfigException, verify_tls_files + +try: + import cherrypy + from cherrypy._cptools import HandlerWrapperTool +except ImportError: + # To be picked up and reported by .can_run() + cherrypy = None + +from .services.sso import load_sso_db + +if cherrypy is not None: + from .cherrypy_backports import patch_cherrypy + patch_cherrypy(cherrypy.__version__) + +if 'COVERAGE_ENABLED' in os.environ: + import coverage + __cov = coverage.Coverage(config_file="{}/.coveragerc".format(os.path.dirname(__file__)), + data_suffix=True) + + cherrypy.engine.subscribe('start', __cov.start) + cherrypy.engine.subscribe('after_request', __cov.save) + cherrypy.engine.subscribe('stop', __cov.stop) + +# pylint: disable=wrong-import-position +from . import logger, mgr +from .controllers import generate_routes, json_error_page +from .grafana import push_local_dashboards +from .tools import NotificationQueue, RequestLoggingTool, TaskManager, \ + prepare_url_prefix, str_to_bool +from .services.auth import AuthManager, AuthManagerTool, JwtManager +from .services.sso import SSO_COMMANDS, \ + handle_sso_command +from .services.exception import dashboard_exception_handler +from .settings import options_command_list, options_schema_list, \ + handle_option_command + +from .plugins import PLUGIN_MANAGER +from .plugins import feature_toggles, debug # noqa # pylint: disable=unused-import + + +PLUGIN_MANAGER.hook.init() + + +# cherrypy likes to sys.exit on error. don't let it take us down too! +# pylint: disable=W0613 +def os_exit_noop(*args): + pass + + +# pylint: disable=W0212 +os._exit = os_exit_noop + + +class CherryPyConfig(object): + """ + Class for common server configuration done by both active and + standby module, especially setting up SSL. + """ + + def __init__(self): + self._stopping = threading.Event() + self._url_prefix = "" + + self.cert_tmp = None + self.pkey_tmp = None + + def shutdown(self): + self._stopping.set() + + @property + def url_prefix(self): + return self._url_prefix + + @staticmethod + def update_cherrypy_config(config): + PLUGIN_MANAGER.hook.configure_cherrypy(config=config) + cherrypy.config.update(config) + + # pylint: disable=too-many-branches + def _configure(self): + """ + Configure CherryPy and initialize self.url_prefix + + :returns our URI + """ + server_addr = self.get_localized_module_option( + 'server_addr', get_default_addr()) + use_ssl = self.get_localized_module_option('ssl', True) + if not use_ssl: + server_port = self.get_localized_module_option('server_port', 8080) + else: + server_port = self.get_localized_module_option('ssl_server_port', 8443) + + if server_addr is None: + raise ServerConfigException( + 'no server_addr configured; ' + 'try "ceph config set mgr mgr/{}/{}/server_addr "' + .format(self.module_name, self.get_mgr_id())) + self.log.info('server: ssl=%s host=%s port=%d', 'yes' if use_ssl else 'no', + server_addr, server_port) + + # Initialize custom handlers. + cherrypy.tools.authenticate = AuthManagerTool() + cherrypy.tools.plugin_hooks_filter_request = cherrypy.Tool( + 'before_handler', + lambda: PLUGIN_MANAGER.hook.filter_request_before_handler(request=cherrypy.request), + priority=1) + cherrypy.tools.request_logging = RequestLoggingTool() + cherrypy.tools.dashboard_exception_handler = HandlerWrapperTool(dashboard_exception_handler, + priority=31) + + # Apply the 'global' CherryPy configuration. + config = { + 'engine.autoreload.on': False, + 'server.socket_host': server_addr, + 'server.socket_port': int(server_port), + 'error_page.default': json_error_page, + 'tools.request_logging.on': True, + 'tools.gzip.on': True, + 'tools.gzip.mime_types': [ + # text/html and text/plain are the default types to compress + 'text/html', 'text/plain', + # We also want JSON and JavaScript to be compressed + 'application/json', + 'application/javascript', + ], + 'tools.json_in.on': True, + 'tools.json_in.force': True, + 'tools.plugin_hooks_filter_request.on': True, + } + + if use_ssl: + # SSL initialization + cert = self.get_store("crt") + if cert is not None: + self.cert_tmp = tempfile.NamedTemporaryFile() + self.cert_tmp.write(cert.encode('utf-8')) + self.cert_tmp.flush() # cert_tmp must not be gc'ed + cert_fname = self.cert_tmp.name + else: + cert_fname = self.get_localized_module_option('crt_file') + + pkey = self.get_store("key") + if pkey is not None: + self.pkey_tmp = tempfile.NamedTemporaryFile() + self.pkey_tmp.write(pkey.encode('utf-8')) + self.pkey_tmp.flush() # pkey_tmp must not be gc'ed + pkey_fname = self.pkey_tmp.name + else: + pkey_fname = self.get_localized_module_option('key_file') + + verify_tls_files(cert_fname, pkey_fname) + + # Create custom SSL context to disable TLS 1.0 and 1.1. + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + context.load_cert_chain(cert_fname, pkey_fname) + if sys.version_info >= (3, 7): + context.minimum_version = ssl.TLSVersion.TLSv1_2 + else: + # Based on tests limiting TLS to specific versions + # starts working with CherryPy >= 8.9.1 (Ubuntu 18.04 + # or SUSE Leap 15.1). + if StrictVersion(cherrypy.__version__) >= StrictVersion('8.9.1'): + context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 + + config['server.ssl_module'] = 'builtin' + config['server.ssl_certificate'] = cert_fname + config['server.ssl_private_key'] = pkey_fname + config['server.ssl_context'] = context + + self.update_cherrypy_config(config) + + self._url_prefix = prepare_url_prefix(self.get_module_option('url_prefix', + default='')) + + uri = "{0}://{1}:{2}{3}/".format( + 'https' if use_ssl else 'http', + socket.getfqdn(server_addr if server_addr != '::' else ''), + server_port, + self.url_prefix + ) + + return uri + + def await_configuration(self): + """ + Block until configuration is ready (i.e. all needed keys are set) + or self._stopping is set. + + :returns URI of configured webserver + """ + while not self._stopping.is_set(): + try: + uri = self._configure() + except ServerConfigException as e: + self.log.info("Config not ready to serve, waiting: {0}".format( + e + )) + # Poll until a non-errored config is present + self._stopping.wait(5) + else: + self.log.info("Configured CherryPy, starting engine...") + return uri + + +class Module(MgrModule, CherryPyConfig): + """ + dashboard module entrypoint + """ + + COMMANDS = [ + { + 'cmd': 'dashboard set-jwt-token-ttl ' + 'name=seconds,type=CephInt', + 'desc': 'Set the JWT token TTL in seconds', + 'perm': 'w' + }, + { + 'cmd': 'dashboard get-jwt-token-ttl', + 'desc': 'Get the JWT token TTL in seconds', + 'perm': 'r' + }, + { + "cmd": "dashboard create-self-signed-cert", + "desc": "Create self signed certificate", + "perm": "w" + }, + { + "cmd": "dashboard grafana dashboards update", + "desc": "Push dashboards to Grafana", + "perm": "w", + }, + ] + COMMANDS.extend(options_command_list()) + COMMANDS.extend(SSO_COMMANDS) + PLUGIN_MANAGER.hook.register_commands() + + MODULE_OPTIONS = [ + Option(name='server_addr', type='str', default=get_default_addr()), + Option(name='server_port', type='int', default=8080), + Option(name='ssl_server_port', type='int', default=8443), + Option(name='jwt_token_ttl', type='int', default=28800), + Option(name='password', type='str', default=''), + Option(name='url_prefix', type='str', default=''), + Option(name='username', type='str', default=''), + Option(name='key_file', type='str', default=''), + Option(name='crt_file', type='str', default=''), + Option(name='ssl', type='bool', default=True), + Option(name='standby_behaviour', type='str', default='redirect', + enum_allowed=['redirect', 'error']), + Option(name='standby_error_status_code', type='int', default=500, + min=400, max=599) + ] + MODULE_OPTIONS.extend(options_schema_list()) + for options in PLUGIN_MANAGER.hook.get_options() or []: + MODULE_OPTIONS.extend(options) + + __pool_stats = collections.defaultdict(lambda: collections.defaultdict( + lambda: collections.deque(maxlen=10))) + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + CherryPyConfig.__init__(self) + + mgr.init(self) + + self._stopping = threading.Event() + self.shutdown_event = threading.Event() + self.ACCESS_CTRL_DB = None + self.SSO_DB = None + self.health_checks = {} + + @classmethod + def can_run(cls): + if cherrypy is None: + return False, "Missing dependency: cherrypy" + + if not os.path.exists(cls.get_frontend_path()): + return False, "Frontend assets not found: incomplete build?" + + return True, "" + + @classmethod + def get_frontend_path(cls): + current_dir = os.path.dirname(os.path.abspath(__file__)) + return os.path.join(current_dir, 'frontend/dist') + + def serve(self): + AuthManager.initialize() + load_sso_db() + + uri = self.await_configuration() + if uri is None: + # We were shut down while waiting + return + + # Publish the URI that others may use to access the service we're + # about to start serving + self.set_uri(uri) + + mapper, parent_urls = generate_routes(self.url_prefix) + + config = {} + for purl in parent_urls: + config[purl] = { + 'request.dispatch': mapper + } + + cherrypy.tree.mount(None, config=config) + + PLUGIN_MANAGER.hook.setup() + + cherrypy.engine.start() + NotificationQueue.start_queue() + TaskManager.init() + logger.info('Engine started.') + update_dashboards = str_to_bool( + self.get_module_option('GRAFANA_UPDATE_DASHBOARDS', 'False')) + if update_dashboards: + logger.info('Starting Grafana dashboard task') + TaskManager.run( + 'grafana/dashboards/update', + {}, + push_local_dashboards, + kwargs=dict(tries=10, sleep=60), + ) + # wait for the shutdown event + self.shutdown_event.wait() + self.shutdown_event.clear() + NotificationQueue.stop() + cherrypy.engine.stop() + logger.info('Engine stopped') + + def shutdown(self): + super(Module, self).shutdown() + CherryPyConfig.shutdown(self) + logger.info('Stopping engine...') + self.shutdown_event.set() + + @CLIWriteCommand("dashboard set-ssl-certificate", + "name=mgr_id,type=CephString,req=false") + def set_ssl_certificate(self, mgr_id=None, inbuf=None): + if inbuf is None: + return -errno.EINVAL, '',\ + 'Please specify the certificate file with "-i" option' + if mgr_id is not None: + self.set_store('{}/crt'.format(mgr_id), inbuf) + else: + self.set_store('crt', inbuf) + return 0, 'SSL certificate updated', '' + + @CLIWriteCommand("dashboard set-ssl-certificate-key", + "name=mgr_id,type=CephString,req=false") + def set_ssl_certificate_key(self, mgr_id=None, inbuf=None): + if inbuf is None: + return -errno.EINVAL, '',\ + 'Please specify the certificate key file with "-i" option' + if mgr_id is not None: + self.set_store('{}/key'.format(mgr_id), inbuf) + else: + self.set_store('key', inbuf) + return 0, 'SSL certificate key updated', '' + + def handle_command(self, inbuf, cmd): + # pylint: disable=too-many-return-statements + res = handle_option_command(cmd, inbuf) + if res[0] != -errno.ENOSYS: + return res + res = handle_sso_command(cmd) + if res[0] != -errno.ENOSYS: + return res + if cmd['prefix'] == 'dashboard set-jwt-token-ttl': + self.set_module_option('jwt_token_ttl', str(cmd['seconds'])) + return 0, 'JWT token TTL updated', '' + if cmd['prefix'] == 'dashboard get-jwt-token-ttl': + ttl = self.get_module_option('jwt_token_ttl', JwtManager.JWT_TOKEN_TTL) + return 0, str(ttl), '' + if cmd['prefix'] == 'dashboard create-self-signed-cert': + self.create_self_signed_cert() + return 0, 'Self-signed certificate created', '' + if cmd['prefix'] == 'dashboard grafana dashboards update': + push_local_dashboards() + return 0, 'Grafana dashboards updated', '' + + return (-errno.EINVAL, '', 'Command not found \'{0}\'' + .format(cmd['prefix'])) + + def create_self_signed_cert(self): + # create a key pair + pkey = crypto.PKey() + pkey.generate_key(crypto.TYPE_RSA, 2048) + + # create a self-signed cert + cert = crypto.X509() + cert.get_subject().O = "IT" + cert.get_subject().CN = "ceph-dashboard" + cert.set_serial_number(int(uuid4())) + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(10*365*24*60*60) + cert.set_issuer(cert.get_subject()) + cert.set_pubkey(pkey) + cert.sign(pkey, 'sha512') + + cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) + self.set_store('crt', cert.decode('utf-8')) + + pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey) + self.set_store('key', pkey.decode('utf-8')) + + def notify(self, notify_type, notify_id): + NotificationQueue.new_notification(notify_type, notify_id) + + def get_updated_pool_stats(self): + df = self.get('df') + pool_stats = {p['id']: p['stats'] for p in df['pools']} + now = time.time() + for pool_id, stats in pool_stats.items(): + for stat_name, stat_val in stats.items(): + self.__pool_stats[pool_id][stat_name].append((now, stat_val)) + + return self.__pool_stats + + def config_notify(self): + """ + This method is called whenever one of our config options is changed. + """ + PLUGIN_MANAGER.hook.config_notify() + + def refresh_health_checks(self): + self.set_health_checks(self.health_checks) + + +class StandbyModule(MgrStandbyModule, CherryPyConfig): + def __init__(self, *args, **kwargs): + super(StandbyModule, self).__init__(*args, **kwargs) + CherryPyConfig.__init__(self) + self.shutdown_event = threading.Event() + + # We can set the global mgr instance to ourselves even though + # we're just a standby, because it's enough for logging. + mgr.init(self) + + def serve(self): + uri = self.await_configuration() + if uri is None: + # We were shut down while waiting + return + + module = self + + class Root(object): + @cherrypy.expose + def default(self, *args, **kwargs): + if module.get_module_option('standby_behaviour', 'redirect') == 'redirect': + active_uri = module.get_active_uri() + if active_uri: + module.log.info("Redirecting to active '%s'", active_uri) + raise cherrypy.HTTPRedirect(active_uri) + else: + template = """ + + + + Ceph + + + + No active ceph-mgr instance is currently running + the dashboard. A failover may be in progress. + Retrying in {delay} seconds... + + + """ + return template.format(delay=5) + else: + status = module.get_module_option('standby_error_status_code', 500) + raise cherrypy.HTTPError(status, message="Keep on looking") + + cherrypy.tree.mount(Root(), "{}/".format(self.url_prefix), {}) + self.log.info("Starting engine...") + cherrypy.engine.start() + self.log.info("Engine started...") + # Wait for shutdown event + self.shutdown_event.wait() + self.shutdown_event.clear() + cherrypy.engine.stop() + self.log.info("Engine stopped.") + + def shutdown(self): + CherryPyConfig.shutdown(self) + + self.log.info("Stopping engine...") + self.shutdown_event.set() + self.log.info("Stopped engine...") diff --git a/src/pybind/mgr/dashboard/plugins/__init__.py b/src/pybind/mgr/dashboard/plugins/__init__.py new file mode 100644 index 00000000..43d71fde --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/__init__.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import abc +import six + +from .pluggy import HookspecMarker, HookimplMarker, PluginManager + + +@six.add_metaclass(abc.ABCMeta) +class Interface(object): + pass + + +class Mixin(object): + pass + + +class DashboardPluginManager(object): + def __init__(self, project_name): + self.__pm = PluginManager(project_name) + self.__add_spec = HookspecMarker(project_name) + self.__add_abcspec = lambda *args, **kwargs: abc.abstractmethod( + self.__add_spec(*args, **kwargs)) + self.__add_hook = HookimplMarker(project_name) + + pm = property(lambda self: self.__pm) + hook = property(lambda self: self.pm.hook) + + add_spec = property(lambda self: self.__add_spec) + add_abcspec = property(lambda self: self.__add_abcspec) + add_hook = property(lambda self: self.__add_hook) + + def add_interface(self, cls): + assert issubclass(cls, Interface) + self.pm.add_hookspecs(cls) + return cls + + @staticmethod + def final(func): + setattr(func, '__final__', True) + return func + + def add_plugin(self, plugin): + """ Provides decorator interface for PluginManager.register(): + @PLUGIN_MANAGER.add_plugin + class Plugin(...): + ... + Additionally it checks whether the Plugin instance has all Interface + methods implemented and marked with add_hook decorator. + As a con of this approach, plugins cannot call super() from __init__() + """ + assert issubclass(plugin, Interface) + from inspect import getmembers, ismethod + for interface in plugin.__bases__: + for method_name, _ in getmembers(interface, predicate=ismethod): + if hasattr(getattr(interface, method_name), '__final__'): + continue + + if self.pm.parse_hookimpl_opts(plugin, method_name) is None: + raise NotImplementedError( + "Plugin '{}' implements interface '{}' but existing" + " method '{}' is not declared added as hook".format( + plugin.__name__, + interface.__name__, + method_name)) + self.pm.register(plugin()) + return plugin + + +PLUGIN_MANAGER = DashboardPluginManager("ceph-mgr.dashboard") + +# Load all interfaces and their hooks +from . import interfaces diff --git a/src/pybind/mgr/dashboard/plugins/debug.py b/src/pybind/mgr/dashboard/plugins/debug.py new file mode 100644 index 00000000..5f4cdbea --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/debug.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from enum import Enum +import json + +from . import PLUGIN_MANAGER as PM +from . import interfaces as I # noqa: E741,N812 +from .plugin import SimplePlugin as SP + + +class Actions(Enum): + ENABLE = 'enable' + DISABLE = 'disable' + STATUS = 'status' + + +@PM.add_plugin # pylint: disable=too-many-ancestors +class Debug(SP, I.CanCherrypy, I.ConfiguresCherryPy, # pylint: disable=too-many-ancestors + I.Setupable, I.ConfigNotify): + NAME = 'debug' + + OPTIONS = [ + SP.Option( + name=NAME, + default=False, + type='bool', + desc="Enable/disable debug options" + ) + ] + + def _refresh_health_checks(self): + debug = self.get_option(self.NAME) + if debug: + self.mgr.health_checks.update({'DASHBOARD_DEBUG': { + 'severity': 'warning', + 'summary': 'Dashboard debug mode is enabled', + 'detail': [ + 'Please disable debug mode in production environments using ' + '"ceph dashboard {} {}"'.format(self.NAME, Actions.DISABLE.value) + ] + }}) + else: + self.mgr.health_checks.pop('DASHBOARD_DEBUG', None) + self.mgr.refresh_health_checks() + + @PM.add_hook + def setup(self): + self._refresh_health_checks() + + def handler(self, action): + ret = 0 + msg = '' + if action in [Actions.ENABLE.value, Actions.DISABLE.value]: + self.set_option(self.NAME, action == Actions.ENABLE.value) + self.mgr.update_cherrypy_config({}) + self._refresh_health_checks() + else: + debug = self.get_option(self.NAME) + msg = "Debug: '{}'".format('enabled' if debug else 'disabled') + return ret, msg, None + + COMMANDS = [ + SP.Command( + prefix="dashboard {name}".format(name=NAME), + args="name=action,type=CephChoices,strings={states}".format( + states="|".join(a.value for a in Actions)), + desc="Control and report debug status in Ceph-Dashboard", + handler=handler + ) + ] + + def custom_error_response(self, status, message, traceback, version): + self.response.headers['Content-Type'] = 'application/json' + error_response = dict(status=status, detail=message, request_id=str(self.request.unique_id)) + + if self.get_option(self.NAME): + error_response.update(dict(traceback=traceback, version=version)) + + return json.dumps(error_response) + + @PM.add_hook + def configure_cherrypy(self, config): + config.update({ + 'environment': 'test_suite' if self.get_option(self.NAME) else 'production', + 'error_page.default': self.custom_error_response, + }) + + @PM.add_hook + def config_notify(self): + self._refresh_health_checks() diff --git a/src/pybind/mgr/dashboard/plugins/feature_toggles.py b/src/pybind/mgr/dashboard/plugins/feature_toggles.py new file mode 100644 index 00000000..7edbfa8f --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/feature_toggles.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from enum import Enum +import cherrypy +from mgr_module import CLICommand, Option + +from . import PLUGIN_MANAGER as PM +from . import interfaces as I +from .ttl_cache import ttl_cache + +from ..controllers.rbd import Rbd, RbdSnapshot, RbdTrash +from ..controllers.rbd_mirroring import ( + RbdMirroringSummary, RbdMirroringPoolMode, RbdMirroringPoolPeer) +from ..controllers.iscsi import Iscsi, IscsiTarget +from ..controllers.cephfs import CephFS +from ..controllers.rgw import Rgw, RgwDaemon, RgwBucket, RgwUser + + +class Features(Enum): + RBD = 'rbd' + MIRRORING = 'mirroring' + ISCSI = 'iscsi' + CEPHFS = 'cephfs' + RGW = 'rgw' + + +PREDISABLED_FEATURES = set() + + +Feature2Controller = { + Features.RBD: [Rbd, RbdSnapshot, RbdTrash], + Features.MIRRORING: [ + RbdMirroringSummary, RbdMirroringPoolMode, RbdMirroringPoolPeer], + Features.ISCSI: [Iscsi, IscsiTarget], + Features.CEPHFS: [CephFS], + Features.RGW: [Rgw, RgwDaemon, RgwBucket, RgwUser], +} + + +class Actions(Enum): + ENABLE = 'enable' + DISABLE = 'disable' + STATUS = 'status' + + +@PM.add_plugin +class FeatureToggles(I.CanMgr, I.CanLog, I.Setupable, I.HasOptions, + I.HasCommands, I.FilterRequest.BeforeHandler, + I.HasControllers): + OPTION_FMT = 'FEATURE_TOGGLE_{}' + CACHE_MAX_SIZE = 128 # Optimum performance with 2^N sizes + CACHE_TTL = 10 # seconds + + @PM.add_hook + def setup(self): + self.Controller2Feature = { + controller: feature + for feature, controllers in Feature2Controller.items() + for controller in controllers} + + @PM.add_hook + def get_options(self): + return [Option( + name=self.OPTION_FMT.format(feature.value), + default=(feature not in PREDISABLED_FEATURES), + type='bool',) for feature in Features] + + @PM.add_hook + def register_commands(self): + @CLICommand( + "dashboard feature", + "name=action,type=CephChoices,strings={} ".format( + "|".join(a.value for a in Actions)) + + "name=features,type=CephChoices,strings={},req=false,n=N".format( + "|".join(f.value for f in Features)), + "Enable or disable features in Ceph-Mgr Dashboard") + def cmd(mgr, action, features=None): + ret = 0 + msg = [] + if action in [Actions.ENABLE.value, Actions.DISABLE.value]: + if features is None: + ret = 1 + msg = ["At least one feature must be specified"] + else: + for feature in features: + mgr.set_module_option( + self.OPTION_FMT.format(feature), + action == Actions.ENABLE.value) + msg += ["Feature '{}': {}".format( + feature, + 'enabled' if action == Actions.ENABLE.value else + 'disabled')] + else: + for feature in features or [f.value for f in Features]: + enabled = mgr.get_module_option(self.OPTION_FMT.format(feature)) + msg += ["Feature '{}': '{}'".format( + feature, + 'enabled' if enabled else 'disabled')] + return ret, '\n'.join(msg), '' + return {'handle_command': cmd} + + def _get_feature_from_request(self, request): + try: + return self.Controller2Feature[ + request.handler.callable.__self__] + except (AttributeError, KeyError): + return None + + @ttl_cache(ttl=CACHE_TTL, maxsize=CACHE_MAX_SIZE) + def _is_feature_enabled(self, feature): + return self.mgr.get_module_option(self.OPTION_FMT.format(feature.value)) + + @PM.add_hook + def filter_request_before_handler(self, request): + feature = self._get_feature_from_request(request) + if feature is None: + return + + if not self._is_feature_enabled(feature): + raise cherrypy.HTTPError( + 404, "Feature='{}' disabled by option '{}'".format( + feature.value, + self.OPTION_FMT.format(feature.value), + ) + ) + + @PM.add_hook + def get_controllers(self): + from ..controllers import ApiController, RESTController + + @ApiController('/feature_toggles') + class FeatureTogglesEndpoint(RESTController): + + def list(_): + return { + feature.value: self._is_feature_enabled(feature) + for feature in Features + } + return [FeatureTogglesEndpoint] diff --git a/src/pybind/mgr/dashboard/plugins/interfaces.py b/src/pybind/mgr/dashboard/plugins/interfaces.py new file mode 100644 index 00000000..dbcd60a0 --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/interfaces.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import PLUGIN_MANAGER as PM, Interface, Mixin # pylint: disable=cyclic-import + + +class CanMgr(Mixin): + from .. import mgr + mgr = mgr + + +class CanLog(Mixin): + from .. import logger + log = logger + + +class CanCherrypy(Mixin): + import cherrypy + request = cherrypy.request + response = cherrypy.response + + +@PM.add_interface +class Initializable(Interface): + @PM.add_abcspec + def init(self): + """ + Placeholder for module scope initialization + """ + + +@PM.add_interface +class Setupable(Interface): + @PM.add_abcspec + def setup(self): + """ + Placeholder for plugin setup, right after server start. + CanMgr.mgr and CanLog.log are initialized by then. + """ + pass + + +@PM.add_interface +class HasOptions(Interface): + @PM.add_abcspec + def get_options(self): pass + + +@PM.add_interface +class HasCommands(Interface): + @PM.add_abcspec + def register_commands(self): pass + + +@PM.add_interface +class HasControllers(Interface): + @PM.add_abcspec + def get_controllers(self): pass + + +@PM.add_interface +class ConfiguresCherryPy(Interface): + @PM.add_abcspec + def configure_cherrypy(self, config): + pass + + +class FilterRequest(object): + @PM.add_interface + class BeforeHandler(Interface): + @PM.add_abcspec + def filter_request_before_handler(self, request): pass + + +@PM.add_interface +class ConfigNotify(Interface): + @PM.add_abcspec + def config_notify(self): + """ + This method is called whenever a option of this mgr module has + been modified. + """ diff --git a/src/pybind/mgr/dashboard/plugins/lru_cache.py b/src/pybind/mgr/dashboard/plugins/lru_cache.py new file mode 100644 index 00000000..19ad1b85 --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/lru_cache.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +""" +This is a minimal implementation of lru_cache function. + +Based on Python 3 functools and backports.functools_lru_cache. +""" +from __future__ import absolute_import + +from functools import wraps +from collections import OrderedDict +from threading import RLock + + +def lru_cache(maxsize=128, typed=False): + if typed is not False: + raise NotImplementedError("typed caching not supported") + + def decorating_function(function): + cache = OrderedDict() + stats = [0, 0] + rlock = RLock() + setattr( + function, + 'cache_info', + lambda: + "hits={}, misses={}, maxsize={}, currsize={}".format( + stats[0], stats[1], maxsize, len(cache))) + + @wraps(function) + def wrapper(*args, **kwargs): + key = args + tuple(kwargs.items()) + with rlock: + if key in cache: + ret = cache[key] + del cache[key] + cache[key] = ret + stats[0] += 1 + else: + ret = function(*args, **kwargs) + if len(cache) == maxsize: + cache.popitem(last=False) + cache[key] = ret + stats[1] += 1 + return ret + + return wrapper + return decorating_function diff --git a/src/pybind/mgr/dashboard/plugins/pluggy.py b/src/pybind/mgr/dashboard/plugins/pluggy.py new file mode 100644 index 00000000..7517e6d6 --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/pluggy.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +""" +The MIT License (MIT) + +Copyright (c) 2015 holger krekel (rather uses bitbucket/hpk42) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + +""" +CAVEAT: +This is a minimal implementation of python-pluggy (based on 0.8.0 interface: +https://github.com/pytest-dev/pluggy/releases/tag/0.8.0). + + +Despite being a widely available Python library, it does not reach all the +distros and releases currently targeted for Ceph Nautilus: +- CentOS/RHEL 7.5 [ ] +- CentOS/RHEL 8 [ ] +- Debian 8.0 [ ] +- Debian 9.0 [ ] +- Ubuntu 14.05 [ ] +- Ubuntu 16.04 [X] + +TODO: Once this becomes available in the above distros, this file should be +REMOVED, and the fully featured python-pluggy should be used instead. +""" + + +class HookspecMarker(object): + """ Dummy implementation. No spec validation. """ + def __init__(self, project_name): + self.project_name = project_name + + def __call__(self, function, *args, **kwargs): + """ No options supported. """ + if any(args) or any(kwargs): + raise NotImplementedError( + "This is a minimal implementation of pluggy") + return function + + +class HookimplMarker(object): + def __init__(self, project_name): + self.project_name = project_name + + def __call__(self, function, *args, **kwargs): + """ No options supported.""" + if any(args) or any(kwargs): + raise NotImplementedError( + "This is a minimal implementation of pluggy") + setattr(function, self.project_name + "_impl", {}) + return function + + +class _HookRelay(object): + """ + Provides the PluginManager.hook.() syntax and + functionality. + """ + def __init__(self): + from collections import defaultdict + self._registry = defaultdict(list) + + def __getattr__(self, hook_name): + return lambda *args, **kwargs: [ + hook(*args, **kwargs) for hook in self._registry[hook_name]] + + def _add_hookimpl(self, hook_name, hook_method): + self._registry[hook_name].append(hook_method) + + +class PluginManager(object): + def __init__(self, project_name): + self.project_name = project_name + self.__hook = _HookRelay() + + @property + def hook(self): + return self.__hook + + def parse_hookimpl_opts(self, plugin, name): + return getattr( + getattr(plugin, name), + self.project_name + "_impl", + None) + + def add_hookspecs(self, module_or_class): + """ Dummy method""" + pass + + def register(self, plugin, name=None): + for attr in dir(plugin): + if self.parse_hookimpl_opts(plugin, attr) is not None: + self.hook._add_hookimpl(attr, getattr(plugin, attr)) diff --git a/src/pybind/mgr/dashboard/plugins/plugin.py b/src/pybind/mgr/dashboard/plugins/plugin.py new file mode 100644 index 00000000..0f52aefb --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/plugin.py @@ -0,0 +1,33 @@ +from mgr_module import Option, Command + +from . import PLUGIN_MANAGER as PM +from . import interfaces as I # noqa: E741,N812 + + +class SimplePlugin(I.CanMgr, I.CanLog, I.HasOptions, I.HasCommands): + """ + Helper class that provides simplified creation of plugins: + - Default Mixins/Interfaces: CanMgr, CanLog, HasOptions & HasCommands + - Options are defined by OPTIONS class variable, instead from get_options hook + - Commands are created with by COMMANDS list of Commands() and handlers + (less compact than CLICommand, but allows using method instances) + """ + Option = Option + Command = Command + + @PM.add_hook + def get_options(self): + return self.OPTIONS + + @PM.final + def get_option(self, option): + return self.mgr.get_module_option(option) + + @PM.final + def set_option(self, option, value): + self.mgr.set_module_option(option, value) + + @PM.add_hook + def register_commands(self): + for cmd in self.COMMANDS: + cmd.register(instance=self) diff --git a/src/pybind/mgr/dashboard/plugins/ttl_cache.py b/src/pybind/mgr/dashboard/plugins/ttl_cache.py new file mode 100644 index 00000000..a0698542 --- /dev/null +++ b/src/pybind/mgr/dashboard/plugins/ttl_cache.py @@ -0,0 +1,55 @@ +""" +This is a minimal implementation of TTL-ed lru_cache function. + +Based on Python 3 functools and backports.functools_lru_cache. +""" +from __future__ import absolute_import + +from functools import wraps +from collections import OrderedDict +from threading import RLock +from time import time + + +def ttl_cache(ttl, maxsize=128, typed=False): + if typed is not False: + raise NotImplementedError("typed caching not supported") + + def decorating_function(function): + cache = OrderedDict() + stats = [0, 0, 0] + rlock = RLock() + setattr( + function, + 'cache_info', + lambda: + "hits={}, misses={}, expired={}, maxsize={}, currsize={}".format( + stats[0], stats[1], stats[2], maxsize, len(cache))) + + @wraps(function) + def wrapper(*args, **kwargs): + key = args + tuple(kwargs.items()) + with rlock: + refresh = True + if key in cache: + (ret, ts) = cache[key] + del cache[key] + if time() - ts < ttl: + refresh = False + stats[0] += 1 + else: + stats[2] += 1 + + if refresh: + ret = function(*args, **kwargs) + ts = time() + if len(cache) == maxsize: + cache.popitem(last=False) + stats[1] += 1 + + cache[key] = (ret, ts) + + return ret + + return wrapper + return decorating_function diff --git a/src/pybind/mgr/dashboard/requirements-py27.txt b/src/pybind/mgr/dashboard/requirements-py27.txt new file mode 100644 index 00000000..d8fb6f6a --- /dev/null +++ b/src/pybind/mgr/dashboard/requirements-py27.txt @@ -0,0 +1,3 @@ +astroid==1.6.1 +pylint==1.8.2 +python-saml==2.4.2 diff --git a/src/pybind/mgr/dashboard/requirements-py3.txt b/src/pybind/mgr/dashboard/requirements-py3.txt new file mode 100644 index 00000000..364ce283 --- /dev/null +++ b/src/pybind/mgr/dashboard/requirements-py3.txt @@ -0,0 +1,3 @@ +astroid==2.1.0 +pylint==2.2.2 +python3-saml==1.4.1 diff --git a/src/pybind/mgr/dashboard/requirements.txt b/src/pybind/mgr/dashboard/requirements.txt new file mode 100644 index 00000000..9a7c71f1 --- /dev/null +++ b/src/pybind/mgr/dashboard/requirements.txt @@ -0,0 +1,36 @@ +attrs==17.4.0 +backports.functools-lru-cache==1.4 +bcrypt==3.1.4 +cheroot==6.0.0 +CherryPy==13.1.0 +configparser==3.5.0 +coverage==4.5.2 +enum34; python_version<'3.4' +funcsigs==1.0.2 +isort==4.2.15 +lazy-object-proxy==1.3.1 +mccabe==0.6.1 +mock==2.0.0 +more-itertools==4.1.0 +pbr==3.1.1 +pluggy==0.6.0 +portend==2.2 +py==1.5.2 +pycodestyle==2.4.0 +pycparser==2.18 +PyJWT +pyopenssl +pytest==3.3.2 +pytest-cov==2.5.1 +pytest-faulthandler==1.0.1 +pytz==2017.3 +requests==2.20.0 +Routes==2.4.1 +singledispatch==3.4.0.3 +six==1.14.0 +tempora==1.10 +tox==2.9.1 +virtualenv==15.1.0 +werkzeug==0.14.1 +wrapt==1.10.11 +pyfakefs diff --git a/src/pybind/mgr/dashboard/rest_client.py b/src/pybind/mgr/dashboard/rest_client.py new file mode 100644 index 00000000..b287086f --- /dev/null +++ b/src/pybind/mgr/dashboard/rest_client.py @@ -0,0 +1,531 @@ +# -*- coding: utf-8 -*- +""" + * Copyright (c) 2017 SUSE LLC + * + * openATTIC is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +""" +from __future__ import absolute_import + +from .settings import Settings +from .tools import build_url +import inspect +import re +import requests +from requests.exceptions import ConnectionError, InvalidURL, Timeout +from . import logger + +try: + from requests.packages.urllib3.exceptions import SSLError +except ImportError: + from urllib3.exceptions import SSLError + + +class TimeoutRequestsSession(requests.Session): + """ + Set timeout argument for all requests if this is not already done. + """ + def request(self, *args, **kwargs): + if ((args[8] if len(args) > 8 else None) is None) \ + and kwargs.get('timeout') is None: + if Settings.REST_REQUESTS_TIMEOUT > 0: + kwargs['timeout'] = Settings.REST_REQUESTS_TIMEOUT + return super(TimeoutRequestsSession, self).request(*args, **kwargs) + + +class RequestException(Exception): + def __init__(self, + message, + status_code=None, + content=None, + conn_errno=None, + conn_strerror=None): + super(RequestException, self).__init__(message) + self.status_code = status_code + self.content = content + self.conn_errno = conn_errno + self.conn_strerror = conn_strerror + + +class BadResponseFormatException(RequestException): + def __init__(self, message): + super(BadResponseFormatException, self).__init__( + "Bad response format" if message is None else message, None) + + +class _ResponseValidator(object): + """Simple JSON schema validator + + This class implements a very simple validator for the JSON formatted + messages received by request responses from a RestClient instance. + + The validator validates the JSON response against a "structure" string that + specifies the structure that the JSON response must comply. The validation + procedure raises a BadResponseFormatException in case of a validation + failure. + + The structure syntax is given by the following grammar: + + Structure ::= Level + Level ::= Path | Path '&' Level + Path ::= Step | Step '>'+ Path + Step ::= Key | '?' Key | '*' | '(' Level ')' + Key ::= | Array+ + Array ::= '[' ']' | '[' '*' ']' | '[' '+' ']' + + The symbols enclosed in ' ' are tokens of the language, and the + symbol + denotes repetition of of the preceding token at least once. + + Examples of usage: + + Example 1: + Validator args: + structure = "return > *" + response = { 'return': { ... } } + + In the above example the structure will validate against any response + that contains a key named "return" in the root of the response + dictionary and its value is also a dictionary. + + Example 2: + Validator args: + structure = "[*]" + response = [...] + + In the above example the structure will validate against any response + that is an array of any size. + + Example 3: + Validator args: + structure = "return[*]" + response = { 'return': [....] } + + In the above example the structure will validate against any response + that contains a key named "return" in the root of the response + dictionary and its value is an array. + + Example 4: + Validator args: + structure = "return[0] > token" + response = { 'return': [ { 'token': .... } ] } + + In the above example the structure will validate against any response + that contains a key named "return" in the root of the response + dictionary and its value is an array, and the first element of the + array is a dictionary that contains the key 'token'. + + Example 5: + Validator args: + structure = "return[0][*] > key1" + response = { 'return': [ [ { 'key1': ... } ], ...] } + + In the above example the structure will validate against any response + that contains a key named "return" in the root of the response + dictionary where its value is an array, and the first value of this + array is also an array where all it's values must be a dictionary + containing a key named "key1". + + Example 6: + Validator args: + structure = "return > (key1[*] & key2 & ?key3 > subkey)" + response = { 'return': { 'key1': [...], 'key2: .... } ] } + + In the above example the structure will validate against any response + that contains a key named "return" in the root of the response + dictionary and its value is a dictionary that must contain a key named + "key1" that is an array, a key named "key2", and optionally a key named + "key3" that is a dictionary that contains a key named "subkey". + + Example 7: + Validator args: + structure = "return >> roles[*]" + response = { 'return': { 'key1': { 'roles': [...] }, 'key2': { 'roles': [...] } } } + + In the above example the structure will validate against any response + that contains a key named "return" in the root of the response + dictionary, and its value is a dictionary that for any key present in + the dictionary their value is also a dictionary that must contain a key + named 'roles' that is an array. Please note that you can use any + number of successive '>' to denote the level in the JSON tree that you + want to match next step in the path. + + """ + + @staticmethod + def validate(structure, response): + if structure is None: + return + + _ResponseValidator._validate_level(structure, response) + + @staticmethod + def _validate_level(level, resp): + if not isinstance(resp, dict) and not isinstance(resp, list): + raise BadResponseFormatException( + "{} is neither a dict nor a list".format(resp)) + + paths = _ResponseValidator._parse_level_paths(level) + for path in paths: + path_sep = path.find('>') + if path_sep != -1: + level_next = path[path_sep + 1:].strip() + else: + path_sep = len(path) + level_next = None + key = path[:path_sep].strip() + + if key == '*': + continue + elif key == '': # check all keys + for k in resp.keys(): + _ResponseValidator._validate_key(k, level_next, resp) + else: + _ResponseValidator._validate_key(key, level_next, resp) + + @staticmethod + def _validate_array(array_seq, level_next, resp): + if array_seq: + if not isinstance(resp, list): + raise BadResponseFormatException( + "{} is not an array".format(resp)) + if array_seq[0].isdigit(): + idx = int(array_seq[0]) + if len(resp) <= idx: + raise BadResponseFormatException( + "length of array {} is lower than the index {}".format( + resp, idx)) + _ResponseValidator._validate_array(array_seq[1:], level_next, + resp[idx]) + elif array_seq[0] == '*': + for r in resp: + _ResponseValidator._validate_array(array_seq[1:], + level_next, r) + elif array_seq[0] == '+': + if len(resp) < 1: + raise BadResponseFormatException( + "array should not be empty") + for r in resp: + _ResponseValidator._validate_array(array_seq[1:], + level_next, r) + else: + raise Exception( + "Response structure is invalid: only | '*' are " + "allowed as array index arguments") + else: + if level_next: + _ResponseValidator._validate_level(level_next, resp) + + @staticmethod + def _validate_key(key, level_next, resp): + array_access = [a.strip() for a in key.split("[")] + key = array_access[0] + if key: + optional = key[0] == '?' + if optional: + key = key[1:] + if key not in resp: + if optional: + return + raise BadResponseFormatException( + "key {} is not in dict {}".format(key, resp)) + resp_next = resp[key] + else: + resp_next = resp + if len(array_access) > 1: + _ResponseValidator._validate_array( + [a[0:-1] for a in array_access[1:]], level_next, resp_next) + else: + if level_next: + _ResponseValidator._validate_level(level_next, resp_next) + + @staticmethod + def _parse_level_paths(level): + level = level.strip() + if level[0] == '(': + level = level[1:] + if level[-1] == ')': + level = level[:-1] + + paths = [] + lp = 0 + nested = 0 + for i, c in enumerate(level): + if c == '&' and nested == 0: + paths.append(level[lp:i].strip()) + lp = i + 1 + elif c == '(': + nested += 1 + elif c == ')': + nested -= 1 + paths.append(level[lp:].strip()) + return paths + + +class _Request(object): + def __init__(self, method, path, path_params, rest_client, resp_structure): + self.method = method + self.path = path + self.path_params = path_params + self.rest_client = rest_client + self.resp_structure = resp_structure + + def _gen_path(self): + new_path = self.path + matches = re.finditer(r'\{(\w+?)\}', self.path) + for match in matches: + if match: + param_key = match.group(1) + if param_key in self.path_params: + new_path = new_path.replace( + match.group(0), self.path_params[param_key]) + else: + raise RequestException( + 'Invalid path. Param "{}" was not specified' + .format(param_key), None) + return new_path + + def __call__(self, + req_data=None, + method=None, + params=None, + data=None, + raw_content=False): + method = method if method else self.method + if not method: + raise Exception('No HTTP request method specified') + if req_data: + if method == 'get': + if params: + raise Exception('Ambiguous source of GET params') + params = req_data + else: + if data: + raise Exception('Ambiguous source of {} data'.format( + method.upper())) + data = req_data + resp = self.rest_client.do_request(method, self._gen_path(), params, + data, raw_content) + if raw_content and self.resp_structure: + raise Exception("Cannot validate response in raw format") + _ResponseValidator.validate(self.resp_structure, resp) + return resp + + +class RestClient(object): + def __init__(self, host, port, client_name=None, ssl=False, auth=None, ssl_verify=True): + super(RestClient, self).__init__() + self.client_name = client_name if client_name else '' + self.host = host + self.port = port + self.base_url = build_url( + scheme='https' if ssl else 'http', host=host, port=port) + logger.debug("REST service base URL: %s", self.base_url) + self.headers = {'Accept': 'application/json'} + self.auth = auth + self.session = TimeoutRequestsSession() + self.session.verify = ssl_verify + + def _login(self, request=None): + pass + + def _is_logged_in(self): + pass + + def _reset_login(self): + pass + + def is_service_online(self, request=None): + pass + + @staticmethod + def requires_login(func): + def func_wrapper(self, *args, **kwargs): + retries = 2 + while True: + try: + if not self._is_logged_in(): + self._login() + resp = func(self, *args, **kwargs) + return resp + except RequestException as e: + if isinstance(e, BadResponseFormatException): + raise e + retries -= 1 + if e.status_code not in [401, 403] or retries == 0: + raise e + self._reset_login() + + return func_wrapper + + def do_request(self, + method, + path, + params=None, + data=None, + raw_content=False): + url = '{}{}'.format(self.base_url, path) + logger.debug('%s REST API %s req: %s data: %s', self.client_name, + method.upper(), path, data) + try: + if method.lower() == 'get': + resp = self.session.get( + url, headers=self.headers, params=params, auth=self.auth) + elif method.lower() == 'post': + resp = self.session.post( + url, + headers=self.headers, + params=params, + data=data, + auth=self.auth) + elif method.lower() == 'put': + resp = self.session.put( + url, + headers=self.headers, + params=params, + data=data, + auth=self.auth) + elif method.lower() == 'delete': + resp = self.session.delete( + url, + headers=self.headers, + params=params, + data=data, + auth=self.auth) + else: + raise RequestException('Method "{}" not supported'.format( + method.upper()), None) + if resp.ok: + logger.debug("%s REST API %s res status: %s content: %s", + self.client_name, method.upper(), + resp.status_code, resp.text) + if raw_content: + return resp.content + try: + return resp.json() if resp.text else None + except ValueError: + logger.error( + "%s REST API failed %s req while decoding JSON " + "response : %s", + self.client_name, method.upper(), resp.text) + raise RequestException( + "{} REST API failed request while decoding JSON " + "response: {}".format(self.client_name, resp.text), + resp.status_code, resp.text) + else: + logger.error( + "%s REST API failed %s req status: %s", self.client_name, + method.upper(), resp.status_code) + from pprint import pprint as pp + from pprint import pformat as pf + + raise RequestException( + "{} REST API failed request with status code {}\n" + "{}" # TODO remove + .format(self.client_name, resp.status_code, pf( + resp.content)), + resp.status_code, + resp.content) + except ConnectionError as ex: + if ex.args: + if isinstance(ex.args[0], SSLError): + errno = "n/a" + strerror = "SSL error. Probably trying to access a non " \ + "SSL connection." + logger.error("%s REST API failed %s, SSL error.", + self.client_name, method.upper()) + else: + try: + match = re.match(r'.*: \[Errno (-?\d+)\] (.+)', + ex.args[0].reason.args[0]) + except AttributeError: + match = False + if match: + errno = match.group(1) + strerror = match.group(2) + logger.error( + "%s REST API failed %s, connection error: " + "[errno: %s] %s", + self.client_name, method.upper(), errno, strerror) + else: + errno = "n/a" + strerror = "n/a" + logger.error( + "%s REST API failed %s, connection error.", + self.client_name, method.upper()) + else: + errno = "n/a" + strerror = "n/a" + logger.error("%s REST API failed %s, connection error.", + self.client_name, method.upper()) + + if errno != "n/a": + ex_msg = ( + "{} REST API cannot be reached: {} [errno {}]. " + "Please check your configuration and that the API endpoint" + " is accessible" + .format(self.client_name, strerror, errno)) + else: + ex_msg = ( + "{} REST API cannot be reached. Please check " + "your configuration and that the API endpoint is" + " accessible" + .format(self.client_name)) + raise RequestException( + ex_msg, conn_errno=errno, conn_strerror=strerror) + except InvalidURL as ex: + logger.exception("%s REST API failed %s: %s", self.client_name, + method.upper(), str(ex)) + raise RequestException(str(ex)) + except Timeout as ex: + msg = "{} REST API {} timed out after {} seconds (url={}).".format( + self.client_name, ex.request.method, Settings.REST_REQUESTS_TIMEOUT, + ex.request.url) + logger.exception(msg) + raise RequestException(msg) + + @staticmethod + def api(path, **api_kwargs): + def call_decorator(func): + def func_wrapper(self, *args, **kwargs): + method = api_kwargs.get('method', None) + resp_structure = api_kwargs.get('resp_structure', None) + args_name = inspect.getargspec(func).args + args_dict = dict(zip(args_name[1:], args)) + for key, val in kwargs: + args_dict[key] = val + return func( + self, + *args, + request=_Request(method, path, args_dict, self, + resp_structure), + **kwargs) + + return func_wrapper + + return call_decorator + + @staticmethod + def api_get(path, resp_structure=None): + return RestClient.api( + path, method='get', resp_structure=resp_structure) + + @staticmethod + def api_post(path, resp_structure=None): + return RestClient.api( + path, method='post', resp_structure=resp_structure) + + @staticmethod + def api_put(path, resp_structure=None): + return RestClient.api( + path, method='put', resp_structure=resp_structure) + + @staticmethod + def api_delete(path, resp_structure=None): + return RestClient.api( + path, method='delete', resp_structure=resp_structure) diff --git a/src/pybind/mgr/dashboard/run-backend-api-request.sh b/src/pybind/mgr/dashboard/run-backend-api-request.sh new file mode 100755 index 00000000..5c4c1559 --- /dev/null +++ b/src/pybind/mgr/dashboard/run-backend-api-request.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +CURR_DIR=`pwd` +cd ../../../../build +API_URL=`./bin/ceph mgr services 2>/dev/null | jq .dashboard | sed -e 's/"//g' -e 's!/$!!g'` +if [ "$API_URL" = "null" ]; then + echo "Couldn't retrieve API URL, exiting..." >&2 + exit 1 +fi +cd $CURR_DIR + +TOKEN=`curl --insecure -s -H "Content-Type: application/json" -X POST \ + -d '{"username":"admin","password":"admin"}' $API_URL/api/auth \ + | jq .token | sed -e 's/"//g'` + +echo "METHOD: $1" +echo "URL: ${API_URL}${2}" +echo "DATA: $3" +echo "" + +curl --insecure -s -b /tmp/cd-cookie.txt -H "Authorization: Bearer $TOKEN " \ + -H "Content-Type: application/json" -X $1 -d "$3" ${API_URL}$2 | jq + diff --git a/src/pybind/mgr/dashboard/run-backend-api-tests.sh b/src/pybind/mgr/dashboard/run-backend-api-tests.sh new file mode 100755 index 00000000..66831399 --- /dev/null +++ b/src/pybind/mgr/dashboard/run-backend-api-tests.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env bash + +set -eo pipefail + +if [[ "$1" = "-h" || "$1" = "--help" ]]; then + echo "Usage (run from ./):" + echo -e "\t./run-backend-api-tests.sh" + echo -e "\t./run-backend-api-tests.sh [tests]..." + echo + echo "Example:" + echo -e "\t./run-backend-api-tests.sh tasks.mgr.dashboard.test_pool.DashboardTest" + echo + echo "Or source this script. This allows to re-run tests faster:" + echo -e "\tsource run-backend-api-tests.sh" + echo -e "\trun_teuthology_tests [tests]..." + echo -e "\tcleanup_teuthology" + echo + + exit 0 +fi + +get_cmake_variable() { + local variable=$1 + grep "$variable" CMakeCache.txt | cut -d "=" -f 2 +} + +get_build_py_version() { + CURR_DIR=`pwd` + BUILD_DIR="$CURR_DIR/../../../../build" + cd $BUILD_DIR + + CEPH_MGR_PY_VERSION_MAJOR=$(get_cmake_variable MGR_PYTHON_VERSION | cut -d '.' -f1) + if [ -n "$CEPH_MGR_PY_VERSION_MAJOR" ]; then + CEPH_PY_VERSION_MAJOR=${CEPH_MGR_PY_VERSION_MAJOR} + else + if [ $(get_cmake_variable WITH_PYTHON2) = ON ]; then + CEPH_PY_VERSION_MAJOR=2 + else + CEPH_PY_VERSION_MAJOR=3 + fi + fi +} + +setup_teuthology() { + TEMP_DIR=`mktemp -d` + cd $TEMP_DIR + virtualenv --python=${TEUTHOLOGY_PYTHON_BIN:-/usr/bin/python3} venv + source venv/bin/activate + pip install 'setuptools >= 12' + pip install git+https://github.com/ceph/teuthology#egg=teuthology[test] + pushd $CURR_DIR + pip install -r requirements.txt -c constraints.txt + popd + + deactivate +} + +setup_coverage() { + # In CI environment we cannot install coverage in system, so we install it in a dedicated venv + # so only coverage is available when adding this path. + cd $TEMP_DIR + virtualenv --python=${TEUTHOLOGY_PYTHON_BIN:-/usr/bin/python} coverage-venv + source coverage-venv/bin/activate + cd $CURR_DIR + pip install coverage==4.5.2 + COVERAGE_PATH=$(python -c "import sysconfig; print(sysconfig.get_paths()['platlib'])") + deactivate +} + +on_tests_error() { + if [[ -n "$JENKINS_HOME" ]]; then + CEPH_OUT_DIR=${CEPH_OUT_DIR:-"$BUILD_DIR"/out} + MGR_LOG_FILES=$(find "$CEPH_OUT_DIR" -iname "mgr.*.log" | tr '\n' ' ') + MGR_LOG_FILE_LAST_LINES=1000 + for mgr_log_file in ${MGR_LOG_FILES[@]}; do + printf "\n\nDisplaying last ${MGR_LOG_FILE_LAST_LINES} lines of: $mgr_log_file\n\n" + tail -n ${MGR_LOG_FILE_LAST_LINES} $mgr_log_file + printf "\n\nEnd of: $mgr_log_file\n\n" + done + printf "\n\nTEST FAILED.\n\n" + fi +} + +run_teuthology_tests() { + trap on_tests_error ERR + + cd "$BUILD_DIR" + find ../src/pybind/mgr/dashboard/ -name '*.pyc' -exec rm -f {} \; + + OPTIONS='' + TEST_CASES='' + if [[ "$@" == '' || "$@" == '--create-cluster-only' ]]; then + TEST_CASES=`for i in \`ls $BUILD_DIR/../qa/tasks/mgr/dashboard/test_*\`; do F=$(basename $i); M="${F%.*}"; echo -n " tasks.mgr.dashboard.$M"; done` + # Mgr selftest module tests have to be run at the end as they stress the mgr daemon. + TEST_CASES="tasks.mgr.test_dashboard $TEST_CASES tasks.mgr.test_module_selftest" + if [[ "$@" == '--create-cluster-only' ]]; then + OPTIONS="$@" + fi + else + for t in "$@"; do + TEST_CASES="$TEST_CASES $t" + done + fi + + export PATH=$BUILD_DIR/bin:$PATH + source $TEMP_DIR/venv/bin/activate # Run after setting PATH as it does the last PATH export. + export LD_LIBRARY_PATH=$BUILD_DIR/lib/cython_modules/lib.${CEPH_PY_VERSION_MAJOR}/:$BUILD_DIR/lib + local source_dir=$(dirname "$BUILD_DIR") + local pybind_dir=$source_dir/src/pybind + local python_common_dir=$source_dir/src/python-common + # In CI environment we set python paths inside build (where you find the required frontend build: "dist" dir). + if [[ -n "$JENKINS_HOME" ]]; then + export PYBIND=$BUILD_DIR/src/pybind + pybind_dir=$PYBIND + fi + export PYTHONPATH=$source_dir/qa:$BUILD_DIR/lib/cython_modules/lib.${CEPH_PY_VERSION_MAJOR}/:$pybind_dir:$python_common_dir:${COVERAGE_PATH} + export RGW=${RGW:-1} + + export COVERAGE_ENABLED=true + export COVERAGE_FILE=.coverage.mgr.dashboard + find . -iname "*${COVERAGE_FILE}*" -type f -delete + + python ../qa/tasks/vstart_runner.py --ignore-missing-binaries --no-verbose $OPTIONS $TEST_CASES + + deactivate + cd $CURR_DIR +} + +cleanup_teuthology() { + cd "$BUILD_DIR" + killall ceph-mgr + sleep 10 + if [[ "$COVERAGE_ENABLED" == 'true' ]]; then + source $TEMP_DIR/coverage-venv/bin/activate + (coverage combine && coverage report) || true + deactivate + fi + ../src/stop.sh + sleep 5 + + cd $CURR_DIR + rm -rf $TEMP_DIR + + unset TEMP_DIR + unset CURR_DIR + unset BUILD_DIR + unset COVERAGE_PATH + unset get_build_py_version + unset setup_teuthology + unset setup_coverage + unset on_tests_error + unset run_teuthology_tests + unset cleanup_teuthology +} + +get_build_py_version +setup_teuthology +setup_coverage +run_teuthology_tests --create-cluster-only + +# End sourced section. Do not exit shell when the script has been sourced. +set +e +return 2>/dev/null || set -eo pipefail + +run_teuthology_tests "$@" +cleanup_teuthology diff --git a/src/pybind/mgr/dashboard/run-backend-rook-api-request.sh b/src/pybind/mgr/dashboard/run-backend-rook-api-request.sh new file mode 100755 index 00000000..ef221dcf --- /dev/null +++ b/src/pybind/mgr/dashboard/run-backend-rook-api-request.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# +# Query k8s to determine where the mgr is running and how to reach the +# dashboard from the local machine. This assumes that the dashboard is being +# exposed via a nodePort service +CURR_DIR=`pwd` +K8S_NAMESPACE='rook-ceph' + +HOST=$(kubectl get pods -n $K8S_NAMESPACE -l "app=rook-ceph-mgr" -o json | jq .items[0].spec.nodeName | sed s/\"//g) +if [ "$HOST" = "minikube" ]; then + HOST=$(minikube ip) +fi +PORT=$(kubectl get service -n $K8S_NAMESPACE rook-ceph-mgr-dashboard -o yaml | grep nodePort: | awk '{print $2}') +API_URL="https://${HOST}:${PORT}" + +# +# Rook automagically sets up an "admin" account with a random PW and stuffs +# that into a k8s secret. This fetches it. +# +PASSWD=$(kubectl -n $K8S_NAMESPACE get secret rook-ceph-dashboard-password -o yaml | grep "password:" | awk '{print $2}' | base64 --decode) + +if [ "$API_URL" = "null" ]; then + echo "Couldn't retrieve API URL, exiting..." >&2 + exit 1 +fi +cd $CURR_DIR + +TOKEN=`curl --insecure -s -H "Content-Type: application/json" -X POST \ + -d "{\"username\":\"admin\",\"password\":\"${PASSWD}\"}" $API_URL/api/auth \ + | jq .token | sed -e 's/"//g'` + +echo "METHOD: $1" +echo "URL: ${API_URL}${2}" +echo "DATA: $3" +echo "" + +curl --insecure -s -b /tmp/cd-cookie.txt -H "Authorization: Bearer $TOKEN " \ + -H "Content-Type: application/json" -X $1 -d "$3" ${API_URL}$2 | jq + diff --git a/src/pybind/mgr/dashboard/run-frontend-e2e-tests.sh b/src/pybind/mgr/dashboard/run-frontend-e2e-tests.sh new file mode 100755 index 00000000..280debdc --- /dev/null +++ b/src/pybind/mgr/dashboard/run-frontend-e2e-tests.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +set -e + +stop() { + if [ "$REMOTE" == "false" ]; then + cd $BUILD_DIR + ../src/stop.sh + fi + exit $1 +} + +BASE_URL='' +DEVICE='' +REMOTE='false' + +while getopts 'd:r:' flag; do + case "${flag}" in + d) DEVICE=$OPTARG;; + r) REMOTE='true' + # jq is expecting a string literal, otherwise it will fail on the url ':'. + # We need to ensure that jq gets a json string for assignment; we achieve + # that by introducing literal double quotes (i.e., '"'). + BASE_URL='"'$OPTARG'"';; + esac +done + +if [ "$DEVICE" == "" ]; then + if [ -x "$(command -v google-chrome)" ] || [ -x "$(command -v google-chrome-stable)" ]; then + DEVICE="chrome" + elif [ -x "$(command -v docker)" ]; then + DEVICE="docker" + else + echo "ERROR: Chrome and Docker not found. You need to install one of \ +them to run the e2e frontend tests." + stop 1 + fi +fi + +DASH_DIR=`pwd` + +cd ../../../../build +BUILD_DIR=`pwd` + +if [ "$BASE_URL" == "" ]; then + MGR=2 RGW=1 ../src/vstart.sh -n -d + sleep 10 + + # Create an Object Gateway User + ./bin/radosgw-admin user create --uid=dev --display-name=Developer --system + # Set the user-id + ./bin/ceph dashboard set-rgw-api-user-id dev + # Obtain and set access and secret key for the previously created user + RGW_ACCESS_KEY_FILE="/tmp/rgw-user-access-key.txt" + printf "$(./bin/radosgw-admin user info --uid=dev | jq -r .keys[0].access_key)" > "${RGW_ACCESS_KEY_FILE}" + ./bin/ceph dashboard set-rgw-api-access-key -i "${RGW_ACCESS_KEY_FILE}" + RGW_SECRET_KEY_FILE="/tmp/rgw-user-secret-key.txt" + printf "$(./bin/radosgw-admin user info --uid=dev | jq -r .keys[0].secret_key)" > "${RGW_SECRET_KEY_FILE}" + ./bin/ceph dashboard set-rgw-api-secret-key -i "${RGW_SECRET_KEY_FILE}" + # Set SSL verify to False + ./bin/ceph dashboard set-rgw-api-ssl-verify False + + BASE_URL=`./bin/ceph mgr services | jq .dashboard` +fi + +cd $DASH_DIR/frontend +jq .[].target=$BASE_URL proxy.conf.json.sample > proxy.conf.json + +[ -z $(command -v npm) ] && . $BUILD_DIR/src/pybind/mgr/dashboard/node-env/bin/activate +npm ci + +if [ $DEVICE == "chrome" ]; then + npm run e2e -- --dev-server-target --baseUrl=$(echo $BASE_URL | tr -d '"') || stop 1 + stop 0 +elif [ $DEVICE == "docker" ]; then + failed=0 + docker run -d -v $(pwd):/workdir --net=host --name angular-e2e-container rogargon/angular-e2e || failed=1 + docker exec angular-e2e-container npm run e2e || failed=1 + docker stop angular-e2e-container + docker rm angular-e2e-container + stop $failed +else + echo "ERROR: Device not recognized. Valid devices are 'chrome' and 'docker'." + stop 1 +fi diff --git a/src/pybind/mgr/dashboard/run-frontend-unittests.sh b/src/pybind/mgr/dashboard/run-frontend-unittests.sh new file mode 100755 index 00000000..dd8bac59 --- /dev/null +++ b/src/pybind/mgr/dashboard/run-frontend-unittests.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +failed=false +: ${CEPH_ROOT:=$PWD/../../../../} +cd $CEPH_ROOT/src/pybind/mgr/dashboard/frontend +if [ `uname` != "FreeBSD" ]; then + . $CEPH_ROOT/build/src/pybind/mgr/dashboard/node-env/bin/activate +fi + +# Build +npm run build -- --prod --progress=false || failed=true + +# Unit Tests +config='src/unit-test-configuration.ts' +if [ -e $config ]; then + mv $config ${config}_old +fi +cp ${config}.sample $config + +npm run test:ci || failed=true + +rm $config +if [ -e ${config}_old ]; then + mv ${config}_old $config +fi + +# Linting +npm run lint --silent +if [ $? -gt 0 ]; then + failed=true + echo -e "\nTry running 'npm run fix' to fix some linting errors. \ +Some errors might need a manual fix." +fi + +# I18N +npm run i18n:extract +if [ $? -gt 0 ]; then + failed=true + echo -e "\nTranslations extraction has failed." +else + i18n_lint=`awk '/ |$| <\/source>/,/<\/context-group>/ {printf "%-4s ", NR; print}' src/locale/messages.xlf` + if [ "$i18n_lint" ]; then + echo -e "The following source translations in 'messages.xlf' need to be \ + fixed, please check the I18N suggestions in 'HACKING.rst':\n" + echo "${i18n_lint}" + failed=true + fi +fi + +if [ `uname` != "FreeBSD" ]; then + deactivate +fi + +if [ "$failed" = "true" ]; then + exit 1 +fi diff --git a/src/pybind/mgr/dashboard/run-tox.sh b/src/pybind/mgr/dashboard/run-tox.sh new file mode 100755 index 00000000..8086bb4e --- /dev/null +++ b/src/pybind/mgr/dashboard/run-tox.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +function dump_envvars { + echo "WITH_PYTHON2: ->$WITH_PYTHON2<-" + echo "WITH_PYTHON3: ->$WITH_PYTHON3<-" + echo "TOX_PATH: ->$TOX_PATH<-" + echo "ENV_LIST: ->$ENV_LIST<-" +} + +# run from ./ or from ../ +: ${CEPH_BUILD_DIR:=$PWD/.tox} +: ${MGR_DASHBOARD_VIRTUALENV:=$CEPH_BUILD_DIR/mgr-dashboard-virtualenv} +: ${WITH_PYTHON2:=ON} +: ${WITH_PYTHON3:=3} +test -d dashboard && cd dashboard + +if [ -e tox.ini ]; then + TOX_PATH=$(readlink -f tox.ini) +else + TOX_PATH=$(readlink -f $(dirname $0)/tox.ini) +fi + +# tox.ini will take care of this. +unset PYTHONPATH +export CEPH_BUILD_DIR=$CEPH_BUILD_DIR + +source ${MGR_DASHBOARD_VIRTUALENV}/bin/activate + +if [ "$WITH_PYTHON2" = "ON" ]; then + if [[ -n "$@" ]]; then + ENV_LIST+="py27-run," + else + ENV_LIST+="py27-cov,py27-lint,py27-check," + fi +fi +# WITH_PYTHON3 might be set to "ON" or to the python3 RPM version number +# prevailing on the system - e.g. "3", "36" +if [[ "$WITH_PYTHON3" =~ (^3|^ON) ]]; then + if [[ -n "$@" ]]; then + ENV_LIST+="py3-run," + else + ENV_LIST+="py3-cov,py3-lint,py3-check," + fi +fi +# use bash string manipulation to strip off any trailing comma +ENV_LIST=${ENV_LIST%,} + +tox -c "${TOX_PATH}" -e "${ENV_LIST}" "$@" +TOX_STATUS="$?" +test "$TOX_STATUS" -ne "0" && dump_envvars +exit $TOX_STATUS diff --git a/src/pybind/mgr/dashboard/security.py b/src/pybind/mgr/dashboard/security.py new file mode 100644 index 00000000..cbeda6da --- /dev/null +++ b/src/pybind/mgr/dashboard/security.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import inspect + + +class Scope(object): + """ + List of Dashboard Security Scopes. + If you need another security scope, please add it here. + """ + + HOSTS = "hosts" + CONFIG_OPT = "config-opt" + POOL = "pool" + OSD = "osd" + MONITOR = "monitor" + RBD_IMAGE = "rbd-image" + ISCSI = "iscsi" + RBD_MIRRORING = "rbd-mirroring" + RGW = "rgw" + CEPHFS = "cephfs" + MANAGER = "manager" + LOG = "log" + GRAFANA = "grafana" + PROMETHEUS = "prometheus" + USER = "user" + DASHBOARD_SETTINGS = "dashboard-settings" + NFS_GANESHA = "nfs-ganesha" + + @classmethod + def all_scopes(cls): + return [val for scope, val in + inspect.getmembers(cls, + lambda memb: not inspect.isroutine(memb)) + if not scope.startswith('_')] + + @classmethod + def valid_scope(cls, scope_name): + return scope_name in cls.all_scopes() + + +class Permission(object): + """ + Scope permissions types + """ + READ = "read" + CREATE = "create" + UPDATE = "update" + DELETE = "delete" + + @classmethod + def all_permissions(cls): + return [val for perm, val in + inspect.getmembers(cls, + lambda memb: not inspect.isroutine(memb)) + if not perm.startswith('_')] + + @classmethod + def valid_permission(cls, perm_name): + return perm_name in cls.all_permissions() diff --git a/src/pybind/mgr/dashboard/services/__init__.py b/src/pybind/mgr/dashboard/services/__init__.py new file mode 100644 index 00000000..139759b6 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import diff --git a/src/pybind/mgr/dashboard/services/access_control.py b/src/pybind/mgr/dashboard/services/access_control.py new file mode 100644 index 00000000..9ea7a01c --- /dev/null +++ b/src/pybind/mgr/dashboard/services/access_control.py @@ -0,0 +1,670 @@ +# -*- coding: utf-8 -*- +# pylint: disable=too-many-arguments,too-many-return-statements +# pylint: disable=too-many-branches, too-many-locals, too-many-statements +from __future__ import absolute_import + +import errno +import json +import threading +import time +import six + +import bcrypt + +from mgr_module import CLICheckNonemptyFileInput, CLIReadCommand, CLIWriteCommand + +from .. import mgr, logger +from ..security import Scope, Permission +from ..exceptions import RoleAlreadyExists, RoleDoesNotExist, ScopeNotValid, \ + PermissionNotValid, RoleIsAssociatedWithUser, \ + UserAlreadyExists, UserDoesNotExist, ScopeNotInRole, \ + RoleNotInUser + + +# password hashing algorithm +def password_hash(password, salt_password=None): + if not password: + return None + if six.PY2: + password = unicode(password, 'utf-8') if isinstance(password, str) else password + if not salt_password: + salt_password = bcrypt.gensalt() + else: + salt_password = salt_password.encode('utf8') + return bcrypt.hashpw(password.encode('utf8'), salt_password).decode('utf8') + + +_P = Permission # short alias + + +class Role(object): + def __init__(self, name, description=None, scope_permissions=None): + self.name = name + self.description = description + if scope_permissions is None: + self.scopes_permissions = {} + else: + self.scopes_permissions = scope_permissions + + def __hash__(self): + return hash(self.name) + + def __eq__(self, other): + return self.name == other.name + + def set_scope_permissions(self, scope, permissions): + if not Scope.valid_scope(scope): + raise ScopeNotValid(scope) + for perm in permissions: + if not Permission.valid_permission(perm): + raise PermissionNotValid(perm) + + permissions.sort() + self.scopes_permissions[scope] = permissions + + def del_scope_permissions(self, scope): + if scope not in self.scopes_permissions: + raise ScopeNotInRole(scope, self.name) + del self.scopes_permissions[scope] + + def reset_scope_permissions(self): + self.scopes_permissions = {} + + def authorize(self, scope, permissions): + if scope in self.scopes_permissions: + role_perms = self.scopes_permissions[scope] + for perm in permissions: + if perm not in role_perms: + return False + return True + return False + + def to_dict(self): + return { + 'name': self.name, + 'description': self.description, + 'scopes_permissions': self.scopes_permissions + } + + @classmethod + def from_dict(cls, r_dict): + return Role(r_dict['name'], r_dict['description'], + r_dict['scopes_permissions']) + + +# static pre-defined system roles +# this roles cannot be deleted nor updated + +# admin role provides all permissions for all scopes +ADMIN_ROLE = Role('administrator', 'Administrator', { + scope_name: Permission.all_permissions() + for scope_name in Scope.all_scopes() +}) + + +# read-only role provides read-only permission for all scopes +READ_ONLY_ROLE = Role('read-only', 'Read-Only', { + scope_name: [_P.READ] for scope_name in Scope.all_scopes() + if scope_name != Scope.DASHBOARD_SETTINGS +}) + + +# block manager role provides all permission for block related scopes +BLOCK_MGR_ROLE = Role('block-manager', 'Block Manager', { + Scope.RBD_IMAGE: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.POOL: [_P.READ], + Scope.ISCSI: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.RBD_MIRRORING: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.GRAFANA: [_P.READ], +}) + + +# RadosGW manager role provides all permissions for block related scopes +RGW_MGR_ROLE = Role('rgw-manager', 'RGW Manager', { + Scope.RGW: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.GRAFANA: [_P.READ], +}) + + +# Cluster manager role provides all permission for OSDs, Monitors, and +# Config options +CLUSTER_MGR_ROLE = Role('cluster-manager', 'Cluster Manager', { + Scope.HOSTS: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.OSD: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.MONITOR: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.MANAGER: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.CONFIG_OPT: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.LOG: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.GRAFANA: [_P.READ], +}) + + +# Pool manager role provides all permissions for pool related scopes +POOL_MGR_ROLE = Role('pool-manager', 'Pool Manager', { + Scope.POOL: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.GRAFANA: [_P.READ], +}) + +# CephFS manager role provides all permissions for CephFS related scopes +CEPHFS_MGR_ROLE = Role('cephfs-manager', 'CephFS Manager', { + Scope.CEPHFS: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.GRAFANA: [_P.READ], +}) + +GANESHA_MGR_ROLE = Role('ganesha-manager', 'NFS Ganesha Manager', { + Scope.NFS_GANESHA: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.CEPHFS: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.RGW: [_P.READ, _P.CREATE, _P.UPDATE, _P.DELETE], + Scope.GRAFANA: [_P.READ], +}) + + +SYSTEM_ROLES = { + ADMIN_ROLE.name: ADMIN_ROLE, + READ_ONLY_ROLE.name: READ_ONLY_ROLE, + BLOCK_MGR_ROLE.name: BLOCK_MGR_ROLE, + RGW_MGR_ROLE.name: RGW_MGR_ROLE, + CLUSTER_MGR_ROLE.name: CLUSTER_MGR_ROLE, + POOL_MGR_ROLE.name: POOL_MGR_ROLE, + CEPHFS_MGR_ROLE.name: CEPHFS_MGR_ROLE, + GANESHA_MGR_ROLE.name: GANESHA_MGR_ROLE, +} + + +class User(object): + def __init__(self, username, password, name=None, email=None, roles=None, + lastUpdate=None): + self.username = username + self.password = password + self.name = name + self.email = email + if roles is None: + self.roles = set() + else: + self.roles = roles + if lastUpdate is None: + self.refreshLastUpdate() + else: + self.lastUpdate = lastUpdate + + def refreshLastUpdate(self): + self.lastUpdate = int(time.time()) + + def set_password(self, password): + self.password = password_hash(password) + self.refreshLastUpdate() + + def set_roles(self, roles): + self.roles = set(roles) + self.refreshLastUpdate() + + def add_roles(self, roles): + self.roles = self.roles.union(set(roles)) + self.refreshLastUpdate() + + def del_roles(self, roles): + for role in roles: + if role not in self.roles: + raise RoleNotInUser(role.name, self.username) + self.roles.difference_update(set(roles)) + self.refreshLastUpdate() + + def authorize(self, scope, permissions): + for role in self.roles: + if role.authorize(scope, permissions): + return True + return False + + def permissions_dict(self): + perms = {} + for role in self.roles: + for scope, perms_list in role.scopes_permissions.items(): + if scope in perms: + perms_tmp = set(perms[scope]).union(set(perms_list)) + perms[scope] = list(perms_tmp) + else: + perms[scope] = perms_list + + return perms + + def to_dict(self): + return { + 'username': self.username, + 'password': self.password, + 'roles': sorted([r.name for r in self.roles]), + 'name': self.name, + 'email': self.email, + 'lastUpdate': self.lastUpdate + } + + @classmethod + def from_dict(cls, u_dict, roles): + return User(u_dict['username'], u_dict['password'], u_dict['name'], + u_dict['email'], {roles[r] for r in u_dict['roles']}, + u_dict['lastUpdate']) + + +class AccessControlDB(object): + VERSION = 1 + ACDB_CONFIG_KEY = "accessdb_v" + + def __init__(self, version, users, roles): + self.users = users + self.version = version + self.roles = roles + self.lock = threading.RLock() + + def create_role(self, name, description=None): + with self.lock: + if name in SYSTEM_ROLES or name in self.roles: + raise RoleAlreadyExists(name) + role = Role(name, description) + self.roles[name] = role + return role + + def get_role(self, name): + with self.lock: + if name not in self.roles: + raise RoleDoesNotExist(name) + return self.roles[name] + + def delete_role(self, name): + with self.lock: + if name not in self.roles: + raise RoleDoesNotExist(name) + role = self.roles[name] + + # check if role is not associated with a user + for username, user in self.users.items(): + if role in user.roles: + raise RoleIsAssociatedWithUser(name, username) + + del self.roles[name] + + def create_user(self, username, password, name, email): + logger.debug("AC: creating user: username=%s", username) + with self.lock: + if username in self.users: + raise UserAlreadyExists(username) + user = User(username, password_hash(password), name, email) + self.users[username] = user + return user + + def get_user(self, username): + with self.lock: + if username not in self.users: + raise UserDoesNotExist(username) + return self.users[username] + + def delete_user(self, username): + with self.lock: + if username not in self.users: + raise UserDoesNotExist(username) + del self.users[username] + + def update_users_with_roles(self, role): + with self.lock: + if not role: + return + for _, user in self.users.items(): + if role in user.roles: + user.refreshLastUpdate() + + def save(self): + with self.lock: + db = { + 'users': {un: u.to_dict() for un, u in self.users.items()}, + 'roles': {rn: r.to_dict() for rn, r in self.roles.items()}, + 'version': self.version + } + mgr.set_store(self.accessdb_config_key(), json.dumps(db)) + + @classmethod + def accessdb_config_key(cls, version=None): + if version is None: + version = cls.VERSION + return "{}{}".format(cls.ACDB_CONFIG_KEY, version) + + def check_and_update_db(self): + logger.debug("AC: Checking for previews DB versions") + if self.VERSION == 1: # current version + # check if there is username/password from previous version + username = mgr.get_module_option('username', None) + password = mgr.get_module_option('password', None) + if username and password: + logger.debug("AC: Found single user credentials: user=%s", + username) + # found user credentials + user = self.create_user(username, "", None, None) + # password is already hashed, so setting manually + user.password = password + user.add_roles([ADMIN_ROLE]) + self.save() + else: + raise NotImplementedError() + + @classmethod + def load(cls): + logger.info("AC: Loading user roles DB version=%s", cls.VERSION) + + json_db = mgr.get_store(cls.accessdb_config_key()) + if json_db is None: + logger.debug("AC: No DB v%s found, creating new...", cls.VERSION) + db = cls(cls.VERSION, {}, {}) + # check if we can update from a previous version database + db.check_and_update_db() + return db + + db = json.loads(json_db) + roles = {rn: Role.from_dict(r) + for rn, r in db.get('roles', {}).items()} + users = {un: User.from_dict(u, dict(roles, **SYSTEM_ROLES)) + for un, u in db.get('users', {}).items()} + return cls(db['version'], users, roles) + + +def load_access_control_db(): + mgr.ACCESS_CTRL_DB = AccessControlDB.load() + + +# CLI dashboard access control scope commands + +@CLIWriteCommand('dashboard set-login-credentials', + 'name=username,type=CephString', + 'Set the login credentials. Password read from -i ') +@CLICheckNonemptyFileInput +def set_login_credentials_cmd(_, username, inbuf): + password = inbuf + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + user.set_password(password) + except UserDoesNotExist: + user = mgr.ACCESS_CTRL_DB.create_user(username, password, None, None) + user.set_roles([ADMIN_ROLE]) + + mgr.ACCESS_CTRL_DB.save() + + return 0, '''\ +****************************************************************** +*** WARNING: this command is deprecated. *** +*** Please use the ac-user-* related commands to manage users. *** +****************************************************************** +Username and password updated''', '' + + +@CLIReadCommand('dashboard ac-role-show', + 'name=rolename,type=CephString,req=false', + 'Show role info') +def ac_role_show_cmd(_, rolename=None): + if not rolename: + roles = dict(mgr.ACCESS_CTRL_DB.roles) + roles.update(SYSTEM_ROLES) + roles_list = [name for name, _ in roles.items()] + return 0, json.dumps(roles_list), '' + try: + role = mgr.ACCESS_CTRL_DB.get_role(rolename) + except RoleDoesNotExist as ex: + if rolename not in SYSTEM_ROLES: + return -errno.ENOENT, '', str(ex) + role = SYSTEM_ROLES[rolename] + return 0, json.dumps(role.to_dict()), '' + + +@CLIWriteCommand('dashboard ac-role-create', + 'name=rolename,type=CephString ' + 'name=description,type=CephString,req=false', + 'Create a new access control role') +def ac_role_create_cmd(_, rolename, description=None): + try: + role = mgr.ACCESS_CTRL_DB.create_role(rolename, description) + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(role.to_dict()), '' + except RoleAlreadyExists as ex: + return -errno.EEXIST, '', str(ex) + + +@CLIWriteCommand('dashboard ac-role-delete', + 'name=rolename,type=CephString', + 'Delete an access control role') +def ac_role_delete_cmd(_, rolename): + try: + mgr.ACCESS_CTRL_DB.delete_role(rolename) + mgr.ACCESS_CTRL_DB.save() + return 0, "Role '{}' deleted".format(rolename), "" + except RoleDoesNotExist as ex: + if rolename in SYSTEM_ROLES: + return -errno.EPERM, '', "Cannot delete system role '{}'" \ + .format(rolename) + return -errno.ENOENT, '', str(ex) + except RoleIsAssociatedWithUser as ex: + return -errno.EPERM, '', str(ex) + + +@CLIWriteCommand('dashboard ac-role-add-scope-perms', + 'name=rolename,type=CephString ' + 'name=scopename,type=CephString ' + 'name=permissions,type=CephString,n=N', + 'Add the scope permissions for a role') +def ac_role_add_scope_perms_cmd(_, rolename, scopename, permissions): + try: + role = mgr.ACCESS_CTRL_DB.get_role(rolename) + perms_array = [perm.strip() for perm in permissions] + role.set_scope_permissions(scopename, perms_array) + mgr.ACCESS_CTRL_DB.update_users_with_roles(role) + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(role.to_dict()), '' + except RoleDoesNotExist as ex: + if rolename in SYSTEM_ROLES: + return -errno.EPERM, '', "Cannot update system role '{}'" \ + .format(rolename) + return -errno.ENOENT, '', str(ex) + except ScopeNotValid as ex: + return -errno.EINVAL, '', str(ex) + "\n Possible values: {}" \ + .format(Scope.all_scopes()) + except PermissionNotValid as ex: + return -errno.EINVAL, '', str(ex) + \ + "\n Possible values: {}" \ + .format(Permission.all_permissions()) + + +@CLIWriteCommand('dashboard ac-role-del-scope-perms', + 'name=rolename,type=CephString ' + 'name=scopename,type=CephString', + 'Delete the scope permissions for a role') +def ac_role_del_scope_perms_cmd(_, rolename, scopename): + try: + role = mgr.ACCESS_CTRL_DB.get_role(rolename) + role.del_scope_permissions(scopename) + mgr.ACCESS_CTRL_DB.update_users_with_roles(role) + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(role.to_dict()), '' + except RoleDoesNotExist as ex: + if rolename in SYSTEM_ROLES: + return -errno.EPERM, '', "Cannot update system role '{}'" \ + .format(rolename) + return -errno.ENOENT, '', str(ex) + except ScopeNotInRole as ex: + return -errno.ENOENT, '', str(ex) + + +@CLIReadCommand('dashboard ac-user-show', + 'name=username,type=CephString,req=false', + 'Show user info') +def ac_user_show_cmd(_, username=None): + if not username: + users = mgr.ACCESS_CTRL_DB.users + users_list = [name for name, _ in users.items()] + return 0, json.dumps(users_list), '' + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + return 0, json.dumps(user.to_dict()), '' + except UserDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + + +@CLIWriteCommand('dashboard ac-user-create', + 'name=username,type=CephString ' + 'name=rolename,type=CephString,req=false ' + 'name=name,type=CephString,req=false ' + 'name=email,type=CephString,req=false', + 'Create a user. Password read from -i ') +@CLICheckNonemptyFileInput +def ac_user_create_cmd(_, username, inbuf, rolename=None, name=None, + email=None): + password = inbuf + try: + role = mgr.ACCESS_CTRL_DB.get_role(rolename) if rolename else None + except RoleDoesNotExist as ex: + if rolename not in SYSTEM_ROLES: + return -errno.ENOENT, '', str(ex) + role = SYSTEM_ROLES[rolename] + + try: + user = mgr.ACCESS_CTRL_DB.create_user(username, password, name, email) + except UserAlreadyExists as ex: + return -errno.EEXIST, '', str(ex) + + if role: + user.set_roles([role]) + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(user.to_dict()), '' + + +@CLIWriteCommand('dashboard ac-user-delete', + 'name=username,type=CephString', + 'Delete user') +def ac_user_delete_cmd(_, username): + try: + mgr.ACCESS_CTRL_DB.delete_user(username) + mgr.ACCESS_CTRL_DB.save() + return 0, "User '{}' deleted".format(username), "" + except UserDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + + +@CLIWriteCommand('dashboard ac-user-set-roles', + 'name=username,type=CephString ' + 'name=roles,type=CephString,n=N', + 'Set user roles') +def ac_user_set_roles_cmd(_, username, roles): + rolesname = roles + roles = [] + for rolename in rolesname: + try: + roles.append(mgr.ACCESS_CTRL_DB.get_role(rolename)) + except RoleDoesNotExist as ex: + if rolename not in SYSTEM_ROLES: + return -errno.ENOENT, '', str(ex) + roles.append(SYSTEM_ROLES[rolename]) + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + user.set_roles(roles) + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(user.to_dict()), '' + except UserDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + + +@CLIWriteCommand('dashboard ac-user-add-roles', + 'name=username,type=CephString ' + 'name=roles,type=CephString,n=N', + 'Add roles to user') +def ac_user_add_roles_cmd(_, username, roles): + rolesname = roles + roles = [] + for rolename in rolesname: + try: + roles.append(mgr.ACCESS_CTRL_DB.get_role(rolename)) + except RoleDoesNotExist as ex: + if rolename not in SYSTEM_ROLES: + return -errno.ENOENT, '', str(ex) + roles.append(SYSTEM_ROLES[rolename]) + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + user.add_roles(roles) + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(user.to_dict()), '' + except UserDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + + +@CLIWriteCommand('dashboard ac-user-del-roles', + 'name=username,type=CephString ' + 'name=roles,type=CephString,n=N', + 'Delete roles from user') +def ac_user_del_roles_cmd(_, username, roles): + rolesname = roles + roles = [] + for rolename in rolesname: + try: + roles.append(mgr.ACCESS_CTRL_DB.get_role(rolename)) + except RoleDoesNotExist as ex: + if rolename not in SYSTEM_ROLES: + return -errno.ENOENT, '', str(ex) + roles.append(SYSTEM_ROLES[rolename]) + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + user.del_roles(roles) + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(user.to_dict()), '' + except UserDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + except RoleNotInUser as ex: + return -errno.ENOENT, '', str(ex) + + +@CLIWriteCommand('dashboard ac-user-set-password', + 'name=username,type=CephString', + 'Set user password from -i ') +@CLICheckNonemptyFileInput +def ac_user_set_password(_, username, inbuf): + password = inbuf + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + user.set_password(password) + + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(user.to_dict()), '' + except UserDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + + +@CLIWriteCommand('dashboard ac-user-set-info', + 'name=username,type=CephString ' + 'name=name,type=CephString ' + 'name=email,type=CephString', + 'Set user info') +def ac_user_set_info(_, username, name, email): + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + if name: + user.name = name + if email: + user.email = email + mgr.ACCESS_CTRL_DB.save() + return 0, json.dumps(user.to_dict()), '' + except UserDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + + +class LocalAuthenticator(object): + def __init__(self): + load_access_control_db() + + def get_user(self, username): + return mgr.ACCESS_CTRL_DB.get_user(username) + + def authenticate(self, username, password): + try: + user = mgr.ACCESS_CTRL_DB.get_user(username) + if user.password: + pass_hash = password_hash(password, user.password) + if pass_hash == user.password: + return user.permissions_dict() + except UserDoesNotExist: + logger.debug("User '%s' does not exist", username) + return None + + def authorize(self, username, scope, permissions): + user = mgr.ACCESS_CTRL_DB.get_user(username) + return user.authorize(scope, permissions) diff --git a/src/pybind/mgr/dashboard/services/auth.py b/src/pybind/mgr/dashboard/services/auth.py new file mode 100644 index 00000000..239efae8 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/auth.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from base64 import b64encode +import json +import os +import threading +import time +import uuid + +import cherrypy +import jwt + +from .access_control import LocalAuthenticator, UserDoesNotExist +from .. import mgr, logger + +cherrypy.config.update({ + 'response.headers.server': 'Ceph-Dashboard', + 'response.headers.content-security-policy': "frame-ancestors 'self';", + 'response.headers.x-content-type-options': 'nosniff', + 'response.headers.strict-transport-security': 'max-age=63072000; includeSubDomains; preload' +}) + + +class JwtManager(object): + JWT_TOKEN_BLACKLIST_KEY = "jwt_token_black_list" + JWT_TOKEN_TTL = 28800 # default 8 hours + JWT_ALGORITHM = 'HS256' + _secret = None + + LOCAL_USER = threading.local() + + @staticmethod + def _gen_secret(): + secret = os.urandom(16) + return b64encode(secret).decode('utf-8') + + @classmethod + def init(cls): + # generate a new secret if it does not exist + secret = mgr.get_store('jwt_secret') + if secret is None: + secret = cls._gen_secret() + mgr.set_store('jwt_secret', secret) + cls._secret = secret + + @classmethod + def gen_token(cls, username): + if not cls._secret: + cls.init() + ttl = mgr.get_module_option('jwt_token_ttl', cls.JWT_TOKEN_TTL) + ttl = int(ttl) + now = int(time.time()) + payload = { + 'iss': 'ceph-dashboard', + 'jti': str(uuid.uuid4()), + 'exp': now + ttl, + 'iat': now, + 'username': username + } + return jwt.encode(payload, cls._secret, algorithm=cls.JWT_ALGORITHM) + + @classmethod + def decode_token(cls, token): + if not cls._secret: + cls.init() + return jwt.decode(token, cls._secret, algorithms=cls.JWT_ALGORITHM) + + @classmethod + def get_token_from_header(cls): + auth_cookie_name = 'token' + try: + # use cookie + return cherrypy.request.cookie[auth_cookie_name].value + except KeyError: + try: + # fall-back: use Authorization header + auth_header = cherrypy.request.headers.get('authorization') + if auth_header is not None: + scheme, params = auth_header.split(' ', 1) + if scheme.lower() == 'bearer': + return params + except IndexError: + return None + + @classmethod + def set_user(cls, token): + cls.LOCAL_USER.username = token['username'] + + @classmethod + def reset_user(cls): + cls.set_user({'username': None, 'permissions': None}) + + @classmethod + def get_username(cls): + return getattr(cls.LOCAL_USER, 'username', None) + + @classmethod + def blacklist_token(cls, token): + token = cls.decode_token(token) + blacklist_json = mgr.get_store(cls.JWT_TOKEN_BLACKLIST_KEY) + if not blacklist_json: + blacklist_json = "{}" + bl_dict = json.loads(blacklist_json) + now = time.time() + + # remove expired tokens + to_delete = [] + for jti, exp in bl_dict.items(): + if exp < now: + to_delete.append(jti) + for jti in to_delete: + del bl_dict[jti] + + bl_dict[token['jti']] = token['exp'] + mgr.set_store(cls.JWT_TOKEN_BLACKLIST_KEY, json.dumps(bl_dict)) + + @classmethod + def is_blacklisted(cls, jti): + blacklist_json = mgr.get_store(cls.JWT_TOKEN_BLACKLIST_KEY) + if not blacklist_json: + blacklist_json = "{}" + bl_dict = json.loads(blacklist_json) + return jti in bl_dict + + +class AuthManager(object): + AUTH_PROVIDER = None + + @classmethod + def initialize(cls): + cls.AUTH_PROVIDER = LocalAuthenticator() + + @classmethod + def get_user(cls, username): + return cls.AUTH_PROVIDER.get_user(username) + + @classmethod + def authenticate(cls, username, password): + return cls.AUTH_PROVIDER.authenticate(username, password) + + @classmethod + def authorize(cls, username, scope, permissions): + return cls.AUTH_PROVIDER.authorize(username, scope, permissions) + + +class AuthManagerTool(cherrypy.Tool): + def __init__(self): + super(AuthManagerTool, self).__init__( + 'before_handler', self._check_authentication, priority=20) + + def _check_authentication(self): + JwtManager.reset_user() + token = JwtManager.get_token_from_header() + logger.debug("AMT: token: %s", token) + if token: + try: + token = JwtManager.decode_token(token) + if not JwtManager.is_blacklisted(token['jti']): + user = AuthManager.get_user(token['username']) + if user.lastUpdate <= token['iat']: + self._check_authorization(token) + return + + logger.debug("AMT: user info changed after token was" + " issued, iat=%s lastUpdate=%s", + token['iat'], user.lastUpdate) + else: + logger.debug('AMT: Token is black-listed') + except jwt.exceptions.ExpiredSignatureError: + logger.debug("AMT: Token has expired") + except jwt.exceptions.InvalidTokenError: + logger.debug("AMT: Failed to decode token") + except UserDoesNotExist: + logger.debug("AMT: Invalid token: user %s does not exist", + token['username']) + + logger.debug('AMT: Unauthorized access to %s', + cherrypy.url(relative='server')) + raise cherrypy.HTTPError(401, 'You are not authorized to access ' + 'that resource') + + def _check_authorization(self, token): + logger.debug("AMT: checking authorization...") + username = token['username'] + handler = cherrypy.request.handler.callable + controller = handler.__self__ + sec_scope = getattr(controller, '_security_scope', None) + sec_perms = getattr(handler, '_security_permissions', None) + JwtManager.set_user(token) + + if not sec_scope: + # controller does not define any authorization restrictions + return + + logger.debug("AMT: checking '%s' access to '%s' scope", sec_perms, + sec_scope) + + if not sec_perms: + logger.debug("Fail to check permission on: %s:%s", controller, + handler) + raise cherrypy.HTTPError(403, "You don't have permissions to " + "access that resource") + + if not AuthManager.authorize(username, sec_scope, sec_perms): + raise cherrypy.HTTPError(403, "You don't have permissions to " + "access that resource") diff --git a/src/pybind/mgr/dashboard/services/ceph_service.py b/src/pybind/mgr/dashboard/services/ceph_service.py new file mode 100644 index 00000000..6d38fa41 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/ceph_service.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json + +import rados + +from mgr_module import CommandResult +from mgr_util import get_time_series_rates, get_most_recent_rate + +from .. import logger, mgr + +try: + from typing import Dict, Any, Union # pylint: disable=unused-import +except ImportError: + pass # For typing only + + +class SendCommandError(rados.Error): + def __init__(self, err, prefix, argdict, errno): + self.prefix = prefix + self.argdict = argdict + super(SendCommandError, self).__init__(err, errno) + + +class CephService(object): + + OSD_FLAG_NO_SCRUB = 'noscrub' + OSD_FLAG_NO_DEEP_SCRUB = 'nodeep-scrub' + + PG_STATUS_SCRUBBING = 'scrubbing' + PG_STATUS_DEEP_SCRUBBING = 'deep' + + SCRUB_STATUS_DISABLED = 'Disabled' + SCRUB_STATUS_ACTIVE = 'Active' + SCRUB_STATUS_INACTIVE = 'Inactive' + + @classmethod + def get_service_map(cls, service_name): + service_map = {} # type: Dict[str, Dict[str, Any]] + for server in mgr.list_servers(): + for service in server['services']: + if service['type'] == service_name: + if server['hostname'] not in service_map: + service_map[server['hostname']] = { + 'server': server, + 'services': [] + } + inst_id = service['id'] + metadata = mgr.get_metadata(service_name, inst_id) + status = mgr.get_daemon_status(service_name, inst_id) + service_map[server['hostname']]['services'].append({ + 'id': inst_id, + 'type': service_name, + 'hostname': server['hostname'], + 'metadata': metadata, + 'status': status + }) + return service_map + + @classmethod + def get_service_list(cls, service_name): + service_map = cls.get_service_map(service_name) + return [svc for _, svcs in service_map.items() for svc in svcs['services']] + + @classmethod + def get_service(cls, service_name, service_id): + for server in mgr.list_servers(): + for service in server['services']: + if service['type'] == service_name: + inst_id = service['id'] + if inst_id == service_id: + metadata = mgr.get_metadata(service_name, inst_id) + status = mgr.get_daemon_status(service_name, inst_id) + return { + 'id': inst_id, + 'type': service_name, + 'hostname': server['hostname'], + 'metadata': metadata, + 'status': status + } + return None + + @classmethod + def get_pool_list(cls, application=None): + osd_map = mgr.get('osd_map') + if not application: + return osd_map['pools'] + return [pool for pool in osd_map['pools'] + if application in pool.get('application_metadata', {})] + + @classmethod + def get_pool_list_with_stats(cls, application=None): + # pylint: disable=too-many-locals + pools = cls.get_pool_list(application) + + pools_w_stats = [] + + pg_summary = mgr.get("pg_summary") + pool_stats = mgr.get_updated_pool_stats() + + for pool in pools: + pool['pg_status'] = pg_summary['by_pool'][pool['pool'].__str__()] + stats = pool_stats[pool['pool']] + s = {} + + for stat_name, stat_series in stats.items(): + rates = get_time_series_rates(stat_series) + s[stat_name] = { + 'latest': stat_series[0][1], + 'rate': get_most_recent_rate(rates), + 'rates': rates + } + pool['stats'] = s + pools_w_stats.append(pool) + return pools_w_stats + + @classmethod + def get_pool_name_from_id(cls, pool_id): + # type: (int) -> Union[str, None] + return mgr.rados.pool_reverse_lookup(pool_id) + + @classmethod + def get_pool_by_attribute(cls, attribute, value): + # type: (str, Any) -> Union[dict, None] + pool_list = cls.get_pool_list() + for pool in pool_list: + if attribute in pool and pool[attribute] == value: + return pool + return None + + @classmethod + def get_pool_pg_status(cls, pool_name): + # type: (str) -> dict + pool = cls.get_pool_by_attribute('pool_name', pool_name) + if pool is None: + return {} + return mgr.get("pg_summary")['by_pool'][pool['pool'].__str__()] + + @classmethod + def send_command(cls, srv_type, prefix, srv_spec='', **kwargs): + """ + :type prefix: str + :param srv_type: mon | + :param kwargs: will be added to argdict + :param srv_spec: typically empty. or something like ":0" + + :raises PermissionError: See rados.make_ex + :raises ObjectNotFound: See rados.make_ex + :raises IOError: See rados.make_ex + :raises NoSpace: See rados.make_ex + :raises ObjectExists: See rados.make_ex + :raises ObjectBusy: See rados.make_ex + :raises NoData: See rados.make_ex + :raises InterruptedOrTimeoutError: See rados.make_ex + :raises TimedOut: See rados.make_ex + :raises ValueError: return code != 0 + """ + argdict = { + "prefix": prefix, + "format": "json", + } + argdict.update({k: v for k, v in kwargs.items() if v is not None}) + result = CommandResult("") + mgr.send_command(result, srv_type, srv_spec, json.dumps(argdict), "") + r, outb, outs = result.wait() + if r != 0: + msg = "send_command '{}' failed. (r={}, outs=\"{}\", kwargs={})".format(prefix, r, outs, + kwargs) + logger.error(msg) + raise SendCommandError(outs, prefix, argdict, r) + else: + try: + return json.loads(outb) + except Exception: # pylint: disable=broad-except + return outb + + @classmethod + def get_rates(cls, svc_type, svc_name, path): + """ + :return: the derivative of mgr.get_counter() + :rtype: list[tuple[int, float]]""" + data = mgr.get_counter(svc_type, svc_name, path)[path] + return get_time_series_rates(data) + + @classmethod + def get_rate(cls, svc_type, svc_name, path): + """returns most recent rate""" + return get_most_recent_rate(cls.get_rates(svc_type, svc_name, path)) + + @classmethod + def get_client_perf(cls): + pools_stats = mgr.get('osd_pool_stats')['pool_stats'] + + io_stats = { + 'read_bytes_sec': 0, + 'read_op_per_sec': 0, + 'write_bytes_sec': 0, + 'write_op_per_sec': 0, + } + recovery_stats = {'recovering_bytes_per_sec': 0} + + for pool_stats in pools_stats: + client_io = pool_stats['client_io_rate'] + for stat in list(io_stats.keys()): + if stat in client_io: + io_stats[stat] += client_io[stat] + + client_recovery = pool_stats['recovery_rate'] + for stat in list(recovery_stats.keys()): + if stat in client_recovery: + recovery_stats[stat] += client_recovery[stat] + + client_perf = io_stats.copy() + client_perf.update(recovery_stats) + + return client_perf + + @classmethod + def get_scrub_status(cls): + enabled_flags = mgr.get('osd_map')['flags_set'] + if cls.OSD_FLAG_NO_SCRUB in enabled_flags or cls.OSD_FLAG_NO_DEEP_SCRUB in enabled_flags: + return cls.SCRUB_STATUS_DISABLED + + grouped_pg_statuses = mgr.get('pg_summary')['all'] + for grouped_pg_status in grouped_pg_statuses.keys(): + if len(grouped_pg_status.split(cls.PG_STATUS_SCRUBBING)) > 1 \ + or len(grouped_pg_status.split(cls.PG_STATUS_DEEP_SCRUBBING)) > 1: + return cls.SCRUB_STATUS_ACTIVE + + return cls.SCRUB_STATUS_INACTIVE + + @classmethod + def get_pg_info(cls): + pg_summary = mgr.get('pg_summary') + object_stats = {stat: pg_summary['pg_stats_sum']['stat_sum'][stat] for stat in [ + 'num_objects', 'num_object_copies', 'num_objects_degraded', + 'num_objects_misplaced', 'num_objects_unfound']} + + pgs_per_osd = 0.0 + total_osds = len(pg_summary['by_osd']) + if total_osds > 0: + total_pgs = 0.0 + for _, osd_pg_statuses in pg_summary['by_osd'].items(): + for _, pg_amount in osd_pg_statuses.items(): + total_pgs += pg_amount + + pgs_per_osd = total_pgs / total_osds + + return { + 'object_stats': object_stats, + 'statuses': pg_summary['all'], + 'pgs_per_osd': pgs_per_osd, + } diff --git a/src/pybind/mgr/dashboard/services/cephfs.py b/src/pybind/mgr/dashboard/services/cephfs.py new file mode 100644 index 00000000..bb75b4e2 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/cephfs.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from contextlib import contextmanager + +import cephfs + +from .. import mgr, logger + + +class CephFS(object): + @classmethod + def list_filesystems(cls): + fsmap = mgr.get("fs_map") + return [{'id': fs['id'], 'name': fs['mdsmap']['fs_name']} + for fs in fsmap['filesystems']] + + def __init__(self, fs_name=None): + logger.debug("[CephFS] initializing cephfs connection") + self.cfs = cephfs.LibCephFS(rados_inst=mgr.rados) + logger.debug("[CephFS] mounting cephfs filesystem: %s", fs_name) + if fs_name: + self.cfs.mount(filesystem_name=fs_name) + else: + self.cfs.mount() + logger.debug("[CephFS] mounted cephfs filesystem") + + def __del__(self): + logger.debug("[CephFS] shutting down cephfs filesystem") + self.cfs.shutdown() + + @contextmanager + def opendir(self, dirpath): + d = None + try: + d = self.cfs.opendir(dirpath) + yield d + finally: + if d: + self.cfs.closedir(d) + + def get_dir_list(self, dirpath, level): + logger.debug("[CephFS] get_dir_list dirpath=%s level=%s", dirpath, + level) + if level == 0: + return [dirpath] + logger.debug("[CephFS] opening dirpath=%s", dirpath) + with self.opendir(dirpath) as d: + dent = self.cfs.readdir(d) + paths = [dirpath] + while dent: + logger.debug("[CephFS] found entry=%s", dent.d_name) + if dent.d_name in ['.', '..']: + dent = self.cfs.readdir(d) + continue + if dent.is_dir(): + logger.debug("[CephFS] found dir=%s", dent.d_name) + subdirpath = '{}{}/'.format(dirpath, dent.d_name) + paths.extend(self.get_dir_list(subdirpath, level-1)) + dent = self.cfs.readdir(d) + return paths + + def dir_exists(self, dirpath): + try: + with self.opendir(dirpath): + return True + except cephfs.ObjectNotFound: + return False + + def mkdirs(self, dirpath): + if dirpath == '/': + raise Exception('Cannot create root directory "/"') + if self.dir_exists(dirpath): + return + + logger.info("[CephFS] Creating directory: %s", dirpath) + self.cfs.mkdirs("{}".format(dirpath).encode('utf-8'), 0o755) diff --git a/src/pybind/mgr/dashboard/services/cephx.py b/src/pybind/mgr/dashboard/services/cephx.py new file mode 100644 index 00000000..ccda3879 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/cephx.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from .ceph_service import CephService + + +class CephX(object): + @classmethod + def _entities_map(cls, entity_type=None): + auth_dump = CephService.send_command("mon", "auth list") + result = {} + for auth_entry in auth_dump['auth_dump']: + entity = auth_entry['entity'] + if not entity_type or entity.startswith('{}.'.format(entity_type)): + entity_id = entity[entity.find('.')+1:] + result[entity_id] = auth_entry + return result + + @classmethod + def _clients_map(cls): + return cls._entities_map("client") + + @classmethod + def list_clients(cls): + return [client for client in cls._clients_map()] + + @classmethod + def get_client_key(cls, client_id): + return cls._clients_map()[client_id]['key'] diff --git a/src/pybind/mgr/dashboard/services/exception.py b/src/pybind/mgr/dashboard/services/exception.py new file mode 100644 index 00000000..b5c0bd58 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/exception.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json +import sys +from contextlib import contextmanager + +import cherrypy + +import rbd +import rados + +from .. import logger +from ..services.ceph_service import SendCommandError +from ..exceptions import ViewCacheNoDataException, DashboardException +from ..tools import wraps + +if sys.version_info < (3, 0): + # Monkey-patch a __call__ method into @contextmanager to make + # it compatible to Python 3 + + from contextlib import GeneratorContextManager # pylint: disable=no-name-in-module + + def init(self, *args): + if len(args) == 1: + self.gen = args[0] + elif len(args) == 3: + self.func, self.args, self.kwargs = args + else: + raise TypeError() + + def enter(self): + if hasattr(self, 'func'): + self.gen = self.func(*self.args, **self.kwargs) + try: + return self.gen.next() + except StopIteration: + raise RuntimeError("generator didn't yield") + + def call(self, f): + @wraps(f) + def wrapper(*args, **kwargs): + with self: + return f(*args, **kwargs) + + return wrapper + + GeneratorContextManager.__init__ = init + GeneratorContextManager.__enter__ = enter + GeneratorContextManager.__call__ = call + + # pylint: disable=function-redefined + def contextmanager(func): + + @wraps(func) + def helper(*args, **kwds): + return GeneratorContextManager(func, args, kwds) + + return helper + + +def serialize_dashboard_exception(e, include_http_status=False, task=None): + """ + :type e: Exception + :param include_http_status: Used for Tasks, where the HTTP status code is not available. + """ + from ..tools import ViewCache + if isinstance(e, ViewCacheNoDataException): + return {'status': ViewCache.VALUE_NONE, 'value': None} + + out = dict(detail=str(e)) + try: + out['code'] = e.code + except AttributeError: + pass + component = getattr(e, 'component', None) + out['component'] = component if component else None + if include_http_status: + out['status'] = getattr(e, 'status', 500) + if task: + out['task'] = dict(name=task.name, metadata=task.metadata) + return out + + +def dashboard_exception_handler(handler, *args, **kwargs): + try: + with handle_rados_error(component=None): # make the None controller the fallback. + return handler(*args, **kwargs) + # Don't catch cherrypy.* Exceptions. + except (ViewCacheNoDataException, DashboardException) as e: + logger.exception('dashboard_exception_handler') + cherrypy.response.headers['Content-Type'] = 'application/json' + cherrypy.response.status = getattr(e, 'status', 400) + return json.dumps(serialize_dashboard_exception(e)).encode('utf-8') + + +@contextmanager +def handle_rbd_error(): + try: + yield + except rbd.OSError as e: + raise DashboardException(e, component='rbd') + except rbd.Error as e: + raise DashboardException(e, component='rbd', code=e.__class__.__name__) + + +@contextmanager +def handle_rados_error(component): + try: + yield + except rados.OSError as e: + raise DashboardException(e, component=component) + except rados.Error as e: + raise DashboardException(e, component=component, code=e.__class__.__name__) + + +@contextmanager +def handle_send_command_error(component): + try: + yield + except SendCommandError as e: + raise DashboardException(e, component=component) diff --git a/src/pybind/mgr/dashboard/services/ganesha.py b/src/pybind/mgr/dashboard/services/ganesha.py new file mode 100644 index 00000000..4053d20c --- /dev/null +++ b/src/pybind/mgr/dashboard/services/ganesha.py @@ -0,0 +1,998 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import re + +from orchestrator import OrchestratorError +from .cephfs import CephFS +from .cephx import CephX +from .orchestrator import OrchClient +from .rgw_client import RgwClient, RequestException, NoCredentialsException +from .. import mgr, logger +from ..settings import Settings +from ..exceptions import DashboardException + + +class NFSException(DashboardException): + def __init__(self, msg): + super(NFSException, self).__init__(component="nfs", msg=msg) + + +class Ganesha(object): + @classmethod + def _get_clusters_locations(cls): + result = {} + location_list_str = Settings.GANESHA_CLUSTERS_RADOS_POOL_NAMESPACE + if not location_list_str: + raise NFSException("Ganesha config location is not configured. " + "Please set the GANESHA_RADOS_POOL_NAMESPACE " + "setting.") + location_list = [l.strip() for l in location_list_str.split(",")] + for location in location_list: + cluster = None + pool = None + namespace = None + if not location: + raise NFSException("Invalid Ganesha cluster RADOS " + "[cluster_id:]pool/namespace setting: {}" + .format(location)) + if location.count(':') < 1: + # default cluster_id + if location.count('/') > 1: + raise NFSException("Invalid Ganesha RADOS pool/namespace " + "setting: {}".format(location)) + # in this case accept pool/namespace only + cluster = "_default_" + if location.count('/') == 0: + pool, namespace = location, None + else: + pool, namespace = location.split('/', 1) + else: + cluster = location[:location.find(':')] + pool_nm = location[location.find(':')+1:] + if pool_nm.count('/') == 0: + pool, namespace = pool_nm, None + else: + pool, namespace = pool_nm.split('/', 1) + + if cluster in result: + raise NFSException("Duplicate Ganesha cluster definition in " + "the setting: {}".format(location_list_str)) + result[cluster] = (pool, namespace) + + return result + + @classmethod + def get_ganesha_clusters(cls): + return [cluster_id for cluster_id in cls._get_clusters_locations()] + + @staticmethod + def _get_orch_nfs_instances(): + try: + return OrchClient().list_service_info("nfs") + except (RuntimeError, OrchestratorError, ImportError): + return [] + + @classmethod + def get_daemons_status(cls): + instances = cls._get_orch_nfs_instances() + if not instances: + return None + + result = {} + for instance in instances: + if instance.service is None: + instance.service = "_default_" + if instance.service not in result: + result[instance.service] = {} + result[instance.service][instance.nodename] = { + 'status': instance.status, + 'desc': instance.status_desc, + } + return result + + @classmethod + def parse_rados_url(cls, rados_url): + if not rados_url.startswith("rados://"): + raise NFSException("Invalid NFS Ganesha RADOS configuration URL: {}" + .format(rados_url)) + rados_url = rados_url[8:] + url_comps = rados_url.split("/") + if len(url_comps) < 2 or len(url_comps) > 3: + raise NFSException("Invalid NFS Ganesha RADOS configuration URL: " + "rados://{}".format(rados_url)) + if len(url_comps) == 2: + return url_comps[0], None, url_comps[1] + return url_comps + + @classmethod + def make_rados_url(cls, pool, namespace, obj): + if namespace: + return "rados://{}/{}/{}".format(pool, namespace, obj) + return "rados://{}/{}".format(pool, obj) + + @classmethod + def get_pool_and_namespace(cls, cluster_id): + instances = cls._get_orch_nfs_instances() + # we assume that every instance stores there configuration in the + # same RADOS pool/namespace + if instances: + location = instances[0].rados_config_location + pool, ns, _ = cls.parse_rados_url(location) + return pool, ns + locations = cls._get_clusters_locations() + if cluster_id not in locations: + raise NFSException("Cluster not found: cluster_id={}" + .format(cluster_id)) + return locations[cluster_id] + + @classmethod + def reload_daemons(cls, cluster_id, daemons_id): + logger.debug("[NFS] issued reload of daemons: %s", daemons_id) + if not OrchClient().available(): + logger.debug("[NFS] orchestrator not available") + return + reload_list = [] + daemons = cls.get_daemons_status() + if cluster_id not in daemons: + raise NFSException("Cluster not found: cluster_id={}" + .format(cluster_id)) + for daemon_id in daemons_id: + if daemon_id not in daemons[cluster_id]: + continue + if daemons[cluster_id][daemon_id] == 1: + reload_list.append((cluster_id, daemon_id)) + OrchClient().reload_service("nfs", reload_list) + + @classmethod + def fsals_available(cls): + result = [] + if CephFS.list_filesystems(): + result.append("CEPH") + try: + if RgwClient.admin_instance().is_service_online() and \ + RgwClient.admin_instance().is_system_user(): + result.append("RGW") + except (NoCredentialsException, RequestException, LookupError): + pass + return result + + +class GaneshaConfParser(object): + def __init__(self, raw_config): + self.pos = 0 + self.text = "" + self.clean_config(raw_config) + + def clean_config(self, raw_config): + for line in raw_config.split("\n"): + cardinal_idx = line.find('#') + if cardinal_idx == -1: + self.text += line + else: + # remove comments + self.text += line[:cardinal_idx] + if line.startswith("%"): + self.text += "\n" + + def remove_all_whitespaces(self): + new_text = "" + in_string = False + in_section = False + for i, cha in enumerate(self.text): + if in_section: + if cha != '"' and self.text[i-1] != '\\': + new_text += cha + elif cha == '\n': + new_text += cha + in_section = False + elif i == (len(self.text)-1): + if cha != '"' and self.text[i-1] != '\\': + new_text += cha + in_section = False + elif not in_section and (i == 0 or self.text[i-1] == '\n') and cha == '%': + in_section = True + new_text += cha + elif in_string or cha not in [' ', '\n', '\t']: + new_text += cha + elif cha == '"' and self.text[i-1] != '\\': + in_string = not in_string + self.text = new_text + + def stream(self): + return self.text[self.pos:] + + def parse_block_name(self): + idx = self.stream().find('{') + if idx == -1: + raise Exception("Cannot find block name") + block_name = self.stream()[:idx] + self.pos += idx+1 + return block_name + + def parse_block_or_section(self): + if self.stream().startswith("%url "): + # section line + self.pos += 5 + idx = self.stream().find('\n') + if idx == -1: + value = self.stream() + self.pos += len(self.stream()) + else: + value = self.stream()[:idx] + self.pos += idx+1 + block_dict = {'block_name': '%url', 'value': value} + return block_dict + + block_name = self.parse_block_name().upper() + block_dict = {'block_name': block_name} + self.parse_block_body(block_dict) + if self.stream()[0] != '}': + raise Exception("No closing bracket '}' found at the end of block") + self.pos += 1 + return block_dict + + def parse_parameter_value(self, raw_value): + colon_idx = raw_value.find(',') + + if colon_idx == -1: + try: + return int(raw_value) + except ValueError: + if raw_value == "true": + return True + if raw_value == "false": + return False + if raw_value.find('"') == 0: + return raw_value[1:-1] + return raw_value + else: + return [self.parse_parameter_value(v.strip()) + for v in raw_value.split(',')] + + def parse_stanza(self, block_dict): + equal_idx = self.stream().find('=') + semicolon_idx = self.stream().find(';') + if equal_idx == -1: + raise Exception("Malformed stanza: no equal symbol found.") + parameter_name = self.stream()[:equal_idx].lower() + parameter_value = self.stream()[equal_idx+1:semicolon_idx] + block_dict[parameter_name] = self.parse_parameter_value( + parameter_value) + self.pos += semicolon_idx+1 + + def parse_block_body(self, block_dict): + last_pos = self.pos + while True: + semicolon_idx = self.stream().find(';') + lbracket_idx = self.stream().find('{') + rbracket_idx = self.stream().find('}') + + if rbracket_idx == 0: + # block end + return + + if (semicolon_idx != -1 and lbracket_idx != -1 + and semicolon_idx < lbracket_idx) \ + or (semicolon_idx != -1 and lbracket_idx == -1): + self.parse_stanza(block_dict) + elif (semicolon_idx != -1 and lbracket_idx != -1 + and semicolon_idx > lbracket_idx) or ( + semicolon_idx == -1 and lbracket_idx != -1): + if '_blocks_' not in block_dict: + block_dict['_blocks_'] = [] + block_dict['_blocks_'].append(self.parse_block_or_section()) + else: + raise Exception("Malformed stanza: no semicolon found.") + + if last_pos == self.pos: + raise Exception("Infinite loop while parsing block content") + last_pos = self.pos + + def parse(self): + self.remove_all_whitespaces() + blocks = [] + while self.stream(): + block_dict = self.parse_block_or_section() + blocks.append(block_dict) + return blocks + + @staticmethod + def _indentation(depth, size=4): + conf_str = "" + for _ in range(0, depth*size): + conf_str += " " + return conf_str + + @staticmethod + def write_block_body(block, depth=0): + def format_val(key, val): + if isinstance(val, list): + return ', '.join([format_val(key, v) for v in val]) + if isinstance(val, bool): + return str(val).lower() + if isinstance(val, int) or (block['block_name'] == 'CLIENT' + and key == 'clients'): + return '{}'.format(val) + return '"{}"'.format(val) + + conf_str = "" + for key, val in block.items(): + if key == 'block_name': + continue + elif key == '_blocks_': + for blo in val: + conf_str += GaneshaConfParser.write_block(blo, depth) + elif val: + conf_str += GaneshaConfParser._indentation(depth) + conf_str += '{} = {};\n'.format(key, format_val(key, val)) + return conf_str + + @staticmethod + def write_block(block, depth): + if block['block_name'] == "%url": + return '%url "{}"\n\n'.format(block['value']) + + conf_str = "" + conf_str += GaneshaConfParser._indentation(depth) + conf_str += format(block['block_name']) + conf_str += " {\n" + conf_str += GaneshaConfParser.write_block_body(block, depth+1) + conf_str += GaneshaConfParser._indentation(depth) + conf_str += "}\n\n" + return conf_str + + @staticmethod + def write_conf(blocks): + if not isinstance(blocks, list): + blocks = [blocks] + conf_str = "" + for block in blocks: + conf_str += GaneshaConfParser.write_block(block, 0) + return conf_str + + +class FSal(object): + def __init__(self, name): + self.name = name + + @classmethod + def validate_path(cls, _): + raise NotImplementedError() + + def validate(self): + raise NotImplementedError() + + def fill_keys(self): + raise NotImplementedError() + + def create_path(self, path): + raise NotImplementedError() + + @staticmethod + def from_fsal_block(fsal_block): + if fsal_block['name'] == "CEPH": + return CephFSFSal.from_fsal_block(fsal_block) + if fsal_block['name'] == 'RGW': + return RGWFSal.from_fsal_block(fsal_block) + return None + + def to_fsal_block(self): + raise NotImplementedError() + + @staticmethod + def from_dict(fsal_dict): + if fsal_dict['name'] == "CEPH": + return CephFSFSal.from_dict(fsal_dict) + if fsal_dict['name'] == 'RGW': + return RGWFSal.from_dict(fsal_dict) + return None + + def to_dict(self): + raise NotImplementedError() + + +class RGWFSal(FSal): + def __init__(self, name, rgw_user_id, access_key, secret_key): + super(RGWFSal, self).__init__(name) + self.rgw_user_id = rgw_user_id + self.access_key = access_key + self.secret_key = secret_key + + @classmethod + def validate_path(cls, path): + return path == "/" or re.match(r'^[^/><|&()#?]+$', path) + + def validate(self): + if not self.rgw_user_id: + raise NFSException('RGW user must be specified') + + if not RgwClient.admin_instance().user_exists(self.rgw_user_id): + raise NFSException("RGW user '{}' does not exist" + .format(self.rgw_user_id)) + + def fill_keys(self): + keys = RgwClient.admin_instance().get_user_keys(self.rgw_user_id) + self.access_key = keys['access_key'] + self.secret_key = keys['secret_key'] + + def create_path(self, path): + if path == '/': # nothing to do + return + rgw = RgwClient.instance(self.rgw_user_id) + try: + exists = rgw.bucket_exists(path, self.rgw_user_id) + logger.debug('Checking existence of RGW bucket "%s" for user "%s": %s', + path, self.rgw_user_id, exists) + except RequestException as exp: + if exp.status_code == 403: + raise NFSException('Cannot create bucket "{}" as it already ' + 'exists, and belongs to other user.' + .format(path)) + else: + raise exp + if not exists: + logger.info('Creating new RGW bucket "%s" for user "%s"', path, + self.rgw_user_id) + rgw.create_bucket(path) + + @classmethod + def from_fsal_block(cls, fsal_block): + return cls(fsal_block['name'], + fsal_block['user_id'], + fsal_block['access_key_id'], + fsal_block['secret_access_key']) + + def to_fsal_block(self): + return { + 'block_name': 'FSAL', + 'name': self.name, + 'user_id': self.rgw_user_id, + 'access_key_id': self.access_key, + 'secret_access_key': self.secret_key + } + + @classmethod + def from_dict(cls, fsal_dict): + return cls(fsal_dict['name'], fsal_dict['rgw_user_id'], None, None) + + def to_dict(self): + return { + 'name': self.name, + 'rgw_user_id': self.rgw_user_id + } + + +class CephFSFSal(FSal): + def __init__(self, name, user_id=None, fs_name=None, sec_label_xattr=None, + cephx_key=None): + super(CephFSFSal, self).__init__(name) + self.fs_name = fs_name + self.user_id = user_id + self.sec_label_xattr = sec_label_xattr + self.cephx_key = cephx_key + + @classmethod + def validate_path(cls, path): + return re.match(r'^/[^><|&()?]*$', path) + + def validate(self): + if self.user_id and self.user_id not in CephX.list_clients(): + raise NFSException("cephx user '{}' does not exist" + .format(self.user_id)) + + def fill_keys(self): + if self.user_id: + self.cephx_key = CephX.get_client_key(self.user_id) + + def create_path(self, path): + cfs = CephFS() + if not cfs.dir_exists(path): + cfs.mkdirs(path) + + @classmethod + def from_fsal_block(cls, fsal_block): + return cls(fsal_block['name'], + fsal_block.get('user_id', None), + fsal_block.get('filesystem', None), + fsal_block.get('sec_label_xattr', None), + fsal_block.get('secret_access_key', None)) + + def to_fsal_block(self): + result = { + 'block_name': 'FSAL', + 'name': self.name, + } + if self.user_id: + result['user_id'] = self.user_id + if self.fs_name: + result['filesystem'] = self.fs_name + if self.sec_label_xattr: + result['sec_label_xattr'] = self.sec_label_xattr + if self.cephx_key: + result['secret_access_key'] = self.cephx_key + return result + + @classmethod + def from_dict(cls, fsal_dict): + return cls(fsal_dict['name'], fsal_dict['user_id'], + fsal_dict['fs_name'], fsal_dict['sec_label_xattr'], None) + + def to_dict(self): + return { + 'name': self.name, + 'user_id': self.user_id, + 'fs_name': self.fs_name, + 'sec_label_xattr': self.sec_label_xattr + } + + +class Client(object): + def __init__(self, addresses, access_type=None, squash=None): + self.addresses = addresses + self.access_type = access_type + self.squash = GaneshaConf.format_squash(squash) + + @classmethod + def from_client_block(cls, client_block): + addresses = client_block['clients'] + if not isinstance(addresses, list): + addresses = [addresses] + return cls(addresses, + client_block.get('access_type', None), + client_block.get('squash', None)) + + def to_client_block(self): + result = { + 'block_name': 'CLIENT', + 'clients': self.addresses, + } + if self.access_type: + result['access_type'] = self.access_type + if self.squash: + result['squash'] = self.squash + return result + + @classmethod + def from_dict(cls, client_dict): + return cls(client_dict['addresses'], client_dict['access_type'], + client_dict['squash']) + + def to_dict(self): + return { + 'addresses': self.addresses, + 'access_type': self.access_type, + 'squash': self.squash + } + + +class Export(object): + # pylint: disable=R0902 + def __init__(self, export_id, path, fsal, cluster_id, daemons, pseudo=None, + tag=None, access_type=None, squash=None, + attr_expiration_time=None, security_label=False, + protocols=None, transports=None, clients=None): + self.export_id = export_id + self.path = GaneshaConf.format_path(path) + self.fsal = fsal + self.cluster_id = cluster_id + self.daemons = set(daemons) + self.pseudo = GaneshaConf.format_path(pseudo) + self.tag = tag + self.access_type = access_type + self.squash = GaneshaConf.format_squash(squash) + if attr_expiration_time is None: + self.attr_expiration_time = 0 + else: + self.attr_expiration_time = attr_expiration_time + self.security_label = security_label + self.protocols = {GaneshaConf.format_protocol(p) for p in protocols} + self.transports = set(transports) + self.clients = clients + + def validate(self, daemons_list): + # pylint: disable=R0912 + for daemon_id in self.daemons: + if daemon_id not in daemons_list: + raise NFSException("Daemon '{}' does not exist" + .format(daemon_id)) + + if not self.fsal.validate_path(self.path): + raise NFSException("Export path ({}) is invalid.".format(self.path)) + + if not self.protocols: + raise NFSException( + "No NFS protocol version specified for the export.") + + if not self.transports: + raise NFSException( + "No network transport type specified for the export.") + + for t in self.transports: + match = re.match(r'^TCP$|^UDP$', t) + if not match: + raise NFSException( + "'{}' is an invalid network transport type identifier" + .format(t)) + + self.fsal.validate() + + if 4 in self.protocols: + if not self.pseudo: + raise NFSException( + "Pseudo path is required when NFSv4 protocol is used") + match = re.match(r'^/[^><|&()]*$', self.pseudo) + if not match: + raise NFSException( + "Export pseudo path ({}) is invalid".format(self.pseudo)) + + if self.tag: + match = re.match(r'^[^/><|:&()]+$', self.tag) + if not match: + raise NFSException( + "Export tag ({}) is invalid".format(self.tag)) + + if self.fsal.name == 'RGW' and 4 not in self.protocols and not self.tag: + raise NFSException( + "Tag is mandatory for RGW export when using only NFSv3") + + @classmethod + def from_export_block(cls, export_block, cluster_id, defaults): + logger.debug("[NFS] parsing export block: %s", export_block) + + fsal_block = [b for b in export_block['_blocks_'] + if b['block_name'] == "FSAL"] + + protocols = export_block.get('protocols', defaults['protocols']) + if not isinstance(protocols, list): + protocols = [protocols] + + transports = export_block.get('transports', defaults['transports']) + if not isinstance(transports, list): + transports = [transports] + + client_blocks = [b for b in export_block['_blocks_'] + if b['block_name'] == "CLIENT"] + + return cls(export_block['export_id'], + export_block['path'], + FSal.from_fsal_block(fsal_block[0]), + cluster_id, + [], + export_block.get('pseudo', None), + export_block.get('tag', None), + export_block.get('access_type', defaults['access_type']), + export_block.get('squash', defaults['squash']), + export_block.get('attr_expiration_time', None), + export_block.get('security_label', False), + protocols, + transports, + [Client.from_client_block(client) + for client in client_blocks]) + + def to_export_block(self, defaults): + # pylint: disable=too-many-branches + result = { + 'block_name': 'EXPORT', + 'export_id': self.export_id, + 'path': self.path + } + if self.pseudo: + result['pseudo'] = self.pseudo + if self.tag: + result['tag'] = self.tag + if 'access_type' not in defaults \ + or self.access_type != defaults['access_type']: + result['access_type'] = self.access_type + if 'squash' not in defaults or self.squash != defaults['squash']: + result['squash'] = self.squash + if self.fsal.name == 'CEPH': + result['attr_expiration_time'] = self.attr_expiration_time + result['security_label'] = self.security_label + if 'protocols' not in defaults: + result['protocols'] = [p for p in self.protocols] + else: + def_proto = defaults['protocols'] + if not isinstance(def_proto, list): + def_proto = set([def_proto]) + if self.protocols != def_proto: + result['protocols'] = [p for p in self.protocols] + if 'transports' not in defaults: + result['transports'] = [t for t in self.transports] + else: + def_transp = defaults['transports'] + if not isinstance(def_transp, list): + def_transp = set([def_transp]) + if self.transports != def_transp: + result['transports'] = [t for t in self.transports] + + result['_blocks_'] = [self.fsal.to_fsal_block()] + result['_blocks_'].extend([client.to_client_block() + for client in self.clients]) + return result + + @classmethod + def from_dict(cls, export_id, ex_dict, old_export=None): + return cls(export_id, + ex_dict['path'], + FSal.from_dict(ex_dict['fsal']), + ex_dict['cluster_id'], + ex_dict['daemons'], + ex_dict['pseudo'], + ex_dict['tag'], + ex_dict['access_type'], + ex_dict['squash'], + old_export.attr_expiration_time if old_export else None, + ex_dict['security_label'], + ex_dict['protocols'], + ex_dict['transports'], + [Client.from_dict(client) for client in ex_dict['clients']]) + + def to_dict(self): + return { + 'export_id': self.export_id, + 'path': self.path, + 'fsal': self.fsal.to_dict(), + 'cluster_id': self.cluster_id, + 'daemons': sorted([d for d in self.daemons]), + 'pseudo': self.pseudo, + 'tag': self.tag, + 'access_type': self.access_type, + 'squash': self.squash, + 'security_label': self.security_label, + 'protocols': sorted([p for p in self.protocols]), + 'transports': sorted([t for t in self.transports]), + 'clients': [client.to_dict() for client in self.clients] + } + + +class GaneshaConf(object): + # pylint: disable=R0902 + + def __init__(self, cluster_id, rados_pool, rados_namespace): + self.cluster_id = cluster_id + self.rados_pool = rados_pool + self.rados_namespace = rados_namespace + self.export_conf_blocks = [] + self.daemons_conf_blocks = {} + self._defaults = {} + self.exports = {} + + self._read_raw_config() + + # load defaults + def_block = [b for b in self.export_conf_blocks + if b['block_name'] == "EXPORT_DEFAULTS"] + self.export_defaults = def_block[0] if def_block else {} + self._defaults = self.ganesha_defaults(self.export_defaults) + + for export_block in [block for block in self.export_conf_blocks + if block['block_name'] == "EXPORT"]: + export = Export.from_export_block(export_block, cluster_id, + self._defaults) + self.exports[export.export_id] = export + + # link daemons to exports + for daemon_id, daemon_blocks in self.daemons_conf_blocks.items(): + for block in daemon_blocks: + if block['block_name'] == "%url": + rados_url = block['value'] + _, _, obj = Ganesha.parse_rados_url(rados_url) + if obj.startswith("export-"): + export_id = int(obj[obj.find('-')+1:]) + self.exports[export_id].daemons.add(daemon_id) + + @classmethod + def instance(cls, cluster_id): + pool, ns = Ganesha.get_pool_and_namespace(cluster_id) + return cls(cluster_id, pool, ns) + + def _read_raw_config(self): + with mgr.rados.open_ioctx(self.rados_pool) as ioctx: + if self.rados_namespace: + ioctx.set_namespace(self.rados_namespace) + objs = ioctx.list_objects() + for obj in objs: + if obj.key.startswith("export-"): + size, _ = obj.stat() + raw_config = obj.read(size) + raw_config = raw_config.decode("utf-8") + logger.debug("[NFS] read export configuration from rados " + "object %s/%s/%s:\n%s", self.rados_pool, + self.rados_namespace, obj.key, raw_config) + self.export_conf_blocks.extend( + GaneshaConfParser(raw_config).parse()) + elif obj.key.startswith("conf-"): + size, _ = obj.stat() + raw_config = obj.read(size) + raw_config = raw_config.decode("utf-8") + logger.debug("[NFS] read daemon configuration from rados " + "object %s/%s/%s:\n%s", self.rados_pool, + self.rados_namespace, obj.key, raw_config) + idx = obj.key.find('-') + self.daemons_conf_blocks[obj.key[idx+1:]] = \ + GaneshaConfParser(raw_config).parse() + + def _write_raw_config(self, conf_block, obj): + raw_config = GaneshaConfParser.write_conf(conf_block) + with mgr.rados.open_ioctx(self.rados_pool) as ioctx: + if self.rados_namespace: + ioctx.set_namespace(self.rados_namespace) + ioctx.write_full(obj, raw_config.encode('utf-8')) + logger.debug( + "[NFS] write configuration into rados object %s/%s/%s:\n%s", + self.rados_pool, self.rados_namespace, obj, raw_config) + + @classmethod + def ganesha_defaults(cls, export_defaults): + """ + According to + https://github.com/nfs-ganesha/nfs-ganesha/blob/next/src/config_samples/export.txt + """ + return { + 'access_type': export_defaults.get('access_type', 'NONE'), + 'protocols': export_defaults.get('protocols', [3, 4]), + 'transports': export_defaults.get('transports', ['TCP', 'UDP']), + 'squash': export_defaults.get('squash', 'root_squash') + } + + @classmethod + def format_squash(cls, squash): + if squash is None: + return None + if squash.lower() in ["no_root_squash", "noidsquash", "none"]: + return "no_root_squash" + if squash.lower() in ["rootid", "root_id_squash", "rootidsquash"]: + return "root_id_squash" + if squash.lower() in ["root", "root_squash", "rootsquash"]: + return "root_squash" + if squash.lower() in ["all", "all_squash", "allsquash", + "all_anonymous", "allanonymous"]: + return "all_squash" + logger.error("[NFS] could not parse squash value: %s", squash) + raise NFSException("'{}' is an invalid squash option".format(squash)) + + @classmethod + def format_protocol(cls, protocol): + if str(protocol) in ["NFSV3", "3", "V3", "NFS3"]: + return 3 + if str(protocol) in ["NFSV4", "4", "V4", "NFS4"]: + return 4 + logger.error("[NFS] could not parse protocol value: %s", protocol) + raise NFSException("'{}' is an invalid NFS protocol version identifier" + .format(protocol)) + + @classmethod + def format_path(cls, path): + if path is not None: + path = path.strip() + if len(path) > 1 and path[-1] == '/': + path = path[:-1] + return path + + def validate(self, export): + export.validate(self.list_daemons()) + + if 4 in export.protocols: # NFSv4 protocol + len_prefix = 1 + parent_export = None + for ex in self.list_exports(): + if export.tag and ex.tag == export.tag: + raise NFSException( + "Another export exists with the same tag: {}" + .format(export.tag)) + + if export.pseudo and ex.pseudo == export.pseudo: + raise NFSException( + "Another export exists with the same pseudo path: {}" + .format(export.pseudo)) + + if not ex.pseudo: + continue + + if export.pseudo[:export.pseudo.rfind('/')+1].startswith(ex.pseudo): + if export.pseudo[len(ex.pseudo)] == '/': + if len(ex.pseudo) > len_prefix: + len_prefix = len(ex.pseudo) + parent_export = ex + + if len_prefix > 1: + # validate pseudo path + idx = len(parent_export.pseudo) + idx = idx + 1 if idx > 1 else idx + real_path = "{}/{}".format(parent_export.path + if len(parent_export.path) > 1 else "", + export.pseudo[idx:]) + if export.fsal.name == 'CEPH': + cfs = CephFS() + if export.path != real_path and not cfs.dir_exists(real_path): + raise NFSException( + "Pseudo path ({}) invalid, path {} does not exist." + .format(export.pseudo, real_path)) + + def _gen_export_id(self): + exports = sorted(self.exports) + nid = 1 + for e_id in exports: + if e_id == nid: + nid += 1 + else: + break + return nid + + def _persist_daemon_configuration(self): + daemon_map = {} + for daemon_id in self.list_daemons(): + daemon_map[daemon_id] = [] + + for _, ex in self.exports.items(): + for daemon in ex.daemons: + daemon_map[daemon].append({ + 'block_name': "%url", + 'value': Ganesha.make_rados_url( + self.rados_pool, self.rados_namespace, + "export-{}".format(ex.export_id)) + }) + for daemon_id, conf_blocks in daemon_map.items(): + self._write_raw_config(conf_blocks, "conf-{}".format(daemon_id)) + + def _save_export(self, export): + self.validate(export) + export.fsal.create_path(export.path) + export.fsal.fill_keys() + self.exports[export.export_id] = export + conf_block = export.to_export_block(self.export_defaults) + self._write_raw_config(conf_block, "export-{}".format(export.export_id)) + self._persist_daemon_configuration() + + def _delete_export(self, export_id): + self._persist_daemon_configuration() + with mgr.rados.open_ioctx(self.rados_pool) as ioctx: + if self.rados_namespace: + ioctx.set_namespace(self.rados_namespace) + ioctx.remove_object("export-{}".format(export_id)) + + def list_exports(self): + return [ex for _, ex in self.exports.items()] + + def create_export(self, ex_dict): + ex_id = self._gen_export_id() + export = Export.from_dict(ex_id, ex_dict) + self._save_export(export) + return ex_id + + def has_export(self, export_id): + return export_id in self.exports + + def update_export(self, ex_dict): + if ex_dict['export_id'] not in self.exports: + return None + old_export = self.exports[ex_dict['export_id']] + del self.exports[ex_dict['export_id']] + export = Export.from_dict(ex_dict['export_id'], ex_dict, old_export) + self._save_export(export) + self.exports[export.export_id] = export + return old_export + + def remove_export(self, export_id): + if export_id not in self.exports: + return None + export = self.exports[export_id] + del self.exports[export_id] + self._delete_export(export_id) + return export + + def get_export(self, export_id): + if export_id in self.exports: + return self.exports[export_id] + return None + + def list_daemons(self): + return [daemon_id for daemon_id in self.daemons_conf_blocks] + + def reload_daemons(self, daemons): + with mgr.rados.open_ioctx(self.rados_pool) as ioctx: + if self.rados_namespace: + ioctx.set_namespace(self.rados_namespace) + for daemon_id in daemons: + ioctx.notify("conf-{}".format(daemon_id)) diff --git a/src/pybind/mgr/dashboard/services/iscsi_cli.py b/src/pybind/mgr/dashboard/services/iscsi_cli.py new file mode 100644 index 00000000..f962de59 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/iscsi_cli.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import errno +import json + +from mgr_module import CLICheckNonemptyFileInput, CLIReadCommand, CLIWriteCommand + +from .iscsi_client import IscsiClient +from .iscsi_config import IscsiGatewaysConfig, IscsiGatewayAlreadyExists, InvalidServiceUrl, \ + ManagedByOrchestratorException, IscsiGatewayDoesNotExist +from ..rest_client import RequestException + + +@CLIReadCommand('dashboard iscsi-gateway-list', desc='List iSCSI gateways') +def list_iscsi_gateways(_): + return 0, json.dumps(IscsiGatewaysConfig.get_gateways_config()), '' + + +@CLIWriteCommand('dashboard iscsi-gateway-add', + desc='Add iSCSI gateway configuration. Gateway URL read from -i ') +@CLICheckNonemptyFileInput +def add_iscsi_gateway(_, inbuf): + service_url = inbuf + try: + IscsiGatewaysConfig.validate_service_url(service_url) + name = IscsiClient.instance(service_url=service_url).get_hostname()['data'] + IscsiGatewaysConfig.add_gateway(name, service_url) + return 0, 'Success', '' + except IscsiGatewayAlreadyExists as ex: + return -errno.EEXIST, '', str(ex) + except InvalidServiceUrl as ex: + return -errno.EINVAL, '', str(ex) + except ManagedByOrchestratorException as ex: + return -errno.EINVAL, '', str(ex) + except RequestException as ex: + return -errno.EINVAL, '', str(ex) + + +@CLIWriteCommand('dashboard iscsi-gateway-rm', + 'name=name,type=CephString', + 'Remove iSCSI gateway configuration') +def remove_iscsi_gateway(_, name): + try: + IscsiGatewaysConfig.remove_gateway(name) + return 0, 'Success', '' + except IscsiGatewayDoesNotExist as ex: + return -errno.ENOENT, '', str(ex) + except ManagedByOrchestratorException as ex: + return -errno.EINVAL, '', str(ex) diff --git a/src/pybind/mgr/dashboard/services/iscsi_client.py b/src/pybind/mgr/dashboard/services/iscsi_client.py new file mode 100644 index 00000000..e66bd3cc --- /dev/null +++ b/src/pybind/mgr/dashboard/services/iscsi_client.py @@ -0,0 +1,257 @@ +# -*- coding: utf-8 -*- +# pylint: disable=too-many-public-methods +from __future__ import absolute_import + +import json + +from requests.auth import HTTPBasicAuth + +try: + from urlparse import urlparse +except ImportError: + from urllib.parse import urlparse + +from .iscsi_config import IscsiGatewaysConfig +from .. import logger +from ..settings import Settings +from ..rest_client import RestClient + + +class IscsiClient(RestClient): + _CLIENT_NAME = 'iscsi' + _instances = {} + + service_url = None + gateway_name = None + + @classmethod + def instance(cls, gateway_name=None, service_url=None): + if not service_url: + if not gateway_name: + gateway_name = list(IscsiGatewaysConfig.get_gateways_config()['gateways'].keys())[0] + gateways_config = IscsiGatewaysConfig.get_gateway_config(gateway_name) + service_url = gateways_config['service_url'] + + instance = cls._instances.get(gateway_name) + if not instance or service_url != instance.service_url or \ + instance.session.verify != Settings.ISCSI_API_SSL_VERIFICATION: + url = urlparse(service_url) + ssl = url.scheme == 'https' + host = url.hostname + port = url.port + username = url.username + password = url.password + if not port: + port = 443 if ssl else 80 + + auth = HTTPBasicAuth(username, password) + instance = IscsiClient(host, port, IscsiClient._CLIENT_NAME, ssl, + auth, Settings.ISCSI_API_SSL_VERIFICATION) + instance.service_url = service_url + instance.gateway_name = gateway_name + if gateway_name: + cls._instances[gateway_name] = instance + + return instance + + @RestClient.api_get('/api/_ping') + def ping(self, request=None): + return request() + + @RestClient.api_get('/api/settings') + def get_settings(self, request=None): + return request() + + @RestClient.api_get('/api/sysinfo/ip_addresses') + def get_ip_addresses(self, request=None): + return request() + + @RestClient.api_get('/api/sysinfo/hostname') + def get_hostname(self, request=None): + return request() + + @RestClient.api_get('/api/config') + def get_config(self, request=None): + return request({ + 'decrypt_passwords': True + }) + + @RestClient.api_put('/api/target/{target_iqn}') + def create_target(self, target_iqn, target_controls, request=None): + logger.debug("iSCSI[%s] Creating target: %s", self.gateway_name, target_iqn) + return request({ + 'controls': json.dumps(target_controls) + }) + + @RestClient.api_delete('/api/target/{target_iqn}') + def delete_target(self, target_iqn, request=None): + logger.debug("iSCSI[%s] Deleting target: %s", self.gateway_name, target_iqn) + return request() + + @RestClient.api_put('/api/target/{target_iqn}') + def reconfigure_target(self, target_iqn, target_controls, request=None): + logger.debug("iSCSI[%s] Reconfiguring target: %s", self.gateway_name, target_iqn) + return request({ + 'mode': 'reconfigure', + 'controls': json.dumps(target_controls) + }) + + @RestClient.api_put('/api/gateway/{target_iqn}/{gateway_name}') + def create_gateway(self, target_iqn, gateway_name, ip_address, request=None): + logger.debug("iSCSI[%s] Creating gateway: %s/%s", self.gateway_name, target_iqn, + gateway_name) + return request({ + 'ip_address': ','.join(ip_address), + 'skipchecks': 'true' + }) + + @RestClient.api_get('/api/gatewayinfo') + def get_gatewayinfo(self, request=None): + return request() + + @RestClient.api_delete('/api/gateway/{target_iqn}/{gateway_name}') + def delete_gateway(self, target_iqn, gateway_name, request=None): + logger.debug("iSCSI: Deleting gateway: %s/%s", target_iqn, gateway_name) + return request() + + @RestClient.api_put('/api/disk/{pool}/{image}') + def create_disk(self, pool, image, backstore, wwn, request=None): + logger.debug("iSCSI[%s] Creating disk: %s/%s", self.gateway_name, pool, image) + return request({ + 'mode': 'create', + 'backstore': backstore, + 'wwn': wwn + }) + + @RestClient.api_delete('/api/disk/{pool}/{image}') + def delete_disk(self, pool, image, request=None): + logger.debug("iSCSI[%s] Deleting disk: %s/%s", self.gateway_name, pool, image) + return request({ + 'preserve_image': 'true' + }) + + @RestClient.api_put('/api/disk/{pool}/{image}') + def reconfigure_disk(self, pool, image, controls, request=None): + logger.debug("iSCSI[%s] Reconfiguring disk: %s/%s", self.gateway_name, pool, image) + return request({ + 'controls': json.dumps(controls), + 'mode': 'reconfigure' + }) + + @RestClient.api_put('/api/targetlun/{target_iqn}') + def create_target_lun(self, target_iqn, image_id, lun, request=None): + logger.debug("iSCSI[%s] Creating target lun: %s/%s", self.gateway_name, target_iqn, + image_id) + return request({ + 'disk': image_id, + 'lun_id': lun + }) + + @RestClient.api_delete('/api/targetlun/{target_iqn}') + def delete_target_lun(self, target_iqn, image_id, request=None): + logger.debug("iSCSI[%s] Deleting target lun: %s/%s", self.gateway_name, target_iqn, + image_id) + return request({ + 'disk': image_id + }) + + @RestClient.api_put('/api/client/{target_iqn}/{client_iqn}') + def create_client(self, target_iqn, client_iqn, request=None): + logger.debug("iSCSI[%s] Creating client: %s/%s", self.gateway_name, target_iqn, client_iqn) + return request() + + @RestClient.api_delete('/api/client/{target_iqn}/{client_iqn}') + def delete_client(self, target_iqn, client_iqn, request=None): + logger.debug("iSCSI[%s] Deleting client: %s/%s", self.gateway_name, target_iqn, client_iqn) + return request() + + @RestClient.api_put('/api/clientlun/{target_iqn}/{client_iqn}') + def create_client_lun(self, target_iqn, client_iqn, image_id, request=None): + logger.debug("iSCSI[%s] Creating client lun: %s/%s", self.gateway_name, target_iqn, + client_iqn) + return request({ + 'disk': image_id + }) + + @RestClient.api_delete('/api/clientlun/{target_iqn}/{client_iqn}') + def delete_client_lun(self, target_iqn, client_iqn, image_id, request=None): + logger.debug("iSCSI[%s] Deleting client lun: %s/%s", self.gateway_name, target_iqn, + client_iqn) + return request({ + 'disk': image_id + }) + + @RestClient.api_put('/api/clientauth/{target_iqn}/{client_iqn}') + def create_client_auth(self, target_iqn, client_iqn, username, password, mutual_username, + mutual_password, request=None): + logger.debug("iSCSI[%s] Creating client auth: %s/%s/%s/%s/%s/%s", + self.gateway_name, target_iqn, client_iqn, username, password, mutual_username, + mutual_password) + return request({ + 'username': username, + 'password': password, + 'mutual_username': mutual_username, + 'mutual_password': mutual_password + }) + + @RestClient.api_put('/api/hostgroup/{target_iqn}/{group_name}') + def create_group(self, target_iqn, group_name, members, image_ids, request=None): + logger.debug("iSCSI[%s] Creating group: %s/%s", self.gateway_name, target_iqn, group_name) + return request({ + 'members': ','.join(members), + 'disks': ','.join(image_ids) + }) + + @RestClient.api_put('/api/hostgroup/{target_iqn}/{group_name}') + def update_group(self, target_iqn, group_name, members, image_ids, request=None): + logger.debug("iSCSI[%s] Updating group: %s/%s", self.gateway_name, target_iqn, group_name) + return request({ + 'action': 'remove', + 'members': ','.join(members), + 'disks': ','.join(image_ids) + }) + + @RestClient.api_delete('/api/hostgroup/{target_iqn}/{group_name}') + def delete_group(self, target_iqn, group_name, request=None): + logger.debug("iSCSI[%s] Deleting group: %s/%s", self.gateway_name, target_iqn, group_name) + return request() + + @RestClient.api_put('/api/discoveryauth') + def update_discoveryauth(self, user, password, mutual_user, mutual_password, request=None): + logger.debug("iSCSI[%s] Updating discoveryauth: %s/%s/%s/%s", self.gateway_name, user, + password, mutual_user, mutual_password) + return request({ + 'username': user, + 'password': password, + 'mutual_username': mutual_user, + 'mutual_password': mutual_password + }) + + @RestClient.api_put('/api/targetauth/{target_iqn}') + def update_targetacl(self, target_iqn, action, request=None): + logger.debug("iSCSI[%s] Updating targetacl: %s/%s", self.gateway_name, target_iqn, action) + return request({ + 'action': action + }) + + @RestClient.api_put('/api/targetauth/{target_iqn}') + def update_targetauth(self, target_iqn, user, password, mutual_user, mutual_password, + request=None): + logger.debug("iSCSI[%s] Updating targetauth: %s/%s/%s/%s/%s", self.gateway_name, + target_iqn, user, password, mutual_user, mutual_password) + return request({ + 'username': user, + 'password': password, + 'mutual_username': mutual_user, + 'mutual_password': mutual_password + }) + + @RestClient.api_get('/api/targetinfo/{target_iqn}') + def get_targetinfo(self, target_iqn, request=None): + # pylint: disable=unused-argument + return request() + + @RestClient.api_get('/api/clientinfo/{target_iqn}/{client_iqn}') + def get_clientinfo(self, target_iqn, client_iqn, request=None): + # pylint: disable=unused-argument + return request() diff --git a/src/pybind/mgr/dashboard/services/iscsi_config.py b/src/pybind/mgr/dashboard/services/iscsi_config.py new file mode 100644 index 00000000..2f119136 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/iscsi_config.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json + +from orchestrator import OrchestratorError + +try: + from urlparse import urlparse +except ImportError: + from urllib.parse import urlparse + +from mgr_util import merge_dicts +from .orchestrator import OrchClient +from .. import mgr + + +class IscsiGatewayAlreadyExists(Exception): + def __init__(self, gateway_name): + super(IscsiGatewayAlreadyExists, self).__init__( + "iSCSI gateway '{}' already exists".format(gateway_name)) + + +class IscsiGatewayDoesNotExist(Exception): + def __init__(self, hostname): + super(IscsiGatewayDoesNotExist, self).__init__( + "iSCSI gateway '{}' does not exist".format(hostname)) + + +class InvalidServiceUrl(Exception): + def __init__(self, service_url): + super(InvalidServiceUrl, self).__init__( + "Invalid service URL '{}'. " + "Valid format: '://:@[:port]'.".format(service_url)) + + +class ManagedByOrchestratorException(Exception): + def __init__(self): + super(ManagedByOrchestratorException, self).__init__( + "iSCSI configuration is managed by the orchestrator") + + +_ISCSI_STORE_KEY = "_iscsi_config" + + +class IscsiGatewaysConfig(object): + @classmethod + def _load_config_from_store(cls): + json_db = mgr.get_store(_ISCSI_STORE_KEY, + '{"gateways": {}}') + config = json.loads(json_db) + cls.update_iscsi_config(config) + return config + + @classmethod + def update_iscsi_config(cls, config): + """ + Since `ceph-iscsi` config v10, gateway names were renamed from host short name to FQDN. + If Ceph Dashboard were configured before v10, we try to update our internal gateways + database automatically. + """ + for gateway_name, gateway_config in config['gateways'].items(): + if '.' not in gateway_name: + from .iscsi_client import IscsiClient + from ..rest_client import RequestException + try: + service_url = gateway_config['service_url'] + new_gateway_name = IscsiClient.instance( + service_url=service_url).get_hostname()['data'] + if gateway_name != new_gateway_name: + config['gateways'][new_gateway_name] = gateway_config + del config['gateways'][gateway_name] + cls._save_config(config) + except RequestException: + # If gateway is not acessible, it should be removed manually + # or we will try to update automatically next time + continue + + @staticmethod + def _load_config_from_orchestrator(): + config = {'gateways': {}} + try: + instances = OrchClient().list_service_info("iscsi") + for instance in instances: + config['gateways'][instance.nodename] = { + 'service_url': instance.service_url + } + except (RuntimeError, OrchestratorError, ImportError): + pass + return config + + @classmethod + def _save_config(cls, config): + mgr.set_store(_ISCSI_STORE_KEY, json.dumps(config)) + + @classmethod + def validate_service_url(cls, service_url): + url = urlparse(service_url) + if not url.scheme or not url.hostname or not url.username or not url.password: + raise InvalidServiceUrl(service_url) + + @classmethod + def add_gateway(cls, name, service_url): + config = cls.get_gateways_config() + if name in config: + raise IscsiGatewayAlreadyExists(name) + IscsiGatewaysConfig.validate_service_url(service_url) + config['gateways'][name] = {'service_url': service_url} + cls._save_config(config) + + @classmethod + def remove_gateway(cls, name): + if name in cls._load_config_from_orchestrator()['gateways']: + raise ManagedByOrchestratorException() + + config = cls._load_config_from_store() + if name not in config['gateways']: + raise IscsiGatewayDoesNotExist(name) + + del config['gateways'][name] + cls._save_config(config) + + @classmethod + def get_gateways_config(cls): + orch_config = cls._load_config_from_orchestrator() + local_config = cls._load_config_from_store() + + return {'gateways': merge_dicts(orch_config['gateways'], local_config['gateways'])} + + @classmethod + def get_gateway_config(cls, name): + config = IscsiGatewaysConfig.get_gateways_config() + if name not in config['gateways']: + raise IscsiGatewayDoesNotExist(name) + return config['gateways'][name] diff --git a/src/pybind/mgr/dashboard/services/orchestrator.py b/src/pybind/mgr/dashboard/services/orchestrator.py new file mode 100644 index 00000000..366ff7de --- /dev/null +++ b/src/pybind/mgr/dashboard/services/orchestrator.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from orchestrator import OrchestratorClientMixin, raise_if_exception, OrchestratorError +from .. import mgr, logger + + +# pylint: disable=abstract-method +class OrchClient(OrchestratorClientMixin): + def __init__(self): + super(OrchClient, self).__init__() + self.set_mgr(mgr) + + def list_service_info(self, service_type): + # type: (str) -> list + completion = self.describe_service(service_type, None, None) + self._orchestrator_wait([completion]) + raise_if_exception(completion) + return completion.result + + def available(self): + try: + status, desc = super(OrchClient, self).available() + logger.info("[ORCH] is orchestrator available: %s, %s", status, desc) + return status + except (RuntimeError, OrchestratorError, ImportError): + return False + + def reload_service(self, service_type, service_ids): + if not isinstance(service_ids, list): + service_ids = [service_ids] + + completion_list = [self.service_action('reload', service_type, + service_name, service_id) + for service_name, service_id in service_ids] + self._orchestrator_wait(completion_list) + for c in completion_list: + raise_if_exception(c) diff --git a/src/pybind/mgr/dashboard/services/rbd.py b/src/pybind/mgr/dashboard/services/rbd.py new file mode 100644 index 00000000..55c6f542 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/rbd.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import six + +import rbd + +from .. import mgr +from .ceph_service import CephService + + +RBD_FEATURES_NAME_MAPPING = { + rbd.RBD_FEATURE_LAYERING: "layering", + rbd.RBD_FEATURE_STRIPINGV2: "striping", + rbd.RBD_FEATURE_EXCLUSIVE_LOCK: "exclusive-lock", + rbd.RBD_FEATURE_OBJECT_MAP: "object-map", + rbd.RBD_FEATURE_FAST_DIFF: "fast-diff", + rbd.RBD_FEATURE_DEEP_FLATTEN: "deep-flatten", + rbd.RBD_FEATURE_JOURNALING: "journaling", + rbd.RBD_FEATURE_DATA_POOL: "data-pool", + rbd.RBD_FEATURE_OPERATIONS: "operations", +} + + +def format_bitmask(features): + """ + Formats the bitmask: + + >>> format_bitmask(45) + ['deep-flatten', 'exclusive-lock', 'layering', 'object-map'] + """ + names = [val for key, val in RBD_FEATURES_NAME_MAPPING.items() + if key & features == key] + return sorted(names) + + +def format_features(features): + """ + Converts the features list to bitmask: + + >>> format_features(['deep-flatten', 'exclusive-lock', 'layering', 'object-map']) + 45 + + >>> format_features(None) is None + True + + >>> format_features('deep-flatten, exclusive-lock') + 32 + """ + if isinstance(features, six.string_types): + features = features.split(',') + + if not isinstance(features, list): + return None + + res = 0 + for key, value in RBD_FEATURES_NAME_MAPPING.items(): + if value in features: + res = key | res + return res + + +class RbdConfiguration(object): + _rbd = rbd.RBD() + + def __init__(self, pool_name='', image_name='', pool_ioctx=None, image_ioctx=None): + # type: (str, str, object, object) -> None + assert bool(pool_name) != bool(pool_ioctx) # xor + self._pool_name = pool_name + self._image_name = image_name + self._pool_ioctx = pool_ioctx + self._image_ioctx = image_ioctx + + @staticmethod + def _ensure_prefix(option): + # type: (str) -> str + return option if option.startswith('conf_') else 'conf_' + option + + def list(self): + # type: () -> [dict] + def _list(ioctx): + if self._image_name: # image config + try: + with rbd.Image(ioctx, self._image_name) as image: + result = image.config_list() + except rbd.ImageNotFound: + result = [] + else: # pool config + pg_status = list(CephService.get_pool_pg_status(self._pool_name).keys()) + if len(pg_status) == 1 and 'incomplete' in pg_status[0]: + # If config_list would be called with ioctx if it's a bad pool, + # the dashboard would stop working, waiting for the response + # that would not happen. + # + # This is only a workaround for https://tracker.ceph.com/issues/43771 which + # already got rejected as not worth the effort. + # + # Are more complete workaround for the dashboard will be implemented with + # https://tracker.ceph.com/issues/44224 + # + # @TODO: If #44224 is addressed remove this workaround + return [] + result = self._rbd.config_list(ioctx) + return list(result) + + if self._pool_name: + ioctx = mgr.rados.open_ioctx(self._pool_name) + else: + ioctx = self._pool_ioctx + + return _list(ioctx) + + def get(self, option_name): + # type: (str) -> str + option_name = self._ensure_prefix(option_name) + with mgr.rados.open_ioctx(self._pool_name) as pool_ioctx: + if self._image_name: + with rbd.Image(pool_ioctx, self._image_name) as image: + return image.metadata_get(option_name) + return self._rbd.pool_metadata_get(pool_ioctx, option_name) + + def set(self, option_name, option_value): + # type: (str, str) -> None + + option_value = str(option_value) + option_name = self._ensure_prefix(option_name) + + pool_ioctx = self._pool_ioctx + if self._pool_name: # open ioctx + pool_ioctx = mgr.rados.open_ioctx(self._pool_name) + pool_ioctx.__enter__() + + image_ioctx = self._image_ioctx + if self._image_name: + image_ioctx = rbd.Image(pool_ioctx, self._image_name) + image_ioctx.__enter__() + + if image_ioctx: + image_ioctx.metadata_set(option_name, option_value) + else: + self._rbd.pool_metadata_set(pool_ioctx, option_name, option_value) + + if self._image_name: # Name provided, so we opened it and now have to close it + image_ioctx.__exit__(None, None, None) + if self._pool_name: + pool_ioctx.__exit__(None, None, None) + + def remove(self, option_name): + """ + Removes an option by name. Will not raise an error, if the option hasn't been found. + :type option_name str + """ + def _remove(ioctx): + try: + if self._image_name: + with rbd.Image(ioctx, self._image_name) as image: + image.metadata_remove(option_name) + else: + self._rbd.pool_metadata_remove(ioctx, option_name) + except KeyError: + pass + + option_name = self._ensure_prefix(option_name) + + if self._pool_name: + with mgr.rados.open_ioctx(self._pool_name) as pool_ioctx: + _remove(pool_ioctx) + else: + _remove(self._pool_ioctx) + + def set_configuration(self, configuration): + if configuration: + for option_name, option_value in configuration.items(): + if option_value is not None: + self.set(option_name, option_value) + else: + self.remove(option_name) diff --git a/src/pybind/mgr/dashboard/services/rgw_client.py b/src/pybind/mgr/dashboard/services/rgw_client.py new file mode 100644 index 00000000..eef11794 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/rgw_client.py @@ -0,0 +1,437 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import re +from distutils.util import strtobool +from ..awsauth import S3Auth +from ..settings import Settings, Options +from ..rest_client import RestClient, RequestException +from ..tools import build_url, dict_contains_path, is_valid_ip_address +from .. import mgr, logger + + +class NoCredentialsException(RequestException): + def __init__(self): + super(NoCredentialsException, self).__init__( + 'No RGW credentials found, ' + 'please consult the documentation on how to enable RGW for ' + 'the dashboard.') + + +def _determine_rgw_addr(): + """ + Get a RGW daemon to determine the configured host (IP address) and port. + Note, the service id of the RGW daemons may differ depending on the setup. + Example 1: + { + ... + 'services': { + 'rgw': { + 'daemons': { + 'summary': '', + '0': { + ... + 'addr': '[2001:db8:85a3::8a2e:370:7334]:49774/1534999298', + 'metadata': { + 'frontend_config#0': 'civetweb port=7280', + } + ... + } + } + } + } + } + Example 2: + { + ... + 'services': { + 'rgw': { + 'daemons': { + 'summary': '', + 'rgw': { + ... + 'addr': '192.168.178.3:49774/1534999298', + 'metadata': { + 'frontend_config#0': 'civetweb port=8000', + } + ... + } + } + } + } + } + """ + service_map = mgr.get('service_map') + if not dict_contains_path(service_map, ['services', 'rgw', 'daemons']): + raise LookupError('No RGW found') + daemon = None + daemons = service_map['services']['rgw']['daemons'] + for key in daemons.keys(): + if dict_contains_path(daemons[key], ['metadata', 'frontend_config#0']): + daemon = daemons[key] + break + if daemon is None: + raise LookupError('No RGW daemon found') + + addr = _parse_addr(daemon['addr']) + port, ssl = _parse_frontend_config(daemon['metadata']['frontend_config#0']) + + logger.info('Auto-detected RGW configuration: addr=%s, port=%d, ssl=%s', + addr, port, str(ssl)) + + return addr, port, ssl + + +def _parse_addr(value): + """ + Get the IP address the RGW is running on. + + >>> _parse_addr('192.168.178.3:49774/1534999298') + '192.168.178.3' + + >>> _parse_addr('[2001:db8:85a3::8a2e:370:7334]:49774/1534999298') + '2001:db8:85a3::8a2e:370:7334' + + >>> _parse_addr('xyz') + Traceback (most recent call last): + ... + LookupError: Failed to determine RGW address + + >>> _parse_addr('192.168.178.a:8080/123456789') + Traceback (most recent call last): + ... + LookupError: Invalid RGW address '192.168.178.a' found + + >>> _parse_addr('[2001:0db8:1234]:443/123456789') + Traceback (most recent call last): + ... + LookupError: Invalid RGW address '2001:0db8:1234' found + + >>> _parse_addr('2001:0db8::1234:49774/1534999298') + Traceback (most recent call last): + ... + LookupError: Failed to determine RGW address + + :param value: The string to process. The syntax is ':/'. + :type: str + :raises LookupError if parsing fails to determine the IP address. + :return: The IP address. + :rtype: str + """ + match = re.search(r'^(\[)?(?(1)([^\]]+)\]|([^:]+)):\d+/\d+?', value) + if match: + # IPv4: + # Group 0: 192.168.178.3:49774/1534999298 + # Group 3: 192.168.178.3 + # IPv6: + # Group 0: [2001:db8:85a3::8a2e:370:7334]:49774/1534999298 + # Group 1: [ + # Group 2: 2001:db8:85a3::8a2e:370:7334 + addr = match.group(3) if match.group(3) else match.group(2) + if not is_valid_ip_address(addr): + raise LookupError('Invalid RGW address \'{}\' found'.format(addr)) + return addr + raise LookupError('Failed to determine RGW address') + + +def _parse_frontend_config(config): + """ + Get the port the RGW is running on. Due the complexity of the + syntax not all variations are supported. + + If there are multiple (ssl_)ports/(ssl_)endpoints options, then + the first found option will be returned. + + Get more details about the configuration syntax here: + http://docs.ceph.com/docs/master/radosgw/frontends/ + https://civetweb.github.io/civetweb/UserManual.html + + :param config: The configuration string to parse. + :type config: str + :raises LookupError if parsing fails to determine the port. + :return: A tuple containing the port number and the information + whether SSL is used. + :rtype: (int, boolean) + """ + match = re.search(r'^(beast|civetweb)\s+.+$', config) + if match: + if match.group(1) == 'beast': + match = re.search(r'(port|ssl_port|endpoint|ssl_endpoint)=(.+)', + config) + if match: + option_name = match.group(1) + if option_name in ['port', 'ssl_port']: + match = re.search(r'(\d+)', match.group(2)) + if match: + port = int(match.group(1)) + ssl = option_name == 'ssl_port' + return port, ssl + if option_name in ['endpoint', 'ssl_endpoint']: + match = re.search(r'([\d.]+|\[.+\])(:(\d+))?', + match.group(2)) + if match: + port = int(match.group(3)) if \ + match.group(2) is not None else 443 if \ + option_name == 'ssl_endpoint' else \ + 80 + ssl = option_name == 'ssl_endpoint' + return port, ssl + if match.group(1) == 'civetweb': + match = re.search(r'port=(.*:)?(\d+)(s)?', config) + if match: + port = int(match.group(2)) + ssl = match.group(3) == 's' + return port, ssl + raise LookupError('Failed to determine RGW port from "{}"'.format(config)) + + +class RgwClient(RestClient): + _SYSTEM_USERID = None + _ADMIN_PATH = None + _host = None + _port = None + _ssl = None + _user_instances = {} + _rgw_settings_snapshot = None + + @staticmethod + def _load_settings(): + # The API access key and secret key are mandatory for a minimal configuration. + if not (Settings.RGW_API_ACCESS_KEY and Settings.RGW_API_SECRET_KEY): + logger.warning('No credentials found, please consult the ' + 'documentation about how to enable RGW for the ' + 'dashboard.') + raise NoCredentialsException() + + if Options.has_default_value('RGW_API_HOST') and \ + Options.has_default_value('RGW_API_PORT') and \ + Options.has_default_value('RGW_API_SCHEME'): + host, port, ssl = _determine_rgw_addr() + else: + host = Settings.RGW_API_HOST + port = Settings.RGW_API_PORT + ssl = Settings.RGW_API_SCHEME == 'https' + + RgwClient._host = host + RgwClient._port = port + RgwClient._ssl = ssl + RgwClient._ADMIN_PATH = Settings.RGW_API_ADMIN_RESOURCE + + # Create an instance using the configured settings. + instance = RgwClient(Settings.RGW_API_USER_ID, + Settings.RGW_API_ACCESS_KEY, + Settings.RGW_API_SECRET_KEY) + + RgwClient._SYSTEM_USERID = instance.userid + + # Append the instance to the internal map. + RgwClient._user_instances[RgwClient._SYSTEM_USERID] = instance + + @staticmethod + def _rgw_settings(): + return (Settings.RGW_API_HOST, + Settings.RGW_API_PORT, + Settings.RGW_API_ACCESS_KEY, + Settings.RGW_API_SECRET_KEY, + Settings.RGW_API_ADMIN_RESOURCE, + Settings.RGW_API_SCHEME, + Settings.RGW_API_USER_ID, + Settings.RGW_API_SSL_VERIFY) + + @staticmethod + def instance(userid): + # Discard all cached instances if any rgw setting has changed + if RgwClient._rgw_settings_snapshot != RgwClient._rgw_settings(): + RgwClient._rgw_settings_snapshot = RgwClient._rgw_settings() + RgwClient.drop_instance() + + if not RgwClient._user_instances: + RgwClient._load_settings() + + if not userid: + userid = RgwClient._SYSTEM_USERID + + if userid not in RgwClient._user_instances: + # Get the access and secret keys for the specified user. + keys = RgwClient.admin_instance().get_user_keys(userid) + if not keys: + raise RequestException( + "User '{}' does not have any keys configured.".format( + userid)) + + # Create an instance and append it to the internal map. + RgwClient._user_instances[userid] = RgwClient(userid, + keys['access_key'], + keys['secret_key']) + + return RgwClient._user_instances[userid] + + @staticmethod + def admin_instance(): + return RgwClient.instance(RgwClient._SYSTEM_USERID) + + @staticmethod + def drop_instance(userid=None): + """ + Drop a cached instance by name or all. + """ + if userid: + RgwClient._user_instances.pop(userid, None) + else: + RgwClient._user_instances.clear() + + def _reset_login(self): + if self.userid != RgwClient._SYSTEM_USERID: + logger.info("Fetching new keys for user: %s", self.userid) + keys = RgwClient.admin_instance().get_user_keys(self.userid) + self.auth = S3Auth(keys['access_key'], keys['secret_key'], + service_url=self.service_url) + else: + raise RequestException('Authentication failed for the "{}" user: wrong credentials' + .format(self.userid), status_code=401) + + def __init__(self, # pylint: disable-msg=R0913 + userid, + access_key, + secret_key, + host=None, + port=None, + admin_path=None, + ssl=False): + + if not host and not RgwClient._host: + RgwClient._load_settings() + host = host if host else RgwClient._host + port = port if port else RgwClient._port + admin_path = admin_path if admin_path else RgwClient._ADMIN_PATH + ssl = ssl if ssl else RgwClient._ssl + ssl_verify = Settings.RGW_API_SSL_VERIFY + + self.service_url = build_url(host=host, port=port) + self.admin_path = admin_path + + s3auth = S3Auth(access_key, secret_key, service_url=self.service_url) + super(RgwClient, self).__init__(host, port, 'RGW', ssl, s3auth, ssl_verify=ssl_verify) + + # If user ID is not set, then try to get it via the RGW Admin Ops API. + self.userid = userid if userid else self._get_user_id(self.admin_path) + + logger.info("Created new connection: user=%s, host=%s, port=%s, ssl=%d, sslverify=%d", + self.userid, host, port, ssl, ssl_verify) + + @RestClient.api_get('/', resp_structure='[0] > (ID & DisplayName)') + def is_service_online(self, request=None): + """ + Consider the service as online if the response contains the + specified keys. Nothing more is checked here. + """ + _ = request({'format': 'json'}) + return True + + @RestClient.api_get('/{admin_path}/metadata/user?myself', + resp_structure='data > user_id') + def _get_user_id(self, admin_path, request=None): + # pylint: disable=unused-argument + """ + Get the user ID of the user that is used to communicate with the + RGW Admin Ops API. + :rtype: str + :return: The user ID of the user that is used to sign the + RGW Admin Ops API calls. + """ + response = request() + return response['data']['user_id'] + + @RestClient.api_get('/{admin_path}/metadata/user', resp_structure='[+]') + def _user_exists(self, admin_path, user_id, request=None): + # pylint: disable=unused-argument + response = request() + if user_id: + return user_id in response + return self.userid in response + + def user_exists(self, user_id=None): + return self._user_exists(self.admin_path, user_id) + + @RestClient.api_get('/{admin_path}/metadata/user?key={userid}', + resp_structure='data > system') + def _is_system_user(self, admin_path, userid, request=None): + # pylint: disable=unused-argument + response = request() + return strtobool(response['data']['system']) + + def is_system_user(self): + return self._is_system_user(self.admin_path, self.userid) + + @RestClient.api_get( + '/{admin_path}/user', + resp_structure='tenant & user_id & email & keys[*] > ' + ' (user & access_key & secret_key)') + def _admin_get_user_keys(self, admin_path, userid, request=None): + # pylint: disable=unused-argument + colon_idx = userid.find(':') + user = userid if colon_idx == -1 else userid[:colon_idx] + response = request({'uid': user}) + for key in response['keys']: + if key['user'] == userid: + return { + 'access_key': key['access_key'], + 'secret_key': key['secret_key'] + } + return None + + def get_user_keys(self, userid): + return self._admin_get_user_keys(self.admin_path, userid) + + @RestClient.api('/{admin_path}/{path}') + def _proxy_request(self, # pylint: disable=too-many-arguments + admin_path, + path, + method, + params, + data, + request=None): + # pylint: disable=unused-argument + return request( + method=method, params=params, data=data, raw_content=True) + + def proxy(self, method, path, params, data): + logger.debug("proxying method=%s path=%s params=%s data=%s", method, + path, params, data) + return self._proxy_request(self.admin_path, path, method, params, data) + + @RestClient.api_get('/', resp_structure='[1][*] > Name') + def get_buckets(self, request=None): + """ + Get a list of names from all existing buckets of this user. + :return: Returns a list of bucket names. + """ + response = request({'format': 'json'}) + return [bucket['Name'] for bucket in response[1]] + + @RestClient.api_get('/{bucket_name}') + def bucket_exists(self, bucket_name, userid, request=None): + """ + Check if the specified bucket exists for this user. + :param bucket_name: The name of the bucket. + :return: Returns True if the bucket exists, otherwise False. + """ + # pylint: disable=unused-argument + try: + request() + my_buckets = self.get_buckets() + if bucket_name not in my_buckets: + raise RequestException( + 'Bucket "{}" belongs to other user'.format(bucket_name), + 403) + return True + except RequestException as e: + if e.status_code == 404: + return False + + raise e + + @RestClient.api_put('/{bucket_name}') + def create_bucket(self, bucket_name, request=None): + logger.info("Creating bucket: %s", bucket_name) + return request() diff --git a/src/pybind/mgr/dashboard/services/sso.py b/src/pybind/mgr/dashboard/services/sso.py new file mode 100644 index 00000000..007a5307 --- /dev/null +++ b/src/pybind/mgr/dashboard/services/sso.py @@ -0,0 +1,268 @@ +# -*- coding: utf-8 -*- +# pylint: disable=too-many-return-statements,too-many-branches +from __future__ import absolute_import + +import errno +import json +import sys +import threading +import six + +try: + from onelogin.saml2.settings import OneLogin_Saml2_Settings + from onelogin.saml2.errors import OneLogin_Saml2_Error + from onelogin.saml2.idp_metadata_parser import OneLogin_Saml2_IdPMetadataParser + + python_saml_imported = True +except ImportError: + python_saml_imported = False + + +from .. import mgr, logger +from ..tools import prepare_url_prefix + + +class Saml2(object): + def __init__(self, onelogin_settings): + self.onelogin_settings = onelogin_settings + + def get_username_attribute(self): + return self.onelogin_settings['sp']['attributeConsumingService']['requestedAttributes'][0][ + 'name'] + + def to_dict(self): + return { + 'onelogin_settings': self.onelogin_settings + } + + @classmethod + def from_dict(cls, s_dict): + return Saml2(s_dict['onelogin_settings']) + + +class SsoDB(object): + VERSION = 1 + SSODB_CONFIG_KEY = "ssodb_v" + + def __init__(self, version, protocol, saml2): + self.version = version + self.protocol = protocol + self.saml2 = saml2 + self.lock = threading.RLock() + + def save(self): + with self.lock: + db = { + 'protocol': self.protocol, + 'saml2': self.saml2.to_dict(), + 'version': self.version + } + mgr.set_store(self.ssodb_config_key(), json.dumps(db)) + + @classmethod + def ssodb_config_key(cls, version=None): + if version is None: + version = cls.VERSION + return "{}{}".format(cls.SSODB_CONFIG_KEY, version) + + def check_and_update_db(self): + logger.debug("SSO: Checking for previews DB versions") + if self.VERSION != 1: + raise NotImplementedError() + + @classmethod + def load(cls): + logger.info("SSO: Loading SSO DB version=%s", cls.VERSION) + + json_db = mgr.get_store(cls.ssodb_config_key(), None) + if json_db is None: + logger.debug("SSO: No DB v%s found, creating new...", cls.VERSION) + db = cls(cls.VERSION, '', Saml2({})) + # check if we can update from a previous version database + db.check_and_update_db() + return db + + db = json.loads(json_db) + return cls(db['version'], db.get('protocol'), Saml2.from_dict(db.get('saml2'))) + + +def load_sso_db(): + mgr.SSO_DB = SsoDB.load() + + +SSO_COMMANDS = [ + { + 'cmd': 'dashboard sso enable saml2', + 'desc': 'Enable SAML2 Single Sign-On', + 'perm': 'w' + }, + { + 'cmd': 'dashboard sso disable', + 'desc': 'Disable Single Sign-On', + 'perm': 'w' + }, + { + 'cmd': 'dashboard sso status', + 'desc': 'Get Single Sign-On status', + 'perm': 'r' + }, + { + 'cmd': 'dashboard sso show saml2', + 'desc': 'Show SAML2 configuration', + 'perm': 'r' + }, + { + 'cmd': 'dashboard sso setup saml2 ' + 'name=ceph_dashboard_base_url,type=CephString ' + 'name=idp_metadata,type=CephString ' + 'name=idp_username_attribute,type=CephString,req=false ' + 'name=idp_entity_id,type=CephString,req=false ' + 'name=sp_x_509_cert,type=CephString,req=false ' + 'name=sp_private_key,type=CephString,req=false', + 'desc': 'Setup SAML2 Single Sign-On', + 'perm': 'w' + } +] + + +def _get_optional_attr(cmd, attr, default): + if attr in cmd: + if cmd[attr] != '': + return cmd[attr] + return default + + +def handle_sso_command(cmd): + if cmd['prefix'] not in ['dashboard sso enable saml2', + 'dashboard sso disable', + 'dashboard sso status', + 'dashboard sso show saml2', + 'dashboard sso setup saml2']: + return -errno.ENOSYS, '', '' + + if cmd['prefix'] == 'dashboard sso disable': + mgr.SSO_DB.protocol = '' + mgr.SSO_DB.save() + return 0, 'SSO is "disabled".', '' + + if not python_saml_imported: + python_saml_name = 'python3-saml' if sys.version_info >= (3, 0) else 'python-saml' + return -errno.EPERM, '', 'Required library not found: `{}`'.format(python_saml_name) + + if cmd['prefix'] == 'dashboard sso enable saml2': + try: + OneLogin_Saml2_Settings(mgr.SSO_DB.saml2.onelogin_settings) + except OneLogin_Saml2_Error: + return -errno.EPERM, '', 'Single Sign-On is not configured: ' \ + 'use `ceph dashboard sso setup saml2`' + mgr.SSO_DB.protocol = 'saml2' + mgr.SSO_DB.save() + return 0, 'SSO is "enabled" with "SAML2" protocol.', '' + + if cmd['prefix'] == 'dashboard sso status': + if mgr.SSO_DB.protocol == 'saml2': + return 0, 'SSO is "enabled" with "SAML2" protocol.', '' + + return 0, 'SSO is "disabled".', '' + + if cmd['prefix'] == 'dashboard sso show saml2': + return 0, json.dumps(mgr.SSO_DB.saml2.to_dict()), '' + + if cmd['prefix'] == 'dashboard sso setup saml2': + ceph_dashboard_base_url = cmd['ceph_dashboard_base_url'] + idp_metadata = cmd['idp_metadata'] + idp_username_attribute = _get_optional_attr(cmd, 'idp_username_attribute', 'uid') + idp_entity_id = _get_optional_attr(cmd, 'idp_entity_id', None) + sp_x_509_cert = _get_optional_attr(cmd, 'sp_x_509_cert', '') + sp_private_key = _get_optional_attr(cmd, 'sp_private_key', '') + if sp_x_509_cert and not sp_private_key: + return -errno.EINVAL, '', 'Missing parameter `sp_private_key`.' + if not sp_x_509_cert and sp_private_key: + return -errno.EINVAL, '', 'Missing parameter `sp_x_509_cert`.' + has_sp_cert = sp_x_509_cert != "" and sp_private_key != "" + try: + # pylint: disable=undefined-variable + FileNotFoundError + except NameError: + # pylint: disable=redefined-builtin + FileNotFoundError = IOError + try: + f = open(sp_x_509_cert, 'r', encoding='utf-8') if six.PY3 else \ + open(sp_x_509_cert, 'rb') + sp_x_509_cert = f.read() + f.close() + except FileNotFoundError: + pass + try: + f = open(sp_private_key, 'r', encoding='utf-8') if six.PY3 else \ + open(sp_private_key, 'rb') + sp_private_key = f.read() + f.close() + except FileNotFoundError: + pass + try: + idp_settings = OneLogin_Saml2_IdPMetadataParser.parse_remote(idp_metadata, + validate_cert=False, + entity_id=idp_entity_id) + # pylint: disable=broad-except + except Exception: + try: + f = open(idp_metadata, 'r', encoding='utf-8') if six.PY3 else \ + open(idp_metadata, 'rb') + idp_metadata = f.read() + f.close() + except FileNotFoundError: + pass + try: + idp_settings = OneLogin_Saml2_IdPMetadataParser.parse(idp_metadata, + entity_id=idp_entity_id) + # pylint: disable=broad-except + except Exception: + return -errno.EINVAL, '', 'Invalid parameter `idp_metadata`.' + + url_prefix = prepare_url_prefix(mgr.get_module_option('url_prefix', default='')) + settings = { + 'sp': { + 'entityId': '{}{}/auth/saml2/metadata'.format(ceph_dashboard_base_url, url_prefix), + 'assertionConsumerService': { + 'url': '{}{}/auth/saml2'.format(ceph_dashboard_base_url, url_prefix), + 'binding': "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + }, + 'attributeConsumingService': { + 'serviceName': "Ceph Dashboard", + "serviceDescription": "Ceph Dashboard Service", + "requestedAttributes": [ + { + "name": idp_username_attribute, + "isRequired": True + } + ] + }, + 'singleLogoutService': { + 'url': '{}{}/auth/saml2/logout'.format(ceph_dashboard_base_url, url_prefix), + 'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' + }, + "x509cert": sp_x_509_cert, + "privateKey": sp_private_key + }, + 'security': { + "nameIdEncrypted": has_sp_cert, + "authnRequestsSigned": has_sp_cert, + "logoutRequestSigned": has_sp_cert, + "logoutResponseSigned": has_sp_cert, + "signMetadata": has_sp_cert, + "wantMessagesSigned": has_sp_cert, + "wantAssertionsSigned": has_sp_cert, + "wantAssertionsEncrypted": has_sp_cert, + "wantNameIdEncrypted": False, # Not all Identity Providers support this. + "metadataValidUntil": '', + "wantAttributeStatement": False + } + } + settings = OneLogin_Saml2_IdPMetadataParser.merge_settings(settings, idp_settings) + mgr.SSO_DB.saml2.onelogin_settings = settings + mgr.SSO_DB.protocol = 'saml2' + mgr.SSO_DB.save() + return 0, json.dumps(mgr.SSO_DB.saml2.onelogin_settings), '' + + return -errno.ENOSYS, '', '' diff --git a/src/pybind/mgr/dashboard/services/tcmu_service.py b/src/pybind/mgr/dashboard/services/tcmu_service.py new file mode 100644 index 00000000..1f3e4d8d --- /dev/null +++ b/src/pybind/mgr/dashboard/services/tcmu_service.py @@ -0,0 +1,96 @@ +from mgr_util import get_most_recent_rate + +from dashboard.services.ceph_service import CephService +from .. import mgr + +SERVICE_TYPE = 'tcmu-runner' + + +class TcmuService(object): + # pylint: disable=too-many-nested-blocks + @staticmethod + def get_iscsi_info(): + daemons = {} + images = {} + for service in CephService.get_service_list(SERVICE_TYPE): + metadata = service['metadata'] + if metadata is None: + continue + status = service['status'] + hostname = service['hostname'] + + daemon = daemons.get(hostname, None) + if daemon is None: + daemon = { + 'server_hostname': hostname, + 'version': metadata['ceph_version'], + 'optimized_paths': 0, + 'non_optimized_paths': 0 + } + daemons[hostname] = daemon + + service_id = service['id'] + device_id = service_id.split(':')[-1] + image = images.get(device_id) + if image is None: + image = { + 'device_id': device_id, + 'pool_name': metadata['pool_name'], + 'name': metadata['image_name'], + 'id': metadata.get('image_id', None), + 'optimized_paths': [], + 'non_optimized_paths': [] + } + images[device_id] = image + + if status.get('lock_owner', 'false') == 'true': + daemon['optimized_paths'] += 1 + image['optimized_paths'].append(hostname) + + perf_key_prefix = "librbd-{id}-{pool}-{name}.".format( + id=metadata.get('image_id', ''), + pool=metadata['pool_name'], + name=metadata['image_name']) + perf_key = "{}lock_acquired_time".format(perf_key_prefix) + lock_acquired_time = (mgr.get_counter( + 'tcmu-runner', service_id, perf_key)[perf_key] + or [[0, 0]])[-1][1] / 1000000000 + if lock_acquired_time > image.get('optimized_since', 0): + image['optimized_daemon'] = hostname + image['optimized_since'] = lock_acquired_time + image['stats'] = {} + image['stats_history'] = {} + for s in ['rd', 'wr', 'rd_bytes', 'wr_bytes']: + perf_key = "{}{}".format(perf_key_prefix, s) + rates = CephService.get_rates('tcmu-runner', service_id, perf_key) + image['stats'][s] = get_most_recent_rate(rates) + image['stats_history'][s] = rates + else: + daemon['non_optimized_paths'] += 1 + image['non_optimized_paths'].append(hostname) + + # clear up races w/ tcmu-runner clients that haven't detected + # loss of optimized path + for image in images.values(): + optimized_daemon = image.get('optimized_daemon', None) + if optimized_daemon: + for daemon_name in image['optimized_paths']: + if daemon_name != optimized_daemon: + daemon = daemons[daemon_name] + daemon['optimized_paths'] -= 1 + daemon['non_optimized_paths'] += 1 + image['non_optimized_paths'].append(daemon_name) + image['optimized_paths'] = [optimized_daemon] + + return { + 'daemons': sorted(daemons.values(), + key=lambda d: d['server_hostname']), + 'images': sorted(images.values(), key=lambda i: ['id']), + } + + @staticmethod + def get_image_info(pool_name, image_name, get_iscsi_info): + for image in get_iscsi_info['images']: + if image['pool_name'] == pool_name and image['name'] == image_name: + return image + return None diff --git a/src/pybind/mgr/dashboard/settings.py b/src/pybind/mgr/dashboard/settings.py new file mode 100644 index 00000000..95b1cdf4 --- /dev/null +++ b/src/pybind/mgr/dashboard/settings.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import errno +import inspect +from six import add_metaclass + +from mgr_module import CLICheckNonemptyFileInput + +from . import mgr + + +class Options(object): + """ + If you need to store some configuration value please add the config option + name as a class attribute to this class. + + Example:: + + GRAFANA_API_HOST = ('localhost', str) + GRAFANA_API_PORT = (3000, int) + """ + ENABLE_BROWSABLE_API = (True, bool) + REST_REQUESTS_TIMEOUT = (45, int) + + # API auditing + AUDIT_API_ENABLED = (False, bool) + AUDIT_API_LOG_PAYLOAD = (True, bool) + + # RGW settings + RGW_API_HOST = ('', str) + RGW_API_PORT = (80, int) + RGW_API_ACCESS_KEY = ('', str) + RGW_API_SECRET_KEY = ('', str) + RGW_API_ADMIN_RESOURCE = ('admin', str) + RGW_API_SCHEME = ('http', str) + RGW_API_USER_ID = ('', str) + RGW_API_SSL_VERIFY = (True, bool) + + # Grafana settings + GRAFANA_API_URL = ('', str) + GRAFANA_FRONTEND_API_URL = ('', str) + GRAFANA_API_USERNAME = ('admin', str) + GRAFANA_API_PASSWORD = ('admin', str) + GRAFANA_API_SSL_VERIFY = (True, bool) + GRAFANA_UPDATE_DASHBOARDS = (False, bool) + + # NFS Ganesha settings + GANESHA_CLUSTERS_RADOS_POOL_NAMESPACE = ('', str) + + # Prometheus settings + PROMETHEUS_API_HOST = ('', str) + ALERTMANAGER_API_HOST = ('', str) + + # iSCSI management settings + ISCSI_API_SSL_VERIFICATION = (True, bool) + + @staticmethod + def has_default_value(name): + return getattr(Settings, name, None) is None or \ + getattr(Settings, name) == getattr(Options, name)[0] + + +class SettingsMeta(type): + def __getattr__(cls, attr): + default, stype = getattr(Options, attr) + if stype == bool and str(mgr.get_module_option( + attr, + default)).lower() == 'false': + value = False + else: + value = stype(mgr.get_module_option(attr, default)) + return value + + def __setattr__(cls, attr, value): + if not attr.startswith('_') and hasattr(Options, attr): + mgr.set_module_option(attr, str(value)) + else: + setattr(SettingsMeta, attr, value) + + def __delattr__(cls, attr): + if not attr.startswith('_') and hasattr(Options, attr): + mgr.set_module_option(attr, None) + + +# pylint: disable=no-init +@add_metaclass(SettingsMeta) +class Settings(object): + pass + + +def _options_command_map(): + def filter_attr(member): + return not inspect.isroutine(member) + + cmd_map = {} + for option, value in inspect.getmembers(Options, filter_attr): + if option.startswith('_'): + continue + key_get = 'dashboard get-{}'.format(option.lower().replace('_', '-')) + key_set = 'dashboard set-{}'.format(option.lower().replace('_', '-')) + key_reset = 'dashboard reset-{}'.format(option.lower().replace('_', '-')) + cmd_map[key_get] = {'name': option, 'type': None} + cmd_map[key_set] = {'name': option, 'type': value[1]} + cmd_map[key_reset] = {'name': option, 'type': None} + return cmd_map + + +_OPTIONS_COMMAND_MAP = _options_command_map() + + +def options_command_list(): + """ + This function generates a list of ``get`` and ``set`` commands + for each declared configuration option in class ``Options``. + """ + def py2ceph(pytype): + if pytype == str: + return 'CephString' + elif pytype == int: + return 'CephInt' + return 'CephString' + + cmd_list = [] + for cmd, opt in _OPTIONS_COMMAND_MAP.items(): + if cmd.startswith('dashboard get'): + cmd_list.append({ + 'cmd': '{}'.format(cmd), + 'desc': 'Get the {} option value'.format(opt['name']), + 'perm': 'r' + }) + elif cmd.startswith('dashboard set'): + cmd_entry = { + 'cmd': '{} name=value,type={}' + .format(cmd, py2ceph(opt['type'])), + 'desc': 'Set the {} option value'.format(opt['name']), + 'perm': 'w' + } + if handles_secret(cmd): + cmd_entry['cmd'] = cmd + cmd_entry['desc'] = '{} read from -i '.format(cmd_entry['desc']) + cmd_list.append(cmd_entry) + elif cmd.startswith('dashboard reset'): + desc = 'Reset the {} option to its default value'.format( + opt['name']) + cmd_list.append({ + 'cmd': '{}'.format(cmd), + 'desc': desc, + 'perm': 'w' + }) + + return cmd_list + + +def options_schema_list(): + def filter_attr(member): + return not inspect.isroutine(member) + + result = [] + for option, value in inspect.getmembers(Options, filter_attr): + if option.startswith('_'): + continue + result.append({'name': option, 'default': value[0], + 'type': value[1].__name__}) + + return result + + +def handle_option_command(cmd, inbuf): + if cmd['prefix'] not in _OPTIONS_COMMAND_MAP: + return -errno.ENOSYS, '', "Command not found '{}'".format(cmd['prefix']) + + opt = _OPTIONS_COMMAND_MAP[cmd['prefix']] + + if cmd['prefix'].startswith('dashboard reset'): + delattr(Settings, opt['name']) + return 0, 'Option {} reset to default value "{}"'.format( + opt['name'], getattr(Settings, opt['name'])), '' + elif cmd['prefix'].startswith('dashboard get'): + return 0, str(getattr(Settings, opt['name'])), '' + elif cmd['prefix'].startswith('dashboard set'): + if handles_secret(cmd['prefix']): + value, stdout, stderr = get_secret(inbuf=inbuf) + if stderr: + return value, stdout, stderr + else: + value = cmd['value'] + value = opt['type'](value) + if opt['type'] == bool and cmd['value'].lower() == 'false': + value = False + setattr(Settings, opt['name'], value) + return 0, 'Option {} updated'.format(opt['name']), '' + + +def handles_secret(cmd): + return bool([cmd for secret_word in ['password', 'key'] if (secret_word in cmd)]) + + +@CLICheckNonemptyFileInput +def get_secret(inbuf=None): + return inbuf, None, None diff --git a/src/pybind/mgr/dashboard/tests/__init__.py b/src/pybind/mgr/dashboard/tests/__init__.py new file mode 100644 index 00000000..58998690 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/__init__.py @@ -0,0 +1,262 @@ +# -*- coding: utf-8 -*- +# pylint: disable=too-many-arguments +from __future__ import absolute_import + +import json +import threading +import sys +import time + +import cherrypy +from cherrypy._cptools import HandlerWrapperTool +from cherrypy.test import helper +from pyfakefs import fake_filesystem + +from mgr_module import CLICommand, MgrModule + +from .. import logger, mgr +from ..controllers import json_error_page, generate_controller_routes +from ..services.auth import AuthManagerTool +from ..services.exception import dashboard_exception_handler + +from ..plugins import PLUGIN_MANAGER +from ..plugins import feature_toggles, debug # noqa # pylint: disable=unused-import + + +PLUGIN_MANAGER.hook.init() +PLUGIN_MANAGER.hook.register_commands() + + +class CmdException(Exception): + def __init__(self, retcode, message): + super(CmdException, self).__init__(message) + self.retcode = retcode + + +def exec_dashboard_cmd(command_handler, cmd, **kwargs): + inbuf = kwargs['inbuf'] if 'inbuf' in kwargs else None + cmd_dict = {'prefix': 'dashboard {}'.format(cmd)} + cmd_dict.update(kwargs) + if cmd_dict['prefix'] not in CLICommand.COMMANDS: + ret, out, err = command_handler(cmd_dict) + if ret < 0: + raise CmdException(ret, err) + try: + return json.loads(out) + except ValueError: + return out + + ret, out, err = CLICommand.COMMANDS[cmd_dict['prefix']].call(mgr, cmd_dict, inbuf) + if ret < 0: + raise CmdException(ret, err) + try: + return json.loads(out) + except ValueError: + return out + + +class KVStoreMockMixin(object): + CONFIG_KEY_DICT = {} + + @classmethod + def mock_set_module_option(cls, attr, val): + cls.CONFIG_KEY_DICT[attr] = val + + @classmethod + def mock_get_module_option(cls, attr, default=None): + return cls.CONFIG_KEY_DICT.get(attr, default) + + @classmethod + def mock_kv_store(cls): + cls.CONFIG_KEY_DICT.clear() + mgr.set_module_option.side_effect = cls.mock_set_module_option + mgr.get_module_option.side_effect = cls.mock_get_module_option + # kludge below + mgr.set_store.side_effect = cls.mock_set_module_option + mgr.get_store.side_effect = cls.mock_get_module_option + + @classmethod + def get_key(cls, key): + return cls.CONFIG_KEY_DICT.get(key, None) + + +class CLICommandTestMixin(KVStoreMockMixin): + @classmethod + def exec_cmd(cls, cmd, **kwargs): + return exec_dashboard_cmd(None, cmd, **kwargs) + + +class FakeFsMixin(object): + fs = fake_filesystem.FakeFilesystem() + f_open = fake_filesystem.FakeFileOpen(fs) + f_os = fake_filesystem.FakeOsModule(fs) + + if sys.version_info > (3, 0): + builtins_open = 'builtins.open' + else: + builtins_open = '__builtin__.open' + + +class ControllerTestCase(helper.CPWebCase): + _endpoints_cache = {} + + @classmethod + def setup_controllers(cls, ctrl_classes, base_url=''): + if not isinstance(ctrl_classes, list): + ctrl_classes = [ctrl_classes] + mapper = cherrypy.dispatch.RoutesDispatcher() + endpoint_list = [] + for ctrl in ctrl_classes: + inst = ctrl() + + # We need to cache the controller endpoints because + # BaseController#endpoints method is not idempontent + # and a controller might be needed by more than one + # unit test. + if ctrl not in cls._endpoints_cache: + ctrl_endpoints = ctrl.endpoints() + cls._endpoints_cache[ctrl] = ctrl_endpoints + + ctrl_endpoints = cls._endpoints_cache[ctrl] + for endpoint in ctrl_endpoints: + endpoint.inst = inst + endpoint_list.append(endpoint) + endpoint_list = sorted(endpoint_list, key=lambda e: e.url) + for endpoint in endpoint_list: + generate_controller_routes(endpoint, mapper, base_url) + if base_url == '': + base_url = '/' + cherrypy.tree.mount(None, config={ + base_url: {'request.dispatch': mapper}}) + + def __init__(self, *args, **kwargs): + cherrypy.tools.authenticate = AuthManagerTool() + cherrypy.tools.dashboard_exception_handler = HandlerWrapperTool(dashboard_exception_handler, + priority=31) + cherrypy.config.update({ + 'error_page.default': json_error_page, + 'tools.json_in.on': True, + 'tools.json_in.force': False + }) + PLUGIN_MANAGER.hook.configure_cherrypy(config=cherrypy.config) + super(ControllerTestCase, self).__init__(*args, **kwargs) + + def _request(self, url, method, data=None, headers=None): + if not data: + b = None + h = None + else: + b = json.dumps(data) + h = [('Content-Type', 'application/json'), + ('Content-Length', str(len(b)))] + if headers: + h = headers + self.getPage(url, method=method, body=b, headers=h) + + def _get(self, url, headers=None): + self._request(url, 'GET', headers=headers) + + def _post(self, url, data=None): + self._request(url, 'POST', data) + + def _delete(self, url, data=None): + self._request(url, 'DELETE', data) + + def _put(self, url, data=None): + self._request(url, 'PUT', data) + + def _task_request(self, method, url, data, timeout): + self._request(url, method, data) + if self.status != '202 Accepted': + logger.info("task finished immediately") + return + + res = self.jsonBody() + self.assertIsInstance(res, dict) + self.assertIn('name', res) + self.assertIn('metadata', res) + + task_name = res['name'] + task_metadata = res['metadata'] + + # pylint: disable=protected-access + class Waiter(threading.Thread): + def __init__(self, task_name, task_metadata, tc): + super(Waiter, self).__init__() + self.task_name = task_name + self.task_metadata = task_metadata + self.ev = threading.Event() + self.abort = False + self.res_task = None + self.tc = tc + + def run(self): + running = True + while running and not self.abort: + logger.info("task (%s, %s) is still executing", self.task_name, + self.task_metadata) + time.sleep(1) + self.tc._get('/api/task?name={}'.format(self.task_name)) + res = self.tc.jsonBody() + for task in res['finished_tasks']: + if task['metadata'] == self.task_metadata: + # task finished + running = False + self.res_task = task + self.ev.set() + + thread = Waiter(task_name, task_metadata, self) + thread.start() + status = thread.ev.wait(timeout) + if not status: + # timeout expired + thread.abort = True + thread.join() + raise Exception("Waiting for task ({}, {}) to finish timed out" + .format(task_name, task_metadata)) + logger.info("task (%s, %s) finished", task_name, task_metadata) + if thread.res_task['success']: + self.body = json.dumps(thread.res_task['ret_value']) + if method == 'POST': + self.status = '201 Created' + elif method == 'PUT': + self.status = '200 OK' + elif method == 'DELETE': + self.status = '204 No Content' + return + else: + if 'status' in thread.res_task['exception']: + self.status = thread.res_task['exception']['status'] + else: + self.status = 500 + self.body = json.dumps(thread.res_task['exception']) + return + + def _task_post(self, url, data=None, timeout=60): + self._task_request('POST', url, data, timeout) + + def _task_delete(self, url, timeout=60): + self._task_request('DELETE', url, None, timeout) + + def _task_put(self, url, data=None, timeout=60): + self._task_request('PUT', url, data, timeout) + + def jsonBody(self): + body_str = self.body.decode('utf-8') if isinstance(self.body, bytes) else self.body + return json.loads(body_str) + + def assertJsonBody(self, data, msg=None): + """Fail if value != self.body.""" + json_body = self.jsonBody() + if data != json_body: + if msg is None: + msg = 'expected body:\n%r\n\nactual body:\n%r' % ( + data, json_body) + self._handlewebError(msg) + + def assertInJsonBody(self, data, msg=None): + json_body = self.jsonBody() + if data not in json_body: + if msg is None: + msg = 'expected %r to be in %r' % (data, json_body) + self._handlewebError(msg) diff --git a/src/pybind/mgr/dashboard/tests/helper.py b/src/pybind/mgr/dashboard/tests/helper.py new file mode 100644 index 00000000..9ec043d6 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/helper.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +try: + from typing import Dict, Any # pylint: disable=unused-import +except ImportError: + pass + + +def update_dict(data, update_data): + # type: (Dict[Any, Any], Dict[Any, Any]) -> Dict[Any] + """ Update a dictionary recursively. + + Eases doing so by providing the option to separate the key to be updated by dot characters. If + a key provided does not exist, it will raise an KeyError instead of just updating the + dictionary. + + Limitations + + Please note that the functionality provided by this method can only be used if the dictionary to + be updated (`data`) does not contain dot characters in its keys. + + :raises KeyError: + + >>> update_dict({'foo': {'bar': 5}}, {'foo.bar': 10}) + {'foo': {'bar': 10}} + + >>> update_dict({'foo': {'bar': 5}}, {'xyz': 10}) + Traceback (most recent call last): + ... + KeyError: 'xyz' + + >>> update_dict({'foo': {'bar': 5}}, {'foo.xyz': 10}) + Traceback (most recent call last): + ... + KeyError: 'xyz' + """ + for k, v in update_data.items(): + keys = k.split('.') + element = None + for i, key in enumerate(keys): + last = False + if len(keys) == i + 1: + last = True + + if not element: + element = data[key] + elif not last: + element = element[key] # pylint: disable=unsubscriptable-object + + if last: + if key not in element: + raise KeyError(key) + + element[key] = v + return data diff --git a/src/pybind/mgr/dashboard/tests/test_access_control.py b/src/pybind/mgr/dashboard/tests/test_access_control.py new file mode 100644 index 00000000..34452267 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_access_control.py @@ -0,0 +1,695 @@ +# -*- coding: utf-8 -*- +# pylint: disable=dangerous-default-value,too-many-public-methods +from __future__ import absolute_import + +import errno +import json +import tempfile +import time +import unittest + +from mgr_module import ERROR_MSG_EMPTY_INPUT_FILE + +from . import CmdException, CLICommandTestMixin +from .. import mgr +from ..security import Scope, Permission +from ..services.access_control import load_access_control_db, \ + password_hash, AccessControlDB, \ + SYSTEM_ROLES + + +class AccessControlTest(unittest.TestCase, CLICommandTestMixin): + + @classmethod + def setUpClass(cls): + cls.mock_kv_store() + mgr.ACCESS_CONTROL_DB = None + + def setUp(self): + self.CONFIG_KEY_DICT.clear() + load_access_control_db() + + def load_persistent_db(self): + config_key = AccessControlDB.accessdb_config_key() + self.assertIn(config_key, self.CONFIG_KEY_DICT) + db_json = self.CONFIG_KEY_DICT[config_key] + db = json.loads(db_json) + return db + + # The DB is written to persistent storage the first time it is saved. + # However, should an operation fail due to , we may end up in + # a state where we have a completely empty CONFIG_KEY_DICT (our mock + # equivalent to the persistent state). While this works for most of the + # tests in this class, that would prevent us from testing things like + # "run a command that is expected to fail, and then ensure nothing + # happened", because we'd be asserting in `load_persistent_db()` due to + # the map being empty. + # + # This function will therefore force state to be written to our mock + # persistent state. We could have added this extra step to + # `load_persistent_db()` directly, but that would conflict with the + # upgrade tests. This way, we can selectively enforce this requirement + # where we believe it to be necessary; generically speaking, this should + # not be needed unless we're testing very specific behaviors. + # + def setup_and_load_persistent_db(self): + mgr.ACCESS_CTRL_DB.save() + self.load_persistent_db() + + def validate_persistent_role(self, rolename, scopes_permissions, + description=None): + db = self.load_persistent_db() + self.assertIn('roles', db) + self.assertIn(rolename, db['roles']) + self.assertEqual(db['roles'][rolename]['name'], rolename) + self.assertEqual(db['roles'][rolename]['description'], description) + self.assertDictEqual(db['roles'][rolename]['scopes_permissions'], + scopes_permissions) + + def validate_persistent_no_role(self, rolename): + db = self.load_persistent_db() + self.assertIn('roles', db) + self.assertNotIn(rolename, db['roles']) + + def validate_persistent_user(self, username, roles, password=None, + name=None, email=None, lastUpdate=None): + db = self.load_persistent_db() + self.assertIn('users', db) + self.assertIn(username, db['users']) + self.assertEqual(db['users'][username]['username'], username) + self.assertListEqual(db['users'][username]['roles'], roles) + if password: + self.assertEqual(db['users'][username]['password'], password) + if name: + self.assertEqual(db['users'][username]['name'], name) + if email: + self.assertEqual(db['users'][username]['email'], email) + if lastUpdate: + self.assertEqual(db['users'][username]['lastUpdate'], lastUpdate) + + def validate_persistent_no_user(self, username): + db = self.load_persistent_db() + self.assertIn('users', db) + self.assertNotIn(username, db['users']) + + def test_create_role(self): + role = self.exec_cmd('ac-role-create', rolename='test_role') + self.assertDictEqual(role, {'name': 'test_role', 'description': None, + 'scopes_permissions': {}}) + self.validate_persistent_role('test_role', {}) + + def test_create_role_with_desc(self): + role = self.exec_cmd('ac-role-create', rolename='test_role', + description='Test Role') + self.assertDictEqual(role, {'name': 'test_role', + 'description': 'Test Role', + 'scopes_permissions': {}}) + self.validate_persistent_role('test_role', {}, 'Test Role') + + def test_create_duplicate_role(self): + self.test_create_role() + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-create', rolename='test_role') + + self.assertEqual(ctx.exception.retcode, -errno.EEXIST) + self.assertEqual(str(ctx.exception), "Role 'test_role' already exists") + + def test_delete_role(self): + self.test_create_role() + out = self.exec_cmd('ac-role-delete', rolename='test_role') + self.assertEqual(out, "Role 'test_role' deleted") + self.validate_persistent_no_role('test_role') + + def test_delete_nonexistent_role(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-delete', rolename='test_role') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "Role 'test_role' does not exist") + + def test_show_single_role(self): + self.test_create_role() + role = self.exec_cmd('ac-role-show', rolename='test_role') + self.assertDictEqual(role, {'name': 'test_role', 'description': None, + 'scopes_permissions': {}}) + + def test_show_nonexistent_role(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-show', rolename='test_role') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "Role 'test_role' does not exist") + + def test_show_system_roles(self): + roles = self.exec_cmd('ac-role-show') + self.assertEqual(len(roles), len(SYSTEM_ROLES)) + for role in roles: + self.assertIn(role, SYSTEM_ROLES) + + def test_show_system_role(self): + role = self.exec_cmd('ac-role-show', rolename="read-only") + self.assertEqual(role['name'], 'read-only') + self.assertEqual(role['description'], 'Read-Only') + + def test_delete_system_role(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-delete', rolename='administrator') + + self.assertEqual(ctx.exception.retcode, -errno.EPERM) + self.assertEqual(str(ctx.exception), + "Cannot delete system role 'administrator'") + + def test_add_role_scope_perms(self): + self.test_create_role() + self.exec_cmd('ac-role-add-scope-perms', rolename='test_role', + scopename=Scope.POOL, + permissions=[Permission.READ, Permission.DELETE]) + role = self.exec_cmd('ac-role-show', rolename='test_role') + self.assertDictEqual(role, {'name': 'test_role', + 'description': None, + 'scopes_permissions': { + Scope.POOL: [Permission.DELETE, + Permission.READ] + }}) + self.validate_persistent_role('test_role', { + Scope.POOL: [Permission.DELETE, Permission.READ] + }) + + def test_del_role_scope_perms(self): + self.test_add_role_scope_perms() + self.exec_cmd('ac-role-add-scope-perms', rolename='test_role', + scopename=Scope.MONITOR, + permissions=[Permission.READ, Permission.CREATE]) + self.validate_persistent_role('test_role', { + Scope.POOL: [Permission.DELETE, Permission.READ], + Scope.MONITOR: [Permission.CREATE, Permission.READ] + }) + self.exec_cmd('ac-role-del-scope-perms', rolename='test_role', + scopename=Scope.POOL) + role = self.exec_cmd('ac-role-show', rolename='test_role') + self.assertDictEqual(role, {'name': 'test_role', + 'description': None, + 'scopes_permissions': { + Scope.MONITOR: [Permission.CREATE, + Permission.READ] + }}) + self.validate_persistent_role('test_role', { + Scope.MONITOR: [Permission.CREATE, Permission.READ] + }) + + def test_add_role_scope_perms_nonexistent_role(self): + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-add-scope-perms', rolename='test_role', + scopename='pool', + permissions=['read', 'delete']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "Role 'test_role' does not exist") + + def test_add_role_invalid_scope_perms(self): + self.test_create_role() + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-add-scope-perms', rolename='test_role', + scopename='invalidscope', + permissions=['read', 'delete']) + + self.assertEqual(ctx.exception.retcode, -errno.EINVAL) + self.assertEqual(str(ctx.exception), + "Scope 'invalidscope' is not valid\n Possible values: " + "{}".format(Scope.all_scopes())) + + def test_add_role_scope_invalid_perms(self): + self.test_create_role() + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-add-scope-perms', rolename='test_role', + scopename='pool', permissions=['invalidperm']) + + self.assertEqual(ctx.exception.retcode, -errno.EINVAL) + self.assertEqual(str(ctx.exception), + "Permission 'invalidperm' is not valid\n Possible " + "values: {}".format(Permission.all_permissions())) + + def test_del_role_scope_perms_nonexistent_role(self): + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-del-scope-perms', rolename='test_role', + scopename='pool') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "Role 'test_role' does not exist") + + def test_del_role_nonexistent_scope_perms(self): + self.test_add_role_scope_perms() + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-del-scope-perms', rolename='test_role', + scopename='nonexistentscope') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), + "There are no permissions for scope 'nonexistentscope' " + "in role 'test_role'") + + def test_not_permitted_add_role_scope_perms(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-add-scope-perms', rolename='read-only', + scopename='pool', permissions=['read', 'delete']) + + self.assertEqual(ctx.exception.retcode, -errno.EPERM) + self.assertEqual(str(ctx.exception), + "Cannot update system role 'read-only'") + + def test_not_permitted_del_role_scope_perms(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-del-scope-perms', rolename='read-only', + scopename='pool') + + self.assertEqual(ctx.exception.retcode, -errno.EPERM) + self.assertEqual(str(ctx.exception), + "Cannot update system role 'read-only'") + + def test_create_user(self, username='admin', rolename=None): + user = self.exec_cmd('ac-user-create', username=username, + rolename=rolename, inbuf='admin', + name='{} User'.format(username), + email='{}@user.com'.format(username)) + + pass_hash = password_hash('admin', user['password']) + self.assertDictEqual(user, { + 'username': username, + 'password': pass_hash, + 'lastUpdate': user['lastUpdate'], + 'name': '{} User'.format(username), + 'email': '{}@user.com'.format(username), + 'roles': [rolename] if rolename else [] + }) + self.validate_persistent_user(username, [rolename] if rolename else [], + pass_hash, '{} User'.format(username), + '{}@user.com'.format(username), + user['lastUpdate']) + return user + + def test_create_user_with_role(self): + self.test_add_role_scope_perms() + self.test_create_user(rolename='test_role') + + def test_create_user_with_system_role(self): + self.test_create_user(rolename='administrator') + + def test_delete_user(self): + self.test_create_user() + out = self.exec_cmd('ac-user-delete', username='admin') + self.assertEqual(out, "User 'admin' deleted") + users = self.exec_cmd('ac-user-show') + self.assertEqual(len(users), 0) + self.validate_persistent_no_user('admin') + + def test_create_duplicate_user(self): + self.test_create_user() + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-create', username='admin', inbuf='admin') + + self.assertEqual(ctx.exception.retcode, -errno.EEXIST) + self.assertEqual(str(ctx.exception), "User 'admin' already exists") + + def test_create_users_with_dne_role(self): + # one time call to setup our persistent db + self.setup_and_load_persistent_db() + + # create a user with a role that does not exist; expect a failure + try: + self.exec_cmd('ac-user-create', username='foo', + rolename='dne_role', inbuf='foopass', + name='foo User', email='foo@user.com') + except CmdException as e: + self.assertEqual(e.retcode, -errno.ENOENT) + + db = self.load_persistent_db() + if 'users' in db: + self.assertNotIn('foo', db['users']) + + # We could just finish our test here, given we ensured that the user + # with a non-existent role is not in persistent storage. However, + # we're going to test the database's consistency, making sure that + # side-effects are not written to persistent storage once we commit + # an unrelated operation. To ensure this, we'll issue another + # operation that is sharing the same code path, and will check whether + # the next operation commits dirty state. + + # create a role (this will be 'test_role') + self.test_create_role() + self.exec_cmd('ac-user-create', username='bar', + rolename='test_role', inbuf='barpass', + name='bar User', email='bar@user.com') + + # validate db: + # user 'foo' should not exist + # user 'bar' should exist and have role 'test_role' + self.validate_persistent_user('bar', ['test_role']) + + db = self.load_persistent_db() + self.assertIn('users', db) + self.assertNotIn('foo', db['users']) + + def test_delete_nonexistent_user(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-delete', username='admin') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "User 'admin' does not exist") + + def test_add_user_roles(self, username='admin', + roles=['pool-manager', 'block-manager']): + user_orig = self.test_create_user(username) + uroles = [] + for role in roles: + uroles.append(role) + uroles.sort() + user = self.exec_cmd('ac-user-add-roles', username=username, + roles=[role]) + self.assertDictContainsSubset({'roles': uroles}, user) + self.validate_persistent_user(username, uroles) + self.assertGreaterEqual(user['lastUpdate'], user_orig['lastUpdate']) + + def test_add_user_roles2(self): + user_orig = self.test_create_user() + user = self.exec_cmd('ac-user-add-roles', username="admin", + roles=['pool-manager', 'block-manager']) + self.assertDictContainsSubset( + {'roles': ['block-manager', 'pool-manager']}, user) + self.validate_persistent_user('admin', ['block-manager', + 'pool-manager']) + self.assertGreaterEqual(user['lastUpdate'], user_orig['lastUpdate']) + + def test_add_user_roles_not_existent_user(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-add-roles', username="admin", + roles=['pool-manager', 'block-manager']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "User 'admin' does not exist") + + def test_add_user_roles_not_existent_role(self): + self.test_create_user() + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-add-roles', username="admin", + roles=['Invalid Role']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), + "Role 'Invalid Role' does not exist") + + def test_set_user_roles(self): + user_orig = self.test_create_user() + user = self.exec_cmd('ac-user-add-roles', username="admin", + roles=['pool-manager']) + self.assertDictContainsSubset( + {'roles': ['pool-manager']}, user) + self.validate_persistent_user('admin', ['pool-manager']) + self.assertGreaterEqual(user['lastUpdate'], user_orig['lastUpdate']) + user2 = self.exec_cmd('ac-user-set-roles', username="admin", + roles=['rgw-manager', 'block-manager']) + self.assertDictContainsSubset( + {'roles': ['block-manager', 'rgw-manager']}, user2) + self.validate_persistent_user('admin', ['block-manager', + 'rgw-manager']) + self.assertGreaterEqual(user2['lastUpdate'], user['lastUpdate']) + + def test_set_user_roles_not_existent_user(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-set-roles', username="admin", + roles=['pool-manager', 'block-manager']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "User 'admin' does not exist") + + def test_set_user_roles_not_existent_role(self): + self.test_create_user() + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-set-roles', username="admin", + roles=['Invalid Role']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), + "Role 'Invalid Role' does not exist") + + def test_del_user_roles(self): + self.test_add_user_roles() + user = self.exec_cmd('ac-user-del-roles', username="admin", + roles=['pool-manager']) + self.assertDictContainsSubset( + {'roles': ['block-manager']}, user) + self.validate_persistent_user('admin', ['block-manager']) + + def test_del_user_roles_not_existent_user(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-del-roles', username="admin", + roles=['pool-manager', 'block-manager']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "User 'admin' does not exist") + + def test_del_user_roles_not_existent_role(self): + self.test_create_user() + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-del-roles', username="admin", + roles=['Invalid Role']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), + "Role 'Invalid Role' does not exist") + + def test_del_user_roles_not_associated_role(self): + self.test_create_user() + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-del-roles', username="admin", + roles=['rgw-manager']) + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), + "Role 'rgw-manager' is not associated with user " + "'admin'") + + def test_show_user(self): + self.test_add_user_roles() + user = self.exec_cmd('ac-user-show', username='admin') + pass_hash = password_hash('admin', user['password']) + self.assertDictEqual(user, { + 'username': 'admin', + 'lastUpdate': user['lastUpdate'], + 'password': pass_hash, + 'name': 'admin User', + 'email': 'admin@user.com', + 'roles': ['block-manager', 'pool-manager'] + }) + + def test_show_nonexistent_user(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-show', username='admin') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "User 'admin' does not exist") + + def test_show_all_users(self): + self.test_add_user_roles('admin', ['administrator']) + self.test_add_user_roles('guest', ['read-only']) + users = self.exec_cmd('ac-user-show') + self.assertEqual(len(users), 2) + for user in users: + self.assertIn(user, ['admin', 'guest']) + + def test_del_role_associated_with_user(self): + self.test_create_role() + self.test_add_user_roles('guest', ['test_role']) + + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-role-delete', rolename='test_role') + + self.assertEqual(ctx.exception.retcode, -errno.EPERM) + self.assertEqual(str(ctx.exception), + "Role 'test_role' is still associated with user " + "'guest'") + + def test_set_user_info(self): + user_orig = self.test_create_user() + user = self.exec_cmd('ac-user-set-info', username='admin', + name='Admin Name', email='admin@admin.com') + pass_hash = password_hash('admin', user['password']) + self.assertDictEqual(user, { + 'username': 'admin', + 'password': pass_hash, + 'name': 'Admin Name', + 'email': 'admin@admin.com', + 'lastUpdate': user['lastUpdate'], + 'roles': [] + }) + self.validate_persistent_user('admin', [], pass_hash, 'Admin Name', + 'admin@admin.com') + self.assertEqual(user['lastUpdate'], user_orig['lastUpdate']) + + def test_set_user_info_nonexistent_user(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-set-info', username='admin', + name='Admin Name', email='admin@admin.com') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "User 'admin' does not exist") + + def test_set_user_password(self): + user_orig = self.test_create_user() + user = self.exec_cmd('ac-user-set-password', username='admin', + inbuf='newpass') + pass_hash = password_hash('newpass', user['password']) + self.assertDictEqual(user, { + 'username': 'admin', + 'password': pass_hash, + 'name': 'admin User', + 'email': 'admin@user.com', + 'lastUpdate': user['lastUpdate'], + 'roles': [] + }) + self.validate_persistent_user('admin', [], pass_hash, 'admin User', + 'admin@user.com') + self.assertGreaterEqual(user['lastUpdate'], user_orig['lastUpdate']) + + def test_sanitize_password(self): + self.test_create_user() + password = 'myPass\\n\\r\\n' + with tempfile.TemporaryFile(mode='w+') as pwd_file: + # Add new line separators (like some text editors when a file is saved). + pwd_file.write('{}{}'.format(password, '\n\r\n\n')) + pwd_file.seek(0) + user = self.exec_cmd('ac-user-set-password', username='admin', + inbuf=pwd_file.read(), force_password=True) + pass_hash = password_hash(password, user['password']) + self.assertEqual(user['password'], pass_hash) + + def test_unicode_password(self): + self.test_create_user() + password = '章鱼不是密码' + with tempfile.TemporaryFile(mode='w+') as pwd_file: + pwd_file.write(password) + pwd_file.seek(0) + user = self.exec_cmd('ac-user-set-password', username='admin', + inbuf=pwd_file.read(), force_password=True) + pass_hash = password_hash(password, user['password']) + self.assertEqual(user['password'], pass_hash) + + def test_set_user_password_nonexistent_user(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-set-password', username='admin', + inbuf='newpass') + + self.assertEqual(ctx.exception.retcode, -errno.ENOENT) + self.assertEqual(str(ctx.exception), "User 'admin' does not exist") + + def test_set_user_password_empty(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('ac-user-set-password', username='admin', inbuf='\n') + + self.assertEqual(ctx.exception.retcode, -errno.EINVAL) + self.assertEqual(str(ctx.exception), ERROR_MSG_EMPTY_INPUT_FILE) + + def test_set_login_credentials(self): + self.exec_cmd('set-login-credentials', username='admin', + inbuf='admin') + user = self.exec_cmd('ac-user-show', username='admin') + pass_hash = password_hash('admin', user['password']) + self.assertDictEqual(user, { + 'username': 'admin', + 'password': pass_hash, + 'name': None, + 'email': None, + 'lastUpdate': user['lastUpdate'], + 'roles': ['administrator'] + }) + self.validate_persistent_user('admin', ['administrator'], pass_hash, + None, None) + + def test_set_login_credentials_for_existing_user(self): + self.test_add_user_roles('admin', ['read-only']) + self.exec_cmd('set-login-credentials', username='admin', + inbuf='admin2') + user = self.exec_cmd('ac-user-show', username='admin') + pass_hash = password_hash('admin2', user['password']) + self.assertDictEqual(user, { + 'username': 'admin', + 'password': pass_hash, + 'name': 'admin User', + 'email': 'admin@user.com', + 'lastUpdate': user['lastUpdate'], + 'roles': ['read-only'] + }) + self.validate_persistent_user('admin', ['read-only'], pass_hash, + 'admin User', 'admin@user.com') + + def test_load_v1(self): + self.CONFIG_KEY_DICT['accessdb_v1'] = ''' + {{ + "users": {{ + "admin": {{ + "username": "admin", + "password": + "$2b$12$sd0Az7mm3FaJl8kN3b/xwOuztaN0sWUwC1SJqjM4wcDw/s5cmGbLK", + "roles": ["block-manager", "test_role"], + "name": "admin User", + "email": "admin@user.com", + "lastUpdate": {} + }} + }}, + "roles": {{ + "test_role": {{ + "name": "test_role", + "description": "Test Role", + "scopes_permissions": {{ + "{}": ["{}", "{}"], + "{}": ["{}"] + }} + }} + }}, + "version": 1 + }} + '''.format(int(round(time.time())), Scope.ISCSI, Permission.READ, + Permission.UPDATE, Scope.POOL, Permission.CREATE) + + load_access_control_db() + role = self.exec_cmd('ac-role-show', rolename="test_role") + self.assertDictEqual(role, { + 'name': 'test_role', + 'description': "Test Role", + 'scopes_permissions': { + Scope.ISCSI: [Permission.READ, Permission.UPDATE], + Scope.POOL: [Permission.CREATE] + } + }) + user = self.exec_cmd('ac-user-show', username="admin") + self.assertDictEqual(user, { + 'username': 'admin', + 'lastUpdate': user['lastUpdate'], + 'password': + "$2b$12$sd0Az7mm3FaJl8kN3b/xwOuztaN0sWUwC1SJqjM4wcDw/s5cmGbLK", + 'name': 'admin User', + 'email': 'admin@user.com', + 'roles': ['block-manager', 'test_role'] + }) + + def test_update_from_previous_version_v1(self): + self.CONFIG_KEY_DICT['username'] = 'admin' + self.CONFIG_KEY_DICT['password'] = \ + '$2b$12$sd0Az7mm3FaJl8kN3b/xwOuztaN0sWUwC1SJqjM4wcDw/s5cmGbLK' + load_access_control_db() + user = self.exec_cmd('ac-user-show', username="admin") + self.assertDictEqual(user, { + 'username': 'admin', + 'lastUpdate': user['lastUpdate'], + 'password': + "$2b$12$sd0Az7mm3FaJl8kN3b/xwOuztaN0sWUwC1SJqjM4wcDw/s5cmGbLK", + 'name': None, + 'email': None, + 'roles': ['administrator'] + }) diff --git a/src/pybind/mgr/dashboard/tests/test_api_auditing.py b/src/pybind/mgr/dashboard/tests/test_api_auditing.py new file mode 100644 index 00000000..ae95e340 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_api_auditing.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import re +import json +import cherrypy +import mock + +from . import ControllerTestCase, KVStoreMockMixin +from ..controllers import RESTController, Controller +from ..tools import RequestLoggingTool +from .. import mgr + + +# pylint: disable=W0613 +@Controller('/foo', secure=False) +class FooResource(RESTController): + def create(self, password): + pass + + def get(self, key): + pass + + def delete(self, key): + pass + + def set(self, key, password, secret_key=None): + pass + + +class ApiAuditingTest(ControllerTestCase, KVStoreMockMixin): + + def __init__(self, *args, **kwargs): + cherrypy.tools.request_logging = RequestLoggingTool() + cherrypy.config.update({'tools.request_logging.on': True}) + super(ApiAuditingTest, self).__init__(*args, **kwargs) + + @classmethod + def setup_server(cls): + cls.setup_controllers([FooResource]) + + def setUp(self): + self.mock_kv_store() + mgr.cluster_log = mock.Mock() + mgr.set_module_option('AUDIT_API_ENABLED', True) + mgr.set_module_option('AUDIT_API_LOG_PAYLOAD', True) + + def _validate_cluster_log_msg(self, path, method, user, params): + channel, _, msg = mgr.cluster_log.call_args_list[0][0] + self.assertEqual(channel, 'audit') + pattern = r'^\[DASHBOARD\] from=\'(.+)\' path=\'(.+)\' ' \ + 'method=\'(.+)\' user=\'(.+)\' params=\'(.+)\'$' + m = re.match(pattern, msg) + self.assertEqual(m.group(2), path) + self.assertEqual(m.group(3), method) + self.assertEqual(m.group(4), user) + self.assertDictEqual(json.loads(m.group(5)), params) + + def test_no_audit(self): + mgr.set_module_option('AUDIT_API_ENABLED', False) + self._delete('/foo/test1') + mgr.cluster_log.assert_not_called() + + def test_no_payload(self): + mgr.set_module_option('AUDIT_API_LOG_PAYLOAD', False) + self._delete('/foo/test1') + _, _, msg = mgr.cluster_log.call_args_list[0][0] + self.assertNotIn('params=', msg) + + def test_no_audit_get(self): + self._get('/foo/test1') + mgr.cluster_log.assert_not_called() + + def test_audit_put(self): + self._put('/foo/test1', {'password': 'y', 'secret_key': 1234}) + mgr.cluster_log.assert_called_once() + self._validate_cluster_log_msg('/foo/test1', 'PUT', 'None', + {'key': 'test1', + 'password': '***', + 'secret_key': '***'}) + + def test_audit_post(self): + with mock.patch('dashboard.services.auth.JwtManager.get_username', + return_value='hugo'): + self._post('/foo?password=1234') + mgr.cluster_log.assert_called_once() + self._validate_cluster_log_msg('/foo', 'POST', 'hugo', + {'password': '***'}) + + def test_audit_delete(self): + self._delete('/foo/test1') + mgr.cluster_log.assert_called_once() + self._validate_cluster_log_msg('/foo/test1', 'DELETE', + 'None', {'key': 'test1'}) diff --git a/src/pybind/mgr/dashboard/tests/test_auth.py b/src/pybind/mgr/dashboard/tests/test_auth.py new file mode 100644 index 00000000..6f1d2a08 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_auth.py @@ -0,0 +1,20 @@ +import unittest + +from .. import mgr +from ..services.auth import JwtManager + + +class JwtManagerTest(unittest.TestCase): + + def test_generate_token_and_decode(self): + mgr.get_module_option.return_value = JwtManager.JWT_TOKEN_TTL + mgr.get_store.return_value = 'jwt_secret' + + token = JwtManager.gen_token('my-username') + self.assertIsInstance(token, str) + self.assertTrue(token) + + decoded_token = JwtManager.decode_token(token) + self.assertIsInstance(decoded_token, dict) + self.assertEqual(decoded_token['iss'], 'ceph-dashboard') + self.assertEqual(decoded_token['username'], 'my-username') diff --git a/src/pybind/mgr/dashboard/tests/test_ceph_service.py b/src/pybind/mgr/dashboard/tests/test_ceph_service.py new file mode 100644 index 00000000..5111e68d --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_ceph_service.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# pylint: disable=dangerous-default-value,too-many-public-methods +from __future__ import absolute_import + +import unittest +try: + import mock +except ImportError: + import unittest.mock as mock + +from ..services.ceph_service import CephService + + +class CephServiceTest(unittest.TestCase): + pools = [{ + 'pool_name': 'good_pool', + 'pool': 1, + }, { + 'pool_name': 'bad_pool', + 'pool': 2, + 'flaky': 'option_x' + }] + + def setUp(self): + # Mock get_pool_list + self.list_patch = mock.patch('dashboard.services.ceph_service.CephService.get_pool_list') + self.list = self.list_patch.start() + self.list.return_value = self.pools + # Mock mgr.get + self.mgr_patch = mock.patch('dashboard.mgr.get') + self.mgr = self.mgr_patch.start() + self.mgr.return_value = { + 'by_pool': { + '1': {'active+clean': 16}, + '2': {'creating+incomplete': 16}, + } + } + self.service = CephService() + + def tearDown(self): + self.list_patch.stop() + self.mgr_patch.stop() + + def test_get_pool_by_attribute_with_match(self): + self.assertEqual(self.service.get_pool_by_attribute('pool', 1), self.pools[0]) + self.assertEqual(self.service.get_pool_by_attribute('pool_name', 'bad_pool'), self.pools[1]) + + def test_get_pool_by_attribute_without_a_match(self): + self.assertEqual(self.service.get_pool_by_attribute('pool', 3), None) + self.assertEqual(self.service.get_pool_by_attribute('not_there', 'sth'), None) + + def test_get_pool_by_attribute_matching_a_not_always_set_attribute(self): + self.assertEqual(self.service.get_pool_by_attribute('flaky', 'option_x'), self.pools[1]) + + @mock.patch('dashboard.mgr.rados.pool_reverse_lookup', return_value='good_pool') + def test_get_pool_name_from_id_with_match(self, _mock): + self.assertEqual(self.service.get_pool_name_from_id(1), 'good_pool') + + @mock.patch('dashboard.mgr.rados.pool_reverse_lookup', return_value=None) + def test_get_pool_name_from_id_without_match(self, _mock): + self.assertEqual(self.service.get_pool_name_from_id(3), None) + + def test_get_pool_pg_status(self): + self.assertEqual(self.service.get_pool_pg_status('good_pool'), {'active+clean': 16}) + + def test_get_pg_status_without_match(self): + self.assertEqual(self.service.get_pool_pg_status('no-pool'), {}) diff --git a/src/pybind/mgr/dashboard/tests/test_cephfs.py b/src/pybind/mgr/dashboard/tests/test_cephfs.py new file mode 100644 index 00000000..e9abda53 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_cephfs.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +from collections import defaultdict +try: + from mock import Mock +except ImportError: + from unittest.mock import Mock + +from .. import mgr +from . import ControllerTestCase +from ..controllers.cephfs import CephFS + + +class MetaDataMock(object): + def get(self, _x, _y): + return 'bar' + + +def get_metadata_mock(key, meta_key): + return { + 'mds': { + None: None, # Unknown key + 'foo': MetaDataMock() + }[meta_key] + }[key] + + +class CephFsTest(ControllerTestCase): + cephFs = CephFS() + + @classmethod + def setup_server(cls): + mgr.get_metadata = Mock(side_effect=get_metadata_mock) + + def tearDown(self): + mgr.get_metadata.stop() + + def test_append_of_mds_metadata_if_key_is_not_found(self): + mds_versions = defaultdict(list) + # pylint: disable=protected-access + self.cephFs._append_mds_metadata(mds_versions, None) + self.assertEqual(len(mds_versions), 0) + + def test_append_of_mds_metadata_with_existing_metadata(self): + mds_versions = defaultdict(list) + # pylint: disable=protected-access + self.cephFs._append_mds_metadata(mds_versions, 'foo') + self.assertEqual(len(mds_versions), 1) + self.assertEqual(mds_versions['bar'], ['foo']) diff --git a/src/pybind/mgr/dashboard/tests/test_controllers.py b/src/pybind/mgr/dashboard/tests/test_controllers.py new file mode 100644 index 00000000..0e880470 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_controllers.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import ControllerTestCase +from ..controllers import BaseController, RESTController, Controller, \ + ApiController, Endpoint + + +@Controller("/btest/{key}", base_url="/ui", secure=False) +class BTest(BaseController): + @Endpoint() + def test1(self, key, opt=1): + return {'key': key, 'opt': opt} + + @Endpoint() + def test2(self, key, skey, opt=1): + return {'key': key, 'skey': skey, 'opt': opt} + + @Endpoint(path="/foo/{skey}/test-3") + def test3(self, key, skey, opt=1): + return {'key': key, 'skey': skey, 'opt': opt} + + @Endpoint('POST', path="/foo/{skey}/test-3", query_params=['opt']) + def test4(self, key, skey, data, opt=1): + return {'key': key, 'skey': skey, 'data': data, 'opt': opt} + + @Endpoint('PUT', path_params=['skey'], query_params=['opt']) + def test5(self, key, skey, data1, data2=None, opt=1): + return {'key': key, 'skey': skey, 'data1': data1, 'data2': data2, + 'opt': opt} + + @Endpoint('GET', json_response=False) + def test6(self, key, opt=1): + return "My Formatted string key={} opt={}".format(key, opt) + + @Endpoint() + def __call__(self, key, opt=1): + return {'key': key, 'opt': opt} + + +@ApiController("/rtest/{key}", secure=False) +class RTest(RESTController): + RESOURCE_ID = 'skey/ekey' + + def list(self, key, opt=1): + return {'key': key, 'opt': opt} + + def create(self, key, data1, data2=None): + return {'key': key, 'data1': data1, 'data2': data2} + + def get(self, key, skey, ekey, opt=1): + return {'key': key, 'skey': skey, 'ekey': ekey, 'opt': opt} + + def set(self, key, skey, ekey, data): + return {'key': key, 'skey': skey, 'ekey': ekey, 'data': data} + + def delete(self, key, skey, ekey, opt=1): + pass + + def bulk_set(self, key, data1, data2=None): + return {'key': key, 'data1': data1, 'data2': data2} + + def bulk_delete(self, key, opt=1): + pass + + @RESTController.Collection('POST') + def cmethod(self, key, data): + return {'key': key, 'data': data} + + @RESTController.Resource('GET') + def rmethod(self, key, skey, ekey, opt=1): + return {'key': key, 'skey': skey, 'ekey': ekey, 'opt': opt} + + +@Controller("/", secure=False) +class Root(BaseController): + @Endpoint(json_response=False) + def __call__(self): + return "" + + +class ControllersTest(ControllerTestCase): + @classmethod + def setup_server(cls): + cls.setup_controllers([BTest, RTest], "/test") + + def test_1(self): + self._get('/test/ui/btest/{}/test1?opt=3'.format(100)) + self.assertStatus(200) + self.assertJsonBody({'key': '100', 'opt': '3'}) + + def test_2(self): + self._get('/test/ui/btest/{}/test2/{}?opt=3'.format(100, 200)) + self.assertStatus(200) + self.assertJsonBody({'key': '100', 'skey': '200', 'opt': '3'}) + + def test_3(self): + self._get('/test/ui/btest/{}/foo/{}/test-3?opt=3'.format(100, 200)) + self.assertStatus(200) + self.assertJsonBody({'key': '100', 'skey': '200', 'opt': '3'}) + + def test_4(self): + self._post('/test/ui/btest/{}/foo/{}/test-3?opt=3'.format(100, 200), + {'data': 30}) + self.assertStatus(200) + self.assertJsonBody({'key': '100', 'skey': '200', 'data': 30, + 'opt': '3'}) + + def test_5(self): + self._put('/test/ui/btest/{}/test5/{}?opt=3'.format(100, 200), + {'data1': 40, 'data2': "hello"}) + self.assertStatus(200) + self.assertJsonBody({'key': '100', 'skey': '200', 'data1': 40, + 'data2': "hello", 'opt': '3'}) + + def test_6(self): + self._get('/test/ui/btest/{}/test6'.format(100)) + self.assertStatus(200) + self.assertBody("My Formatted string key=100 opt=1") + + def test_7(self): + self._get('/test/ui/btest/{}?opt=3'.format(100)) + self.assertStatus(200) + self.assertJsonBody({'key': '100', 'opt': '3'}) + + def test_rest_list(self): + self._get('/test/api/rtest/{}?opt=2'.format(300)) + self.assertStatus(200) + self.assertJsonBody({'key': '300', 'opt': '2'}) + + def test_rest_create(self): + self._post('/test/api/rtest/{}'.format(300), + {'data1': 20, 'data2': True}) + self.assertStatus(201) + self.assertJsonBody({'key': '300', 'data1': 20, 'data2': True}) + + def test_rest_get(self): + self._get('/test/api/rtest/{}/{}/{}?opt=3'.format(300, 1, 2)) + self.assertStatus(200) + self.assertJsonBody({'key': '300', 'skey': '1', 'ekey': '2', + 'opt': '3'}) + + def test_rest_set(self): + self._put('/test/api/rtest/{}/{}/{}'.format(300, 1, 2), + {'data': 40}) + self.assertStatus(200) + self.assertJsonBody({'key': '300', 'skey': '1', 'ekey': '2', + 'data': 40}) + + def test_rest_delete(self): + self._delete('/test/api/rtest/{}/{}/{}?opt=3'.format(300, 1, 2)) + self.assertStatus(204) + + def test_rest_bulk_set(self): + self._put('/test/api/rtest/{}'.format(300), + {'data1': 20, 'data2': True}) + self.assertStatus(200) + self.assertJsonBody({'key': '300', 'data1': 20, 'data2': True}) + + self._put('/test/api/rtest/{}'.format(400), + {'data1': 20, 'data2': ['one', 'two', 'three']}) + self.assertStatus(200) + self.assertJsonBody({ + 'key': '400', + 'data1': 20, + 'data2': ['one', 'two', 'three'], + }) + + def test_rest_bulk_delete(self): + self._delete('/test/api/rtest/{}?opt=2'.format(300)) + self.assertStatus(204) + + def test_rest_collection(self): + self._post('/test/api/rtest/{}/cmethod'.format(300), {'data': 30}) + self.assertStatus(200) + self.assertJsonBody({'key': '300', 'data': 30}) + + def test_rest_resource(self): + self._get('/test/api/rtest/{}/{}/{}/rmethod?opt=4'.format(300, 2, 3)) + self.assertStatus(200) + self.assertJsonBody({'key': '300', 'skey': '2', 'ekey': '3', + 'opt': '4'}) + + +class RootControllerTest(ControllerTestCase): + @classmethod + def setup_server(cls): + cls.setup_controllers([Root]) + + def test_index(self): + self._get("/") + self.assertBody("") diff --git a/src/pybind/mgr/dashboard/tests/test_docs.py b/src/pybind/mgr/dashboard/tests/test_docs.py new file mode 100644 index 00000000..4d6c2576 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_docs.py @@ -0,0 +1,71 @@ +# # -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import ControllerTestCase +from ..controllers import RESTController, ApiController, Endpoint, EndpointDoc, ControllerDoc +from ..controllers.docs import Docs + + +# Dummy controller and endpoint that can be assigned with @EndpointDoc and @GroupDoc +@ControllerDoc("Group description", group="FooGroup") +@ApiController("/doctest/", secure=False) +class DecoratedController(RESTController): + @EndpointDoc( + description="Endpoint description", + group="BarGroup", + parameters={ + 'parameter': (int, "Description of parameter"), + }, + responses={ + 200: { + 'resp': (str, 'Description of response') + }, + }, + ) + @Endpoint(json_response=False) + def decorated_func(self, parameter): + pass + + +# To assure functionality of @EndpointDoc, @GroupDoc +class DocDecoratorsTest(ControllerTestCase): + @classmethod + def setup_server(cls): + cls.setup_controllers([DecoratedController, Docs], "/test") + + def test_group_info_attr(self): + test_ctrl = DecoratedController() + self.assertTrue(hasattr(test_ctrl, 'doc_info')) + self.assertIn('tag_descr', test_ctrl.doc_info) + self.assertIn('tag', test_ctrl.doc_info) + + def test_endpoint_info_attr(self): + test_ctrl = DecoratedController() + test_endpoint = test_ctrl.decorated_func + self.assertTrue(hasattr(test_endpoint, 'doc_info')) + self.assertIn('summary', test_endpoint.doc_info) + self.assertIn('tag', test_endpoint.doc_info) + self.assertIn('parameters', test_endpoint.doc_info) + self.assertIn('response', test_endpoint.doc_info) + + +# To assure functionality of Docs.py +# pylint: disable=protected-access +class DocsTest(ControllerTestCase): + @classmethod + def setup_server(cls): + cls.setup_controllers([Docs], "/test") + + def test_type_to_str(self): + self.assertEqual(Docs()._type_to_str(str), "string") + + def test_gen_paths(self): + outcome = Docs()._gen_paths(False, "")['/api/doctest//decorated_func/{parameter}']['get'] + self.assertIn('tags', outcome) + self.assertIn('summary', outcome) + self.assertIn('parameters', outcome) + self.assertIn('responses', outcome) + + def test_gen_tags(self): + outcome = Docs()._gen_tags(False)[0] + self.assertEqual({'description': 'Group description', 'name': 'FooGroup'}, outcome) diff --git a/src/pybind/mgr/dashboard/tests/test_erasure_code_profile.py b/src/pybind/mgr/dashboard/tests/test_erasure_code_profile.py new file mode 100644 index 00000000..88575c0a --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_erasure_code_profile.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +from .. import mgr +from . import ControllerTestCase +from ..controllers.erasure_code_profile import ErasureCodeProfile + + +class ErasureCodeProfileTest(ControllerTestCase): + @classmethod + def setup_server(cls): + mgr.get.side_effect = lambda key: { + 'osd_map': { + 'erasure_code_profiles': { + 'test': { + 'k': '2', + 'm': '1' + } + } + }, + 'health': {'json': '{"status": 1}'}, + 'fs_map': {'filesystems': []}, + + }[key] + # pylint: disable=protected-access + ErasureCodeProfile._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([ErasureCodeProfile]) + + def test_list(self): + self._get('/api/erasure_code_profile') + self.assertStatus(200) + self.assertJsonBody([{'k': 2, 'm': 1, 'name': 'test'}]) + + def test_get(self): + self._get('/api/erasure_code_profile/test') + self.assertStatus(200) + self.assertJsonBody({'k': 2, 'm': 1, 'name': 'test'}) diff --git a/src/pybind/mgr/dashboard/tests/test_exceptions.py b/src/pybind/mgr/dashboard/tests/test_exceptions.py new file mode 100644 index 00000000..5607f1dd --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_exceptions.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import time + +import rados + +from . import ControllerTestCase +from ..services.ceph_service import SendCommandError +from ..controllers import RESTController, Controller, Task, Endpoint +from ..services.exception import handle_rados_error, handle_send_command_error, \ + serialize_dashboard_exception +from ..tools import ViewCache, TaskManager, NotificationQueue + + +# pylint: disable=W0613 +@Controller('foo', secure=False) +class FooResource(RESTController): + + @Endpoint() + @handle_rados_error('foo') + def no_exception(self, param1, param2): + return [param1, param2] + + @Endpoint() + @handle_rados_error('foo') + def error_foo_controller(self): + raise rados.OSError('hi', errno=-42) + + @Endpoint() + @handle_send_command_error('foo') + def error_send_command(self): + raise SendCommandError('hi', 'prefix', {}, -42) + + @Endpoint() + def error_generic(self): + raise rados.Error('hi') + + @Endpoint() + def vc_no_data(self): + @ViewCache(timeout=0) + def _no_data(): + time.sleep(0.2) + + _no_data() + assert False + + @handle_rados_error('foo') + @Endpoint() + def vc_exception(self): + @ViewCache(timeout=10) + def _raise(): + raise rados.OSError('hi', errno=-42) + + _raise() + assert False + + @Endpoint() + def internal_server_error(self): + return 1/0 + + @handle_send_command_error('foo') + def list(self): + raise SendCommandError('list', 'prefix', {}, -42) + + @Endpoint() + @Task('task_exceptions/task_exception', {1: 2}, 1.0, + exception_handler=serialize_dashboard_exception) + @handle_rados_error('foo') + def task_exception(self): + raise rados.OSError('hi', errno=-42) + + @Endpoint() + def wait_task_exception(self): + ex, _ = TaskManager.list('task_exceptions/task_exception') + return bool(len(ex)) + + +# pylint: disable=C0102 +class Root(object): + foo = FooResource() + + +class RESTControllerTest(ControllerTestCase): + @classmethod + def setup_server(cls): + NotificationQueue.start_queue() + TaskManager.init() + cls.setup_controllers([FooResource]) + + def test_no_exception(self): + self._get('/foo/no_exception/a/b') + self.assertStatus(200) + self.assertJsonBody( + ['a', 'b'] + ) + + def test_error_foo_controller(self): + self._get('/foo/error_foo_controller') + self.assertStatus(400) + self.assertJsonBody( + {'detail': '[errno -42] hi', 'code': "42", 'component': 'foo'} + ) + + def test_error_send_command(self): + self._get('/foo/error_send_command') + self.assertStatus(400) + self.assertJsonBody( + {'detail': '[errno -42] hi', 'code': "42", 'component': 'foo'} + ) + + def test_error_send_command_list(self): + self._get('/foo/') + self.assertStatus(400) + self.assertJsonBody( + {'detail': '[errno -42] list', 'code': "42", 'component': 'foo'} + ) + + def test_error_foo_generic(self): + self._get('/foo/error_generic') + self.assertJsonBody({'detail': 'hi', 'code': 'Error', 'component': None}) + self.assertStatus(400) + + def test_viewcache_no_data(self): + self._get('/foo/vc_no_data') + self.assertStatus(200) + self.assertJsonBody({'status': ViewCache.VALUE_NONE, 'value': None}) + + def test_viewcache_exception(self): + self._get('/foo/vc_exception') + self.assertStatus(400) + self.assertJsonBody( + {'detail': '[errno -42] hi', 'code': "42", 'component': 'foo'} + ) + + def test_task_exception(self): + self._get('/foo/task_exception') + self.assertStatus(400) + self.assertJsonBody( + {'detail': '[errno -42] hi', 'code': "42", 'component': 'foo', + 'task': {'name': 'task_exceptions/task_exception', 'metadata': {'1': 2}}} + ) + + self._get('/foo/wait_task_exception') + while self.jsonBody(): + time.sleep(0.5) + self._get('/foo/wait_task_exception') + + def test_internal_server_error(self): + self._get('/foo/internal_server_error') + self.assertStatus(500) + self.assertIn('unexpected condition', self.jsonBody()['detail']) + + def test_404(self): + self._get('/foonot_found') + self.assertStatus(404) + self.assertIn('detail', self.jsonBody()) diff --git a/src/pybind/mgr/dashboard/tests/test_feature_toggles.py b/src/pybind/mgr/dashboard/tests/test_feature_toggles.py new file mode 100644 index 00000000..5c70c88a --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_feature_toggles.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import unittest +from mock import Mock, patch + +from . import KVStoreMockMixin +from ..plugins.feature_toggles import FeatureToggles, Features + + +class SettingsTest(unittest.TestCase, KVStoreMockMixin): + @classmethod + def setUpClass(cls): + cls.mock_kv_store() + cls.CONFIG_KEY_DICT['url_prefix'] = '' + + # Mock MODULE_OPTIONS + from .. import mgr + cls.mgr = mgr + + # Populate real endpoint map + from ..controllers import load_controllers + cls.controllers = load_controllers() + + # Initialize FeatureToggles plugin + cls.plugin = FeatureToggles() + cls.CONFIG_KEY_DICT.update( + {k['name']: k['default'] for k in cls.plugin.get_options()}) + cls.plugin.setup() + + def test_filter_request_when_all_features_enabled(self): + """ + This test iterates over all the registered endpoints to ensure that, with default + feature toggles, none is disabled. + """ + import cherrypy + + request = Mock() + for controller in self.controllers: + request.path_info = controller.get_path() + try: + self.plugin.filter_request_before_handler(request) + except cherrypy.HTTPError: + self.fail("Request filtered {} and it shouldn't".format( + request.path_info)) + + def test_filter_request_when_some_feature_enabled(self): + """ + This test focuses on a single feature and checks whether it's actually + disabled + """ + import cherrypy + + self.plugin.register_commands()['handle_command']( + self.mgr, 'disable', ['cephfs']) + + with patch.object(self.plugin, '_get_feature_from_request', + return_value=Features.CEPHFS): + with self.assertRaises(cherrypy.HTTPError): + request = Mock() + self.plugin.filter_request_before_handler(request) diff --git a/src/pybind/mgr/dashboard/tests/test_ganesha.py b/src/pybind/mgr/dashboard/tests/test_ganesha.py new file mode 100644 index 00000000..5dced126 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_ganesha.py @@ -0,0 +1,642 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import unittest + +from mock import MagicMock, Mock + +import orchestrator +from . import KVStoreMockMixin +from .. import mgr +from ..settings import Settings +from ..services import ganesha +from ..services.ganesha import GaneshaConf, Export, GaneshaConfParser + + +class GaneshaConfTest(unittest.TestCase, KVStoreMockMixin): + export_1 = """ +EXPORT { + Export_ID=1; + Protocols = 4; + Path = /; + Pseudo = /cephfs_a/; + Access_Type = RW; + Protocols = 4; + Attr_Expiration_Time = 0; + # Delegations = R; + # Squash = root; + + FSAL { + Name = CEPH; + Filesystem = "a"; + User_Id = "ganesha"; + # Secret_Access_Key = "YOUR SECRET KEY HERE"; + } + + CLIENT + { + Clients = 192.168.0.10, 192.168.1.0/8; + Squash = None; + } + + CLIENT + { + Clients = 192.168.0.0/16; + Squash = All; + Access_Type = RO; + } +} +""" + + export_2 = """ +EXPORT +{ + Export_ID=2; + + Path = "/"; + + Pseudo = "/rgw"; + + Access_Type = RW; + + squash = AllAnonymous; + + Protocols = 4, 3; + + Transports = TCP, UDP; + + FSAL { + Name = RGW; + User_Id = "testuser"; + Access_Key_Id ="access_key"; + Secret_Access_Key = "secret_key"; + } +} +""" + + conf_nodea = ''' +%url rados://ganesha/ns/export-2 + +%url "rados://ganesha/ns/export-1"''' + + conf_nodeb = '%url "rados://ganesha/ns/export-1"' + + class RObject(object): + def __init__(self, key, raw): + self.key = key + self.raw = raw + + def read(self, _): + return self.raw.encode('utf-8') + + def stat(self): + return len(self.raw), None + + def _ioctx_write_full_mock(self, key, content): + if key not in self.temp_store: + self.temp_store[key] = GaneshaConfTest.RObject(key, + content.decode('utf-8')) + else: + self.temp_store[key].raw = content.decode('utf-8') + + def _ioctx_remove_mock(self, key): + del self.temp_store[key] + + def _ioctx_list_objects_mock(self): + return [obj for _, obj in self.temp_store.items()] + + def setUp(self): + self.mock_kv_store() + + Settings.GANESHA_CLUSTERS_RADOS_POOL_NAMESPACE = "ganesha/ns" + + self.temp_store = { + 'export-1': GaneshaConfTest.RObject("export-1", self.export_1), + 'conf-nodea': GaneshaConfTest.RObject("conf-nodea", self.conf_nodea), + 'export-2': GaneshaConfTest.RObject("export-2", self.export_2), + 'conf-nodeb': GaneshaConfTest.RObject("conf-nodeb", self.conf_nodeb) + } + + self.io_mock = MagicMock() + self.io_mock.list_objects.side_effect = self._ioctx_list_objects_mock + self.io_mock.write_full.side_effect = self._ioctx_write_full_mock + self.io_mock.remove_object.side_effect = self._ioctx_remove_mock + + ioctx_mock = MagicMock() + ioctx_mock.__enter__ = Mock(return_value=(self.io_mock)) + ioctx_mock.__exit__ = Mock(return_value=None) + + mgr.rados = MagicMock() + mgr.rados.open_ioctx.return_value = ioctx_mock + + # pylint: disable=protected-access + mgr._select_orchestrator.side_effect = orchestrator.NoOrchestrator() + + ganesha.CephX = MagicMock() + ganesha.CephX.list_clients.return_value = ['ganesha'] + ganesha.CephX.get_client_key.return_value = 'ganesha' + + ganesha.CephFS = MagicMock() + + def test_export_parser_1(self): + blocks = GaneshaConfParser(self.export_1).parse() + self.assertIsInstance(blocks, list) + self.assertEqual(len(blocks), 1) + export = Export.from_export_block(blocks[0], '_default_', + GaneshaConf.ganesha_defaults({})) + + self.assertEqual(export.export_id, 1) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/cephfs_a") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "root_squash") + self.assertEqual(export.protocols, {4}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "CEPH") + self.assertEqual(export.fsal.user_id, "ganesha") + self.assertEqual(export.fsal.fs_name, "a") + self.assertEqual(export.fsal.sec_label_xattr, None) + self.assertEqual(len(export.clients), 2) + self.assertEqual(export.clients[0].addresses, + ["192.168.0.10", "192.168.1.0/8"]) + self.assertEqual(export.clients[0].squash, "no_root_squash") + self.assertIsNone(export.clients[0].access_type) + self.assertEqual(export.clients[1].addresses, ["192.168.0.0/16"]) + self.assertEqual(export.clients[1].squash, "all_squash") + self.assertEqual(export.clients[1].access_type, "RO") + self.assertEqual(export.cluster_id, '_default_') + self.assertEqual(export.attr_expiration_time, 0) + self.assertEqual(export.security_label, False) + + def test_export_parser_2(self): + blocks = GaneshaConfParser(self.export_2).parse() + self.assertIsInstance(blocks, list) + self.assertEqual(len(blocks), 1) + export = Export.from_export_block(blocks[0], '_default_', + GaneshaConf.ganesha_defaults({})) + + self.assertEqual(export.export_id, 2) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/rgw") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4, 3}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "RGW") + self.assertEqual(export.fsal.rgw_user_id, "testuser") + self.assertEqual(export.fsal.access_key, "access_key") + self.assertEqual(export.fsal.secret_key, "secret_key") + self.assertEqual(len(export.clients), 0) + self.assertEqual(export.cluster_id, '_default_') + + def test_daemon_conf_parser_a(self): + blocks = GaneshaConfParser(self.conf_nodea).parse() + self.assertIsInstance(blocks, list) + self.assertEqual(len(blocks), 2) + self.assertEqual(blocks[0]['block_name'], "%url") + self.assertEqual(blocks[0]['value'], "rados://ganesha/ns/export-2") + self.assertEqual(blocks[1]['block_name'], "%url") + self.assertEqual(blocks[1]['value'], "rados://ganesha/ns/export-1") + + def test_daemon_conf_parser_b(self): + blocks = GaneshaConfParser(self.conf_nodeb).parse() + self.assertIsInstance(blocks, list) + self.assertEqual(len(blocks), 1) + self.assertEqual(blocks[0]['block_name'], "%url") + self.assertEqual(blocks[0]['value'], "rados://ganesha/ns/export-1") + + def test_ganesha_conf(self): + ganesha_conf = GaneshaConf.instance('_default_') + exports = ganesha_conf.exports + + self.assertEqual(len(exports.items()), 2) + self.assertIn(1, exports) + self.assertIn(2, exports) + + # export_id = 1 asserts + export = exports[1] + self.assertEqual(export.export_id, 1) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/cephfs_a") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "root_squash") + self.assertEqual(export.protocols, {4}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "CEPH") + self.assertEqual(export.fsal.user_id, "ganesha") + self.assertEqual(export.fsal.fs_name, "a") + self.assertEqual(export.fsal.sec_label_xattr, None) + self.assertEqual(len(export.clients), 2) + self.assertEqual(export.clients[0].addresses, + ["192.168.0.10", "192.168.1.0/8"]) + self.assertEqual(export.clients[0].squash, "no_root_squash") + self.assertIsNone(export.clients[0].access_type) + self.assertEqual(export.clients[1].addresses, ["192.168.0.0/16"]) + self.assertEqual(export.clients[1].squash, "all_squash") + self.assertEqual(export.clients[1].access_type, "RO") + self.assertEqual(export.attr_expiration_time, 0) + self.assertEqual(export.security_label, False) + + # export_id = 2 asserts + export = exports[2] + self.assertEqual(export.export_id, 2) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/rgw") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4, 3}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "RGW") + self.assertEqual(export.fsal.rgw_user_id, "testuser") + self.assertEqual(export.fsal.access_key, "access_key") + self.assertEqual(export.fsal.secret_key, "secret_key") + self.assertEqual(len(export.clients), 0) + + def test_config_dict(self): + conf = GaneshaConf.instance('_default_') + export = conf.exports[1] + ex_dict = export.to_dict() + self.assertDictEqual(ex_dict, { + 'daemons': ['nodea', 'nodeb'], + 'export_id': 1, + 'path': '/', + 'pseudo': '/cephfs_a', + 'cluster_id': '_default_', + 'tag': None, + 'access_type': 'RW', + 'squash': 'root_squash', + 'security_label': False, + 'protocols': [4], + 'transports': ['TCP', 'UDP'], + 'clients': [{ + 'addresses': ["192.168.0.10", "192.168.1.0/8"], + 'access_type': None, + 'squash': 'no_root_squash' + }, { + 'addresses': ["192.168.0.0/16"], + 'access_type': 'RO', + 'squash': 'all_squash' + }], + 'fsal': { + 'name': 'CEPH', + 'user_id': 'ganesha', + 'fs_name': 'a', + 'sec_label_xattr': None + } + }) + + export = conf.exports[2] + ex_dict = export.to_dict() + self.assertDictEqual(ex_dict, { + 'daemons': ['nodea'], + 'export_id': 2, + 'path': '/', + 'pseudo': '/rgw', + 'cluster_id': '_default_', + 'tag': None, + 'access_type': 'RW', + 'squash': 'all_squash', + 'security_label': False, + 'protocols': [3, 4], + 'transports': ['TCP', 'UDP'], + 'clients': [], + 'fsal': { + 'name': 'RGW', + 'rgw_user_id': 'testuser' + } + }) + + def test_config_from_dict(self): + export = Export.from_dict(1, { + 'daemons': ['nodea', 'nodeb'], + 'export_id': 1, + 'path': '/', + 'cluster_id': '_default_', + 'pseudo': '/cephfs_a', + 'tag': None, + 'access_type': 'RW', + 'squash': 'root_squash', + 'security_label': True, + 'protocols': [4], + 'transports': ['TCP', 'UDP'], + 'clients': [{ + 'addresses': ["192.168.0.10", "192.168.1.0/8"], + 'access_type': None, + 'squash': 'no_root_squash' + }, { + 'addresses': ["192.168.0.0/16"], + 'access_type': 'RO', + 'squash': 'all_squash' + }], + 'fsal': { + 'name': 'CEPH', + 'user_id': 'ganesha', + 'fs_name': 'a', + 'sec_label_xattr': 'security.selinux' + } + }) + + self.assertEqual(export.export_id, 1) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/cephfs_a") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "root_squash") + self.assertEqual(export.protocols, {4}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "CEPH") + self.assertEqual(export.fsal.user_id, "ganesha") + self.assertEqual(export.fsal.fs_name, "a") + self.assertEqual(export.fsal.sec_label_xattr, 'security.selinux') + self.assertEqual(len(export.clients), 2) + self.assertEqual(export.clients[0].addresses, + ["192.168.0.10", "192.168.1.0/8"]) + self.assertEqual(export.clients[0].squash, "no_root_squash") + self.assertIsNone(export.clients[0].access_type) + self.assertEqual(export.clients[1].addresses, ["192.168.0.0/16"]) + self.assertEqual(export.clients[1].squash, "all_squash") + self.assertEqual(export.clients[1].access_type, "RO") + self.assertEqual(export.daemons, {"nodeb", "nodea"}) + self.assertEqual(export.cluster_id, '_default_') + self.assertEqual(export.attr_expiration_time, 0) + self.assertEqual(export.security_label, True) + + export = Export.from_dict(2, { + 'daemons': ['nodea'], + 'export_id': 2, + 'path': '/', + 'pseudo': '/rgw', + 'cluster_id': '_default_', + 'tag': None, + 'access_type': 'RW', + 'squash': 'all_squash', + 'security_label': False, + 'protocols': [4, 3], + 'transports': ['TCP', 'UDP'], + 'clients': [], + 'fsal': { + 'name': 'RGW', + 'rgw_user_id': 'testuser' + } + }) + + self.assertEqual(export.export_id, 2) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/rgw") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4, 3}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "RGW") + self.assertEqual(export.fsal.rgw_user_id, "testuser") + self.assertIsNone(export.fsal.access_key) + self.assertIsNone(export.fsal.secret_key) + self.assertEqual(len(export.clients), 0) + self.assertEqual(export.daemons, {"nodea"}) + self.assertEqual(export.cluster_id, '_default_') + + def test_gen_raw_config(self): + conf = GaneshaConf.instance('_default_') + # pylint: disable=W0212 + export = conf.exports[1] + del conf.exports[1] + conf._save_export(export) + conf = GaneshaConf.instance('_default_') + exports = conf.exports + self.assertEqual(len(exports.items()), 2) + self.assertIn(1, exports) + self.assertIn(2, exports) + + # export_id = 1 asserts + export = exports[1] + self.assertEqual(export.export_id, 1) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/cephfs_a") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "root_squash") + self.assertEqual(export.protocols, {4}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "CEPH") + self.assertEqual(export.fsal.user_id, "ganesha") + self.assertEqual(export.fsal.fs_name, "a") + self.assertEqual(export.fsal.sec_label_xattr, None) + self.assertEqual(len(export.clients), 2) + self.assertEqual(export.clients[0].addresses, + ["192.168.0.10", "192.168.1.0/8"]) + self.assertEqual(export.clients[0].squash, "no_root_squash") + self.assertIsNone(export.clients[0].access_type) + self.assertEqual(export.clients[1].addresses, ["192.168.0.0/16"]) + self.assertEqual(export.clients[1].squash, "all_squash") + self.assertEqual(export.clients[1].access_type, "RO") + self.assertEqual(export.daemons, {"nodeb", "nodea"}) + self.assertEqual(export.cluster_id, '_default_') + self.assertEqual(export.attr_expiration_time, 0) + self.assertEqual(export.security_label, False) + + # export_id = 2 asserts + export = exports[2] + self.assertEqual(export.export_id, 2) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/rgw") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4, 3}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "RGW") + self.assertEqual(export.fsal.rgw_user_id, "testuser") + self.assertEqual(export.fsal.access_key, "access_key") + self.assertEqual(export.fsal.secret_key, "secret_key") + self.assertEqual(len(export.clients), 0) + self.assertEqual(export.daemons, {"nodea"}) + self.assertEqual(export.cluster_id, '_default_') + + def test_update_export(self): + ganesha.RgwClient = MagicMock() + admin_inst_mock = MagicMock() + admin_inst_mock.get_user_keys.return_value = { + 'access_key': 'access_key', + 'secret_key': 'secret_key' + } + ganesha.RgwClient.admin_instance.return_value = admin_inst_mock + + conf = GaneshaConf.instance('_default_') + conf.update_export({ + 'export_id': 2, + 'daemons': ["nodeb"], + 'path': 'bucket', + 'pseudo': '/rgw/bucket', + 'cluster_id': '_default_', + 'tag': 'bucket_tag', + 'access_type': 'RW', + 'squash': 'all_squash', + 'security_label': False, + 'protocols': [4, 3], + 'transports': ['TCP', 'UDP'], + 'clients': [{ + 'addresses': ["192.168.0.0/16"], + 'access_type': None, + 'squash': None + }], + 'fsal': { + 'name': 'RGW', + 'rgw_user_id': 'testuser' + } + }) + + conf = GaneshaConf.instance('_default_') + export = conf.get_export(2) + self.assertEqual(export.export_id, 2) + self.assertEqual(export.path, "bucket") + self.assertEqual(export.pseudo, "/rgw/bucket") + self.assertEqual(export.tag, "bucket_tag") + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4, 3}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "RGW") + self.assertEqual(export.fsal.rgw_user_id, "testuser") + self.assertEqual(export.fsal.access_key, "access_key") + self.assertEqual(export.fsal.secret_key, "secret_key") + self.assertEqual(len(export.clients), 1) + self.assertEqual(export.clients[0].addresses, ["192.168.0.0/16"]) + self.assertIsNone(export.clients[0].squash) + self.assertIsNone(export.clients[0].access_type) + self.assertEqual(export.daemons, {"nodeb"}) + self.assertEqual(export.cluster_id, '_default_') + + def test_remove_export(self): + conf = GaneshaConf.instance('_default_') + conf.remove_export(1) + exports = conf.list_exports() + self.assertEqual(len(exports), 1) + self.assertEqual(2, exports[0].export_id) + export = conf.get_export(2) + self.assertEqual(export.export_id, 2) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/rgw") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4, 3}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "RGW") + self.assertEqual(export.fsal.rgw_user_id, "testuser") + self.assertEqual(export.fsal.access_key, "access_key") + self.assertEqual(export.fsal.secret_key, "secret_key") + self.assertEqual(len(export.clients), 0) + self.assertEqual(export.daemons, {"nodea"}) + self.assertEqual(export.cluster_id, '_default_') + + def test_create_export_rgw(self): + ganesha.RgwClient = MagicMock() + admin_inst_mock = MagicMock() + admin_inst_mock.get_user_keys.return_value = { + 'access_key': 'access_key2', + 'secret_key': 'secret_key2' + } + ganesha.RgwClient.admin_instance.return_value = admin_inst_mock + + conf = GaneshaConf.instance('_default_') + ex_id = conf.create_export({ + 'daemons': ["nodeb"], + 'path': 'bucket', + 'pseudo': '/rgw/bucket', + 'tag': 'bucket_tag', + 'cluster_id': '_default_', + 'access_type': 'RW', + 'squash': 'all_squash', + 'security_label': False, + 'protocols': [4, 3], + 'transports': ['TCP', 'UDP'], + 'clients': [{ + 'addresses': ["192.168.0.0/16"], + 'access_type': None, + 'squash': None + }], + 'fsal': { + 'name': 'RGW', + 'rgw_user_id': 'testuser' + } + }) + + conf = GaneshaConf.instance('_default_') + exports = conf.list_exports() + self.assertEqual(len(exports), 3) + export = conf.get_export(ex_id) + self.assertEqual(export.export_id, ex_id) + self.assertEqual(export.path, "bucket") + self.assertEqual(export.pseudo, "/rgw/bucket") + self.assertEqual(export.tag, "bucket_tag") + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4, 3}) + self.assertEqual(export.transports, {"TCP", "UDP"}) + self.assertEqual(export.fsal.name, "RGW") + self.assertEqual(export.fsal.rgw_user_id, "testuser") + self.assertEqual(export.fsal.access_key, "access_key2") + self.assertEqual(export.fsal.secret_key, "secret_key2") + self.assertEqual(len(export.clients), 1) + self.assertEqual(export.clients[0].addresses, ["192.168.0.0/16"]) + self.assertIsNone(export.clients[0].squash) + self.assertIsNone(export.clients[0].access_type) + self.assertEqual(export.daemons, {"nodeb"}) + self.assertEqual(export.cluster_id, '_default_') + + def test_create_export_cephfs(self): + ganesha.CephX = MagicMock() + ganesha.CephX.list_clients.return_value = ["fs"] + ganesha.CephX.get_client_key.return_value = "fs_key" + + ganesha.CephFS = MagicMock() + ganesha.CephFS.dir_exists.return_value = True + + conf = GaneshaConf.instance('_default_') + ex_id = conf.create_export({ + 'daemons': ['nodea', 'nodeb'], + 'path': '/', + 'pseudo': '/cephfs2', + 'cluster_id': '_default_', + 'tag': None, + 'access_type': 'RW', + 'squash': 'all_squash', + 'security_label': True, + 'protocols': [4], + 'transports': ['TCP'], + 'clients': [], + 'fsal': { + 'name': 'CEPH', + 'user_id': 'fs', + 'fs_name': None, + 'sec_label_xattr': 'security.selinux' + } + }) + + conf = GaneshaConf.instance('_default_') + exports = conf.list_exports() + self.assertEqual(len(exports), 3) + export = conf.get_export(ex_id) + self.assertEqual(export.export_id, ex_id) + self.assertEqual(export.path, "/") + self.assertEqual(export.pseudo, "/cephfs2") + self.assertIsNone(export.tag) + self.assertEqual(export.access_type, "RW") + self.assertEqual(export.squash, "all_squash") + self.assertEqual(export.protocols, {4}) + self.assertEqual(export.transports, {"TCP"}) + self.assertEqual(export.fsal.name, "CEPH") + self.assertEqual(export.fsal.user_id, "fs") + self.assertEqual(export.fsal.cephx_key, "fs_key") + self.assertEqual(export.fsal.sec_label_xattr, "security.selinux") + self.assertIsNone(export.fsal.fs_name) + self.assertEqual(len(export.clients), 0) + self.assertEqual(export.daemons, {"nodeb", "nodea"}) + self.assertEqual(export.cluster_id, '_default_') + self.assertEqual(export.attr_expiration_time, 0) + self.assertEqual(export.security_label, True) diff --git a/src/pybind/mgr/dashboard/tests/test_grafana.py b/src/pybind/mgr/dashboard/tests/test_grafana.py new file mode 100644 index 00000000..02597dfe --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_grafana.py @@ -0,0 +1,116 @@ +import json +import unittest + +try: + from mock import patch +except ImportError: + from unittest.mock import patch + +from . import ControllerTestCase, KVStoreMockMixin +from ..controllers.grafana import Grafana +from ..grafana import GrafanaRestClient +from ..settings import Settings + + +class GrafanaTest(ControllerTestCase, KVStoreMockMixin): + @classmethod + def setup_server(cls): + # pylint: disable=protected-access + Grafana._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([Grafana]) + + def setUp(self): + self.mock_kv_store() + + @staticmethod + def server_settings( + url='http://localhost:3000', + user='admin', + password='admin', + ): + if url is not None: + Settings.GRAFANA_API_URL = url + if user is not None: + Settings.GRAFANA_API_USERNAME = user + if password is not None: + Settings.GRAFANA_API_PASSWORD = password + + def test_url(self): + self.server_settings() + self._get('/api/grafana/url') + self.assertStatus(200) + self.assertJsonBody({'instance': 'http://localhost:3000'}) + + def test_validation(self): + self.server_settings() + self._get('/api/grafana/validation/foo') + self.assertStatus(500) + + def test_dashboards_unavailable_no_url(self): + self.server_settings(url=None) + self._post('/api/grafana/dashboards') + self.assertStatus(500) + + def test_dashboards_unavailable_no_user(self): + self.server_settings(user=None) + self._post('/api/grafana/dashboards') + self.assertStatus(500) + + def test_dashboards_unavailable_no_password(self): + self.server_settings(password=None) + self._post('/api/grafana/dashboards') + self.assertStatus(500) + + +class GrafanaRestClientTest(unittest.TestCase, KVStoreMockMixin): + headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + } + payload = json.dumps({ + 'dashboard': 'foo', + 'overwrite': True + }) + + def setUp(self): + self.mock_kv_store() + Settings.GRAFANA_API_URL = 'https://foo/bar' + Settings.GRAFANA_API_USERNAME = 'xyz' + Settings.GRAFANA_API_PASSWORD = 'abc' + Settings.GRAFANA_API_SSL_VERIFY = True + + def test_ssl_verify_url_validation(self): + with patch('requests.request') as mock_request: + rest_client = GrafanaRestClient() + rest_client.url_validation('FOO', Settings.GRAFANA_API_URL) + mock_request.assert_called_with('FOO', Settings.GRAFANA_API_URL, + verify=True) + + def test_no_ssl_verify_url_validation(self): + Settings.GRAFANA_API_SSL_VERIFY = False + with patch('requests.request') as mock_request: + rest_client = GrafanaRestClient() + rest_client.url_validation('BAR', Settings.GRAFANA_API_URL) + mock_request.assert_called_with('BAR', Settings.GRAFANA_API_URL, + verify=False) + + def test_ssl_verify_push_dashboard(self): + with patch('requests.post') as mock_request: + rest_client = GrafanaRestClient() + rest_client.push_dashboard('foo') + mock_request.assert_called_with( + Settings.GRAFANA_API_URL + '/api/dashboards/db', + auth=(Settings.GRAFANA_API_USERNAME, + Settings.GRAFANA_API_PASSWORD), + data=self.payload, headers=self.headers, verify=True) + + def test_no_ssl_verify_push_dashboard(self): + Settings.GRAFANA_API_SSL_VERIFY = False + with patch('requests.post') as mock_request: + rest_client = GrafanaRestClient() + rest_client.push_dashboard('foo') + mock_request.assert_called_with( + Settings.GRAFANA_API_URL + '/api/dashboards/db', + auth=(Settings.GRAFANA_API_USERNAME, + Settings.GRAFANA_API_PASSWORD), + data=self.payload, headers=self.headers, verify=False) diff --git a/src/pybind/mgr/dashboard/tests/test_home.py b/src/pybind/mgr/dashboard/tests/test_home.py new file mode 100644 index 00000000..c3088b7a --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_home.py @@ -0,0 +1,68 @@ +from __future__ import absolute_import + +import logging +import os + +try: + import mock +except ImportError: + import unittest.mock as mock + +from . import ControllerTestCase, FakeFsMixin +from .. import mgr + +from ..controllers.home import HomeController, LanguageMixin + +logger = logging.getLogger() + + +class HomeTest(ControllerTestCase, FakeFsMixin): + @classmethod + def setup_server(cls): + frontend_path = mgr.get_frontend_path() + cls.fs.reset() + cls.fs.create_dir(frontend_path) + cls.fs.create_file( + os.path.join(frontend_path, '..', 'package.json'), + contents='{"config":{"locale": "en-US"}}') + with mock.patch(cls.builtins_open, new=cls.f_open),\ + mock.patch('os.listdir', new=cls.f_os.listdir): + lang = LanguageMixin() + cls.fs.create_file( + os.path.join(lang.DEFAULT_LANGUAGE_PATH, 'index.html'), + contents='') + cls.setup_controllers([HomeController]) + + @mock.patch(FakeFsMixin.builtins_open, new=FakeFsMixin.f_open) + @mock.patch('os.stat', new=FakeFsMixin.f_os.stat) + @mock.patch('os.listdir', new=FakeFsMixin.f_os.listdir) + def test_home_default_lang(self): + self._get('/') + self.assertStatus(200) + logger.info(self.body) + self.assertIn('', self.body.decode('utf-8')) + + @mock.patch(FakeFsMixin.builtins_open, new=FakeFsMixin.f_open) + @mock.patch('os.stat', new=FakeFsMixin.f_os.stat) + @mock.patch('os.listdir', new=FakeFsMixin.f_os.listdir) + def test_home_uplevel_check(self): + self._get('/../../../../../../etc/shadow') + self.assertStatus(403) + + @mock.patch(FakeFsMixin.builtins_open, new=FakeFsMixin.f_open) + @mock.patch('os.stat', new=FakeFsMixin.f_os.stat) + @mock.patch('os.listdir', new=FakeFsMixin.f_os.listdir) + def test_home_en_us(self): + self._get('/', headers=[('Accept-Language', 'en-US')]) + self.assertStatus(200) + logger.info(self.body) + self.assertIn('', self.body.decode('utf-8')) + + @mock.patch(FakeFsMixin.builtins_open, new=FakeFsMixin.f_open) + @mock.patch('os.stat', new=FakeFsMixin.f_os.stat) + @mock.patch('os.listdir', new=FakeFsMixin.f_os.listdir) + def test_home_non_supported_lang(self): + self._get('/', headers=[('Accept-Language', 'NO-NO')]) + self.assertStatus(200) + logger.info(self.body) + self.assertIn('', self.body.decode('utf-8')) diff --git a/src/pybind/mgr/dashboard/tests/test_iscsi.py b/src/pybind/mgr/dashboard/tests/test_iscsi.py new file mode 100644 index 00000000..34d2f014 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_iscsi.py @@ -0,0 +1,998 @@ +# pylint: disable=too-many-public-methods, too-many-lines + +import copy +import errno +import json +import unittest + +try: + import mock +except ImportError: + import unittest.mock as mock + +from mgr_module import ERROR_MSG_NO_INPUT_FILE + +from . import CmdException, ControllerTestCase, CLICommandTestMixin, KVStoreMockMixin +from .. import mgr +from ..controllers.iscsi import Iscsi, IscsiTarget +from ..services.iscsi_client import IscsiClient +from ..services.orchestrator import OrchClient +from ..rest_client import RequestException + + +class IscsiTestCli(unittest.TestCase, CLICommandTestMixin): + + def setUp(self): + self.mock_kv_store() + # pylint: disable=protected-access + IscsiClientMock._instance = IscsiClientMock() + IscsiClient.instance = IscsiClientMock.instance + + def test_cli_add_gateway_invalid_url(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('iscsi-gateway-add', inbuf='http:/hello.com') + + self.assertEqual(ctx.exception.retcode, -errno.EINVAL) + self.assertEqual(str(ctx.exception), + "Invalid service URL 'http:/hello.com'. Valid format: " + "'://:@[:port]'.") + + def test_cli_add_gateway_empty_url(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('iscsi-gateway-add', inbuf='') + + self.assertEqual(ctx.exception.retcode, -errno.EINVAL) + self.assertEqual(str(ctx.exception), ERROR_MSG_NO_INPUT_FILE) + + def test_cli_add_gateway(self): + self.exec_cmd('iscsi-gateway-add', inbuf='https://admin:admin@10.17.5.1:5001') + self.exec_cmd('iscsi-gateway-add', inbuf='https://admin:admin@10.17.5.2:5001') + iscsi_config = json.loads(self.get_key("_iscsi_config")) + self.assertEqual(iscsi_config['gateways'], { + 'node1': { + 'service_url': 'https://admin:admin@10.17.5.1:5001' + }, + 'node2': { + 'service_url': 'https://admin:admin@10.17.5.2:5001' + } + }) + + def test_cli_remove_gateway(self): + self.test_cli_add_gateway() + self.exec_cmd('iscsi-gateway-rm', name='node1') + iscsi_config = json.loads(self.get_key("_iscsi_config")) + self.assertEqual(iscsi_config['gateways'], { + 'node2': { + 'service_url': 'https://admin:admin@10.17.5.2:5001' + } + }) + + +class IscsiTestController(ControllerTestCase, KVStoreMockMixin): + + @classmethod + def setup_server(cls): + OrchClient().available = lambda: False + mgr.rados.side_effect = None + # pylint: disable=protected-access + Iscsi._cp_config['tools.authenticate.on'] = False + IscsiTarget._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([Iscsi, IscsiTarget]) + + def setUp(self): + self.mock_kv_store() + self.CONFIG_KEY_DICT['_iscsi_config'] = ''' + { + "gateways": { + "node1": { + "service_url": "https://admin:admin@10.17.5.1:5001" + }, + "node2": { + "service_url": "https://admin:admin@10.17.5.2:5001" + } + } + } + ''' + # pylint: disable=protected-access + IscsiClientMock._instance = IscsiClientMock() + IscsiClient.instance = IscsiClientMock.instance + + def test_enable_discoveryauth(self): + discoveryauth = { + 'user': 'myiscsiusername', + 'password': 'myiscsipassword', + 'mutual_user': 'myiscsiusername2', + 'mutual_password': 'myiscsipassword2' + } + self._put('/api/iscsi/discoveryauth', discoveryauth) + self.assertStatus(200) + self.assertJsonBody(discoveryauth) + self._get('/api/iscsi/discoveryauth') + self.assertStatus(200) + self.assertJsonBody(discoveryauth) + + def test_bad_discoveryauth(self): + discoveryauth = { + 'user': 'myiscsiusername', + 'password': 'myiscsipasswordmyiscsipasswordmyiscsipassword', + 'mutual_user': '', + 'mutual_password': '' + } + put_response = { + 'detail': 'Bad authentication', + 'code': 'target_bad_auth', + 'component': 'iscsi' + } + get_response = { + 'user': '', + 'password': '', + 'mutual_user': '', + 'mutual_password': '' + } + self._put('/api/iscsi/discoveryauth', discoveryauth) + self.assertStatus(400) + self.assertJsonBody(put_response) + self._get('/api/iscsi/discoveryauth') + self.assertStatus(200) + self.assertJsonBody(get_response) + + def test_disable_discoveryauth(self): + discoveryauth = { + 'user': '', + 'password': '', + 'mutual_user': '', + 'mutual_password': '' + } + self._put('/api/iscsi/discoveryauth', discoveryauth) + self.assertStatus(200) + self.assertJsonBody(discoveryauth) + self._get('/api/iscsi/discoveryauth') + self.assertStatus(200) + self.assertJsonBody(discoveryauth) + + def test_list_empty(self): + self._get('/api/iscsi/target') + self.assertStatus(200) + self.assertJsonBody([]) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_list(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw1" + request = copy.deepcopy(iscsi_target_request) + request['target_iqn'] = target_iqn + self._task_post('/api/iscsi/target', request) + self.assertStatus(201) + self._get('/api/iscsi/target') + self.assertStatus(200) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + self.assertJsonBody([response]) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_create(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw2" + request = copy.deepcopy(iscsi_target_request) + request['target_iqn'] = target_iqn + self._task_post('/api/iscsi/target', request) + self.assertStatus(201) + self._get('/api/iscsi/target/{}'.format(request['target_iqn'])) + self.assertStatus(200) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + self.assertJsonBody(response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_delete(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw3" + request = copy.deepcopy(iscsi_target_request) + request['target_iqn'] = target_iqn + self._task_post('/api/iscsi/target', request) + self.assertStatus(201) + self._task_delete('/api/iscsi/target/{}'.format(request['target_iqn'])) + self.assertStatus(204) + self._get('/api/iscsi/target') + self.assertStatus(200) + self.assertJsonBody([]) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_add_client(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw4" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'].append( + { + "luns": [{"image": "lun1", "pool": "rbd"}], + "client_iqn": "iqn.1994-05.com.redhat:rh7-client3", + "auth": { + "password": "myiscsipassword5", + "user": "myiscsiusername5", + "mutual_password": "myiscsipassword6", + "mutual_user": "myiscsiusername6"} + }) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'].append( + { + "luns": [{"image": "lun1", "pool": "rbd"}], + "client_iqn": "iqn.1994-05.com.redhat:rh7-client3", + "auth": { + "password": "myiscsipassword5", + "user": "myiscsiusername5", + "mutual_password": "myiscsipassword6", + "mutual_user": "myiscsiusername6"}, + "info": { + "alias": "", + "ip_address": [], + "state": {} + } + }) + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_add_bad_client(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw4" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'].append( + { + "luns": [{"image": "lun1", "pool": "rbd"}], + "client_iqn": "iqn.1994-05.com.redhat:rh7-client4", + "auth": { + "password": "myiscsipassword7myiscsipassword7myiscsipasswo", + "user": "myiscsiusername7", + "mutual_password": "myiscsipassword8", + "mutual_user": "myiscsiusername8"} + }) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + + self._task_post('/api/iscsi/target', create_request) + self.assertStatus(201) + self._task_put('/api/iscsi/target/{}'.format(create_request['target_iqn']), update_request) + self.assertStatus(400) + self._get('/api/iscsi/target/{}'.format(update_request['new_target_iqn'])) + self.assertStatus(200) + self.assertJsonBody(response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_change_client_password(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw5" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'][0]['auth']['password'] = 'MyNewPassword' + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'][0]['auth']['password'] = 'MyNewPassword' + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_rename_client(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw6" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0' + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'][0]['client_iqn'] = 'iqn.1994-05.com.redhat:rh7-client0' + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_add_disk(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw7" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['disks'].append( + { + "image": "lun3", + "pool": "rbd", + "controls": {}, + "backstore": "user:rbd" + }) + update_request['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"}) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['disks'].append( + { + "image": "lun3", + "pool": "rbd", + "controls": {}, + "backstore": "user:rbd", + "wwn": "64af6678-9694-4367-bacc-f8eb0baa2", + "lun": 2 + + }) + response['clients'][0]['luns'].append({"image": "lun3", "pool": "rbd"}) + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_change_disk_image(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw8" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['disks'][0]['image'] = 'lun0' + update_request['clients'][0]['luns'][0]['image'] = 'lun0' + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['disks'][0]['image'] = 'lun0' + response['clients'][0]['luns'][0]['image'] = 'lun0' + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_change_disk_controls(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw9" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['disks'][0]['controls'] = {"qfull_timeout": 15} + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['disks'][0]['controls'] = {"qfull_timeout": 15} + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_rename_target(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw10" + new_target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw11" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = new_target_iqn + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = new_target_iqn + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_rename_group(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw12" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['groups'][0]['group_id'] = 'mygroup0' + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['groups'][0]['group_id'] = 'mygroup0' + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_add_client_to_group(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw13" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'].append( + { + "luns": [], + "client_iqn": "iqn.1994-05.com.redhat:rh7-client3", + "auth": { + "password": None, + "user": None, + "mutual_password": None, + "mutual_user": None} + }) + update_request['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3') + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'].append( + { + "luns": [], + "client_iqn": "iqn.1994-05.com.redhat:rh7-client3", + "auth": { + "password": None, + "user": None, + "mutual_password": None, + "mutual_user": None}, + "info": { + "alias": "", + "ip_address": [], + "state": {} + } + }) + response['groups'][0]['members'].append('iqn.1994-05.com.redhat:rh7-client3') + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_remove_client_from_group(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw14" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2') + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['groups'][0]['members'].remove('iqn.1994-05.com.redhat:rh7-client2') + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_remove_groups(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw15" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['groups'] = [] + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['groups'] = [] + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_add_client_to_multiple_groups(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw16" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + create_request['groups'].append(copy.deepcopy(create_request['groups'][0])) + create_request['groups'][1]['group_id'] = 'mygroup2' + self._task_post('/api/iscsi/target', create_request) + self.assertStatus(400) + self.assertJsonBody({ + 'detail': 'Each initiator can only be part of 1 group at a time', + 'code': 'initiator_in_multiple_groups', + 'component': 'iscsi' + }) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_remove_client_lun(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw17" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + create_request['clients'][0]['luns'] = [ + {"image": "lun1", "pool": "rbd"}, + {"image": "lun2", "pool": "rbd"}, + {"image": "lun3", "pool": "rbd"} + ] + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'][0]['luns'] = [ + {"image": "lun1", "pool": "rbd"}, + {"image": "lun3", "pool": "rbd"} + ] + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'][0]['luns'] = [ + {"image": "lun1", "pool": "rbd"}, + {"image": "lun3", "pool": "rbd"} + ] + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_change_client_auth(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw18" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'][0]['auth']['password'] = 'myiscsipasswordX' + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'][0]['auth']['password'] = 'myiscsipasswordX' + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_remove_client_logged_in(self, _validate_image_mock): + client_info = { + 'alias': '', + 'ip_address': [], + 'state': {'LOGGED_IN': ['node1']} + } + # pylint: disable=protected-access + IscsiClientMock._instance.clientinfo = client_info + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw19" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'].pop(0) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + for client in response['clients']: + client['info'] = client_info + update_response = { + 'detail': "Client 'iqn.1994-05.com.redhat:rh7-client' cannot be deleted until it's " + "logged out", + 'code': 'client_logged_in', + 'component': 'iscsi' + } + self._update_iscsi_target(create_request, update_request, 400, update_response, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_remove_client(self, _validate_image_mock): + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw20" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'].pop(0) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'].pop(0) + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_add_image_to_group_with_client_logged_in(self, _validate_image_mock): + client_info = { + 'alias': '', + 'ip_address': [], + 'state': {'LOGGED_IN': ['node1']} + } + new_disk = {"pool": "rbd", "image": "lun1"} + # pylint: disable=protected-access + IscsiClientMock._instance.clientinfo = client_info + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw21" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['groups'][0]['disks'].append(new_disk) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['groups'][0]['disks'].insert(0, new_disk) + for client in response['clients']: + client['info'] = client_info + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_add_image_to_initiator_with_client_logged_in(self, _validate_image_mock): + client_info = { + 'alias': '', + 'ip_address': [], + 'state': {'LOGGED_IN': ['node1']} + } + new_disk = {"pool": "rbd", "image": "lun2"} + # pylint: disable=protected-access + IscsiClientMock._instance.clientinfo = client_info + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw22" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['clients'][0]['luns'].append(new_disk) + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['clients'][0]['luns'].append(new_disk) + for client in response['clients']: + client['info'] = client_info + self._update_iscsi_target(create_request, update_request, 200, None, response) + + @mock.patch('dashboard.controllers.iscsi.IscsiTarget._validate_image') + def test_remove_image_from_group_with_client_logged_in(self, _validate_image_mock): + client_info = { + 'alias': '', + 'ip_address': [], + 'state': {'LOGGED_IN': ['node1']} + } + # pylint: disable=protected-access + IscsiClientMock._instance.clientinfo = client_info + target_iqn = "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw23" + create_request = copy.deepcopy(iscsi_target_request) + create_request['target_iqn'] = target_iqn + update_request = copy.deepcopy(create_request) + update_request['new_target_iqn'] = target_iqn + update_request['groups'][0]['disks'] = [] + response = copy.deepcopy(iscsi_target_response) + response['target_iqn'] = target_iqn + response['groups'][0]['disks'] = [] + for client in response['clients']: + client['info'] = client_info + self._update_iscsi_target(create_request, update_request, 200, None, response) + + def _update_iscsi_target(self, create_request, update_request, update_response_code, + update_response, response): + self._task_post('/api/iscsi/target', create_request) + self.assertStatus(201) + self._task_put('/api/iscsi/target/{}'.format(create_request['target_iqn']), update_request) + self.assertStatus(update_response_code) + self.assertJsonBody(update_response) + self._get('/api/iscsi/target/{}'.format(update_request['new_target_iqn'])) + self.assertStatus(200) + self.assertJsonBody(response) + + +iscsi_target_request = { + "target_iqn": "iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw", + "portals": [ + {"ip": "192.168.100.202", "host": "node2"}, + {"ip": "10.0.2.15", "host": "node2"}, + {"ip": "192.168.100.203", "host": "node3"} + ], + "disks": [ + {"image": "lun1", "pool": "rbd", "backstore": "user:rbd", + "controls": {"max_data_area_mb": 128}}, + {"image": "lun2", "pool": "rbd", "backstore": "user:rbd", + "controls": {"max_data_area_mb": 128}} + ], + "clients": [ + { + "luns": [{"image": "lun1", "pool": "rbd"}], + "client_iqn": "iqn.1994-05.com.redhat:rh7-client", + "auth": { + "password": "myiscsipassword1", + "user": "myiscsiusername1", + "mutual_password": "myiscsipassword2", + "mutual_user": "myiscsiusername2"} + }, + { + "luns": [], + "client_iqn": "iqn.1994-05.com.redhat:rh7-client2", + "auth": { + "password": "myiscsipassword3", + "user": "myiscsiusername3", + "mutual_password": "myiscsipassword4", + "mutual_user": "myiscsiusername4" + } + } + ], + "acl_enabled": True, + "auth": { + "password": "", + "user": "", + "mutual_password": "", + "mutual_user": ""}, + "target_controls": {}, + "groups": [ + { + "group_id": "mygroup", + "disks": [{"pool": "rbd", "image": "lun2"}], + "members": ["iqn.1994-05.com.redhat:rh7-client2"] + } + ] +} + +iscsi_target_response = { + 'target_iqn': 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw', + 'portals': [ + {'host': 'node2', 'ip': '10.0.2.15'}, + {'host': 'node2', 'ip': '192.168.100.202'}, + {'host': 'node3', 'ip': '192.168.100.203'} + ], + 'disks': [ + {'pool': 'rbd', 'image': 'lun1', 'backstore': 'user:rbd', + 'wwn': '64af6678-9694-4367-bacc-f8eb0baa0', 'lun': 0, + 'controls': {'max_data_area_mb': 128}}, + {'pool': 'rbd', 'image': 'lun2', 'backstore': 'user:rbd', + 'wwn': '64af6678-9694-4367-bacc-f8eb0baa1', 'lun': 1, + 'controls': {'max_data_area_mb': 128}} + ], + 'clients': [ + { + 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client', + 'luns': [{'pool': 'rbd', 'image': 'lun1'}], + 'auth': { + 'user': 'myiscsiusername1', + 'password': 'myiscsipassword1', + 'mutual_password': 'myiscsipassword2', + 'mutual_user': 'myiscsiusername2' + }, + 'info': { + 'alias': '', + 'ip_address': [], + 'state': {} + } + }, + { + 'client_iqn': 'iqn.1994-05.com.redhat:rh7-client2', + 'luns': [], + 'auth': { + 'user': 'myiscsiusername3', + 'password': 'myiscsipassword3', + 'mutual_password': 'myiscsipassword4', + 'mutual_user': 'myiscsiusername4' + }, + 'info': { + 'alias': '', + 'ip_address': [], + 'state': {} + } + } + ], + "acl_enabled": True, + "auth": { + "password": "", + "user": "", + "mutual_password": "", + "mutual_user": ""}, + 'groups': [ + { + 'group_id': 'mygroup', + 'disks': [{'pool': 'rbd', 'image': 'lun2'}], + 'members': ['iqn.1994-05.com.redhat:rh7-client2'] + } + ], + 'target_controls': {}, + 'info': { + 'num_sessions': 0 + } +} + + +class IscsiClientMock(object): + + _instance = None + + def __init__(self): + self.gateway_name = None + self.service_url = None + self.config = { + "created": "2019/01/17 08:57:16", + "discovery_auth": { + "username": "", + "password": "", + "password_encryption_enabled": False, + "mutual_username": "", + "mutual_password": "", + "mutual_password_encryption_enabled": False + }, + "disks": {}, + "epoch": 0, + "gateways": {}, + "targets": {}, + "updated": "", + "version": 11 + } + self.clientinfo = { + 'alias': '', + 'ip_address': [], + 'state': {} + } + + @classmethod + def instance(cls, gateway_name=None, service_url=None): + cls._instance.gateway_name = gateway_name + cls._instance.service_url = service_url + # pylint: disable=unused-argument + return cls._instance + + def ping(self): + return { + "message": "pong" + } + + def get_settings(self): + return { + "api_version": 2, + "backstores": [ + "user:rbd" + ], + "config": { + "minimum_gateways": 2 + }, + "default_backstore": "user:rbd", + "required_rbd_features": { + "rbd": 0, + "user:rbd": 4, + }, + "unsupported_rbd_features": { + "rbd": 88, + "user:rbd": 0, + }, + "disk_default_controls": { + "user:rbd": { + "hw_max_sectors": 1024, + "max_data_area_mb": 8, + "osd_op_timeout": 30, + "qfull_timeout": 5 + } + }, + "target_default_controls": { + "cmdsn_depth": 128, + "dataout_timeout": 20, + "first_burst_length": 262144, + "immediate_data": "Yes", + "initial_r2t": "Yes", + "max_burst_length": 524288, + "max_outstanding_r2t": 1, + "max_recv_data_segment_length": 262144, + "max_xmit_data_segment_length": 262144, + "nopin_response_timeout": 5, + "nopin_timeout": 5 + } + } + + def get_config(self): + return copy.deepcopy(self.config) + + def create_target(self, target_iqn, target_controls): + self.config['targets'][target_iqn] = { + "clients": {}, + "acl_enabled": True, + "auth": { + "username": "", + "password": "", + "password_encryption_enabled": False, + "mutual_username": "", + "mutual_password": "", + "mutual_password_encryption_enabled": False + }, + "controls": target_controls, + "created": "2019/01/17 09:22:34", + "disks": {}, + "groups": {}, + "portals": {} + } + + def create_gateway(self, target_iqn, gateway_name, ip_addresses): + target_config = self.config['targets'][target_iqn] + if 'ip_list' not in target_config: + target_config['ip_list'] = [] + target_config['ip_list'] += ip_addresses + target_config['portals'][gateway_name] = { + "portal_ip_addresses": ip_addresses + } + + def delete_gateway(self, target_iqn, gateway_name): + target_config = self.config['targets'][target_iqn] + portal_config = target_config['portals'][gateway_name] + for ip in portal_config['portal_ip_addresses']: + target_config['ip_list'].remove(ip) + target_config['portals'].pop(gateway_name) + + def create_disk(self, pool, image, backstore, wwn): + if wwn is None: + wwn = '64af6678-9694-4367-bacc-f8eb0baa' + str(len(self.config['disks'])) + image_id = '{}/{}'.format(pool, image) + self.config['disks'][image_id] = { + "pool": pool, + "image": image, + "backstore": backstore, + "controls": {}, + "wwn": wwn + } + + def create_target_lun(self, target_iqn, image_id, lun): + target_config = self.config['targets'][target_iqn] + if lun is None: + lun = len(target_config['disks']) + target_config['disks'][image_id] = { + "lun_id": lun + } + self.config['disks'][image_id]['owner'] = list(target_config['portals'].keys())[0] + + def reconfigure_disk(self, pool, image, controls): + image_id = '{}/{}'.format(pool, image) + settings = self.get_settings() + backstore = self.config['disks'][image_id]['backstore'] + disk_default_controls = settings['disk_default_controls'][backstore] + new_controls = {} + for control_k, control_v in controls.items(): + if control_v != disk_default_controls[control_k]: + new_controls[control_k] = control_v + self.config['disks'][image_id]['controls'] = new_controls + + def create_client(self, target_iqn, client_iqn): + target_config = self.config['targets'][target_iqn] + target_config['clients'][client_iqn] = { + "auth": { + "username": "", + "password": "", + "password_encryption_enabled": False, + "mutual_username": "", + "mutual_password": "", + "mutual_password_encryption_enabled": False + }, + "group_name": "", + "luns": {} + } + + def create_client_lun(self, target_iqn, client_iqn, image_id): + target_config = self.config['targets'][target_iqn] + target_config['clients'][client_iqn]['luns'][image_id] = {} + + def delete_client_lun(self, target_iqn, client_iqn, image_id): + target_config = self.config['targets'][target_iqn] + del target_config['clients'][client_iqn]['luns'][image_id] + + def create_client_auth(self, target_iqn, client_iqn, user, password, m_user, m_password): + target_config = self.config['targets'][target_iqn] + target_config['clients'][client_iqn]['auth']['username'] = user + target_config['clients'][client_iqn]['auth']['password'] = password + target_config['clients'][client_iqn]['auth']['mutual_username'] = m_user + target_config['clients'][client_iqn]['auth']['mutual_password'] = m_password + + def create_group(self, target_iqn, group_name, members, image_ids): + target_config = self.config['targets'][target_iqn] + target_config['groups'][group_name] = { + "disks": {}, + "members": [] + } + for image_id in image_ids: + target_config['groups'][group_name]['disks'][image_id] = {} + target_config['groups'][group_name]['members'] = members + + def update_group(self, target_iqn, group_name, members, image_ids): + target_config = self.config['targets'][target_iqn] + group = target_config['groups'][group_name] + old_members = group['members'] + disks = group['disks'] + target_config['groups'][group_name] = { + "disks": {}, + "members": [] + } + + for image_id in disks.keys(): + if image_id not in image_ids: + target_config['groups'][group_name]['disks'][image_id] = {} + + new_members = [] + for member_iqn in old_members: + if member_iqn not in members: + new_members.append(member_iqn) + target_config['groups'][group_name]['members'] = new_members + + def delete_group(self, target_iqn, group_name): + target_config = self.config['targets'][target_iqn] + del target_config['groups'][group_name] + + def delete_client(self, target_iqn, client_iqn): + target_config = self.config['targets'][target_iqn] + del target_config['clients'][client_iqn] + + def delete_target_lun(self, target_iqn, image_id): + target_config = self.config['targets'][target_iqn] + target_config['disks'].pop(image_id) + del self.config['disks'][image_id]['owner'] + + def delete_disk(self, pool, image): + image_id = '{}/{}'.format(pool, image) + del self.config['disks'][image_id] + + def delete_target(self, target_iqn): + del self.config['targets'][target_iqn] + + def get_ip_addresses(self): + ips = { + 'node1': ['192.168.100.201'], + 'node2': ['192.168.100.202', '10.0.2.15'], + 'node3': ['192.168.100.203'] + } + return {'data': ips[self.gateway_name]} + + def get_hostname(self): + hostnames = { + 'https://admin:admin@10.17.5.1:5001': 'node1', + 'https://admin:admin@10.17.5.2:5001': 'node2', + 'https://admin:admin@10.17.5.3:5001': 'node3' + } + if self.service_url not in hostnames: + raise RequestException('No route to host') + return {'data': hostnames[self.service_url]} + + def update_discoveryauth(self, user, password, mutual_user, mutual_password): + self.config['discovery_auth']['username'] = user + self.config['discovery_auth']['password'] = password + self.config['discovery_auth']['mutual_username'] = mutual_user + self.config['discovery_auth']['mutual_password'] = mutual_password + + def update_targetacl(self, target_iqn, action): + self.config['targets'][target_iqn]['acl_enabled'] = (action == 'enable_acl') + + def update_targetauth(self, target_iqn, user, password, mutual_user, mutual_password): + target_config = self.config['targets'][target_iqn] + target_config['auth']['username'] = user + target_config['auth']['password'] = password + target_config['auth']['mutual_username'] = mutual_user + target_config['auth']['mutual_password'] = mutual_password + + def get_targetinfo(self, target_iqn): + # pylint: disable=unused-argument + return { + 'num_sessions': 0 + } + + def get_clientinfo(self, target_iqn, client_iqn): + # pylint: disable=unused-argument + return self.clientinfo diff --git a/src/pybind/mgr/dashboard/tests/test_notification.py b/src/pybind/mgr/dashboard/tests/test_notification.py new file mode 100644 index 00000000..185ddc12 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_notification.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import random +import time +import unittest + + +from ..tools import NotificationQueue + + +class Listener(object): + # pylint: disable=too-many-instance-attributes + def __init__(self): + self.type1 = [] + self.type1_ts = [] + self.type2 = [] + self.type2_ts = [] + self.type1_3 = [] + self.type1_3_ts = [] + self.all = [] + self.all_ts = [] + + def register(self): + NotificationQueue.register(self.log_type1, 'type1', priority=90) + NotificationQueue.register(self.log_type2, 'type2') + NotificationQueue.register(self.log_type1_3, ['type1', 'type3']) + NotificationQueue.register(self.log_all, priority=50) + + # these should be ignored by the queue + NotificationQueue.register(self.log_type1, 'type1') + NotificationQueue.register(self.log_type1_3, ['type1', 'type3']) + NotificationQueue.register(self.log_all) + + def log_type1(self, val): + self.type1_ts.append(time.time()) + self.type1.append(val) + + def log_type2(self, val): + self.type2_ts.append(time.time()) + self.type2.append(val) + + def log_type1_3(self, val): + self.type1_3_ts.append(time.time()) + self.type1_3.append(val) + + def log_all(self, val): + self.all_ts.append(time.time()) + self.all.append(val) + + def clear(self): + self.type1 = [] + self.type1_ts = [] + self.type2 = [] + self.type2_ts = [] + self.type1_3 = [] + self.type1_3_ts = [] + self.all = [] + self.all_ts = [] + NotificationQueue.deregister(self.log_type1, 'type1') + NotificationQueue.deregister(self.log_type2, 'type2') + NotificationQueue.deregister(self.log_type1_3, ['type1', 'type3']) + NotificationQueue.deregister(self.log_all) + + +class NotificationQueueTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.listener = Listener() + + def setUp(self): + self.listener.register() + + def tearDown(self): + self.listener.clear() + + def test_invalid_register(self): + with self.assertRaises(Exception) as ctx: + NotificationQueue.register(None, 1) + self.assertEqual(str(ctx.exception), + "n_types param is neither a string nor a list") + + def test_notifications(self): + NotificationQueue.start_queue() + NotificationQueue.new_notification('type1', 1) + NotificationQueue.new_notification('type2', 2) + NotificationQueue.new_notification('type3', 3) + NotificationQueue.stop() + self.assertEqual(self.listener.type1, [1]) + self.assertEqual(self.listener.type2, [2]) + self.assertEqual(self.listener.type1_3, [1, 3]) + self.assertEqual(self.listener.all, [1, 2, 3]) + + # validate priorities + self.assertLessEqual(self.listener.type1_3_ts[0], self.listener.all_ts[0]) + self.assertLessEqual(self.listener.all_ts[0], self.listener.type1_ts[0]) + self.assertLessEqual(self.listener.type2_ts[0], self.listener.all_ts[1]) + self.assertLessEqual(self.listener.type1_3_ts[1], self.listener.all_ts[2]) + + def test_notifications2(self): + NotificationQueue.start_queue() + for i in range(0, 600): + typ = "type{}".format(i % 3 + 1) + if random.random() < 0.5: + time.sleep(0.002) + NotificationQueue.new_notification(typ, i) + NotificationQueue.stop() + for i in range(0, 600): + typ = i % 3 + 1 + if typ == 1: + self.assertIn(i, self.listener.type1) + self.assertIn(i, self.listener.type1_3) + elif typ == 2: + self.assertIn(i, self.listener.type2) + elif typ == 3: + self.assertIn(i, self.listener.type1_3) + self.assertIn(i, self.listener.all) + + self.assertEqual(len(self.listener.type1), 200) + self.assertEqual(len(self.listener.type2), 200) + self.assertEqual(len(self.listener.type1_3), 400) + self.assertEqual(len(self.listener.all), 600) + + def test_deregister(self): + NotificationQueue.start_queue() + NotificationQueue.new_notification('type1', 1) + NotificationQueue.new_notification('type3', 3) + NotificationQueue.stop() + self.assertEqual(self.listener.type1, [1]) + self.assertEqual(self.listener.type1_3, [1, 3]) + + NotificationQueue.start_queue() + NotificationQueue.deregister(self.listener.log_type1_3, ['type1']) + NotificationQueue.new_notification('type1', 4) + NotificationQueue.new_notification('type3', 5) + NotificationQueue.stop() + self.assertEqual(self.listener.type1, [1, 4]) + self.assertEqual(self.listener.type1_3, [1, 3, 5]) diff --git a/src/pybind/mgr/dashboard/tests/test_osd.py b/src/pybind/mgr/dashboard/tests/test_osd.py new file mode 100644 index 00000000..0f24d25e --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_osd.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import uuid +from contextlib import contextmanager + +from mock import patch + +from . import ControllerTestCase +from ..controllers.osd import Osd +from .. import mgr +from .helper import update_dict + +try: + from typing import List, Dict, Any # pylint: disable=unused-import +except ImportError: + pass # Only requried for type hints + + +class OsdHelper(object): + DEFAULT_OSD_IDS = [0, 1, 2] + + @staticmethod + def _gen_osdmap_tree_node(node_id, node_type, children=None, update_data=None): + # type: (int, str, List[int], Dict[str, Any]) -> Dict[str, Any] + assert node_type in ['root', 'host', 'osd'] + if node_type in ['root', 'host']: + assert children is not None + + node_types = { + 'root': { + 'id': node_id, + 'name': 'default', + 'type': 'root', + 'type_id': 10, + 'children': children, + }, + 'host': { + 'id': node_id, + 'name': 'ceph-1', + 'type': 'host', + 'type_id': 1, + 'pool_weights': {}, + 'children': children, + }, + 'osd': { + 'id': node_id, + 'device_class': 'hdd', + 'type': 'osd', + 'type_id': 0, + 'crush_weight': 0.009796142578125, + 'depth': 2, + 'pool_weights': {}, + 'exists': 1, + 'status': 'up', + 'reweight': 1.0, + 'primary_affinity': 1.0, + 'name': 'osd.{}'.format(node_id), + } + } + node = node_types[node_type] + + return update_dict(node, update_data) if update_data else node + + @staticmethod + def _gen_osd_stats(osd_id, update_data=None): + # type: (int, Dict[str, Any]) -> Dict[str, Any] + stats = { + 'osd': osd_id, + 'up_from': 11, + 'seq': 47244640581, + 'num_pgs': 50, + 'kb': 10551288, + 'kb_used': 1119736, + 'kb_used_data': 5504, + 'kb_used_omap': 0, + 'kb_used_meta': 1048576, + 'kb_avail': 9431552, + 'statfs': { + 'total': 10804518912, + 'available': 9657909248, + 'internally_reserved': 1073741824, + 'allocated': 5636096, + 'data_stored': 102508, + 'data_compressed': 0, + 'data_compressed_allocated': 0, + 'data_compressed_original': 0, + 'omap_allocated': 0, + 'internal_metadata': 1073741824 + }, + 'hb_peers': [0, 1], + 'snap_trim_queue_len': 0, + 'num_snap_trimming': 0, + 'op_queue_age_hist': { + 'histogram': [], + 'upper_bound': 1 + }, + 'perf_stat': { + 'commit_latency_ms': 0.0, + 'apply_latency_ms': 0.0, + 'commit_latency_ns': 0, + 'apply_latency_ns': 0 + }, + 'alerts': [], + } + return stats if not update_data else update_dict(stats, update_data) + + @staticmethod + def _gen_osd_map_osd(osd_id): + # type: (int) -> Dict[str, Any] + return { + 'osd': osd_id, + 'up': 1, + 'in': 1, + 'weight': 1.0, + 'primary_affinity': 1.0, + 'last_clean_begin': 0, + 'last_clean_end': 0, + 'up_from': 5, + 'up_thru': 21, + 'down_at': 0, + 'lost_at': 0, + 'public_addrs': { + 'addrvec': [{ + 'type': 'v2', + 'nonce': 1302, + 'addr': '172.23.0.2:6802' + }, { + 'type': 'v1', + 'nonce': 1302, + 'addr': '172.23.0.2:6803' + }] + }, + 'cluster_addrs': { + 'addrvec': [{ + 'type': 'v2', + 'nonce': 1302, + 'addr': '172.23.0.2:6804' + }, { + 'type': 'v1', + 'nonce': 1302, + 'addr': '172.23.0.2:6805' + }] + }, + 'heartbeat_back_addrs': { + 'addrvec': [{ + 'type': 'v2', + 'nonce': 1302, + 'addr': '172.23.0.2:6808' + }, { + 'type': 'v1', + 'nonce': 1302, + 'addr': '172.23.0.2:6809' + }] + }, + 'heartbeat_front_addrs': { + 'addrvec': [{ + 'type': 'v2', + 'nonce': 1302, + 'addr': '172.23.0.2:6806' + }, { + 'type': 'v1', + 'nonce': 1302, + 'addr': '172.23.0.2:6807' + }] + }, + 'state': ['exists', 'up'], + 'uuid': str(uuid.uuid4()), + 'public_addr': '172.23.0.2:6803/1302', + 'cluster_addr': '172.23.0.2:6805/1302', + 'heartbeat_back_addr': '172.23.0.2:6809/1302', + 'heartbeat_front_addr': '172.23.0.2:6807/1302', + 'id': osd_id, + } + + @classmethod + def gen_osdmap(cls, ids=None): + # type: (List[int]) -> Dict[str, Any] + return {str(i): cls._gen_osd_map_osd(i) for i in ids or cls.DEFAULT_OSD_IDS} + + @classmethod + def gen_osd_stats(cls, ids=None): + # type: (List[int]) -> List[Dict[str, Any]] + return [cls._gen_osd_stats(i) for i in ids or cls.DEFAULT_OSD_IDS] + + @classmethod + def gen_osdmap_tree_nodes(cls, ids=None): + # type: (List[int]) -> List[Dict[str, Any]] + return [ + cls._gen_osdmap_tree_node(-1, 'root', [-3]), + cls._gen_osdmap_tree_node(-3, 'host', ids or cls.DEFAULT_OSD_IDS), + ] + [cls._gen_osdmap_tree_node(node_id, 'osd') for node_id in ids or cls.DEFAULT_OSD_IDS] + + @classmethod + def gen_mgr_get_counter(cls): + # type: () -> List[List[int]] + return [[1551973855, 35], [1551973860, 35], [1551973865, 35], [1551973870, 35]] + + +class OsdTest(ControllerTestCase): + @classmethod + def setup_server(cls): + Osd._cp_config['tools.authenticate.on'] = False # pylint: disable=protected-access + cls.setup_controllers([Osd]) + + @contextmanager + def _mock_osd_list(self, osd_stat_ids, osdmap_tree_node_ids, osdmap_ids): + def mgr_get_replacement(*args, **kwargs): + method = args[0] or kwargs['method'] + if method == 'osd_stats': + return {'osd_stats': OsdHelper.gen_osd_stats(osd_stat_ids)} + if method == 'osd_map_tree': + return {'nodes': OsdHelper.gen_osdmap_tree_nodes(osdmap_tree_node_ids)} + raise NotImplementedError() + + def mgr_get_counter_replacement(svc_type, _, path): + if svc_type == 'osd': + return {path: OsdHelper.gen_mgr_get_counter()} + raise NotImplementedError() + + with patch.object(Osd, 'get_osd_map', return_value=OsdHelper.gen_osdmap(osdmap_ids)): + with patch.object(mgr, 'get', side_effect=mgr_get_replacement): + with patch.object(mgr, 'get_counter', side_effect=mgr_get_counter_replacement): + with patch.object(mgr, 'get_latest', return_value=1146609664): + yield + + def test_osd_list_aggregation(self): + """ + This test emulates the state of a cluster where an OSD has only been + removed (with e.g. `ceph osd rm`), but it hasn't been removed from the + CRUSH map. Ceph reports a health warning alongside a `1 osds exist in + the crush map but not in the osdmap` warning in such a case. + """ + osds_actual = [0, 1] + osds_leftover = [0, 1, 2] + with self._mock_osd_list(osd_stat_ids=osds_actual, osdmap_tree_node_ids=osds_leftover, + osdmap_ids=osds_actual): + self._get('/api/osd') + self.assertEqual(len(self.jsonBody()), 2, 'It should display two OSDs without failure') + self.assertStatus(200) diff --git a/src/pybind/mgr/dashboard/tests/test_plugin_debug.py b/src/pybind/mgr/dashboard/tests/test_plugin_debug.py new file mode 100644 index 00000000..e6999782 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_plugin_debug.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from . import CLICommandTestMixin, ControllerTestCase + + +class TestPluginDebug(ControllerTestCase, CLICommandTestMixin): + @classmethod + def setup_server(cls): + # pylint: disable=protected-access + cls.setup_controllers([]) + + def setUp(self): + self.mock_kv_store() + + def test_debug_disabled(self): + self.exec_cmd('debug', action='disable') + + self._get('/api/unexisting_controller') + self.assertStatus(404) + + data = self.jsonBody() + self.assertGreater(len(data), 0) + self.assertNotIn('traceback', data) + self.assertNotIn('version', data) + self.assertIn('request_id', data) + + def test_debug_enabled(self): + self.exec_cmd('debug', action='enable') + + self._get('/api/unexisting_controller') + self.assertStatus(404) + + data = self.jsonBody() + self.assertGreater(len(data), 0) + self.assertIn('traceback', data) + self.assertIn('version', data) + self.assertIn('request_id', data) diff --git a/src/pybind/mgr/dashboard/tests/test_pool.py b/src/pybind/mgr/dashboard/tests/test_pool.py new file mode 100644 index 00000000..16d7d7b1 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_pool.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# pylint: disable=protected-access +import time +import mock + +from . import ControllerTestCase +from ..controllers.pool import Pool +from ..controllers.task import Task +from ..tools import NotificationQueue, TaskManager + + +class MockTask(object): + percentages = [] + + def set_progress(self, percentage): + self.percentages.append(percentage) + + +class PoolControllerTest(ControllerTestCase): + @classmethod + def setup_server(cls): + Task._cp_config['tools.authenticate.on'] = False + Pool._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([Pool, Task]) + + @mock.patch('dashboard.controllers.pool.Pool._get') + @mock.patch('dashboard.services.ceph_service.CephService.send_command') + def test_creation(self, send_command, _get): + _get.side_effect = [{ + 'pool_name': 'test-pool', + 'pg_num': 64, + 'pg_num_target': 63, + 'pg_placement_num': 64, + 'pg_placement_num_target': 63 + }, { + 'pool_name': 'test-pool', + 'pg_num': 64, + 'pg_num_target': 64, + 'pg_placement_num': 64, + 'pg_placement_num_target': 64 + }] + NotificationQueue.start_queue() + TaskManager.init() + + def _send_cmd(*args, **kwargs): # pylint: disable=unused-argument + time.sleep(3) + + send_command.side_effect = _send_cmd + + self._task_post('/api/pool', { + 'pool': 'test-pool', + 'pool_type': 1, + 'pg_num': 64 + }, 10) + self.assertStatus(201) + self.assertEqual(_get.call_count, 2) + NotificationQueue.stop() + + @mock.patch('dashboard.controllers.pool.Pool._get') + def test_wait_for_pgs_without_waiting(self, _get): + _get.side_effect = [{ + 'pool_name': 'test-pool', + 'pg_num': 32, + 'pg_num_target': 32, + 'pg_placement_num': 32, + 'pg_placement_num_target': 32 + }] + Pool._wait_for_pgs('test-pool') + self.assertEqual(_get.call_count, 1) + + @mock.patch('dashboard.controllers.pool.Pool._get') + def test_wait_for_pgs_with_waiting(self, _get): + task = MockTask() + orig_method = TaskManager.current_task + TaskManager.current_task = mock.MagicMock() + TaskManager.current_task.return_value = task + _get.side_effect = [{ + 'pool_name': 'test-pool', + 'pg_num': 64, + 'pg_num_target': 32, + 'pg_placement_num': 64, + 'pg_placement_num_target': 64 + }, { + 'pool_name': 'test-pool', + 'pg_num': 63, + 'pg_num_target': 32, + 'pg_placement_num': 62, + 'pg_placement_num_target': 32 + }, { + 'pool_name': 'test-pool', + 'pg_num': 48, + 'pg_num_target': 32, + 'pg_placement_num': 48, + 'pg_placement_num_target': 32 + }, { + 'pool_name': 'test-pool', + 'pg_num': 48, + 'pg_num_target': 32, + 'pg_placement_num': 33, + 'pg_placement_num_target': 32 + }, { + 'pool_name': 'test-pool', + 'pg_num': 33, + 'pg_num_target': 32, + 'pg_placement_num': 32, + 'pg_placement_num_target': 32 + }, { + 'pool_name': 'test-pool', + 'pg_num': 32, + 'pg_num_target': 32, + 'pg_placement_num': 32, + 'pg_placement_num_target': 32 + }] + Pool._wait_for_pgs('test-pool') + self.assertEqual(_get.call_count, 6) + self.assertEqual(task.percentages, [0, 5, 50, 73, 98]) + TaskManager.current_task = orig_method diff --git a/src/pybind/mgr/dashboard/tests/test_prometheus.py b/src/pybind/mgr/dashboard/tests/test_prometheus.py new file mode 100644 index 00000000..73dedbab --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_prometheus.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# pylint: disable=protected-access +from mock import patch + +from . import ControllerTestCase +from .. import mgr +from ..controllers.prometheus import Prometheus, PrometheusReceiver, PrometheusNotifications + + +class PrometheusControllerTest(ControllerTestCase): + alert_host = 'http://alertmanager:9093/mock' + alert_host_api = alert_host + '/api/v1' + + prometheus_host = 'http://prometheus:9090/mock' + prometheus_host_api = prometheus_host + '/api/v1' + + @classmethod + def setup_server(cls): + settings = { + 'ALERTMANAGER_API_HOST': cls.alert_host, + 'PROMETHEUS_API_HOST': cls.prometheus_host + } + mgr.get_module_option.side_effect = settings.get + Prometheus._cp_config['tools.authenticate.on'] = False + PrometheusNotifications._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([Prometheus, PrometheusNotifications, PrometheusReceiver]) + + def test_rules(self): + with patch('requests.request') as mock_request: + self._get('/api/prometheus/rules') + mock_request.assert_called_with('GET', self.prometheus_host_api + '/rules', + json=None, params={}) + + def test_list(self): + with patch('requests.request') as mock_request: + self._get('/api/prometheus') + mock_request.assert_called_with('GET', self.alert_host_api + '/alerts', + json=None, params={}) + + def test_get_silences(self): + with patch('requests.request') as mock_request: + self._get('/api/prometheus/silences') + mock_request.assert_called_with('GET', self.alert_host_api + '/silences', + json=None, params={}) + + def test_add_silence(self): + with patch('requests.request') as mock_request: + self._post('/api/prometheus/silence', {'id': 'new-silence'}) + mock_request.assert_called_with('POST', self.alert_host_api + '/silences', + params=None, json={'id': 'new-silence'}) + + def test_update_silence(self): + with patch('requests.request') as mock_request: + self._post('/api/prometheus/silence', {'id': 'update-silence'}) + mock_request.assert_called_with('POST', self.alert_host_api + '/silences', + params=None, json={'id': 'update-silence'}) + + def test_expire_silence(self): + with patch('requests.request') as mock_request: + self._delete('/api/prometheus/silence/0') + mock_request.assert_called_with('DELETE', self.alert_host_api + '/silence/0', + json=None, params=None) + + def test_silences_empty_delete(self): + with patch('requests.request') as mock_request: + self._delete('/api/prometheus/silence') + mock_request.assert_not_called() + + def test_post_on_receiver(self): + PrometheusReceiver.notifications = [] + self._post('/api/prometheus_receiver', {'name': 'foo'}) + self.assertEqual(len(PrometheusReceiver.notifications), 1) + notification = PrometheusReceiver.notifications[0] + self.assertEqual(notification['name'], 'foo') + self.assertTrue(len(notification['notified']) > 20) + + def test_get_empty_list_with_no_notifications(self): + PrometheusReceiver.notifications = [] + self._get('/api/prometheus/notifications') + self.assertStatus(200) + self.assertJsonBody([]) + self._get('/api/prometheus/notifications?from=last') + self.assertStatus(200) + self.assertJsonBody([]) + + def test_get_all_notification(self): + PrometheusReceiver.notifications = [] + self._post('/api/prometheus_receiver', {'name': 'foo'}) + self._post('/api/prometheus_receiver', {'name': 'bar'}) + self._get('/api/prometheus/notifications') + self.assertStatus(200) + self.assertJsonBody(PrometheusReceiver.notifications) + + def test_get_last_notification_with_use_of_last_keyword(self): + PrometheusReceiver.notifications = [] + self._post('/api/prometheus_receiver', {'name': 'foo'}) + self._post('/api/prometheus_receiver', {'name': 'bar'}) + self._get('/api/prometheus/notifications?from=last') + self.assertStatus(200) + last = PrometheusReceiver.notifications[1] + self.assertJsonBody([last]) + + def test_get_no_notification_with_unknown_id(self): + PrometheusReceiver.notifications = [] + self._post('/api/prometheus_receiver', {'name': 'foo'}) + self._post('/api/prometheus_receiver', {'name': 'bar'}) + self._get('/api/prometheus/notifications?from=42') + self.assertStatus(200) + self.assertJsonBody([]) + + def test_get_no_notification_since_with_last_notification(self): + PrometheusReceiver.notifications = [] + self._post('/api/prometheus_receiver', {'name': 'foo'}) + notification = PrometheusReceiver.notifications[0] + self._get('/api/prometheus/notifications?from=' + notification['id']) + self.assertStatus(200) + self.assertJsonBody([]) + + def test_get_notifications_since_last_notification(self): + PrometheusReceiver.notifications = [] + self._post('/api/prometheus_receiver', {'name': 'foobar'}) + next_to_last = PrometheusReceiver.notifications[0] + self._post('/api/prometheus_receiver', {'name': 'foo'}) + self._post('/api/prometheus_receiver', {'name': 'bar'}) + self._get('/api/prometheus/notifications?from=' + next_to_last['id']) + forelast = PrometheusReceiver.notifications[1] + last = PrometheusReceiver.notifications[2] + self.assertEqual(self.jsonBody(), [forelast, last]) diff --git a/src/pybind/mgr/dashboard/tests/test_rbd_mirroring.py b/src/pybind/mgr/dashboard/tests/test_rbd_mirroring.py new file mode 100644 index 00000000..b307c209 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_rbd_mirroring.py @@ -0,0 +1,95 @@ +from __future__ import absolute_import + +import json +import mock + +from . import ControllerTestCase +from .. import mgr +from ..controllers.summary import Summary +from ..controllers.rbd_mirroring import RbdMirroringSummary + + +mock_list_servers = [{ + 'hostname': 'ceph-host', + 'services': [{'id': 3, 'type': 'rbd-mirror'}] +}] + +mock_get_metadata = { + 'id': 1, + 'instance_id': 3, + 'ceph_version': 'ceph version 13.0.0-5719 mimic (dev)' +} + +_status = { + 1: { + 'callouts': {}, + 'image_local_count': 5, + 'image_remote_count': 6, + 'image_error_count': 7, + 'image_warning_count': 8, + 'name': 'pool_name' + } +} + +mock_get_daemon_status = { + 'json': json.dumps(_status) +} + +mock_osd_map = { + 'pools': [{ + 'pool_name': 'rbd', + 'application_metadata': {'rbd'} + }] +} + + +class RbdMirroringSummaryControllerTest(ControllerTestCase): + + @classmethod + def setup_server(cls): + mgr.list_servers.return_value = mock_list_servers + mgr.get_metadata = mock.Mock(return_value=mock_get_metadata) + mgr.get_daemon_status.return_value = mock_get_daemon_status + mgr.get.side_effect = lambda key: { + 'osd_map': mock_osd_map, + 'health': {'json': '{"status": 1}'}, + 'fs_map': {'filesystems': []}, + 'mgr_map': { + 'services': { + 'dashboard': 'https://ceph.dev:11000/' + }, + } + }[key] + mgr.url_prefix = '' + mgr.get_mgr_id.return_value = 0 + mgr.have_mon_connection.return_value = True + mgr.version = 'ceph version 13.1.0-534-g23d3751b89 ' \ + '(23d3751b897b31d2bda57aeaf01acb5ff3c4a9cd) ' \ + 'nautilus (dev)' + + # pylint: disable=protected-access + RbdMirroringSummary._cp_config['tools.authenticate.on'] = False + Summary._cp_config['tools.authenticate.on'] = False + # pylint: enable=protected-access + + cls.setup_controllers([RbdMirroringSummary, Summary], '/test') + + @mock.patch('dashboard.controllers.rbd_mirroring.rbd') + def test_default(self, rbd_mock): # pylint: disable=W0613 + self._get('/test/api/block/mirroring/summary') + result = self.jsonBody() + self.assertStatus(200) + self.assertEqual(result['status'], 0) + for k in ['daemons', 'pools', 'image_error', 'image_syncing', 'image_ready']: + self.assertIn(k, result['content_data']) + + @mock.patch('dashboard.controllers.BaseController._has_permissions') + @mock.patch('dashboard.controllers.rbd_mirroring.rbd') + def test_summary(self, rbd_mock, has_perms_mock): # pylint: disable=W0613 + """We're also testing `summary`, as it also uses code from `rbd_mirroring.py`""" + has_perms_mock.return_value = True + self._get('/test/api/summary') + self.assertStatus(200) + + summary = self.jsonBody()['rbd_mirroring'] + self.assertEqual(summary, {'errors': 0, 'warnings': 1}) diff --git a/src/pybind/mgr/dashboard/tests/test_rbd_service.py b/src/pybind/mgr/dashboard/tests/test_rbd_service.py new file mode 100644 index 00000000..a4511fa9 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_rbd_service.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# pylint: disable=dangerous-default-value,too-many-public-methods +from __future__ import absolute_import + +import unittest +try: + import mock +except ImportError: + import unittest.mock as mock + +from ..services.rbd import RbdConfiguration + + +class RbdServiceTest(unittest.TestCase): + + @mock.patch('dashboard.services.rbd.RbdConfiguration._rbd.config_list') + @mock.patch('dashboard.mgr.get') + @mock.patch('dashboard.services.ceph_service.CephService.get_pool_list') + def test_pool_rbd_configuration_with_different_pg_states(self, get_pool_list, get, config_list): + get_pool_list.return_value = [{ + 'pool_name': 'good-pool', + 'pool': 1, + }, { + 'pool_name': 'bad-pool', + 'pool': 2, + }] + get.return_value = { + 'by_pool': { + '1': {'active+clean': 32}, + '2': {'creating+incomplete': 32}, + } + } + config_list.return_value = [1, 2, 3] + config = RbdConfiguration('bad-pool') + self.assertEqual(config.list(), []) + config = RbdConfiguration('good-pool') + self.assertEqual(config.list(), [1, 2, 3]) diff --git a/src/pybind/mgr/dashboard/tests/test_rest_client.py b/src/pybind/mgr/dashboard/tests/test_rest_client.py new file mode 100644 index 00000000..36ecd51a --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_rest_client.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +import unittest +import requests.exceptions + +from mock import patch +from urllib3.exceptions import MaxRetryError, ProtocolError +from .. import mgr +from ..rest_client import RequestException, RestClient + + +class RestClientTest(unittest.TestCase): + def setUp(self): + settings = {'REST_REQUESTS_TIMEOUT': 45} + mgr.get_module_option.side_effect = settings.get + + def test_timeout_auto_set(self): + with patch('requests.Session.request') as mock_request: + rest_client = RestClient('localhost', 8000) + rest_client.session.request('GET', '/test') + mock_request.assert_called_with('GET', '/test', timeout=45) + + def test_timeout_auto_set_arg(self): + with patch('requests.Session.request') as mock_request: + rest_client = RestClient('localhost', 8000) + rest_client.session.request( + 'GET', '/test', None, None, None, None, + None, None, None) + mock_request.assert_called_with( + 'GET', '/test', None, None, None, None, + None, None, None, timeout=45) + + def test_timeout_no_auto_set_kwarg(self): + with patch('requests.Session.request') as mock_request: + rest_client = RestClient('localhost', 8000) + rest_client.session.request('GET', '/test', timeout=20) + mock_request.assert_called_with('GET', '/test', timeout=20) + + def test_timeout_no_auto_set_arg(self): + with patch('requests.Session.request') as mock_request: + rest_client = RestClient('localhost', 8000) + rest_client.session.request( + 'GET', '/test', None, None, None, None, + None, None, 40) + mock_request.assert_called_with( + 'GET', '/test', None, None, None, None, + None, None, 40) + + +class RestClientDoRequestTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.mock_requests = patch('requests.Session').start() + cls.rest_client = RestClient('localhost', 8000, 'UnitTest') + + def test_do_request_exception_no_args(self): + self.mock_requests().get.side_effect = requests.exceptions.ConnectionError() + with self.assertRaises(RequestException) as context: + self.rest_client.do_request('GET', '/test') + self.assertEqual('UnitTest REST API cannot be reached. Please ' + 'check your configuration and that the API ' + 'endpoint is accessible', + context.exception.message) + + def test_do_request_exception_args_1(self): + self.mock_requests().post.side_effect = requests.exceptions.ConnectionError( + MaxRetryError('Abc', 'http://xxx.yyy', 'too many redirects')) + with self.assertRaises(RequestException) as context: + self.rest_client.do_request('POST', '/test') + self.assertEqual('UnitTest REST API cannot be reached. Please ' + 'check your configuration and that the API ' + 'endpoint is accessible', + context.exception.message) + + def test_do_request_exception_args_2(self): + self.mock_requests().put.side_effect = requests.exceptions.ConnectionError( + ProtocolError('Connection broken: xyz')) + with self.assertRaises(RequestException) as context: + self.rest_client.do_request('PUT', '/test') + self.assertEqual('UnitTest REST API cannot be reached. Please ' + 'check your configuration and that the API ' + 'endpoint is accessible', + context.exception.message) + + def test_do_request_exception_nested_args(self): + self.mock_requests().delete.side_effect = requests.exceptions.ConnectionError( + MaxRetryError('Xyz', 'https://foo.bar', + Exception('Foo: [Errno -42] bla bla bla'))) + with self.assertRaises(RequestException) as context: + self.rest_client.do_request('DELETE', '/test') + self.assertEqual('UnitTest REST API cannot be reached: bla ' + 'bla bla [errno -42]. Please check your ' + 'configuration and that the API endpoint ' + 'is accessible', + context.exception.message) diff --git a/src/pybind/mgr/dashboard/tests/test_rest_tasks.py b/src/pybind/mgr/dashboard/tests/test_rest_tasks.py new file mode 100644 index 00000000..191ef812 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_rest_tasks.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# pylint: disable=blacklisted-name + +import time + +from . import ControllerTestCase +from ..controllers import Controller, RESTController, Task +from ..controllers.task import Task as TaskController +from ..tools import NotificationQueue, TaskManager + + +@Controller('/test/task', secure=False) +class TaskTest(RESTController): + sleep_time = 0.0 + + @Task('task/create', {'param': '{param}'}, wait_for=1.0) + def create(self, param): + time.sleep(TaskTest.sleep_time) + return {'my_param': param} + + @Task('task/set', {'param': '{2}'}, wait_for=1.0) + def set(self, key, param=None): + time.sleep(TaskTest.sleep_time) + return {'key': key, 'my_param': param} + + @Task('task/delete', ['{key}'], wait_for=1.0) + def delete(self, key): + # pylint: disable=unused-argument + time.sleep(TaskTest.sleep_time) + + @Task('task/foo', ['{param}']) + @RESTController.Collection('POST') + def foo(self, param): + return {'my_param': param} + + @Task('task/bar', ['{key}', '{param}']) + @RESTController.Resource('PUT') + def bar(self, key, param=None): + return {'my_param': param, 'key': key} + + @Task('task/query', ['{param}']) + @RESTController.Collection('POST', query_params=['param']) + def query(self, param=None): + return {'my_param': param} + + +class TaskControllerTest(ControllerTestCase): + @classmethod + def setup_server(cls): + # pylint: disable=protected-access + NotificationQueue.start_queue() + TaskManager.init() + TaskTest._cp_config['tools.authenticate.on'] = False + TaskController._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([TaskTest, TaskController]) + + @classmethod + def tearDownClass(cls): + NotificationQueue.stop() + + def setUp(self): + TaskTest.sleep_time = 0.0 + + def test_create_task(self): + self._task_post('/test/task', {'param': 'hello'}) + self.assertJsonBody({'my_param': 'hello'}) + + def test_long_set_task(self): + TaskTest.sleep_time = 2.0 + self._task_put('/test/task/2', {'param': 'hello'}) + self.assertJsonBody({'key': '2', 'my_param': 'hello'}) + + def test_delete_task(self): + self._task_delete('/test/task/hello') + + def test_foo_task(self): + self._task_post('/test/task/foo', {'param': 'hello'}) + self.assertJsonBody({'my_param': 'hello'}) + + def test_bar_task(self): + self._task_put('/test/task/3/bar', {'param': 'hello'}) + self.assertJsonBody({'my_param': 'hello', 'key': '3'}) + + def test_query_param(self): + self._task_post('/test/task/query') + self.assertJsonBody({'my_param': None}) diff --git a/src/pybind/mgr/dashboard/tests/test_rgw.py b/src/pybind/mgr/dashboard/tests/test_rgw.py new file mode 100644 index 00000000..9f586be2 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_rgw.py @@ -0,0 +1,129 @@ +import mock + +from .. import mgr +from ..controllers.rgw import Rgw, RgwUser +from . import ControllerTestCase # pylint: disable=no-name-in-module + + +class RgwControllerTestCase(ControllerTestCase): + @classmethod + def setup_server(cls): + Rgw._cp_config['tools.authenticate.on'] = False # pylint: disable=protected-access + cls.setup_controllers([Rgw], '/test') + + def test_status_no_service(self): + mgr.list_servers.return_value = [] + self._get('/test/api/rgw/status') + self.assertStatus(200) + self.assertJsonBody({'available': False, 'message': 'No RGW service is running.'}) + + +class RgwUserControllerTestCase(ControllerTestCase): + @classmethod + def setup_server(cls): + RgwUser._cp_config['tools.authenticate.on'] = False # pylint: disable=protected-access + cls.setup_controllers([RgwUser], '/test') + + @mock.patch('dashboard.controllers.rgw.RgwRESTController.proxy') + def test_user_list(self, mock_proxy): + mock_proxy.side_effect = [{ + 'count': 3, + 'keys': ['test1', 'test2', 'test3'], + 'truncated': False + }] + self._get('/test/api/rgw/user') + self.assertStatus(200) + mock_proxy.assert_has_calls([ + mock.call('GET', 'user?list', {}) + ]) + self.assertJsonBody(['test1', 'test2', 'test3']) + + @mock.patch('dashboard.controllers.rgw.RgwRESTController.proxy') + def test_user_list_marker(self, mock_proxy): + mock_proxy.side_effect = [{ + 'count': 3, + 'keys': ['test1', 'test2', 'test3'], + 'marker': 'foo:bar', + 'truncated': True + }, { + 'count': 1, + 'keys': ['admin'], + 'truncated': False + }] + self._get('/test/api/rgw/user') + self.assertStatus(200) + mock_proxy.assert_has_calls([ + mock.call('GET', 'user?list', {}), + mock.call('GET', 'user?list', {'marker': 'foo:bar'}) + ]) + self.assertJsonBody(['test1', 'test2', 'test3', 'admin']) + + @mock.patch('dashboard.controllers.rgw.RgwRESTController.proxy') + def test_user_list_duplicate_marker(self, mock_proxy): + mock_proxy.side_effect = [{ + 'count': 3, + 'keys': ['test1', 'test2', 'test3'], + 'marker': 'foo:bar', + 'truncated': True + }, { + 'count': 3, + 'keys': ['test4', 'test5', 'test6'], + 'marker': 'foo:bar', + 'truncated': True + }, { + 'count': 1, + 'keys': ['admin'], + 'truncated': False + }] + self._get('/test/api/rgw/user') + self.assertStatus(500) + + @mock.patch('dashboard.controllers.rgw.RgwRESTController.proxy') + def test_user_list_invalid_marker(self, mock_proxy): + mock_proxy.side_effect = [{ + 'count': 3, + 'keys': ['test1', 'test2', 'test3'], + 'marker': 'foo:bar', + 'truncated': True + }, { + 'count': 3, + 'keys': ['test4', 'test5', 'test6'], + 'marker': '', + 'truncated': True + }, { + 'count': 1, + 'keys': ['admin'], + 'truncated': False + }] + self._get('/test/api/rgw/user') + self.assertStatus(500) + + @mock.patch('dashboard.controllers.rgw.RgwRESTController.proxy') + @mock.patch.object(RgwUser, '_keys_allowed') + def test_user_get_with_keys(self, keys_allowed, mock_proxy): + keys_allowed.return_value = True + mock_proxy.return_value = { + 'tenant': '', + 'user_id': 'my_user_id', + 'keys': [], + 'swift_keys': [] + } + self._get('/test/api/rgw/user/testuser') + self.assertStatus(200) + self.assertInJsonBody('keys') + self.assertInJsonBody('swift_keys') + + @mock.patch('dashboard.controllers.rgw.RgwRESTController.proxy') + @mock.patch.object(RgwUser, '_keys_allowed') + def test_user_get_without_keys(self, keys_allowed, mock_proxy): + keys_allowed.return_value = False + mock_proxy.return_value = { + 'tenant': '', + 'user_id': 'my_user_id', + 'keys': [], + 'swift_keys': [] + } + self._get('/test/api/rgw/user/testuser') + self.assertStatus(200) + self.assertNotIn('keys', self.jsonBody()) + self.assertNotIn('swift_keys', self.jsonBody()) diff --git a/src/pybind/mgr/dashboard/tests/test_rgw_client.py b/src/pybind/mgr/dashboard/tests/test_rgw_client.py new file mode 100644 index 00000000..0824665f --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_rgw_client.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# pylint: disable=too-many-public-methods +import unittest + +from ..services.rgw_client import RgwClient, _parse_frontend_config +from ..settings import Settings +from . import KVStoreMockMixin + + +class RgwClientTest(unittest.TestCase, KVStoreMockMixin): + def setUp(self): + RgwClient._user_instances.clear() # pylint: disable=protected-access + self.mock_kv_store() + self.CONFIG_KEY_DICT.update({ + 'RGW_API_ACCESS_KEY': 'klausmustermann', + 'RGW_API_SECRET_KEY': 'supergeheim', + 'RGW_API_HOST': 'localhost', + 'RGW_API_USER_ID': 'rgwadmin' + }) + + def test_ssl_verify(self): + Settings.RGW_API_SSL_VERIFY = True + instance = RgwClient.admin_instance() + self.assertTrue(instance.session.verify) + + def test_no_ssl_verify(self): + Settings.RGW_API_SSL_VERIFY = False + instance = RgwClient.admin_instance() + self.assertFalse(instance.session.verify) + + +class RgwClientHelperTest(unittest.TestCase): + def test_parse_frontend_config_1(self): + self.assertEqual(_parse_frontend_config('beast port=8000'), (8000, False)) + + def test_parse_frontend_config_2(self): + self.assertEqual(_parse_frontend_config('beast port=80 port=8000'), (80, False)) + + def test_parse_frontend_config_3(self): + self.assertEqual(_parse_frontend_config('beast ssl_port=443 port=8000'), (443, True)) + + def test_parse_frontend_config_4(self): + self.assertEqual(_parse_frontend_config('beast endpoint=192.168.0.100:8000'), (8000, False)) + + def test_parse_frontend_config_5(self): + self.assertEqual(_parse_frontend_config('beast endpoint=[::1]'), (80, False)) + + def test_parse_frontend_config_6(self): + self.assertEqual(_parse_frontend_config( + 'beast ssl_endpoint=192.168.0.100:8443'), (8443, True)) + + def test_parse_frontend_config_7(self): + self.assertEqual(_parse_frontend_config('beast ssl_endpoint=192.168.0.100'), (443, True)) + + def test_parse_frontend_config_8(self): + self.assertEqual(_parse_frontend_config( + 'beast ssl_endpoint=[::1]:8443 endpoint=192.0.2.3:80'), (8443, True)) + + def test_parse_frontend_config_9(self): + self.assertEqual(_parse_frontend_config( + 'beast port=8080 endpoint=192.0.2.3:80'), (8080, False)) + + def test_parse_frontend_config_10(self): + self.assertEqual(_parse_frontend_config( + 'beast ssl_endpoint=192.0.2.3:8443 port=8080'), (8443, True)) + + def test_parse_frontend_config_11(self): + self.assertEqual(_parse_frontend_config('civetweb port=8000s'), (8000, True)) + + def test_parse_frontend_config_12(self): + self.assertEqual(_parse_frontend_config('civetweb port=443s port=8000'), (443, True)) + + def test_parse_frontend_config_13(self): + self.assertEqual(_parse_frontend_config('civetweb port=192.0.2.3:80'), (80, False)) + + def test_parse_frontend_config_14(self): + self.assertEqual(_parse_frontend_config('civetweb port=172.5.2.51:8080s'), (8080, True)) + + def test_parse_frontend_config_15(self): + self.assertEqual(_parse_frontend_config('civetweb port=[::]:8080'), (8080, False)) + + def test_parse_frontend_config_16(self): + self.assertEqual(_parse_frontend_config('civetweb port=ip6-localhost:80s'), (80, True)) + + def test_parse_frontend_config_17(self): + self.assertEqual(_parse_frontend_config('civetweb port=[2001:0db8::1234]:80'), (80, False)) + + def test_parse_frontend_config_18(self): + self.assertEqual(_parse_frontend_config('civetweb port=[::1]:8443s'), (8443, True)) + + def test_parse_frontend_config_19(self): + self.assertEqual(_parse_frontend_config('civetweb port=127.0.0.1:8443s+8000'), (8443, True)) + + def test_parse_frontend_config_20(self): + self.assertEqual(_parse_frontend_config('civetweb port=127.0.0.1:8080+443s'), (8080, False)) + + def test_parse_frontend_config_21(self): + with self.assertRaises(LookupError) as ctx: + _parse_frontend_config('civetweb port=xyz') + self.assertEqual(str(ctx.exception), + 'Failed to determine RGW port from "civetweb port=xyz"') + + def test_parse_frontend_config_22(self): + with self.assertRaises(LookupError) as ctx: + _parse_frontend_config('civetweb') + self.assertEqual(str(ctx.exception), 'Failed to determine RGW port from "civetweb"') + + def test_parse_frontend_config_23(self): + with self.assertRaises(LookupError) as ctx: + _parse_frontend_config('mongoose port=8080') + self.assertEqual(str(ctx.exception), + 'Failed to determine RGW port from "mongoose port=8080"') diff --git a/src/pybind/mgr/dashboard/tests/test_settings.py b/src/pybind/mgr/dashboard/tests/test_settings.py new file mode 100644 index 00000000..2d050429 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_settings.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import errno +import unittest + +from mgr_module import ERROR_MSG_EMPTY_INPUT_FILE + +from . import KVStoreMockMixin, ControllerTestCase +from .. import settings +from ..controllers.settings import Settings as SettingsController +from ..settings import Settings, handle_option_command + + +class SettingsTest(unittest.TestCase, KVStoreMockMixin): + @classmethod + def setUpClass(cls): + # pylint: disable=protected-access + settings.Options.GRAFANA_API_HOST = ('localhost', str) + settings.Options.GRAFANA_API_PORT = (3000, int) + settings.Options.GRAFANA_ENABLED = (False, bool) + settings._OPTIONS_COMMAND_MAP = settings._options_command_map() + + def setUp(self): + self.mock_kv_store() + if Settings.GRAFANA_API_HOST != 'localhost': + Settings.GRAFANA_API_HOST = 'localhost' + if Settings.GRAFANA_API_PORT != 3000: + Settings.GRAFANA_API_PORT = 3000 + + def test_get_setting(self): + self.assertEqual(Settings.GRAFANA_API_HOST, 'localhost') + self.assertEqual(Settings.GRAFANA_API_PORT, 3000) + self.assertEqual(Settings.GRAFANA_ENABLED, False) + + def test_set_setting(self): + Settings.GRAFANA_API_HOST = 'grafanahost' + self.assertEqual(Settings.GRAFANA_API_HOST, 'grafanahost') + + Settings.GRAFANA_API_PORT = 50 + self.assertEqual(Settings.GRAFANA_API_PORT, 50) + + Settings.GRAFANA_ENABLED = True + self.assertEqual(Settings.GRAFANA_ENABLED, True) + + def test_get_cmd(self): + r, out, err = handle_option_command( + {'prefix': 'dashboard get-grafana-api-port'}, + None + ) + self.assertEqual(r, 0) + self.assertEqual(out, '3000') + self.assertEqual(err, '') + + def test_set_cmd(self): + r, out, err = handle_option_command( + {'prefix': 'dashboard set-grafana-api-port', + 'value': '4000'}, + None + ) + self.assertEqual(r, 0) + self.assertEqual(out, 'Option GRAFANA_API_PORT updated') + self.assertEqual(err, '') + + def test_set_secret_empty(self): + r, out, err = handle_option_command( + {'prefix': 'dashboard set-rgw-api-secret-key'}, + None + ) + self.assertEqual(r, -errno.EINVAL) + self.assertEqual(out, '') + self.assertEqual(err, ERROR_MSG_EMPTY_INPUT_FILE) + + def test_set_secret(self): + r, out, err = handle_option_command( + {'prefix': 'dashboard set-rgw-api-secret-key'}, + 'my-secret' + ) + self.assertEqual(r, 0) + self.assertEqual(out, 'Option RGW_API_SECRET_KEY updated') + self.assertEqual(err, '') + + def test_reset_cmd(self): + r, out, err = handle_option_command( + {'prefix': 'dashboard reset-grafana-enabled'}, + None + ) + self.assertEqual(r, 0) + self.assertEqual(out, 'Option {} reset to default value "{}"'.format( + 'GRAFANA_ENABLED', Settings.GRAFANA_ENABLED)) + self.assertEqual(err, '') + + def test_inv_cmd(self): + r, out, err = handle_option_command( + {'prefix': 'dashboard get-non-existent-option'}, + None + ) + self.assertEqual(r, -errno.ENOSYS) + self.assertEqual(out, '') + self.assertEqual(err, "Command not found " + "'dashboard get-non-existent-option'") + + def test_sync(self): + Settings.GRAFANA_API_PORT = 5000 + r, out, err = handle_option_command( + {'prefix': 'dashboard get-grafana-api-port'}, + None + ) + self.assertEqual(r, 0) + self.assertEqual(out, '5000') + self.assertEqual(err, '') + r, out, err = handle_option_command( + {'prefix': 'dashboard set-grafana-api-host', + 'value': 'new-local-host'}, + None + ) + self.assertEqual(r, 0) + self.assertEqual(out, 'Option GRAFANA_API_HOST updated') + self.assertEqual(err, '') + self.assertEqual(Settings.GRAFANA_API_HOST, 'new-local-host') + + def test_attribute_error(self): + with self.assertRaises(AttributeError) as ctx: + _ = Settings.NON_EXISTENT_OPTION + + self.assertEqual(str(ctx.exception), + "type object 'Options' has no attribute 'NON_EXISTENT_OPTION'") + + +class SettingsControllerTest(ControllerTestCase, KVStoreMockMixin): + @classmethod + def setup_server(cls): + # pylint: disable=protected-access + + SettingsController._cp_config['tools.authenticate.on'] = False + cls.setup_controllers([SettingsController]) + + def setUp(self): + self.mock_kv_store() + + def test_settings_list(self): + self._get('/api/settings') + data = self.jsonBody() + self.assertTrue(len(data) > 0) + self.assertStatus(200) + self.assertIn('default', data[0].keys()) + self.assertIn('type', data[0].keys()) + self.assertIn('name', data[0].keys()) + self.assertIn('value', data[0].keys()) + + def test_rgw_daemon_get(self): + self._get('/api/settings/grafana-api-username') + self.assertStatus(200) + self.assertJsonBody({ + u'default': u'admin', + u'type': u'str', + u'name': u'GRAFANA_API_USERNAME', + u'value': u'admin', + }) + + def test_set(self): + self._put('/api/settings/GRAFANA_API_USERNAME', {'value': 'foo'},) + self.assertStatus(200) + + self._get('/api/settings/GRAFANA_API_USERNAME') + self.assertStatus(200) + self.assertInJsonBody('default') + self.assertInJsonBody('type') + self.assertInJsonBody('name') + self.assertInJsonBody('value') + self.assertEqual(self.jsonBody()['value'], 'foo') + + def test_bulk_set(self): + self._put('/api/settings', { + 'GRAFANA_API_USERNAME': 'foo', + 'GRAFANA_API_HOST': 'somehost', + }) + self.assertStatus(200) + + self._get('/api/settings/grafana-api-username') + self.assertStatus(200) + body = self.jsonBody() + self.assertEqual(body['value'], 'foo') + + self._get('/api/settings/grafana-api-username') + self.assertStatus(200) + self.assertEqual(self.jsonBody()['value'], 'foo') + + self._get('/api/settings/grafana-api-host') + self.assertStatus(200) + self.assertEqual(self.jsonBody()['value'], 'somehost') diff --git a/src/pybind/mgr/dashboard/tests/test_sso.py b/src/pybind/mgr/dashboard/tests/test_sso.py new file mode 100644 index 00000000..f8681b89 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_sso.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +# pylint: disable=dangerous-default-value,too-many-public-methods +from __future__ import absolute_import + +import errno +import unittest + +from . import CmdException, exec_dashboard_cmd, KVStoreMockMixin +from ..services.sso import handle_sso_command, load_sso_db + + +class AccessControlTest(unittest.TestCase, KVStoreMockMixin): + IDP_METADATA = ''' + + + + + + + + + + + + v6V8fooEUeq/LO/59JCfJF69Tw3ohN52OGAY6X3jX8w= + + + IDP_SIGNATURE_VALUE + + + IDP_X509_CERTIFICATE + + + + + + + + IDP_X509_CERTIFICATE + + + + + + + IDP_X509_CERTIFICATE + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + +''' + + def setUp(self): + self.mock_kv_store() + load_sso_db() + + @classmethod + def exec_cmd(cls, cmd, **kwargs): + return exec_dashboard_cmd(handle_sso_command, cmd, **kwargs) + + def validate_onelogin_settings(self, onelogin_settings, ceph_dashboard_base_url, uid, + sp_x509cert, sp_private_key, signature_enabled): + self.assertIn('sp', onelogin_settings) + self.assertIn('entityId', onelogin_settings['sp']) + self.assertEqual(onelogin_settings['sp']['entityId'], + '{}/auth/saml2/metadata'.format(ceph_dashboard_base_url)) + + self.assertIn('assertionConsumerService', onelogin_settings['sp']) + self.assertIn('url', onelogin_settings['sp']['assertionConsumerService']) + self.assertEqual(onelogin_settings['sp']['assertionConsumerService']['url'], + '{}/auth/saml2'.format(ceph_dashboard_base_url)) + + self.assertIn('attributeConsumingService', onelogin_settings['sp']) + attribute_consuming_service = onelogin_settings['sp']['attributeConsumingService'] + self.assertIn('requestedAttributes', attribute_consuming_service) + requested_attributes = attribute_consuming_service['requestedAttributes'] + self.assertEqual(len(requested_attributes), 1) + self.assertIn('name', requested_attributes[0]) + self.assertEqual(requested_attributes[0]['name'], uid) + + self.assertIn('singleLogoutService', onelogin_settings['sp']) + self.assertIn('url', onelogin_settings['sp']['singleLogoutService']) + self.assertEqual(onelogin_settings['sp']['singleLogoutService']['url'], + '{}/auth/saml2/logout'.format(ceph_dashboard_base_url)) + + self.assertIn('x509cert', onelogin_settings['sp']) + self.assertEqual(onelogin_settings['sp']['x509cert'], sp_x509cert) + + self.assertIn('privateKey', onelogin_settings['sp']) + self.assertEqual(onelogin_settings['sp']['privateKey'], sp_private_key) + + self.assertIn('security', onelogin_settings) + self.assertIn('authnRequestsSigned', onelogin_settings['security']) + self.assertEqual(onelogin_settings['security']['authnRequestsSigned'], signature_enabled) + + self.assertIn('logoutRequestSigned', onelogin_settings['security']) + self.assertEqual(onelogin_settings['security']['logoutRequestSigned'], signature_enabled) + + self.assertIn('logoutResponseSigned', onelogin_settings['security']) + self.assertEqual(onelogin_settings['security']['logoutResponseSigned'], signature_enabled) + + self.assertIn('wantMessagesSigned', onelogin_settings['security']) + self.assertEqual(onelogin_settings['security']['wantMessagesSigned'], signature_enabled) + + self.assertIn('wantAssertionsSigned', onelogin_settings['security']) + self.assertEqual(onelogin_settings['security']['wantAssertionsSigned'], signature_enabled) + + def test_sso_saml2_setup(self): + result = self.exec_cmd('sso setup saml2', + ceph_dashboard_base_url='https://cephdashboard.local', + idp_metadata=self.IDP_METADATA) + self.validate_onelogin_settings(result, 'https://cephdashboard.local', 'uid', '', '', + False) + + def test_sso_enable_saml2(self): + with self.assertRaises(CmdException) as ctx: + self.exec_cmd('sso enable saml2') + + self.assertEqual(ctx.exception.retcode, -errno.EPERM) + self.assertEqual(str(ctx.exception), 'Single Sign-On is not configured: ' + 'use `ceph dashboard sso setup saml2`') + + self.exec_cmd('sso setup saml2', + ceph_dashboard_base_url='https://cephdashboard.local', + idp_metadata=self.IDP_METADATA) + + result = self.exec_cmd('sso enable saml2') + self.assertEqual(result, 'SSO is "enabled" with "SAML2" protocol.') + + def test_sso_disable(self): + result = self.exec_cmd('sso disable') + self.assertEqual(result, 'SSO is "disabled".') + + def test_sso_status(self): + result = self.exec_cmd('sso status') + self.assertEqual(result, 'SSO is "disabled".') + + self.exec_cmd('sso setup saml2', + ceph_dashboard_base_url='https://cephdashboard.local', + idp_metadata=self.IDP_METADATA) + + result = self.exec_cmd('sso status') + self.assertEqual(result, 'SSO is "enabled" with "SAML2" protocol.') + + def test_sso_show_saml2(self): + result = self.exec_cmd('sso show saml2') + self.assertEqual(result, { + 'onelogin_settings': {} + }) diff --git a/src/pybind/mgr/dashboard/tests/test_task.py b/src/pybind/mgr/dashboard/tests/test_task.py new file mode 100644 index 00000000..c10af640 --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_task.py @@ -0,0 +1,433 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import json +import unittest +import threading +import time +from collections import defaultdict +from functools import partial + +from ..services.exception import serialize_dashboard_exception +from ..tools import NotificationQueue, TaskManager, TaskExecutor + + +class MyTask(object): + class CallbackExecutor(TaskExecutor): + def __init__(self, fail, progress): + super(MyTask.CallbackExecutor, self).__init__() + self.fail = fail + self.progress = progress + + def init(self, task): + super(MyTask.CallbackExecutor, self).init(task) + args = [self.callback] + args.extend(self.task.fn_args) + self.task.fn_args = args + + def callback(self, result): + self.task.set_progress(self.progress) + if self.fail: + self.finish(None, Exception("Task Unexpected Exception")) + else: + self.finish(result, None) + + # pylint: disable=too-many-arguments + def __init__(self, op_seconds, wait=False, fail=False, progress=50, + is_async=False, handle_ex=False): + self.op_seconds = op_seconds + self.wait = wait + self.fail = fail + self.progress = progress + self.is_async = is_async + self.handle_ex = handle_ex + self._event = threading.Event() + + def run(self, ns, timeout=None): + args = ['dummy arg'] + kwargs = {'dummy': 'arg'} + h_ex = partial(serialize_dashboard_exception, + include_http_status=True) if self.handle_ex else None + if not self.is_async: + task = TaskManager.run( + ns, self.metadata(), self.task_op, args, kwargs, + exception_handler=h_ex) + else: + task = TaskManager.run( + ns, self.metadata(), self.task_async_op, args, kwargs, + executor=MyTask.CallbackExecutor(self.fail, self.progress), + exception_handler=h_ex) + return task.wait(timeout) + + def task_op(self, *args, **kwargs): + time.sleep(self.op_seconds) + TaskManager.current_task().set_progress(self.progress) + if self.fail: + raise Exception("Task Unexpected Exception") + if self.wait: + self._event.wait() + return {'args': list(args), 'kwargs': kwargs} + + def task_async_op(self, callback, *args, **kwargs): + if self.fail == "premature": + raise Exception("Task Unexpected Exception") + + def _run_bg(): + time.sleep(self.op_seconds) + if self.wait: + self._event.wait() + callback({'args': list(args), 'kwargs': kwargs}) + + worker = threading.Thread(target=_run_bg) + worker.start() + + def resume(self): + self._event.set() + + def metadata(self): + return { + 'op_seconds': self.op_seconds, + 'wait': self.wait, + 'fail': self.fail, + 'progress': self.progress, + 'is_async': self.is_async, + 'handle_ex': self.handle_ex + } + + +class TaskTest(unittest.TestCase): + + TASK_FINISHED_MAP = defaultdict(threading.Event) + + @classmethod + def _handle_task(cls, task): + cls.TASK_FINISHED_MAP[task.name].set() + + @classmethod + def wait_for_task(cls, name): + cls.TASK_FINISHED_MAP[name].wait() + + @classmethod + def setUpClass(cls): + NotificationQueue.start_queue() + TaskManager.init() + NotificationQueue.register(cls._handle_task, 'cd_task_finished', + priority=100) + + @classmethod + def tearDownClass(cls): + NotificationQueue.deregister(cls._handle_task, 'cd_task_finished') + NotificationQueue.stop() + + def setUp(self): + TaskManager.FINISHED_TASK_SIZE = 10 + TaskManager.FINISHED_TASK_TTL = 60.0 + + def assertTaskResult(self, result): + self.assertEqual(result, + {'args': ['dummy arg'], 'kwargs': {'dummy': 'arg'}}) + + def test_fast_task(self): + task1 = MyTask(1) + state, result = task1.run('test1/task1') + self.assertEqual(state, TaskManager.VALUE_DONE) + self.assertTaskResult(result) + self.wait_for_task('test1/task1') + _, fn_t = TaskManager.list('test1/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].exception) + self.assertTaskResult(fn_t[0].ret_value) + self.assertEqual(fn_t[0].progress, 100) + + def test_slow_task(self): + task1 = MyTask(1) + state, result = task1.run('test2/task1', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + self.wait_for_task('test2/task1') + _, fn_t = TaskManager.list('test2/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].exception) + self.assertTaskResult(fn_t[0].ret_value) + self.assertEqual(fn_t[0].progress, 100) + + def test_fast_task_with_failure(self): + task1 = MyTask(1, fail=True, progress=40) + + with self.assertRaises(Exception) as ctx: + task1.run('test3/task1') + + self.assertEqual(str(ctx.exception), "Task Unexpected Exception") + self.wait_for_task('test3/task1') + _, fn_t = TaskManager.list('test3/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].ret_value) + self.assertEqual(str(fn_t[0].exception), "Task Unexpected Exception") + self.assertEqual(fn_t[0].progress, 40) + + def test_slow_task_with_failure(self): + task1 = MyTask(1, fail=True, progress=70) + state, result = task1.run('test4/task1', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + self.wait_for_task('test4/task1') + _, fn_t = TaskManager.list('test4/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].ret_value) + self.assertEqual(str(fn_t[0].exception), "Task Unexpected Exception") + self.assertEqual(fn_t[0].progress, 70) + + def test_executing_tasks_list(self): + task1 = MyTask(0, wait=True, progress=30) + task2 = MyTask(0, wait=True, progress=60) + state, result = task1.run('test5/task1', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + ex_t, _ = TaskManager.list('test5/*') + self.assertEqual(len(ex_t), 1) + self.assertEqual(ex_t[0].name, 'test5/task1') + self.assertEqual(ex_t[0].progress, 30) + state, result = task2.run('test5/task2', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + ex_t, _ = TaskManager.list('test5/*') + self.assertEqual(len(ex_t), 2) + for task in ex_t: + if task.name == 'test5/task1': + self.assertEqual(task.progress, 30) + elif task.name == 'test5/task2': + self.assertEqual(task.progress, 60) + task2.resume() + self.wait_for_task('test5/task2') + ex_t, _ = TaskManager.list('test5/*') + self.assertEqual(len(ex_t), 1) + self.assertEqual(ex_t[0].name, 'test5/task1') + task1.resume() + self.wait_for_task('test5/task1') + ex_t, _ = TaskManager.list('test5/*') + self.assertEqual(len(ex_t), 0) + + def test_task_idempotent(self): + task1 = MyTask(0, wait=True) + task1_clone = MyTask(0, wait=True) + state, result = task1.run('test6/task1', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + ex_t, _ = TaskManager.list('test6/*') + self.assertEqual(len(ex_t), 1) + self.assertEqual(ex_t[0].name, 'test6/task1') + state, result = task1_clone.run('test6/task1', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + ex_t, _ = TaskManager.list('test6/*') + self.assertEqual(len(ex_t), 1) + self.assertEqual(ex_t[0].name, 'test6/task1') + task1.resume() + self.wait_for_task('test6/task1') + ex_t, fn_t = TaskManager.list('test6/*') + self.assertEqual(len(ex_t), 0) + self.assertEqual(len(fn_t), 1) + + def test_finished_cleanup(self): + TaskManager.FINISHED_TASK_SIZE = 2 + TaskManager.FINISHED_TASK_TTL = 0.5 + task1 = MyTask(0) + task2 = MyTask(0) + state, result = task1.run('test7/task1') + self.assertEqual(state, TaskManager.VALUE_DONE) + self.assertTaskResult(result) + self.wait_for_task('test7/task1') + state, result = task2.run('test7/task2') + self.assertEqual(state, TaskManager.VALUE_DONE) + self.assertTaskResult(result) + self.wait_for_task('test7/task2') + time.sleep(1) + _, fn_t = TaskManager.list('test7/*') + self.assertEqual(len(fn_t), 2) + for idx, task in enumerate(fn_t): + self.assertEqual(task.name, + "test7/task{}".format(len(fn_t)-idx)) + task3 = MyTask(0) + state, result = task3.run('test7/task3') + self.assertEqual(state, TaskManager.VALUE_DONE) + self.assertTaskResult(result) + self.wait_for_task('test7/task3') + time.sleep(1) + _, fn_t = TaskManager.list('test7/*') + self.assertEqual(len(fn_t), 3) + for idx, task in enumerate(fn_t): + self.assertEqual(task.name, + "test7/task{}".format(len(fn_t)-idx)) + _, fn_t = TaskManager.list('test7/*') + self.assertEqual(len(fn_t), 2) + for idx, task in enumerate(fn_t): + self.assertEqual(task.name, + "test7/task{}".format(len(fn_t)-idx+1)) + + def test_task_serialization_format(self): + task1 = MyTask(0, wait=True, progress=20) + task2 = MyTask(1) + task1.run('test8/task1', 0.5) + task2.run('test8/task2', 0.5) + self.wait_for_task('test8/task2') + ex_t, fn_t = TaskManager.list_serializable('test8/*') + self.assertEqual(len(ex_t), 1) + self.assertEqual(len(fn_t), 1) + + try: + json.dumps(ex_t) + except ValueError as ex: + self.fail("Failed to serialize executing tasks: {}".format(str(ex))) + + try: + json.dumps(fn_t) + except ValueError as ex: + self.fail("Failed to serialize finished tasks: {}".format(str(ex))) + + # validate executing tasks attributes + self.assertEqual(len(ex_t[0].keys()), 4) + self.assertEqual(ex_t[0]['name'], 'test8/task1') + self.assertEqual(ex_t[0]['metadata'], task1.metadata()) + self.assertIsNotNone(ex_t[0]['begin_time']) + self.assertEqual(ex_t[0]['progress'], 20) + # validate finished tasks attributes + self.assertEqual(len(fn_t[0].keys()), 9) + self.assertEqual(fn_t[0]['name'], 'test8/task2') + self.assertEqual(fn_t[0]['metadata'], task2.metadata()) + self.assertIsNotNone(fn_t[0]['begin_time']) + self.assertIsNotNone(fn_t[0]['end_time']) + self.assertGreaterEqual(fn_t[0]['duration'], 1.0) + self.assertEqual(fn_t[0]['progress'], 100) + self.assertTrue(fn_t[0]['success']) + self.assertTaskResult(fn_t[0]['ret_value']) + self.assertIsNone(fn_t[0]['exception']) + task1.resume() + self.wait_for_task('test8/task1') + + def test_fast_async_task(self): + task1 = MyTask(1, is_async=True) + state, result = task1.run('test9/task1') + self.assertEqual(state, TaskManager.VALUE_DONE) + self.assertTaskResult(result) + self.wait_for_task('test9/task1') + _, fn_t = TaskManager.list('test9/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].exception) + self.assertTaskResult(fn_t[0].ret_value) + self.assertEqual(fn_t[0].progress, 100) + + def test_slow_async_task(self): + task1 = MyTask(1, is_async=True) + state, result = task1.run('test10/task1', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + self.wait_for_task('test10/task1') + _, fn_t = TaskManager.list('test10/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].exception) + self.assertTaskResult(fn_t[0].ret_value) + self.assertEqual(fn_t[0].progress, 100) + + def test_fast_async_task_with_failure(self): + task1 = MyTask(1, fail=True, progress=40, is_async=True) + + with self.assertRaises(Exception) as ctx: + task1.run('test11/task1') + + self.assertEqual(str(ctx.exception), "Task Unexpected Exception") + self.wait_for_task('test11/task1') + _, fn_t = TaskManager.list('test11/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].ret_value) + self.assertEqual(str(fn_t[0].exception), "Task Unexpected Exception") + self.assertEqual(fn_t[0].progress, 40) + + def test_slow_async_task_with_failure(self): + task1 = MyTask(1, fail=True, progress=70, is_async=True) + state, result = task1.run('test12/task1', 0.5) + self.assertEqual(state, TaskManager.VALUE_EXECUTING) + self.assertIsNone(result) + self.wait_for_task('test12/task1') + _, fn_t = TaskManager.list('test12/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].ret_value) + self.assertEqual(str(fn_t[0].exception), "Task Unexpected Exception") + self.assertEqual(fn_t[0].progress, 70) + + def test_fast_async_task_with_premature_failure(self): + task1 = MyTask(1, fail="premature", progress=40, is_async=True) + + with self.assertRaises(Exception) as ctx: + task1.run('test13/task1') + + self.assertEqual(str(ctx.exception), "Task Unexpected Exception") + self.wait_for_task('test13/task1') + _, fn_t = TaskManager.list('test13/*') + self.assertEqual(len(fn_t), 1) + self.assertIsNone(fn_t[0].ret_value) + self.assertEqual(str(fn_t[0].exception), "Task Unexpected Exception") + + def test_task_serialization_format_on_failure(self): + task1 = MyTask(1, fail=True) + task1.run('test14/task1', 0.5) + self.wait_for_task('test14/task1') + ex_t, fn_t = TaskManager.list_serializable('test14/*') + self.assertEqual(len(ex_t), 0) + self.assertEqual(len(fn_t), 1) + # validate finished tasks attributes + + try: + json.dumps(fn_t) + except TypeError as ex: + self.fail("Failed to serialize finished tasks: {}".format(str(ex))) + + self.assertEqual(len(fn_t[0].keys()), 9) + self.assertEqual(fn_t[0]['name'], 'test14/task1') + self.assertEqual(fn_t[0]['metadata'], task1.metadata()) + self.assertIsNotNone(fn_t[0]['begin_time']) + self.assertIsNotNone(fn_t[0]['end_time']) + self.assertGreaterEqual(fn_t[0]['duration'], 1.0) + self.assertEqual(fn_t[0]['progress'], 50) + self.assertFalse(fn_t[0]['success']) + self.assertIsNotNone(fn_t[0]['exception']) + self.assertEqual(fn_t[0]['exception'], + {"detail": "Task Unexpected Exception"}) + + def test_task_serialization_format_on_failure_with_handler(self): + task1 = MyTask(1, fail=True, handle_ex=True) + task1.run('test15/task1', 0.5) + self.wait_for_task('test15/task1') + ex_t, fn_t = TaskManager.list_serializable('test15/*') + self.assertEqual(len(ex_t), 0) + self.assertEqual(len(fn_t), 1) + # validate finished tasks attributes + + try: + json.dumps(fn_t) + except TypeError as ex: + self.fail("Failed to serialize finished tasks: {}".format(str(ex))) + + self.assertEqual(len(fn_t[0].keys()), 9) + self.assertEqual(fn_t[0]['name'], 'test15/task1') + self.assertEqual(fn_t[0]['metadata'], task1.metadata()) + self.assertIsNotNone(fn_t[0]['begin_time']) + self.assertIsNotNone(fn_t[0]['end_time']) + self.assertGreaterEqual(fn_t[0]['duration'], 1.0) + self.assertEqual(fn_t[0]['progress'], 50) + self.assertFalse(fn_t[0]['success']) + self.assertIsNotNone(fn_t[0]['exception']) + self.assertEqual(fn_t[0]['exception'], { + 'component': None, + 'detail': 'Task Unexpected Exception', + 'status': 500, + 'task': { + 'metadata': { + 'fail': True, + 'handle_ex': True, + 'is_async': False, + 'op_seconds': 1, + 'progress': 50, + 'wait': False}, + 'name': 'test15/task1' + } + }) diff --git a/src/pybind/mgr/dashboard/tests/test_tools.py b/src/pybind/mgr/dashboard/tests/test_tools.py new file mode 100644 index 00000000..1c2c2e5b --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_tools.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import unittest + +import cherrypy +from cherrypy.lib.sessions import RamSession +from mock import patch + +from . import ControllerTestCase +from ..services.exception import handle_rados_error +from ..controllers import RESTController, ApiController, Controller, \ + BaseController, Proxy +from ..tools import is_valid_ipv6_address, dict_contains_path, \ + RequestLoggingTool + + +# pylint: disable=W0613 +@Controller('/foo', secure=False) +class FooResource(RESTController): + elems = [] + + def list(self): + return FooResource.elems + + def create(self, a): + FooResource.elems.append({'a': a}) + return {'a': a} + + def get(self, key): + return {'detail': (key, [])} + + def delete(self, key): + del FooResource.elems[int(key)] + + def bulk_delete(self): + FooResource.elems = [] + + def set(self, key, newdata): + FooResource.elems[int(key)] = {'newdata': newdata} + return dict(key=key, newdata=newdata) + + +@Controller('/foo/:key/:method', secure=False) +class FooResourceDetail(RESTController): + def list(self, key, method): + return {'detail': (key, [method])} + + +@ApiController('/rgw/proxy', secure=False) +class GenerateControllerRoutesController(BaseController): + @Proxy() + def __call__(self, path, **params): + pass + + +@ApiController('/fooargs', secure=False) +class FooArgs(RESTController): + def set(self, code, name=None, opt1=None, opt2=None): + return {'code': code, 'name': name, 'opt1': opt1, 'opt2': opt2} + + @handle_rados_error('foo') + def create(self, my_arg_name): + return my_arg_name + + def list(self): + raise cherrypy.NotFound() + + +# pylint: disable=blacklisted-name +class Root(object): + foo = FooResource() + fooargs = FooArgs() + + +class RESTControllerTest(ControllerTestCase): + + @classmethod + def setup_server(cls): + cls.setup_controllers( + [FooResource, FooResourceDetail, FooArgs, GenerateControllerRoutesController]) + + def test_empty(self): + self._delete("/foo") + self.assertStatus(204) + self._get("/foo") + self.assertStatus('200 OK') + self.assertHeader('Content-Type', 'application/json') + self.assertBody('[]') + + def test_fill(self): + sess_mock = RamSession() + with patch('cherrypy.session', sess_mock, create=True): + data = {'a': 'b'} + for _ in range(5): + self._post("/foo", data) + self.assertJsonBody(data) + self.assertStatus(201) + self.assertHeader('Content-Type', 'application/json') + + self._get("/foo") + self.assertStatus('200 OK') + self.assertHeader('Content-Type', 'application/json') + self.assertJsonBody([data] * 5) + + self._put('/foo/0', {'newdata': 'newdata'}) + self.assertStatus('200 OK') + self.assertHeader('Content-Type', 'application/json') + self.assertJsonBody({'newdata': 'newdata', 'key': '0'}) + + def test_not_implemented(self): + self._put("/foo") + self.assertStatus(404) + body = self.jsonBody() + self.assertIsInstance(body, dict) + assert body['detail'] == "The path '/foo' was not found." + assert '404' in body['status'] + + def test_args_from_json(self): + self._put("/api/fooargs/hello", {'name': 'world'}) + self.assertJsonBody({'code': 'hello', 'name': 'world', 'opt1': None, 'opt2': None}) + + self._put("/api/fooargs/hello", {'name': 'world', 'opt1': 'opt1'}) + self.assertJsonBody({'code': 'hello', 'name': 'world', 'opt1': 'opt1', 'opt2': None}) + + self._put("/api/fooargs/hello", {'name': 'world', 'opt2': 'opt2'}) + self.assertJsonBody({'code': 'hello', 'name': 'world', 'opt1': None, 'opt2': 'opt2'}) + + def test_detail_route(self): + self._get('/foo/default') + self.assertJsonBody({'detail': ['default', []]}) + + self._get('/foo/default/default') + self.assertJsonBody({'detail': ['default', ['default']]}) + + self._get('/foo/1/detail') + self.assertJsonBody({'detail': ['1', ['detail']]}) + + self._post('/foo/1/detail', 'post-data') + self.assertStatus(404) + + def test_generate_controller_routes(self): + # We just need to add this controller in setup_server(): + # noinspection PyStatementEffect + # pylint: disable=pointless-statement + GenerateControllerRoutesController + + +class RequestLoggingToolTest(ControllerTestCase): + + def __init__(self, *args, **kwargs): + cherrypy.tools.request_logging = RequestLoggingTool() + cherrypy.config.update({'tools.request_logging.on': True}) + super(RequestLoggingToolTest, self).__init__(*args, **kwargs) + + @classmethod + def setup_server(cls): + cls.setup_controllers([FooResource]) + + def test_is_logged(self): + with patch('logging.Logger.debug') as mock_logger_debug: + self._put('/foo/0', {'newdata': 'xyz'}) + self.assertStatus(200) + call_args_list = mock_logger_debug.call_args_list + _, host, _, method, user, path = call_args_list[0][0] + self.assertEqual(host, '127.0.0.1') + self.assertEqual(method, 'PUT') + self.assertIsNone(user) + self.assertEqual(path, '/foo/0') + + +class TestFunctions(unittest.TestCase): + + def test_is_valid_ipv6_address(self): + self.assertTrue(is_valid_ipv6_address('::')) + self.assertTrue(is_valid_ipv6_address('::1')) + self.assertFalse(is_valid_ipv6_address('127.0.0.1')) + self.assertFalse(is_valid_ipv6_address('localhost')) + self.assertTrue(is_valid_ipv6_address('1200:0000:AB00:1234:0000:2552:7777:1313')) + self.assertFalse(is_valid_ipv6_address('1200::AB00:1234::2552:7777:1313')) + + def test_dict_contains_path(self): + x = {'a': {'b': {'c': 'foo'}}} + self.assertTrue(dict_contains_path(x, ['a', 'b', 'c'])) + self.assertTrue(dict_contains_path(x, ['a', 'b', 'c'])) + self.assertTrue(dict_contains_path(x, ['a'])) + self.assertFalse(dict_contains_path(x, ['a', 'c'])) + self.assertTrue(dict_contains_path(x, [])) diff --git a/src/pybind/mgr/dashboard/tools.py b/src/pybind/mgr/dashboard/tools.py new file mode 100644 index 00000000..82a82194 --- /dev/null +++ b/src/pybind/mgr/dashboard/tools.py @@ -0,0 +1,932 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import sys +import inspect +import json +import functools + +import collections +from datetime import datetime, timedelta +from distutils.util import strtobool +import fnmatch +import time +import threading +import socket +import six +from six.moves import urllib +import cherrypy + +try: + from urlparse import urljoin +except ImportError: + from urllib.parse import urljoin + +from . import logger, mgr +from .exceptions import ViewCacheNoDataException +from .settings import Settings +from .services.auth import JwtManager + + +def ensure_str(s, encoding='utf-8', errors='strict'): + """Ported from six.""" + if not isinstance(s, (six.text_type, six.binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + if six.PY2 and isinstance(s, six.text_type): + s = s.encode(encoding, errors) + elif six.PY3 and isinstance(s, six.binary_type): + s = s.decode(encoding, errors) + return s + + +class RequestLoggingTool(cherrypy.Tool): + def __init__(self): + cherrypy.Tool.__init__(self, 'before_handler', self.request_begin, + priority=10) + + def _setup(self): + cherrypy.Tool._setup(self) + cherrypy.request.hooks.attach('on_end_request', self.request_end, + priority=5) + cherrypy.request.hooks.attach('after_error_response', self.request_error, + priority=5) + + def request_begin(self): + req = cherrypy.request + user = JwtManager.get_username() + if user is not None: + # PY2: Encode user to str to prevent further implicit decoding + user = ensure_str(user) + # Log the request. + logger.debug('[%s:%s] [%s] [%s] %s', req.remote.ip, req.remote.port, + req.method, user, req.path_info) + # Audit the request. + if Settings.AUDIT_API_ENABLED and req.method not in ['GET']: + url = build_url(req.remote.ip, scheme=req.scheme, + port=req.remote.port) + msg = '[DASHBOARD] from=\'{}\' path=\'{}\' method=\'{}\' ' \ + 'user=\'{}\''.format(url, req.path_info, req.method, user) + if Settings.AUDIT_API_LOG_PAYLOAD: + params = dict(req.params or {}, **get_request_body_params(req)) + # Hide sensitive data like passwords, secret keys, ... + # Extend the list of patterns to search for if necessary. + # Currently parameters like this are processed: + # - secret_key + # - user_password + # - new_passwd_to_login + keys = [] + for key in ['password', 'passwd', 'secret']: + keys.extend([x for x in params.keys() if key in x]) + for key in keys: + params[key] = '***' + msg = '{} params=\'{}\''.format(msg, json.dumps(params)) + mgr.cluster_log('audit', mgr.CLUSTER_LOG_PRIO_INFO, msg) + + def request_error(self): + self._request_log(logger.error) + logger.error(cherrypy.response.body) + + def request_end(self): + status = cherrypy.response.status[:3] + if status in ["401"]: + # log unauthorized accesses + self._request_log(logger.warning) + else: + self._request_log(logger.info) + + def _format_bytes(self, num): + units = ['B', 'K', 'M', 'G'] + + if isinstance(num, str): + try: + num = int(num) + except ValueError: + return "n/a" + + format_str = "{:.0f}{}" + for i, unit in enumerate(units): + div = 2**(10*i) + if num < 2**(10*(i+1)): + if num % div == 0: + format_str = "{}{}" + else: + div = float(div) + format_str = "{:.1f}{}" + return format_str.format(num/div, unit[0]) + + # content-length bigger than 1T!! return value in bytes + return "{}B".format(num) + + def _request_log(self, logger_fn): + req = cherrypy.request + res = cherrypy.response + lat = time.time() - res.time + user = JwtManager.get_username() + status = res.status[:3] if isinstance(res.status, str) else res.status + if 'Content-Length' in res.headers: + length = self._format_bytes(res.headers['Content-Length']) + else: + length = self._format_bytes(0) + if user: + logger_fn("[%s:%s] [%s] [%s] [%s] [%s] [%s] %s", req.remote.ip, + req.remote.port, req.method, status, + "{0:.3f}s".format(lat), ensure_str(user), length, req.path_info) + else: + logger_fn("[%s:%s] [%s] [%s] [%s] [%s] %s", req.remote.ip, + req.remote.port, req.method, status, + "{0:.3f}s".format(lat), length, req.path_info) + + +# pylint: disable=too-many-instance-attributes +class ViewCache(object): + VALUE_OK = 0 + VALUE_STALE = 1 + VALUE_NONE = 2 + + class GetterThread(threading.Thread): + def __init__(self, view, fn, args, kwargs): + super(ViewCache.GetterThread, self).__init__() + self._view = view + self.event = threading.Event() + self.fn = fn + self.args = args + self.kwargs = kwargs + + # pylint: disable=broad-except + def run(self): + t0 = 0.0 + t1 = 0.0 + try: + t0 = time.time() + logger.debug("VC: starting execution of %s", self.fn) + val = self.fn(*self.args, **self.kwargs) + t1 = time.time() + except Exception as ex: + with self._view.lock: + logger.exception("Error while calling fn=%s ex=%s", self.fn, + str(ex)) + self._view.value = None + self._view.value_when = None + self._view.getter_thread = None + self._view.exception = ex + else: + with self._view.lock: + self._view.latency = t1 - t0 + self._view.value = val + self._view.value_when = datetime.now() + self._view.getter_thread = None + self._view.exception = None + + logger.debug("VC: execution of %s finished in: %s", self.fn, + t1 - t0) + self.event.set() + + class RemoteViewCache(object): + # Return stale data if + STALE_PERIOD = 1.0 + + def __init__(self, timeout): + self.getter_thread = None + # Consider data within 1s old to be sufficiently fresh + self.timeout = timeout + self.event = threading.Event() + self.value_when = None + self.value = None + self.latency = 0 + self.exception = None + self.lock = threading.Lock() + + def reset(self): + with self.lock: + self.value_when = None + self.value = None + + def run(self, fn, args, kwargs): + """ + If data less than `stale_period` old is available, return it + immediately. + If an attempt to fetch data does not complete within `timeout`, then + return the most recent data available, with a status to indicate that + it is stale. + + Initialization does not count towards the timeout, so the first call + on one of these objects during the process lifetime may be slower + than subsequent calls. + + :return: 2-tuple of value status code, value + """ + with self.lock: + now = datetime.now() + if self.value_when and now - self.value_when < timedelta( + seconds=self.STALE_PERIOD): + return ViewCache.VALUE_OK, self.value + + if self.getter_thread is None: + self.getter_thread = ViewCache.GetterThread(self, fn, args, + kwargs) + self.getter_thread.start() + else: + logger.debug("VC: getter_thread still alive for: %s", fn) + + ev = self.getter_thread.event + + success = ev.wait(timeout=self.timeout) + + with self.lock: + if success: + # We fetched the data within the timeout + if self.exception: + # execution raised an exception + # pylint: disable=raising-bad-type + raise self.exception + return ViewCache.VALUE_OK, self.value + if self.value_when is not None: + # We have some data, but it doesn't meet freshness requirements + return ViewCache.VALUE_STALE, self.value + # We have no data, not even stale data + raise ViewCacheNoDataException() + + def __init__(self, timeout=5): + self.timeout = timeout + self.cache_by_args = {} + + def __call__(self, fn): + def wrapper(*args, **kwargs): + rvc = self.cache_by_args.get(args, None) + if not rvc: + rvc = ViewCache.RemoteViewCache(self.timeout) + self.cache_by_args[args] = rvc + return rvc.run(fn, args, kwargs) + wrapper.reset = self.reset + return wrapper + + def reset(self): + for _, rvc in self.cache_by_args.items(): + rvc.reset() + + +class NotificationQueue(threading.Thread): + _ALL_TYPES_ = '__ALL__' + _listeners = collections.defaultdict(set) + _lock = threading.Lock() + _cond = threading.Condition() + _queue = collections.deque() + _running = False + _instance = None + + def __init__(self): + super(NotificationQueue, self).__init__() + + @classmethod + def start_queue(cls): + with cls._lock: + if cls._instance: + # the queue thread is already running + return + cls._running = True + cls._instance = NotificationQueue() + logger.debug("starting notification queue") + cls._instance.start() + + @classmethod + def stop(cls): + with cls._lock: + if not cls._instance: + # the queue thread was not started + return + instance = cls._instance + cls._instance = None + cls._running = False + with cls._cond: + cls._cond.notify() + logger.debug("waiting for notification queue to finish") + instance.join() + logger.debug("notification queue stopped") + + @classmethod + def _registered_handler(cls, func, n_types): + for _, reg_func in cls._listeners[n_types]: + if reg_func == func: + return True + return False + + @classmethod + def register(cls, func, n_types=None, priority=1): + """Registers function to listen for notifications + + If the second parameter `n_types` is omitted, the function in `func` + parameter will be called for any type of notifications. + + Args: + func (function): python function ex: def foo(val) + n_types (str|list): the single type to listen, or a list of types + priority (int): the priority level (1=max, +inf=min) + """ + with cls._lock: + if not n_types: + n_types = [cls._ALL_TYPES_] + elif isinstance(n_types, str): + n_types = [n_types] + elif not isinstance(n_types, list): + raise Exception("n_types param is neither a string nor a list") + for ev_type in n_types: + if not cls._registered_handler(func, ev_type): + cls._listeners[ev_type].add((priority, func)) + logger.debug("NQ: function %s was registered for events of" + " type %s", func, ev_type) + + @classmethod + def deregister(cls, func, n_types=None): + """Removes the listener function from this notification queue + + If the second parameter `n_types` is omitted, the function is removed + from all event types, otherwise the function is removed only for the + specified event types. + + Args: + func (function): python function + n_types (str|list): the single event type, or a list of event types + """ + with cls._lock: + if not n_types: + n_types = list(cls._listeners.keys()) + elif isinstance(n_types, str): + n_types = [n_types] + elif not isinstance(n_types, list): + raise Exception("n_types param is neither a string nor a list") + for ev_type in n_types: + listeners = cls._listeners[ev_type] + toRemove = None + for pr, fn in listeners: + if fn == func: + toRemove = (pr, fn) + break + if toRemove: + listeners.discard(toRemove) + logger.debug("NQ: function %s was deregistered for events " + "of type %s", func, ev_type) + + @classmethod + def new_notification(cls, notify_type, notify_value): + with cls._cond: + cls._queue.append((notify_type, notify_value)) + cls._cond.notify() + + @classmethod + def _notify_listeners(cls, events): + for ev in events: + notify_type, notify_value = ev + with cls._lock: + listeners = list(cls._listeners[notify_type]) + listeners.extend(cls._listeners[cls._ALL_TYPES_]) + listeners.sort(key=lambda lis: lis[0]) + for listener in listeners: + listener[1](notify_value) + + def run(self): + logger.debug("notification queue started") + while self._running: + private_buffer = [] + logger.debug("NQ: processing queue: %s", len(self._queue)) + try: + while True: + private_buffer.append(self._queue.popleft()) + except IndexError: + pass + self._notify_listeners(private_buffer) + with self._cond: + while self._running and not self._queue: + self._cond.wait() + # flush remaining events + logger.debug("NQ: flush remaining events: %s", len(self._queue)) + self._notify_listeners(self._queue) + self._queue.clear() + logger.debug("notification queue finished") + + +# pylint: disable=too-many-arguments, protected-access +class TaskManager(object): + FINISHED_TASK_SIZE = 10 + FINISHED_TASK_TTL = 60.0 + + VALUE_DONE = "done" + VALUE_EXECUTING = "executing" + + _executing_tasks = set() + _finished_tasks = [] + _lock = threading.Lock() + + _task_local_data = threading.local() + + @classmethod + def init(cls): + NotificationQueue.register(cls._handle_finished_task, 'cd_task_finished') + + @classmethod + def _handle_finished_task(cls, task): + logger.info("TM: finished %s", task) + with cls._lock: + cls._executing_tasks.remove(task) + cls._finished_tasks.append(task) + + @classmethod + def run(cls, name, metadata, fn, args=None, kwargs=None, executor=None, + exception_handler=None): + if not args: + args = [] + if not kwargs: + kwargs = {} + if not executor: + executor = ThreadedExecutor() + task = Task(name, metadata, fn, args, kwargs, executor, + exception_handler) + with cls._lock: + if task in cls._executing_tasks: + logger.debug("TM: task already executing: %s", task) + for t in cls._executing_tasks: + if t == task: + return t + logger.debug("TM: created %s", task) + cls._executing_tasks.add(task) + logger.info("TM: running %s", task) + task._run() + return task + + @classmethod + def current_task(cls): + """ + Returns the current task object. + This method should only be called from a threaded task operation code. + """ + return cls._task_local_data.task + + @classmethod + def _cleanup_old_tasks(cls, task_list): + """ + The cleanup rule is: maintain the FINISHED_TASK_SIZE more recent + finished tasks, and the rest is maintained up to the FINISHED_TASK_TTL + value. + """ + now = datetime.now() + for idx, t in enumerate(task_list): + if idx < cls.FINISHED_TASK_SIZE: + continue + if now - datetime.fromtimestamp(t[1].end_time) > \ + timedelta(seconds=cls.FINISHED_TASK_TTL): + del cls._finished_tasks[t[0]] + + @classmethod + def list(cls, name_glob=None): + executing_tasks = [] + finished_tasks = [] + with cls._lock: + for task in cls._executing_tasks: + if not name_glob or fnmatch.fnmatch(task.name, name_glob): + executing_tasks.append(task) + for idx, task in enumerate(cls._finished_tasks): + if not name_glob or fnmatch.fnmatch(task.name, name_glob): + finished_tasks.append((idx, task)) + finished_tasks.sort(key=lambda t: t[1].end_time, reverse=True) + cls._cleanup_old_tasks(finished_tasks) + executing_tasks.sort(key=lambda t: t.begin_time, reverse=True) + return executing_tasks, [t[1] for t in finished_tasks] + + @classmethod + def list_serializable(cls, ns_glob=None): + ex_t, fn_t = cls.list(ns_glob) + return [{ + 'name': t.name, + 'metadata': t.metadata, + 'begin_time': "{}Z".format(datetime.fromtimestamp(t.begin_time).isoformat()), + 'progress': t.progress + } for t in ex_t if t.begin_time], [{ + 'name': t.name, + 'metadata': t.metadata, + 'begin_time': "{}Z".format(datetime.fromtimestamp(t.begin_time).isoformat()), + 'end_time': "{}Z".format(datetime.fromtimestamp(t.end_time).isoformat()), + 'duration': t.duration, + 'progress': t.progress, + 'success': not t.exception, + 'ret_value': t.ret_value if not t.exception else None, + 'exception': t.ret_value if t.exception and t.ret_value else ( + {'detail': str(t.exception)} if t.exception else None) + } for t in fn_t] + + +# pylint: disable=protected-access +class TaskExecutor(object): + def __init__(self): + self.task = None + + def init(self, task): + self.task = task + + # pylint: disable=broad-except + def start(self): + logger.debug("EX: executing task %s", self.task) + try: + self.task.fn(*self.task.fn_args, **self.task.fn_kwargs) + except Exception as ex: + logger.exception("Error while calling %s", self.task) + self.finish(None, ex) + + def finish(self, ret_value, exception): + if not exception: + logger.debug("EX: successfully finished task: %s", self.task) + else: + logger.debug("EX: task finished with exception: %s", self.task) + self.task._complete(ret_value, exception) + + +# pylint: disable=protected-access +class ThreadedExecutor(TaskExecutor): + def __init__(self): + super(ThreadedExecutor, self).__init__() + self._thread = threading.Thread(target=self._run) + + def start(self): + self._thread.start() + + # pylint: disable=broad-except + def _run(self): + TaskManager._task_local_data.task = self.task + try: + logger.debug("TEX: executing task %s", self.task) + val = self.task.fn(*self.task.fn_args, **self.task.fn_kwargs) + except Exception as ex: + logger.exception("Error while calling %s", self.task) + self.finish(None, ex) + else: + self.finish(val, None) + + +class Task(object): + def __init__(self, name, metadata, fn, args, kwargs, executor, + exception_handler=None): + self.name = name + self.metadata = metadata + self.fn = fn + self.fn_args = args + self.fn_kwargs = kwargs + self.executor = executor + self.ex_handler = exception_handler + self.running = False + self.event = threading.Event() + self.progress = None + self.ret_value = None + self.begin_time = None + self.end_time = None + self.duration = 0 + self.exception = None + self.lock = threading.Lock() + + def __hash__(self): + return hash((self.name, tuple(sorted(self.metadata.items())))) + + def __eq__(self, other): + return self.name == other.name and self.metadata == other.metadata + + def __str__(self): + return "Task(ns={}, md={})" \ + .format(self.name, self.metadata) + + def __repr__(self): + return str(self) + + def _run(self): + NotificationQueue.register(self._handle_task_finished, 'cd_task_finished', 100) + with self.lock: + assert not self.running + self.executor.init(self) + self.set_progress(0, in_lock=True) + self.begin_time = time.time() + self.running = True + self.executor.start() + + def _complete(self, ret_value, exception=None): + now = time.time() + if exception and self.ex_handler: + # pylint: disable=broad-except + try: + ret_value = self.ex_handler(exception, task=self) + except Exception as ex: + exception = ex + with self.lock: + assert self.running, "_complete cannot be called before _run" + self.end_time = now + self.ret_value = ret_value + self.exception = exception + self.duration = now - self.begin_time + if not self.exception: + self.set_progress(100, True) + NotificationQueue.new_notification('cd_task_finished', self) + logger.debug("TK: execution of %s finished in: %s s", self, + self.duration) + + def _handle_task_finished(self, task): + if self == task: + NotificationQueue.deregister(self._handle_task_finished) + self.event.set() + + def wait(self, timeout=None): + with self.lock: + assert self.running, "wait cannot be called before _run" + ev = self.event + + success = ev.wait(timeout=timeout) + with self.lock: + if success: + # the action executed within the timeout + if self.exception: + # pylint: disable=raising-bad-type + # execution raised an exception + raise self.exception + return TaskManager.VALUE_DONE, self.ret_value + # the action is still executing + return TaskManager.VALUE_EXECUTING, None + + def inc_progress(self, delta, in_lock=False): + if not isinstance(delta, int) or delta < 0: + raise Exception("Progress delta value must be a positive integer") + if not in_lock: + self.lock.acquire() + prog = self.progress + delta + self.progress = prog if prog <= 100 else 100 + if not in_lock: + self.lock.release() + + def set_progress(self, percentage, in_lock=False): + if not isinstance(percentage, int) or percentage < 0 or percentage > 100: + raise Exception("Progress value must be in percentage " + "(0 <= percentage <= 100)") + if not in_lock: + self.lock.acquire() + self.progress = percentage + if not in_lock: + self.lock.release() + + +def is_valid_ip_address(addr): + """ + Validate the given IPv4 or IPv6 address. + + >>> is_valid_ip_address('2001:0db8::1234') + True + + >>> is_valid_ip_address('192.168.121.1') + True + + >>> is_valid_ip_address('1:::1') + False + + >>> is_valid_ip_address('8.1.0') + False + + >>> is_valid_ip_address('260.1.0.1') + False + + :param addr: + :type addr: str + :return: Returns ``True`` if the IP address is valid, + otherwise ``False``. + :rtype: bool + """ + return is_valid_ipv4_address(addr) or is_valid_ipv6_address(addr) + + +def is_valid_ipv4_address(addr): + """ + Validate the given IPv4 address. + + >>> is_valid_ipv4_address('0.0.0.0') + True + + >>> is_valid_ipv4_address('192.168.121.1') + True + + >>> is_valid_ipv4_address('a.b.c.d') + False + + >>> is_valid_ipv4_address('172.1.0.a') + False + + >>> is_valid_ipv4_address('2001:0db8::1234') + False + + >>> is_valid_ipv4_address(None) + False + + >>> is_valid_ipv4_address(123456) + False + + :param addr: + :type addr: str + :return: Returns ``True`` if the IPv4 address is valid, + otherwise ``False``. + :rtype: bool + """ + try: + socket.inet_pton(socket.AF_INET, addr) + return True + except (socket.error, TypeError): + return False + + +def is_valid_ipv6_address(addr): + """ + Validate the given IPv6 address. + + >>> is_valid_ipv6_address('2001:0db8::1234') + True + + >>> is_valid_ipv6_address('fe80::bc6c:66b0:5af8:f44') + True + + >>> is_valid_ipv6_address('192.168.121.1') + False + + >>> is_valid_ipv6_address('a:x::1') + False + + >>> is_valid_ipv6_address('1200:0000:AB00:1234:O000:2552:7777:1313') + False + + >>> is_valid_ipv6_address(None) + False + + >>> is_valid_ipv6_address(123456) + False + + :param addr: + :type addr: str + :return: Returns ``True`` if the IPv6 address is valid, + otherwise ``False``. + :rtype: bool + """ + try: + socket.inet_pton(socket.AF_INET6, addr) + return True + except (socket.error, TypeError): + return False + + +def build_url(host, scheme=None, port=None): + """ + Build a valid URL. IPv6 addresses specified in host will be enclosed in brackets + automatically. + + >>> build_url('example.com', 'https', 443) + 'https://example.com:443' + + >>> build_url(host='example.com', port=443) + '//example.com:443' + + >>> build_url('fce:9af7:a667:7286:4917:b8d3:34df:8373', port=80, scheme='http') + 'http://[fce:9af7:a667:7286:4917:b8d3:34df:8373]:80' + + :param scheme: The scheme, e.g. http, https or ftp. + :type scheme: str + :param host: Consisting of either a registered name (including but not limited to + a hostname) or an IP address. + :type host: str + :type port: int + :rtype: str + """ + netloc = host if not is_valid_ipv6_address(host) else '[{}]'.format(host) + if port: + netloc += ':{}'.format(port) + pr = urllib.parse.ParseResult( + scheme=scheme if scheme else '', + netloc=netloc, + path='', + params='', + query='', + fragment='') + return pr.geturl() + + +def prepare_url_prefix(url_prefix): + """ + return '' if no prefix, or '/prefix' without slash in the end. + """ + url_prefix = urljoin('/', url_prefix) + return url_prefix.rstrip('/') + + +def dict_contains_path(dct, keys): + """ + Tests whether the keys exist recursively in `dictionary`. + + :type dct: dict + :type keys: list + :rtype: bool + """ + if keys: + if not isinstance(dct, dict): + return False + key = keys.pop(0) + if key in dct: + dct = dct[key] + return dict_contains_path(dct, keys) + return False + return True + + +if sys.version_info > (3, 0): + wraps = functools.wraps + _getargspec = inspect.getfullargspec +else: + def wraps(func): + def decorator(wrapper): + new_wrapper = functools.wraps(func)(wrapper) + new_wrapper.__wrapped__ = func # set __wrapped__ even for Python 2 + return new_wrapper + return decorator + + _getargspec = inspect.getargspec + + +def getargspec(func): + try: + while True: + func = func.__wrapped__ + except AttributeError: + pass + # pylint: disable=deprecated-method + return _getargspec(func) + + +def str_to_bool(val): + """ + Convert a string representation of truth to True or False. + + >>> str_to_bool('true') and str_to_bool('yes') and str_to_bool('1') and str_to_bool(True) + True + + >>> str_to_bool('false') and str_to_bool('no') and str_to_bool('0') and str_to_bool(False) + False + + >>> str_to_bool('xyz') + Traceback (most recent call last): + ... + ValueError: invalid truth value 'xyz' + + :param val: The value to convert. + :type val: str|bool + :rtype: bool + """ + if isinstance(val, bool): + return val + return bool(strtobool(val)) + + +def get_request_body_params(request): + """ + Helper function to get parameters from the request body. + :param request The CherryPy request object. + :type request: cherrypy.Request + :return: A dictionary containing the parameters. + :rtype: dict + """ + params = {} + if request.method not in request.methods_with_bodies: + return params + + content_type = request.headers.get('Content-Type', '') + if content_type in ['application/json', 'text/javascript']: + if not hasattr(request, 'json'): + raise cherrypy.HTTPError(400, 'Expected JSON body') + if isinstance(request.json, str): + params.update(json.loads(request.json)) + else: + params.update(request.json) + + return params + + +def find_object_in_list(key, value, iterable): + """ + Get the first occurrence of an object within a list with + the specified key/value. + + >>> find_object_in_list('name', 'bar', [{'name': 'foo'}, {'name': 'bar'}]) + {'name': 'bar'} + + >>> find_object_in_list('name', 'xyz', [{'name': 'foo'}, {'name': 'bar'}]) is None + True + + >>> find_object_in_list('foo', 'bar', [{'xyz': 4815162342}]) is None + True + + >>> find_object_in_list('foo', 'bar', []) is None + True + + :param key: The name of the key. + :param value: The value to search for. + :param iterable: The list to process. + :return: Returns the found object or None. + """ + for obj in iterable: + if key in obj and obj[key] == value: + return obj + return None diff --git a/src/pybind/mgr/dashboard/tox.ini b/src/pybind/mgr/dashboard/tox.ini new file mode 100644 index 00000000..e9614a50 --- /dev/null +++ b/src/pybind/mgr/dashboard/tox.ini @@ -0,0 +1,30 @@ +[tox] +envlist = py27-{cov,lint,run,check},py3-{cov,lint,run,check} +skipsdist = true +toxworkdir = {env:CEPH_BUILD_DIR}/dashboard +minversion = 2.8.1 + +[testenv] +setenv= + CFLAGS = -DXMLSEC_NO_SIZE_T + UNITTEST = true + WEBTEST_INTERACTIVE = false + LD_LIBRARY_PATH = {toxinidir}/../../../../build/lib + PATH = {toxinidir}/../../../../build/bin:{env:PATH} + py27: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.2 + py3: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.3 + cov: UNITTEST = true + cov: COVERAGE_FILE = .coverage.{envname} +commands= + pip install -r {toxinidir}/requirements.txt + py27: pip install -r {toxinidir}/requirements-py27.txt + py3: pip install -r {toxinidir}/requirements-py3.txt + cov: coverage erase + cov: {envbindir}/py.test --cov=. --cov-report= --junitxml=junit.{envname}.xml --doctest-modules controllers services/ tests/ tools.py + cov: coverage combine {toxinidir}/{env:COVERAGE_FILE} + cov: coverage report + cov: coverage xml + lint: pylint --rcfile=.pylintrc --jobs=5 . module.py tools.py controllers tests services exceptions.py grafana.py ci/check_grafana_uids.py + lint: pycodestyle --max-line-length=100 --exclude=.tox,venv,frontend,.vscode --ignore=E402,E121,E123,E126,E226,E24,E704,W503,E741 . + check: python ci/check_grafana_uids.py frontend/src/app ../../../../monitoring/grafana/dashboards + run: {posargs} diff --git a/src/pybind/mgr/deepsea/__init__.py b/src/pybind/mgr/deepsea/__init__.py new file mode 100644 index 00000000..99bad018 --- /dev/null +++ b/src/pybind/mgr/deepsea/__init__.py @@ -0,0 +1 @@ +from .module import DeepSeaOrchestrator diff --git a/src/pybind/mgr/deepsea/module.py b/src/pybind/mgr/deepsea/module.py new file mode 100644 index 00000000..734a457d --- /dev/null +++ b/src/pybind/mgr/deepsea/module.py @@ -0,0 +1,527 @@ +# vim: ts=8 et sw=4 sts=4 +""" +ceph-mgr DeepSea orchestrator module +""" + +# We want orchestrator methods in this to be 1:1 mappings to DeepSea runners, +# we don't want to aggregate multiple salt invocations here, because that means +# this module would need to know too much about how DeepSea works internally. +# Better to expose new runners from DeepSea to match what the orchestrator needs. + +import json +import errno +import requests + +from threading import Event, Thread, Lock + +from mgr_module import MgrModule +import orchestrator + + +class RequestException(Exception): + def __init__(self, message, status_code=None): + super(RequestException, self).__init__(message) + self.status_code = status_code + + +class DeepSeaReadCompletion(orchestrator.ReadCompletion): + def __init__(self, process_result_callback): + super(DeepSeaReadCompletion, self).__init__() + self._complete = False + self._cb = process_result_callback + + def _process_result(self, data): + self._result = self._cb(data) + self._complete = True + + @property + def result(self): + return self._result + + @property + def is_complete(self): + return self._complete + + +class DeepSeaOrchestrator(MgrModule, orchestrator.Orchestrator): + MODULE_OPTIONS = [ + { + 'name': 'salt_api_url', + 'default': '' + }, + { + 'name': 'salt_api_eauth', + 'default': 'sharedsecret' + }, + { + 'name': 'salt_api_username', + 'default': '' + }, + { + 'name': 'salt_api_password', + 'default': '' + } + ] + + + COMMANDS = [ + { + "cmd": "deepsea config-set name=key,type=CephString " + "name=value,type=CephString", + "desc": "Set a configuration value", + "perm": "rw" + }, + { + "cmd": "deepsea config-show", + "desc": "Show current configuration", + "perm": "r" + } + ] + + + @property + def config_keys(self): + return dict((o['name'], o.get('default', None)) for o in self.MODULE_OPTIONS) + + + def get_module_option(self, key, default=None): + """ + Overrides the default MgrModule get_module_option() method to pull in defaults + specific to this module + """ + return super(DeepSeaOrchestrator, self).get_module_option(key, default=self.config_keys[key]) + + + def _config_valid(self): + for key in self.config_keys.keys(): + if not self.get_module_option(key, self.config_keys[key]): + return False + return True + + + def __init__(self, *args, **kwargs): + super(DeepSeaOrchestrator, self).__init__(*args, **kwargs) + self._event = Event() + self._token = None + self._event_reader = None + self._reading_events = False + self._last_failure_msg = None + self._all_completions = dict() + self._completion_lock = Lock() + self.inventory_cache = orchestrator.OutdatableDict() + self.service_cache = orchestrator.OutdatableDict() + + def available(self): + if not self._config_valid(): + return False, "Configuration invalid; try `ceph deepsea config-set [...]`" + + if not self._reading_events and self._last_failure_msg: + return False, self._last_failure_msg + + return True, "" + + def get_inventory(self, node_filter=None, refresh=False): + """ + Note that this will raise an exception (e.g. if the salt-api is down, + or the username/password is incorret). Same for other methods. + Callers should expect this and react appropriately. The orchestrator + cli, for example, just prints the traceback in the console, so the + user at least sees the error. + """ + self.inventory_cache.remove_outdated() + if not self.inventory_cache.any_outdated() and not refresh: + if node_filter is None: + return orchestrator.TrivialReadCompletion( + orchestrator.InventoryNode.from_nested_items(self.inventory_cache.items())) + elif node_filter.labels is None: + try: + return orchestrator.TrivialReadCompletion( + orchestrator.InventoryNode.from_nested_items( + self.inventory_cache.items_filtered(node_filter.nodes))) + except KeyError: + # items_filtered() will raise KeyError if passed a node name that doesn't exist + return orchestrator.TrivialReadCompletion([]) + + def process_result(event_data): + result = [] + if event_data['success']: + for node_name, node_devs in event_data["return"].items(): + if node_filter is None: + # The cache will only be populated when this function is invoked + # without a node filter, i.e. if you run it once for the whole + # cluster, you can then call it for individual nodes and return + # cached data. However, if you only *ever* call it for individual + # nodes, the cache will never be populated, and you'll always have + # the full round trip to DeepSea. + self.inventory_cache[node_name] = orchestrator.OutdatableData(node_devs) + devs = orchestrator.InventoryDevice.from_ceph_volume_inventory_list(node_devs) + result.append(orchestrator.InventoryNode(node_name, devs)) + else: + self.log.error(event_data['return']) + return result + + with self._completion_lock: + c = DeepSeaReadCompletion(process_result) + + nodes = [] + roles = [] + if node_filter: + nodes = node_filter.nodes + roles = node_filter.labels + + resp = self._do_request_with_login("POST", data = { + "client": "runner_async", + "fun": "mgr_orch.get_inventory", + "nodes": nodes, + "roles": roles + }) + + # ['return'][0]['tag'] in the resonse JSON is what we need to match + # on when looking for the result event (e.g.: "salt/run/20181018074024331230") + self._all_completions["{}/ret".format(resp.json()['return'][0]['tag'])] = c + + return c + + def describe_service(self, service_type=None, service_id=None, node_name=None, refresh=False): + + # Note: describe_service() does *not* support OSDs. This is because + # DeepSea doesn't really record what OSDs are deployed where; Ceph is + # considered the canonical source of this information, so having this + # function query OSD information from DeepSea doesn't make a lot of + # sense (DeepSea would have to call back into Ceph). + + assert service_type in ("mon", "mgr", "mds", "rgw", "nfs", "iscsi", None), service_type + " unsupported" + + def _deepsea_to_ceph(service): + if service == "ganesha": + return "nfs" + elif service == "igw": + return "iscsi" + else: + return service + + # presently unused + def _ceph_to_deepsea(service): + if service == "nfs": + return "ganesha" + elif service == "iscsi": + return "igw" + else: + return service + + self.service_cache.remove_outdated() + if not self.service_cache.any_outdated() and not refresh: + # Let's hope the services are complete. + try: + node_filter = [node_name] if node_name else None + services_by_node = [d[1].data for d in self.service_cache.items_filtered(node_filter)] + services = [orchestrator.ServiceDescription.from_json(s) for services in services_by_node for s in services] + services = [s for s in services if + (True if service_type is None else s.service_type == service_type) and + (True if service_id is None else s.service_instance == service_id)] + return orchestrator.TrivialReadCompletion(services) + except KeyError: + # items_filtered() will raise KeyError if passed a node name that doesn't exist + return orchestrator.TrivialReadCompletion([]) + + def process_result(event_data): + result = [] + if event_data['success']: + for service_node, service_info in event_data["return"].items(): + node_service_cache = [] + for this_service_type, service_dict in service_info.items(): + if isinstance(service_dict, str): + # map old form where deepsea only returned service IDs + # to new form where it retuns a dict + service_dict = { 'service_instance': service_dict } + desc = orchestrator.ServiceDescription(nodename=service_node, + service_instance=service_dict['service_instance'], + service_type=_deepsea_to_ceph(this_service_type), + # the following may or may not be present + container_id=service_dict.get('container_id', None), + service=service_dict.get('service', None), + version=service_dict.get('version', None), + rados_config_location=service_dict.get('rados_config_location', None), + service_url = service_dict.get('service_url', None), + status=service_dict.get('status', None), + status_desc=service_dict.get('status_desc', None) + ) + # Always add every service to the cache... + node_service_cache.append(desc.to_json()) + # ...but only return the ones the caller asked for + if ((service_type is None or desc.service_type == service_type) and + (service_id is None or desc.service_instance == service_id) and + (node_name is None or desc.nodename == node_name)): + result.append(desc) + + self.service_cache[service_node] = orchestrator.OutdatableData(node_service_cache) + else: + self.log.error(event_data['return']) + return result + + with self._completion_lock: + c = DeepSeaReadCompletion(process_result) + + # Always request all services, so we always have all services cached. + resp = self._do_request_with_login("POST", data = { + "client": "runner_async", + "fun": "mgr_orch.describe_service" + }) + self._all_completions["{}/ret".format(resp.json()['return'][0]['tag'])] = c + + return c + + def wait(self, completions): + incomplete = False + + with self._completion_lock: + for c in completions: + if c.is_complete: + continue + if not c.is_complete: + # TODO: the job is in the bus, it should reach us eventually + # unless something has gone wrong (e.g. salt-api died, etc.), + # in which case it's possible the job finished but we never + # noticed the salt/run/$id/ret event. Need to add the job ID + # (or possibly the full event tag) to the completion object. + # That way, if we want to double check on a job that hasn't + # been completed yet, we can make a synchronous request to + # salt-api to invoke jobs.lookup_jid, and if it's complete we + # should be able to pass its return value to _process_result() + # Question: do we do this automatically after some timeout? + # Or do we add a function so the admin can check and "unstick" + # a stuck completion? + incomplete = True + + return not incomplete + + + def handle_command(self, inbuf, cmd): + if cmd['prefix'] == 'deepsea config-show': + return 0, json.dumps(dict([(key, self.get_module_option(key)) for key in self.config_keys.keys()])), '' + + elif cmd['prefix'] == 'deepsea config-set': + if cmd['key'] not in self.config_keys.keys(): + return (-errno.EINVAL, '', + "Unknown configuration option '{0}'".format(cmd['key'])) + + self.set_module_option(cmd['key'], cmd['value']) + self._event.set() + return 0, "Configuration option '{0}' updated".format(cmd['key']), '' + + return (-errno.EINVAL, '', + "Command not found '{0}'".format(cmd['prefix'])) + + + def serve(self): + self.log.info('DeepSea module starting up') + self.run = True + while self.run: + if not self._config_valid(): + # This will spin until the config is valid, spitting a warning + # that the config is invalid every 60 seconds. The one oddity + # is that while setting the various parameters, this log warning + # will print once for each parameter set until the config is valid. + self.log.warn("Configuration invalid; try `ceph deepsea config-set [...]`") + self._event.wait(60) + self._event.clear() + continue + + if self._event_reader and not self._reading_events: + self._event_reader = None + + if not self._event_reader: + self._last_failure_msg = None + try: + # This spawns a separate thread to read the salt event bus + # stream. We can't do it in the serve thead, because reading + # from the response blocks, which would prevent the serve + # thread from handling anything else. + # + # TODO: figure out how to restart the _event_reader thread if + # config changes, e.g.: a new username or password is set. + # This will be difficult, because _read_sse() just blocks waiting + # for response lines. The closest I got was setting a read timeout + # on the request, but in the general case (where not much is + # happening most of the time), this will result in continual + # timeouts and reconnects. We really need an asynchronous read + # to support this. + self._event_response = self._do_request_with_login("GET", "events", stream=True) + self._event_reader = Thread(target=self._read_sse) + self._reading_events = True + self._event_reader.start() + except Exception as ex: + self._set_last_failure_msg("Failure setting up event reader: " + str(ex)) + # gives an (arbitrary) 60 second retry if we can't attach to + # the salt-api event bus for some reason (e.g.: invalid username, + # or password, which will be logged as "Request failed with status + # code 401"). Note that this 60 second retry will also happen if + # salt-api dies. + self._event.wait(60) + self._event.clear() + continue + + # Wait indefinitely for something interesting to happen (e.g. + # config-set, or shutdown), or the event reader to fail, which + # will happen if the salt-api server dies or restarts). + self._event.wait() + self._event.clear() + + + def shutdown(self): + self.log.info('DeepSea module shutting down') + self.run = False + self._event.set() + + + def _set_last_failure_msg(self, msg): + self._last_failure_msg = msg + self.log.warn(msg) + + + # Reader/parser of SSE events, see: + # - https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html#events) + # - https://www.w3.org/TR/2009/WD-eventsource-20090421/ + # Note: this is pretty braindead and doesn't implement the full eventsource + # spec, but it *does* implement enough for us to listen to events from salt + # and potentially do something with them. + def _read_sse(self): + event = {} + try: + # Just starting the event reader; if we've made it here, we know we're + # talking to salt-api (_do_request would have raised an exception if the + # response wasn't ok), so check if there's any completions inflight that + # need to be dealt with. This handles the case where some command was + # invoked, then salt-api died somehow, and we reconneced, but missed the + # completion at the time it actually happened. + for tag in list(self._all_completions): + self.log.info("Found event {} inflight".format(tag)) + try: + resp = self._do_request_with_login("POST", data = { + "client": "runner", + "fun": "jobs.lookup_jid", + "jid": tag.split('/')[2] + }) + # jobs.lookup_jid returns a dict keyed by hostname. + return_dict = resp.json()['return'][0] + if return_dict: + # If the job is complete, there'll be one item in the dict. + self.log.info("Event {} complete".format(tag)) + # The key is the salt master hostname, but we don't care + # about that, so just grab the data. + data = next(iter(return_dict.items()))[1] + self._all_completions[tag]._process_result(data) + # TODO: decide whether it's bad to delete the completion + # here -- would we ever need to resurrect it? + del self._all_completions[tag] + else: + # if the job is not complete, there'll be nothing in the dict + self.log.info("Event {} still pending".format(tag)) + except Exception as ex: + # Logging a warning if the request failed, so we can continue + # checking any other completions, then get onto reading events + self.log.warn("Error looking up inflight event {}: {}".format(tag, str(ex))) + + for line in self._event_response.iter_lines(): + with self._completion_lock: + if line: + line = line.decode('utf-8') + colon = line.find(':') + if colon > 0: + k = line[:colon] + v = line[colon+2:] + if k == "retry": + # TODO: find out if we need to obey this reconnection time + self.log.warn("Server requested retry {}, ignored".format(v)) + else: + event[k] = v + else: + # Empty line, terminates an event. Note that event['tag'] + # is a salt-api extension to SSE to avoid having to decode + # json data if you don't care about it. To get to the + # interesting stuff, you want event['data'], which is json. + # If you want to have some fun, try + # `ceph daemon mgr.$(hostname) config set debug_mgr 20` + # then `salt '*' test.ping` on the master + self.log.debug("Got event '{}'".format(str(event))) + + # If we're actually interested in this event (i.e. it's + # in our completion dict), fire off that completion's + # _process_result() callback and remove it from our list. + if event['tag'] in self._all_completions: + self.log.info("Event {} complete".format(event['tag'])) + self._all_completions[event['tag']]._process_result(json.loads(event['data'])['data']) + # TODO: decide whether it's bad to delete the completion + # here -- would we ever need to resurrect it? + del self._all_completions[event['tag']] + + event = {} + self._set_last_failure_msg("SSE read terminated") + except Exception as ex: + self.log.exception(ex) + self._set_last_failure_msg("SSE read failed: {}".format(str(ex))) + + self._reading_events = False + self._event.set() + + + # _do_request(), _login() and _do_request_with_login() are an extremely + # minimalist form of the following, with notably terse error handling: + # https://bitbucket.org/openattic/openattic/src/ce4543d4cbedadc21b484a098102a16efec234f9/backend/rest_client.py?at=master&fileviewer=file-view-default + # https://bitbucket.org/openattic/openattic/src/ce4543d4cbedadc21b484a098102a16efec234f9/backend/deepsea.py?at=master&fileviewer=file-view-default + # rationale: + # - I needed slightly different behaviour than in openATTIC (I want the + # caller to read the response, to allow streaming the salt-api event bus) + # - I didn't want to pull in 400+ lines more code into this presently + # experimental module, to save everyone having to review it ;-) + + def _do_request(self, method, path="", data=None, stream=False): + """ + returns the response, which the caller then has to read + """ + url = "{0}/{1}".format(self.get_module_option('salt_api_url'), path) + try: + if method.lower() == 'get': + resp = requests.get(url, headers = { "X-Auth-Token": self._token }, + data=data, stream=stream) + elif method.lower() == 'post': + resp = requests.post(url, headers = { "X-Auth-Token": self._token }, + data=data) + + else: + raise RequestException("Method '{}' not supported".format(method.upper())) + if resp.ok: + return resp + else: + msg = "Request failed with status code {}".format(resp.status_code) + raise RequestException(msg, resp.status_code) + except requests.exceptions.ConnectionError as ex: + self.log.exception(str(ex)) + raise RequestException(str(ex)) + except requests.exceptions.InvalidURL as ex: + self.log.exception(str(ex)) + raise RequestException(str(ex)) + + + def _login(self): + resp = self._do_request('POST', 'login', data = { + "eauth": self.get_module_option('salt_api_eauth'), + "password": self.get_module_option('salt_api_password'), + "username": self.get_module_option('salt_api_username') + }) + self._token = resp.json()['return'][0]['token'] + self.log.info("Salt API login successful") + + + def _do_request_with_login(self, method, path="", data=None, stream=False): + retries = 2 + while True: + try: + if not self._token: + self._login() + return self._do_request(method, path, data, stream) + except RequestException as ex: + retries -= 1 + if ex.status_code not in [401, 403] or retries == 0: + raise ex + self._token = None diff --git a/src/pybind/mgr/devicehealth/__init__.py b/src/pybind/mgr/devicehealth/__init__.py new file mode 100644 index 00000000..4c5b97ce --- /dev/null +++ b/src/pybind/mgr/devicehealth/__init__.py @@ -0,0 +1,2 @@ + +from .module import Module diff --git a/src/pybind/mgr/devicehealth/module.py b/src/pybind/mgr/devicehealth/module.py new file mode 100644 index 00000000..9bddc66f --- /dev/null +++ b/src/pybind/mgr/devicehealth/module.py @@ -0,0 +1,651 @@ +""" +Device health monitoring +""" + +import errno +import json +from mgr_module import MgrModule, CommandResult +import operator +import rados +from threading import Event +from datetime import datetime, timedelta, date, time +import _strptime +from six import iteritems + +TIME_FORMAT = '%Y%m%d-%H%M%S' + +DEVICE_HEALTH = 'DEVICE_HEALTH' +DEVICE_HEALTH_IN_USE = 'DEVICE_HEALTH_IN_USE' +DEVICE_HEALTH_TOOMANY = 'DEVICE_HEALTH_TOOMANY' +HEALTH_MESSAGES = { + DEVICE_HEALTH: '%d device(s) expected to fail soon', + DEVICE_HEALTH_IN_USE: '%d daemons(s) expected to fail soon and still contain data', + DEVICE_HEALTH_TOOMANY: 'Too many daemons are expected to fail soon', +} + +MAX_SAMPLES=500 + + +class Module(MgrModule): + MODULE_OPTIONS = [ + { + 'name': 'enable_monitoring', + 'default': False, + 'type': 'bool', + 'desc': 'monitor device health metrics', + 'runtime': True, + }, + { + 'name': 'scrape_frequency', + 'default': 86400, + 'type': 'secs', + 'desc': 'how frequently to scrape device health metrics', + 'runtime': True, + }, + { + 'name': 'pool_name', + 'default': 'device_health_metrics', + 'type': 'str', + 'desc': 'name of pool in which to store device health metrics', + 'runtime': True, + }, + { + 'name': 'retention_period', + 'default': (86400 * 180), + 'type': 'secs', + 'desc': 'how long to retain device health metrics', + 'runtime': True, + }, + { + 'name': 'mark_out_threshold', + 'default': (86400 * 14 * 2), + 'type': 'secs', + 'desc': 'automatically mark OSD if it may fail before this long', + 'runtime': True, + }, + { + 'name': 'warn_threshold', + 'default': (86400 * 14 * 6), + 'type': 'secs', + 'desc': 'raise health warning if OSD may fail before this long', + 'runtime': True, + }, + { + 'name': 'self_heal', + 'default': True, + 'type': 'bool', + 'desc': 'preemptively heal cluster around devices that may fail', + 'runtime': True, + }, + { + 'name': 'sleep_interval', + 'default': 600, + 'type': 'secs', + 'desc': 'how frequently to wake up and check device health', + 'runtime': True, + }, + ] + + COMMANDS = [ + { + "cmd": "device query-daemon-health-metrics " + "name=who,type=CephString", + "desc": "Get device health metrics for a given daemon", + "perm": "r" + }, + { + "cmd": "device scrape-daemon-health-metrics " + "name=who,type=CephString", + "desc": "Scrape and store device health metrics " + "for a given daemon", + "perm": "r" + }, + { + "cmd": "device scrape-health-metrics " + "name=devid,type=CephString,req=False", + "desc": "Scrape and store health metrics", + "perm": "r" + }, + { + "cmd": "device get-health-metrics " + "name=devid,type=CephString " + "name=sample,type=CephString,req=False", + "desc": "Show stored device metrics for the device", + "perm": "r" + }, + { + "cmd": "device check-health", + "desc": "Check life expectancy of devices", + "perm": "rw", + }, + { + "cmd": "device monitoring on", + "desc": "Enable device health monitoring", + "perm": "rw", + }, + { + "cmd": "device monitoring off", + "desc": "Disable device health monitoring", + "perm": "rw", + }, + { + 'cmd': 'device predict-life-expectancy ' + 'name=devid,type=CephString,req=true', + 'desc': 'Predict life expectancy with local predictor', + 'perm': 'r' + }, + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + + # populate options (just until serve() runs) + for opt in self.MODULE_OPTIONS: + setattr(self, opt['name'], opt['default']) + + # other + self.run = True + self.event = Event() + + def is_valid_daemon_name(self, who): + l = who.split('.') + if len(l) != 2: + return False + if l[0] not in ('osd', 'mon'): + return False; + return True; + + def handle_command(self, _, cmd): + self.log.error("handle_command") + + if cmd['prefix'] == 'device query-daemon-health-metrics': + who = cmd.get('who', '') + if not self.is_valid_daemon_name(who): + return -errno.EINVAL, '', 'not a valid mon or osd daemon name' + (daemon_type, daemon_id) = cmd.get('who', '').split('.') + result = CommandResult('') + self.send_command(result, daemon_type, daemon_id, json.dumps({ + 'prefix': 'smart', + 'format': 'json', + }), '') + r, outb, outs = result.wait() + return r, outb, outs + elif cmd['prefix'] == 'device scrape-daemon-health-metrics': + who = cmd.get('who', '') + if not self.is_valid_daemon_name(who): + return -errno.EINVAL, '', 'not a valid mon or osd daemon name' + (daemon_type, daemon_id) = cmd.get('who', '').split('.') + return self.scrape_daemon(daemon_type, daemon_id) + elif cmd['prefix'] == 'device scrape-health-metrics': + if 'devid' in cmd: + return self.scrape_device(cmd['devid']) + return self.scrape_all() + elif cmd['prefix'] == 'device get-health-metrics': + return self.show_device_metrics(cmd['devid'], cmd.get('sample')) + elif cmd['prefix'] == 'device check-health': + return self.check_health() + elif cmd['prefix'] == 'device monitoring on': + self.set_module_option('enable_monitoring', True) + self.event.set() + return 0, '', '' + elif cmd['prefix'] == 'device monitoring off': + self.set_module_option('enable_monitoring', False) + self.set_health_checks({}) # avoid stuck health alerts + return 0, '', '' + elif cmd['prefix'] == 'device predict-life-expectancy': + return self.predict_lift_expectancy(cmd['devid']) + else: + # mgr should respect our self.COMMANDS and not call us for + # any prefix we don't advertise + raise NotImplementedError(cmd['prefix']) + + def self_test(self): + self.config_notify() + osdmap = self.get('osd_map') + osd_id = osdmap['osds'][0]['osd'] + osdmeta = self.get('osd_metadata') + devs = osdmeta.get(str(osd_id), {}).get('device_ids') + if devs: + devid = devs.split()[0].split('=')[1] + (r, before, err) = self.show_device_metrics(devid, '') + assert r == 0 + (r, out, err) = self.scrape_device(devid) + assert r == 0 + (r, after, err) = self.show_device_metrics(devid, '') + assert r == 0 + assert before != after + + def config_notify(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name'])) + + def serve(self): + self.log.info("Starting") + self.config_notify() + + last_scrape = None + ls = self.get_store('last_scrape') + if ls: + try: + last_scrape = datetime.strptime(ls, TIME_FORMAT) + except ValueError as e: + pass + self.log.debug('Last scrape %s', last_scrape) + + while self.run: + if self.enable_monitoring: + self.log.debug('Running') + self.check_health() + + now = datetime.utcnow() + if not last_scrape: + next_scrape = now + else: + # align to scrape interval + scrape_frequency = int(self.scrape_frequency) or 86400 + seconds = (last_scrape - datetime.utcfromtimestamp(0)).total_seconds() + seconds -= seconds % scrape_frequency + seconds += scrape_frequency + next_scrape = datetime.utcfromtimestamp(seconds) + if last_scrape: + self.log.debug('Last scrape %s, next scrape due %s', + last_scrape.strftime(TIME_FORMAT), + next_scrape.strftime(TIME_FORMAT)) + else: + self.log.debug('Last scrape never, next scrape due %s', + next_scrape.strftime(TIME_FORMAT)) + if now >= next_scrape: + self.scrape_all() + self.predict_all_devices() + last_scrape = now + self.set_store('last_scrape', last_scrape.strftime(TIME_FORMAT)) + + # sleep + sleep_interval = int(self.sleep_interval) or 60 + self.log.debug('Sleeping for %d seconds', sleep_interval) + ret = self.event.wait(sleep_interval) + self.event.clear() + + def shutdown(self): + self.log.info('Stopping') + self.run = False + self.event.set() + + def open_connection(self, create_if_missing=True): + pools = self.rados.list_pools() + is_pool = False + for pool in pools: + if pool == self.pool_name: + is_pool = True + break + if not is_pool: + if not create_if_missing: + return None + self.log.debug('create %s pool' % self.pool_name) + # create pool + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd pool create', + 'format': 'json', + 'pool': self.pool_name, + 'pg_num': 1, + 'pg_num_min': 1, + }), '') + r, outb, outs = result.wait() + assert r == 0 + + # set pool application + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd pool application enable', + 'format': 'json', + 'pool': self.pool_name, + 'app': 'mgr_devicehealth', + }), '') + r, outb, outs = result.wait() + assert r == 0 + + ioctx = self.rados.open_ioctx(self.pool_name) + return ioctx + + def scrape_daemon(self, daemon_type, daemon_id): + ioctx = self.open_connection() + if daemon_type != 'osd': + return -errno.EINVAL, '', 'scraping non-OSDs not currently supported' + raw_smart_data = self.do_scrape_daemon(daemon_type, daemon_id) + if raw_smart_data: + for device, raw_data in raw_smart_data.items(): + data = self.extract_smart_features(raw_data) + if device and data: + self.put_device_metrics(ioctx, device, data) + ioctx.close() + return 0, "", "" + + def scrape_all(self): + osdmap = self.get("osd_map") + assert osdmap is not None + ioctx = self.open_connection() + did_device = {} + ids = [] + for osd in osdmap['osds']: + ids.append(('osd', str(osd['osd']))) + for daemon_type, daemon_id in ids: + raw_smart_data = self.do_scrape_daemon(daemon_type, daemon_id) + if not raw_smart_data: + continue + for device, raw_data in raw_smart_data.items(): + if device in did_device: + self.log.debug('skipping duplicate %s' % device) + continue + did_device[device] = 1 + data = self.extract_smart_features(raw_data) + if device and data: + self.put_device_metrics(ioctx, device, data) + ioctx.close() + return 0, "", "" + + def scrape_device(self, devid): + r = self.get("device " + devid) + if not r or 'device' not in r.keys(): + return -errno.ENOENT, '', 'device ' + devid + ' not found' + daemons = [d for d in r['device'].get('daemons', []) if d.startswith('osd.')] + if not daemons: + return (-errno.EAGAIN, '', + 'device ' + devid + ' not claimed by any active OSD daemons') + (daemon_type, daemon_id) = daemons[0].split('.') + ioctx = self.open_connection() + raw_smart_data = self.do_scrape_daemon(daemon_type, daemon_id, + devid=devid) + if raw_smart_data: + for device, raw_data in raw_smart_data.items(): + data = self.extract_smart_features(raw_data) + if device and data: + self.put_device_metrics(ioctx, device, data) + ioctx.close() + return 0, "", "" + + def do_scrape_daemon(self, daemon_type, daemon_id, devid=''): + """ + :return: a dict, or None if the scrape failed. + """ + self.log.debug('do_scrape_daemon %s.%s' % (daemon_type, daemon_id)) + result = CommandResult('') + self.send_command(result, daemon_type, daemon_id, json.dumps({ + 'prefix': 'smart', + 'format': 'json', + 'devid': devid, + }), '') + r, outb, outs = result.wait() + + try: + return json.loads(outb) + except (IndexError, ValueError): + self.log.error( + "Fail to parse JSON result from daemon {0}.{1} ({2})".format( + daemon_type, daemon_id, outb)) + + def put_device_metrics(self, ioctx, devid, data): + assert devid + old_key = datetime.utcnow() - timedelta( + seconds=int(self.retention_period)) + prune = old_key.strftime(TIME_FORMAT) + self.log.debug('put_device_metrics device %s prune %s' % + (devid, prune)) + erase = [] + try: + with rados.ReadOpCtx() as op: + omap_iter, ret = ioctx.get_omap_keys(op, "", MAX_SAMPLES) # fixme + assert ret == 0 + ioctx.operate_read_op(op, devid) + for key, _ in list(omap_iter): + if key >= prune: + break + erase.append(key) + except rados.ObjectNotFound: + # The object doesn't already exist, no problem. + pass + except rados.Error as e: + # Do not proceed with writes if something unexpected + # went wrong with the reads. + self.log.exception("Error reading OMAP: {0}".format(e)) + return + + key = datetime.utcnow().strftime(TIME_FORMAT) + self.log.debug('put_device_metrics device %s key %s = %s, erase %s' % + (devid, key, data, erase)) + with rados.WriteOpCtx() as op: + ioctx.set_omap(op, (key,), (str(json.dumps(data)),)) + if len(erase): + ioctx.remove_omap_keys(op, tuple(erase)) + ioctx.operate_write_op(op, devid) + + def _get_device_metrics(self, devid, sample=None, min_sample=None): + res = {} + ioctx = self.open_connection(create_if_missing=False) + if not ioctx: + return {} + with ioctx: + with rados.ReadOpCtx() as op: + omap_iter, ret = ioctx.get_omap_vals(op, min_sample or '', sample or '', + MAX_SAMPLES) # fixme + assert ret == 0 + try: + ioctx.operate_read_op(op, devid) + for key, value in list(omap_iter): + if sample and key != sample: + break + if min_sample and key < min_sample: + break + try: + v = json.loads(value) + except (ValueError, IndexError): + self.log.debug('unable to parse value for %s: "%s"' % + (key, value)) + pass + res[key] = v + except rados.ObjectNotFound: + pass + except rados.Error as e: + self.log.exception("RADOS error reading omap: {0}".format(e)) + raise + return res + + def show_device_metrics(self, devid, sample): + # verify device exists + r = self.get("device " + devid) + if not r or 'device' not in r.keys(): + return -errno.ENOENT, '', 'device ' + devid + ' not found' + # fetch metrics + res = self._get_device_metrics(devid, sample=sample) + return 0, json.dumps(res, indent=4, sort_keys=True), '' + + def check_health(self): + self.log.info('Check health') + config = self.get('config') + min_in_ratio = float(config.get('mon_osd_min_in_ratio')) + mark_out_threshold_td = timedelta(seconds=int(self.mark_out_threshold)) + warn_threshold_td = timedelta(seconds=int(self.warn_threshold)) + checks = {} + health_warnings = { + DEVICE_HEALTH: [], + DEVICE_HEALTH_IN_USE: [], + } + devs = self.get("devices") + osds_in = {} + osds_out = {} + now = datetime.utcnow() + osdmap = self.get("osd_map") + assert osdmap is not None + for dev in devs['devices']: + devid = dev['devid'] + if 'life_expectancy_max' not in dev: + continue + # ignore devices that are not consumed by any daemons + if not dev['daemons']: + continue + if not dev['life_expectancy_max'] or \ + dev['life_expectancy_max'] == '0.000000': + continue + # life_expectancy_(min/max) is in the format of: + # '%Y-%m-%d %H:%M:%S.%f', e.g.: + # '2019-01-20 21:12:12.000000' + life_expectancy_max = datetime.strptime( + dev['life_expectancy_max'], + '%Y-%m-%d %H:%M:%S.%f') + self.log.debug('device %s expectancy max %s', dev, + life_expectancy_max) + + if life_expectancy_max - now <= mark_out_threshold_td: + if self.self_heal: + # dev['daemons'] == ["osd.0","osd.1","osd.2"] + if dev['daemons']: + osds = [x for x in dev['daemons'] + if x.startswith('osd.')] + osd_ids = map(lambda x: x[4:], osds) + for _id in osd_ids: + if self.is_osd_in(osdmap, _id): + osds_in[_id] = life_expectancy_max + else: + osds_out[_id] = 1 + + if life_expectancy_max - now <= warn_threshold_td: + # device can appear in more than one location in case + # of SCSI multipath + device_locations = map(lambda x: x['host'] + ':' + x['dev'], + dev['location']) + health_warnings[DEVICE_HEALTH].append( + '%s (%s); daemons %s; life expectancy between %s and %s' + % (dev['devid'], + ','.join(device_locations), + ','.join(dev.get('daemons', ['none'])), + dev['life_expectancy_max'], + dev.get('life_expectancy_max', 'unknown'))) + + # OSD might be marked 'out' (which means it has no + # data), however PGs are still attached to it. + for _id in osds_out: + num_pgs = self.get_osd_num_pgs(_id) + if num_pgs > 0: + health_warnings[DEVICE_HEALTH_IN_USE].append( + 'osd.%s is marked out ' + 'but still has %s PG(s)' % + (_id, num_pgs)) + if osds_in: + self.log.debug('osds_in %s' % osds_in) + # calculate target in ratio + num_osds = len(osdmap['osds']) + num_in = len([x for x in osdmap['osds'] if x['in']]) + num_bad = len(osds_in) + # sort with next-to-fail first + bad_osds = sorted(osds_in.items(), key=operator.itemgetter(1)) + did = 0 + to_mark_out = [] + for osd_id, when in bad_osds: + ratio = float(num_in - did - 1) / float(num_osds) + if ratio < min_in_ratio: + final_ratio = float(num_in - num_bad) / float(num_osds) + checks[DEVICE_HEALTH_TOOMANY] = { + 'severity': 'warning', + 'summary': HEALTH_MESSAGES[DEVICE_HEALTH_TOOMANY], + 'detail': [ + '%d OSDs with failing device(s) would bring "in" ratio to %f < mon_osd_min_in_ratio %f' % (num_bad - did, final_ratio, min_in_ratio) + ] + } + break + to_mark_out.append(osd_id) + did += 1 + if to_mark_out: + self.mark_out_etc(to_mark_out) + for warning, ls in iteritems(health_warnings): + n = len(ls) + if n: + checks[warning] = { + 'severity': 'warning', + 'summary': HEALTH_MESSAGES[warning] % n, + 'detail': ls, + } + self.set_health_checks(checks) + return 0, "", "" + + def is_osd_in(self, osdmap, osd_id): + for osd in osdmap['osds']: + if str(osd_id) == str(osd['osd']): + return bool(osd['in']) + return False + + def get_osd_num_pgs(self, osd_id): + stats = self.get('osd_stats') + assert stats is not None + for stat in stats['osd_stats']: + if str(osd_id) == str(stat['osd']): + return stat['num_pgs'] + return -1 + + def mark_out_etc(self, osd_ids): + self.log.info('Marking out OSDs: %s' % osd_ids) + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd out', + 'format': 'json', + 'ids': osd_ids, + }), '') + r, outb, outs = result.wait() + if r != 0: + self.log.warn('Could not mark OSD %s out. r: [%s], outb: [%s], outs: [%s]' % (osd_ids, r, outb, outs)) + for osd_id in osd_ids: + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd primary-affinity', + 'format': 'json', + 'id': int(osd_id), + 'weight': 0.0, + }), '') + r, outb, outs = result.wait() + if r != 0: + self.log.warn('Could not set osd.%s primary-affinity, r: [%s], outs: [%s]' % (osd_id, r, outb, outs)) + + def extract_smart_features(self, raw): + # FIXME: extract and normalize raw smartctl --json output and + # generate a dict of the fields we care about. + return raw + + def predict_lift_expectancy(self, devid): + plugin_name = '' + model = self.get_ceph_option('device_failure_prediction_mode') + if model and model.lower() == 'cloud': + plugin_name = 'diskprediction_cloud' + elif model and model.lower() == 'local': + plugin_name = 'diskprediction_local' + else: + return -1, '', 'unable to enable any disk prediction model[local/cloud]' + try: + can_run, _ = self.remote(plugin_name, 'can_run') + if can_run: + return self.remote(plugin_name, 'predict_life_expectancy', devid=devid) + except: + return -1, '', 'unable to invoke diskprediction local or remote plugin' + + def predict_all_devices(self): + plugin_name = '' + model = self.get_ceph_option('device_failure_prediction_mode') + if model and model.lower() == 'cloud': + plugin_name = 'diskprediction_cloud' + elif model and model.lower() == 'local': + plugin_name = 'diskprediction_local' + else: + return -1, '', 'unable to enable any disk prediction model[local/cloud]' + try: + can_run, _ = self.remote(plugin_name, 'can_run') + if can_run: + return self.remote(plugin_name, 'predict_all_devices') + except: + return -1, '', 'unable to invoke diskprediction local or remote plugin' + + def get_recent_device_metrics(self, devid, min_sample): + return self._get_device_metrics(devid, min_sample=min_sample) + + def get_time_format(self): + return TIME_FORMAT diff --git a/src/pybind/mgr/diskprediction_cloud/__init__.py b/src/pybind/mgr/diskprediction_cloud/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/diskprediction_cloud/agent/__init__.py b/src/pybind/mgr/diskprediction_cloud/agent/__init__.py new file mode 100644 index 00000000..c7702e52 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/__init__.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import + +from ..common import timeout, TimeoutError + + +class BaseAgent(object): + + measurement = '' + + def __init__(self, mgr_module, obj_sender, timeout=30): + self.data = [] + self._client = None + self._client = obj_sender + self._logger = mgr_module.log + self._module_inst = mgr_module + self._timeout = timeout + + def run(self): + try: + self._collect_data() + self._run() + except TimeoutError: + self._logger.error('{} failed to execute {} task'.format( + __name__, self.measurement)) + + def __nonzero__(self): + if not self._module_inst: + return False + else: + return True + + @timeout() + def _run(self): + pass + + @timeout() + def _collect_data(self): + pass diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/__init__.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/__init__.py new file mode 100644 index 00000000..9e7e5b0b --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/__init__.py @@ -0,0 +1,61 @@ +from __future__ import absolute_import + +from .. import BaseAgent +from ...common import DP_MGR_STAT_FAILED, DP_MGR_STAT_WARNING, DP_MGR_STAT_OK + +AGENT_VERSION = '1.0.0' + + +class MetricsField(object): + def __init__(self): + self.tags = {} + self.fields = {} + self.timestamp = None + + def __str__(self): + return str({ + 'tags': self.tags, + 'fields': self.fields, + 'timestamp': self.timestamp + }) + + +class MetricsAgent(BaseAgent): + + def log_summary(self, status_info): + try: + if status_info: + measurement = status_info['measurement'] + success_count = status_info['success_count'] + failure_count = status_info['failure_count'] + total_count = success_count + failure_count + display_string = \ + '%s agent stats in total count: %s, success count: %s, failure count: %s.' + self._logger.info( + display_string % (measurement, total_count, success_count, failure_count) + ) + except Exception as e: + self._logger.error(str(e)) + + def _run(self): + collect_data = self.data + result = {} + if collect_data and self._client: + status_info = self._client.send_info(collect_data, self.measurement) + # show summary info + self.log_summary(status_info) + # write sub_agent buffer + total_count = status_info['success_count'] + status_info['failure_count'] + if total_count: + if status_info['success_count'] == 0: + self._module_inst.status = \ + {'status': DP_MGR_STAT_FAILED, + 'reason': 'failed to send metrics data to the server'} + elif status_info['failure_count'] == 0: + self._module_inst.status = \ + {'status': DP_MGR_STAT_OK} + else: + self._module_inst.status = \ + {'status': DP_MGR_STAT_WARNING, + 'reason': 'failed to send partial metrics data to the server'} + return result diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py new file mode 100644 index 00000000..2491644a --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_cluster.py @@ -0,0 +1,145 @@ +from __future__ import absolute_import + +import socket + +from . import MetricsAgent, MetricsField +from ...common.clusterdata import ClusterAPI + + +class CephCluster(MetricsField): + """ Ceph cluster structure """ + measurement = 'ceph_cluster' + + def __init__(self): + super(CephCluster, self).__init__() + self.tags['cluster_id'] = None + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.fields['cluster_health'] = '' + self.fields['num_mon'] = None + self.fields['num_mon_quorum'] = None + self.fields['num_osd'] = None + self.fields['num_osd_up'] = None + self.fields['num_osd_in'] = None + self.fields['osd_epoch'] = None + self.fields['osd_bytes'] = None + self.fields['osd_bytes_used'] = None + self.fields['osd_bytes_avail'] = None + self.fields['num_pool'] = None + self.fields['num_pg'] = None + self.fields['num_pg_active_clean'] = None + self.fields['num_pg_active'] = None + self.fields['num_pg_peering'] = None + self.fields['num_object'] = None + self.fields['num_object_degraded'] = None + self.fields['num_object_misplaced'] = None + self.fields['num_object_unfound'] = None + self.fields['num_bytes'] = None + self.fields['num_mds_up'] = None + self.fields['num_mds_in'] = None + self.fields['num_mds_failed'] = None + self.fields['mds_epoch'] = None + + +class CephClusterAgent(MetricsAgent): + measurement = 'ceph_cluster' + + def _collect_data(self): + # process data and save to 'self.data' + obj_api = ClusterAPI(self._module_inst) + cluster_id = obj_api.get_cluster_id() + + c_data = CephCluster() + cluster_state = obj_api.get_health_status() + c_data.tags['cluster_id'] = cluster_id + c_data.fields['cluster_health'] = str(cluster_state) + c_data.fields['agenthost'] = socket.gethostname() + c_data.tags['agenthost_domain_id'] = cluster_id + c_data.fields['osd_epoch'] = obj_api.get_osd_epoch() + c_data.fields['num_mon'] = len(obj_api.get_mons()) + c_data.fields['num_mon_quorum'] = \ + len(obj_api.get_mon_status().get('quorum', [])) + + osds = obj_api.get_osds() + num_osd_up = 0 + num_osd_in = 0 + for osd_data in osds: + if osd_data.get('up'): + num_osd_up = num_osd_up + 1 + if osd_data.get('in'): + num_osd_in = num_osd_in + 1 + if osds: + c_data.fields['num_osd'] = len(osds) + else: + c_data.fields['num_osd'] = 0 + c_data.fields['num_osd_up'] = num_osd_up + c_data.fields['num_osd_in'] = num_osd_in + c_data.fields['num_pool'] = len(obj_api.get_osd_pools()) + + df_stats = obj_api.module.get('df').get('stats', {}) + total_bytes = df_stats.get('total_bytes', 0) + total_used_bytes = df_stats.get('total_used_bytes', 0) + total_avail_bytes = df_stats.get('total_avail_bytes', 0) + c_data.fields['osd_bytes'] = total_bytes + c_data.fields['osd_bytes_used'] = total_used_bytes + c_data.fields['osd_bytes_avail'] = total_avail_bytes + if total_bytes and total_avail_bytes: + c_data.fields['osd_bytes_used_percentage'] = \ + round((float(total_used_bytes) / float(total_bytes)) * 100, 4) + else: + c_data.fields['osd_bytes_used_percentage'] = 0.0000 + + pg_stats = obj_api.module.get('pg_stats').get('pg_stats', []) + num_bytes = 0 + num_object = 0 + num_object_degraded = 0 + num_object_misplaced = 0 + num_object_unfound = 0 + num_pg_active = 0 + num_pg_active_clean = 0 + num_pg_peering = 0 + for pg_data in pg_stats: + num_pg_active = num_pg_active + len(pg_data.get('acting')) + if 'active+clean' in pg_data.get('state'): + num_pg_active_clean = num_pg_active_clean + 1 + if 'peering' in pg_data.get('state'): + num_pg_peering = num_pg_peering + 1 + + stat_sum = pg_data.get('stat_sum', {}) + num_object = num_object + stat_sum.get('num_objects', 0) + num_object_degraded = \ + num_object_degraded + stat_sum.get('num_objects_degraded', 0) + num_object_misplaced = \ + num_object_misplaced + stat_sum.get('num_objects_misplaced', 0) + num_object_unfound = \ + num_object_unfound + stat_sum.get('num_objects_unfound', 0) + num_bytes = num_bytes + stat_sum.get('num_bytes', 0) + + c_data.fields['num_pg'] = len(pg_stats) + c_data.fields['num_object'] = num_object + c_data.fields['num_object_degraded'] = num_object_degraded + c_data.fields['num_object_misplaced'] = num_object_misplaced + c_data.fields['num_object_unfound'] = num_object_unfound + c_data.fields['num_bytes'] = num_bytes + c_data.fields['num_pg_active'] = num_pg_active + c_data.fields['num_pg_active_clean'] = num_pg_active_clean + c_data.fields['num_pg_peering'] = num_pg_active_clean + + filesystems = obj_api.get_file_systems() + num_mds_in = 0 + num_mds_up = 0 + num_mds_failed = 0 + mds_epoch = 0 + for fs_data in filesystems: + num_mds_in = \ + num_mds_in + len(fs_data.get('mdsmap', {}).get('in', [])) + num_mds_up = \ + num_mds_up + len(fs_data.get('mdsmap', {}).get('up', {})) + num_mds_failed = \ + num_mds_failed + len(fs_data.get('mdsmap', {}).get('failed', [])) + mds_epoch = mds_epoch + fs_data.get('mdsmap', {}).get('epoch', 0) + c_data.fields['num_mds_in'] = num_mds_in + c_data.fields['num_mds_up'] = num_mds_up + c_data.fields['num_mds_failed'] = num_mds_failed + c_data.fields['mds_epoch'] = mds_epoch + self.data.append(c_data) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_mon_osd.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_mon_osd.py new file mode 100644 index 00000000..4b4d8fa8 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_mon_osd.py @@ -0,0 +1,222 @@ +from __future__ import absolute_import + +import socket + +from . import MetricsAgent, MetricsField +from ...common.clusterdata import ClusterAPI + + +class CephMON(MetricsField): + """ Ceph monitor structure """ + measurement = 'ceph_mon' + + def __init__(self): + super(CephMON, self).__init__() + self.tags['cluster_id'] = None + self.tags['mon_id'] = None + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.fields['num_sessions'] = None + self.fields['session_add'] = None + self.fields['session_rm'] = None + self.fields['session_trim'] = None + self.fields['num_elections'] = None + self.fields['election_call'] = None + self.fields['election_win'] = None + self.fields['election_lose'] = None + + +class CephErasureProfile(MetricsField): + """ Ceph osd erasure profile """ + measurement = 'ceph_erasure_profile' + + def __init__(self): + super(CephErasureProfile, self).__init__() + self.tags['cluster_id'] = None + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.tags['host_domain_id'] = None + self.fields['name'] = None + + +class CephOsdTree(MetricsField): + """ Ceph osd tree map """ + measurement = 'ceph_osd_tree' + + def __init__(self): + super(CephOsdTree, self).__init__() + self.tags['cluster_id'] = None + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.tags['host_domain_id'] = None + self.fields['name'] = None + + +class CephOSD(MetricsField): + """ Ceph osd structure """ + measurement = 'ceph_osd' + + def __init__(self): + super(CephOSD, self).__init__() + self.tags['cluster_id'] = None + self.tags['osd_id'] = None + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.tags['host_domain_id'] = None + self.fields['op_w'] = None + self.fields['op_in_bytes'] = None + self.fields['op_r'] = None + self.fields['op_out_bytes'] = None + self.fields['op_wip'] = None + self.fields['op_latency'] = None + self.fields['op_process_latency'] = None + self.fields['op_r_latency'] = None + self.fields['op_r_process_latency'] = None + self.fields['op_w_in_bytes'] = None + self.fields['op_w_latency'] = None + self.fields['op_w_process_latency'] = None + self.fields['op_w_prepare_latency'] = None + self.fields['op_rw'] = None + self.fields['op_rw_in_bytes'] = None + self.fields['op_rw_out_bytes'] = None + self.fields['op_rw_latency'] = None + self.fields['op_rw_process_latency'] = None + self.fields['op_rw_prepare_latency'] = None + self.fields['op_before_queue_op_lat'] = None + self.fields['op_before_dequeue_op_lat'] = None + + +class CephMonOsdAgent(MetricsAgent): + measurement = 'ceph_mon_osd' + + # counter types + PERFCOUNTER_LONGRUNAVG = 4 + PERFCOUNTER_COUNTER = 8 + PERFCOUNTER_HISTOGRAM = 0x10 + PERFCOUNTER_TYPE_MASK = ~3 + + def _stattype_to_str(self, stattype): + typeonly = stattype & self.PERFCOUNTER_TYPE_MASK + if typeonly == 0: + return 'gauge' + if typeonly == self.PERFCOUNTER_LONGRUNAVG: + # this lie matches the DaemonState decoding: only val, no counts + return 'counter' + if typeonly == self.PERFCOUNTER_COUNTER: + return 'counter' + if typeonly == self.PERFCOUNTER_HISTOGRAM: + return 'histogram' + return '' + + def _generage_osd_erasure_profile(self, cluster_id): + obj_api = ClusterAPI(self._module_inst) + osd_map = obj_api.module.get('osd_map') + if osd_map: + for n, n_value in osd_map.get('erasure_code_profiles', {}).items(): + e_osd = CephErasureProfile() + e_osd.fields['name'] = n + e_osd.tags['cluster_id'] = cluster_id + e_osd.fields['agenthost'] = socket.gethostname() + e_osd.tags['agenthost_domain_id'] = cluster_id + e_osd.tags['host_domain_id'] = '%s_%s' % (cluster_id, socket.gethostname()) + for k in n_value.keys(): + e_osd.fields[k] = str(n_value[k]) + self.data.append(e_osd) + + def _generate_osd_tree(self, cluster_id): + obj_api = ClusterAPI(self._module_inst) + osd_tree = obj_api.module.get('osd_map_tree') + if osd_tree: + for node in osd_tree.get('nodes', []): + n_node = CephOsdTree() + n_node.tags['cluster_id'] = cluster_id + n_node.fields['agenthost'] = socket.gethostname() + n_node.tags['agenthost_domain_id'] = cluster_id + n_node.tags['host_domain_id'] = '%s_%s' % (cluster_id, socket.gethostname()) + n_node.fields['children'] = ','.join(str(x) for x in node.get('children', [])) + n_node.fields['type_id'] = str(node.get('type_id', '')) + n_node.fields['id'] = str(node.get('id', '')) + n_node.fields['name'] = str(node.get('name', '')) + n_node.fields['type'] = str(node.get('type', '')) + n_node.fields['reweight'] = float(node.get('reweight', 0.0)) + n_node.fields['crush_weight'] = float(node.get('crush_weight', 0.0)) + n_node.fields['primary_affinity'] = float(node.get('primary_affinity', 0.0)) + n_node.fields['device_class'] = str(node.get('device_class', '')) + self.data.append(n_node) + + def _generate_osd(self, cluster_id, service_name, perf_counts): + obj_api = ClusterAPI(self._module_inst) + service_id = service_name[4:] + d_osd = CephOSD() + stat_bytes = 0 + stat_bytes_used = 0 + d_osd.tags['cluster_id'] = cluster_id + d_osd.tags['osd_id'] = service_name[4:] + d_osd.fields['agenthost'] = socket.gethostname() + d_osd.tags['agenthost_domain_id'] = cluster_id + d_osd.tags['host_domain_id'] = \ + '%s_%s' % (cluster_id, + obj_api.get_osd_hostname(d_osd.tags['osd_id'])) + + for i_key, i_val in perf_counts.items(): + if i_key[:4] == 'osd.': + key_name = i_key[4:] + else: + key_name = i_key + if self._stattype_to_str(i_val['type']) == 'counter': + value = obj_api.get_rate('osd', service_id, i_key) + else: + value = obj_api.get_latest('osd', service_id, i_key) + if key_name == 'stat_bytes': + stat_bytes = value + elif key_name == 'stat_bytes_used': + stat_bytes_used = value + else: + d_osd.fields[key_name] = float(value) + + if stat_bytes and stat_bytes_used: + d_osd.fields['stat_bytes_used_percentage'] = \ + round((float(stat_bytes_used) / float(stat_bytes)) * 100, 4) + else: + d_osd.fields['stat_bytes_used_percentage'] = 0.0000 + self.data.append(d_osd) + + def _generate_mon(self, cluster_id, service_name, perf_counts): + d_mon = CephMON() + d_mon.tags['cluster_id'] = cluster_id + d_mon.tags['mon_id'] = service_name[4:] + d_mon.fields['agenthost'] = socket.gethostname() + d_mon.tags['agenthost_domain_id'] = cluster_id + d_mon.fields['num_sessions'] = \ + perf_counts.get('mon.num_sessions', {}).get('value', 0) + d_mon.fields['session_add'] = \ + perf_counts.get('mon.session_add', {}).get('value', 0) + d_mon.fields['session_rm'] = \ + perf_counts.get('mon.session_rm', {}).get('value', 0) + d_mon.fields['session_trim'] = \ + perf_counts.get('mon.session_trim', {}).get('value', 0) + d_mon.fields['num_elections'] = \ + perf_counts.get('mon.num_elections', {}).get('value', 0) + d_mon.fields['election_call'] = \ + perf_counts.get('mon.election_call', {}).get('value', 0) + d_mon.fields['election_win'] = \ + perf_counts.get('mon.election_win', {}).get('value', 0) + d_mon.fields['election_lose'] = \ + perf_counts.get('election_lose', {}).get('value', 0) + self.data.append(d_mon) + + def _collect_data(self): + # process data and save to 'self.data' + obj_api = ClusterAPI(self._module_inst) + perf_data = obj_api.module.get_all_perf_counters(services=('mon', 'osd')) + if not perf_data and not isinstance(perf_data, dict): + self._logger.error('unable to get all perf counters') + return + cluster_id = obj_api.get_cluster_id() + for n_name, i_perf in perf_data.items(): + if n_name[0:3].lower() == 'mon': + self._generate_mon(cluster_id, n_name, i_perf) + elif n_name[0:3].lower() == 'osd': + self._generate_osd(cluster_id, n_name, i_perf) + self._generage_osd_erasure_profile(cluster_id) + self._generate_osd_tree(cluster_id) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_pool.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_pool.py new file mode 100644 index 00000000..e8b39566 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/ceph_pool.py @@ -0,0 +1,57 @@ +from __future__ import absolute_import + +import socket + +from . import MetricsAgent, MetricsField +from ...common.clusterdata import ClusterAPI + + +class CephPool(MetricsField): + """ Ceph pool structure """ + measurement = 'ceph_pool' + + def __init__(self): + super(CephPool, self).__init__() + self.tags['cluster_id'] = None + self.tags['pool_id'] = None + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.fields['bytes_used'] = None + self.fields['max_avail'] = None + self.fields['objects'] = None + self.fields['wr_bytes'] = None + self.fields['dirty'] = None + self.fields['rd_bytes'] = None + self.fields['stored_raw'] = None + + +class CephPoolAgent(MetricsAgent): + measurement = 'ceph_pool' + + def _collect_data(self): + # process data and save to 'self.data' + obj_api = ClusterAPI(self._module_inst) + df_data = obj_api.module.get('df') + cluster_id = obj_api.get_cluster_id() + for pool in df_data.get('pools', []): + d_pool = CephPool() + p_id = pool.get('id') + d_pool.tags['cluster_id'] = cluster_id + d_pool.tags['pool_id'] = p_id + d_pool.fields['agenthost'] = socket.gethostname() + d_pool.tags['agenthost_domain_id'] = cluster_id + d_pool.fields['bytes_used'] = \ + pool.get('stats', {}).get('bytes_used', 0) + d_pool.fields['max_avail'] = \ + pool.get('stats', {}).get('max_avail', 0) + d_pool.fields['objects'] = \ + pool.get('stats', {}).get('objects', 0) + d_pool.fields['wr_bytes'] = \ + pool.get('stats', {}).get('wr_bytes', 0) + d_pool.fields['dirty'] = \ + pool.get('stats', {}).get('dirty', 0) + d_pool.fields['rd_bytes'] = \ + pool.get('stats', {}).get('rd_bytes', 0) + d_pool.fields['stored_raw'] = \ + pool.get('stats', {}).get('stored_raw', 0) + self.data.append(d_pool) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/db_relay.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/db_relay.py new file mode 100644 index 00000000..2f5d60db --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/db_relay.py @@ -0,0 +1,703 @@ +from __future__ import absolute_import + +import re +import socket + +from . import MetricsAgent, MetricsField +from ...common.clusterdata import ClusterAPI +from ...common.cypher import CypherOP, NodeInfo + + +class BaseDP(object): + """ basic diskprediction structure """ + _fields = [] + + def __init__(self, *args, **kwargs): + if len(args) > len(self._fields): + raise TypeError('Expected {} arguments'.format(len(self._fields))) + + for name, value in zip(self._fields, args): + setattr(self, name, value) + + for name in self._fields[len(args):]: + setattr(self, name, kwargs.pop(name)) + + if kwargs: + raise TypeError('Invalid argument(s): {}'.format(','.join(kwargs))) + + +class MGRDpCeph(BaseDP): + _fields = [ + 'fsid', 'health', 'max_osd', 'size', + 'avail_size', 'raw_used', 'raw_used_percent' + ] + + +class MGRDpHost(BaseDP): + _fields = ['fsid', 'host', 'ipaddr'] + + +class MGRDpMon(BaseDP): + _fields = ['fsid', 'host', 'ipaddr'] + + +class MGRDpOsd(BaseDP): + _fields = [ + 'fsid', 'host', '_id', 'uuid', 'up', '_in', 'weight', 'public_addr', + 'cluster_addr', 'state', 'ceph_release', 'osd_devices', 'rotational' + ] + + +class MGRDpMds(BaseDP): + _fields = ['fsid', 'host', 'ipaddr'] + + +class MGRDpPool(BaseDP): + _fields = [ + 'fsid', 'size', 'pool_name', 'pool_id', 'type', 'min_size', + 'pg_num', 'pgp_num', 'created_time', 'pgids', 'osd_ids', 'tiers', 'cache_mode', + 'erasure_code_profile', 'tier_of' + ] + + +class MGRDpRBD(BaseDP): + _fields = ['fsid', '_id', 'name', 'pool_name', 'pool_id'] + + +class MGRDpFS(BaseDP): + _fields = ['fsid', '_id', 'name', 'metadata_pool', 'data_pools', 'mds_nodes'] + + +class MGRDpPG(BaseDP): + _fields = [ + 'fsid', 'pgid', 'up_osds', 'acting_osds', 'state', + 'objects', 'degraded', 'misplaced', 'unfound' + ] + + +class MGRDpDisk(BaseDP): + _fields = ['host_domain_id', 'host', 'fs_journal_osd', 'bs_db_osd', 'bs_wal_osd', 'data_osd', 'osd_ids'] + + +class DBRelay(MetricsField): + """ DB Relay structure """ + measurement = 'db_relay' + + def __init__(self): + super(DBRelay, self).__init__() + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.tags['dc_tag'] = 'na' + self.tags['host'] = None + self.fields['cmd'] = None + + +class DBRelayAgent(MetricsAgent): + measurement = 'db_relay' + + def __init__(self, *args, **kwargs): + super(DBRelayAgent, self).__init__(*args, **kwargs) + self._cluster_node = None + self._cluster_id = None + self._ceph = ClusterAPI(self._module_inst) + self._osd_maps = self._ceph.module.get('osd_map') + self._mon_maps = self._ceph.module.get('mon_map') + self._fs_maps = self._ceph.module.get('fs_map') + self._osd_metadata = self._ceph.module.get('osd_metadata') + self._host_nodes = dict() + self._osd_nodes = dict() + self._mon_nodes = dict() + self._mds_nodes = dict() + self._dev_nodes = dict() + self._pool_nodes = dict() + self._rbd_nodes = dict() + self._fs_nodes = dict() + # initial ceph all node states + self._init_cluster_node() + self._init_hosts() + self._init_mons() + self._init_mds() + self._init_osds() + self._init_devices() + self._init_pools() + self._init_rbds() + self._init_fs() + + def _init_hosts(self): + hosts = set() + # Add host from osd + osd_data = self._osd_maps.get('osds', []) + for _data in osd_data: + osd_id = _data['osd'] + if not _data.get('in'): + continue + osd_addr = _data['public_addr'].split(':')[0] + osd_metadata = self._ceph.get_osd_metadata(osd_id) + if osd_metadata: + osd_host = osd_metadata['hostname'] + hosts.add((osd_host, osd_addr)) + + # Add host from mon + mons = self._mon_maps.get('mons', []) + for _data in mons: + mon_host = _data['name'] + mon_addr = _data['public_addr'].split(':')[0] + if mon_host: + hosts.add((mon_host, mon_addr)) + + # Add host from mds + file_systems = self._fs_maps.get('filesystems', []) + for _data in file_systems: + mds_info = _data.get('mdsmap').get('info') + for _gid in mds_info: + mds_data = mds_info[_gid] + mds_addr = mds_data.get('addr').split(':')[0] + mds_host = mds_data.get('name') + if mds_host: + hosts.add((mds_host, mds_addr)) + for tp in hosts: + host = tp[0] + self._host_nodes[host] = None + + host_node = NodeInfo( + label='VMHost', + domain_id='{}_{}'.format(self._cluster_id, host), + name=host, + meta={} + ) + self._host_nodes[host] = host_node + + def _init_mons(self): + cluster_id = self._cluster_id + mons = self._mon_maps.get('mons') + for mon in mons: + mon_name = mon.get('name', '') + mon_addr = mon.get('addr', '').split(':')[0] + if mon_name not in self._host_nodes.keys(): + continue + + dp_mon = MGRDpMon( + fsid=cluster_id, + host=mon_name, + ipaddr=mon_addr + ) + + # create mon node + mon_node = NodeInfo( + label='CephMon', + domain_id='{}.mon.{}'.format(cluster_id, mon_name), + name=mon_name, + meta=dp_mon.__dict__ + ) + self._mon_nodes[mon_name] = mon_node + + def _init_mds(self): + cluster_id = self._cluster_id + file_systems = self._fs_maps.get('filesystems', []) + for _data in file_systems: + mds_info = _data.get('mdsmap').get('info') + for _gid in mds_info: + mds_data = mds_info[_gid] + mds_addr = mds_data.get('addr').split(':')[0] + mds_host = mds_data.get('name') + mds_gid = mds_data.get('gid') + + if mds_host not in self._host_nodes: + continue + + dp_mds = MGRDpMds( + fsid=cluster_id, + host=mds_host, + ipaddr=mds_addr + ) + + # create osd node + mds_node = NodeInfo( + label='CephMds', + domain_id='{}.mds.{}'.format(cluster_id, mds_gid), + name='MDS.{}'.format(mds_gid), + meta=dp_mds.__dict__ + ) + self._mds_nodes[mds_host] = mds_node + + def _init_osds(self): + for osd in self._osd_maps.get('osds', []): + osd_id = osd.get('osd', -1) + meta = self._osd_metadata.get(str(osd_id), {}) + osd_host = meta['hostname'] + osd_ceph_version = meta['ceph_version'] + osd_rotational = meta['rotational'] + osd_devices = meta['devices'].split(',') + + # filter 'dm' device. + devices = [] + for devname in osd_devices: + if 'dm' in devname: + continue + devices.append(devname) + + if osd_host not in self._host_nodes.keys(): + continue + self._osd_nodes[str(osd_id)] = None + public_addr = [] + cluster_addr = [] + for addr in osd.get('public_addrs', {}).get('addrvec', []): + public_addr.append(addr.get('addr')) + for addr in osd.get('cluster_addrs', {}).get('addrvec', []): + cluster_addr.append(addr.get('addr')) + dp_osd = MGRDpOsd( + fsid=self._cluster_id, + host=osd_host, + _id=osd_id, + uuid=osd.get('uuid'), + up=osd.get('up'), + _in=osd.get('in'), + weight=osd.get('weight'), + public_addr=','.join(public_addr), + cluster_addr=','.join(cluster_addr), + state=','.join(osd.get('state', [])), + ceph_release=osd_ceph_version, + osd_devices=','.join(devices), + rotational=osd_rotational) + for k, v in meta.items(): + setattr(dp_osd, k, v) + + # create osd node + osd_node = NodeInfo( + label='CephOsd', + domain_id='{}.osd.{}'.format(self._cluster_id, osd_id), + name='OSD.{}'.format(osd_id), + meta=dp_osd.__dict__ + ) + self._osd_nodes[str(osd_id)] = osd_node + + def _init_devices(self): + r = re.compile('[^/dev]\D+') + for osdid, o_val in self._osd_nodes.items(): + o_devs = o_val.meta.get('device_ids', '').split(',') + # fs_store + journal_devs = o_val.meta.get('backend_filestore_journal_dev_node', '').split(',') + # bs_store + bs_db_devs = o_val.meta.get('bluefs_db_dev_node', '').split(',') + bs_wal_devs = o_val.meta.get('bluefs_wal_dev_node', '').split(',') + + for dev in o_devs: + fs_journal = [] + bs_db = [] + bs_wal = [] + data = [] + if len(dev.split('=')) != 2: + continue + dev_name = dev.split('=')[0] + dev_id = dev.split('=')[1] + if not dev_id: + continue + + for j_dev in journal_devs: + if dev_name == ''.join(r.findall(j_dev)): + fs_journal.append(osdid) + for db_dev in bs_db_devs: + if dev_name == ''.join(r.findall(db_dev)): + bs_db.append(osdid) + for wal_dev in bs_wal_devs: + if dev_name == ''.join(r.findall(wal_dev)): + bs_wal.append(osdid) + + if not fs_journal and not bs_db and not bs_wal: + data.append(osdid) + + disk_domain_id = dev_id + if disk_domain_id not in self._dev_nodes.keys(): + dp_disk = MGRDpDisk( + host_domain_id='{}_{}'.format(self._cluster_id, o_val.meta.get('host')), + host=o_val.meta.get('host'), + osd_ids=osdid, + fs_journal_osd=','.join(str(x) for x in fs_journal) if fs_journal else '', + bs_db_osd=','.join(str(x) for x in bs_db) if bs_db else '', + bs_wal_osd=','.join(str(x) for x in bs_wal) if bs_wal else '', + data_osd=','.join(str(x) for x in data) if data else '' + ) + # create disk node + disk_node = NodeInfo( + label='VMDisk', + domain_id=disk_domain_id, + name=dev_name, + meta=dp_disk.__dict__ + ) + self._dev_nodes[disk_domain_id] = disk_node + else: + dev_node = self._dev_nodes[disk_domain_id] + osd_ids = dev_node.meta.get('osd_ids', '') + if osdid not in osd_ids.split(','): + arr_value = osd_ids.split(',') + arr_value.append(str(osdid)) + dev_node.meta['osd_ids'] = ','.join(arr_value) + if fs_journal: + arr_value = None + for t in fs_journal: + value = dev_node.meta.get('fs_journal_osd', '') + if value: + arr_value = value.split(',') + else: + arr_value = [] + if t not in arr_value: + arr_value.append(t) + if arr_value: + dev_node.meta['fs_journal_osd'] = ','.join(str(x) for x in arr_value) + if bs_db: + arr_value = None + for t in bs_db: + value = dev_node.meta.get('bs_db_osd', '') + if value: + arr_value = value.split(',') + else: + arr_value = [] + if t not in arr_value: + arr_value.append(t) + if arr_value: + dev_node.meta['bs_db_osd'] = ','.join(str(x) for x in arr_value) + if bs_wal: + arr_value = None + for t in bs_wal: + value = dev_node.meta.get('bs_wal_osd', '') + if value: + arr_value = value.split(',') + else: + arr_value = [] + if t not in arr_value: + arr_value.append(t) + if arr_value: + dev_node.meta['bs_wal_osd'] = ','.join(str(x) for x in arr_value) + if data: + arr_value = None + for t in data: + value = dev_node.meta.get('data_osd', '') + if value: + arr_value = value.split(',') + else: + arr_value = [] + if t not in arr_value: + arr_value.append(t) + if arr_value: + dev_node.meta['data_osd'] = ','.join(str(x) for x in arr_value) + + def _init_cluster_node(self): + cluster_id = self._ceph.get_cluster_id() + ceph_df_stat = self._ceph.get_ceph_df_state() + dp_cluster = MGRDpCeph( + fsid=cluster_id, + health=self._ceph.get_health_status(), + max_osd=len(self._ceph.get_osds()), + size=ceph_df_stat.get('total_size'), + avail_size=ceph_df_stat.get('avail_size'), + raw_used=ceph_df_stat.get('raw_used_size'), + raw_used_percent=ceph_df_stat.get('used_percent') + ) + cluster_name = cluster_id[-12:] + cluster_node = NodeInfo( + label='CephCluster', + domain_id=cluster_id, + name='cluster-{}'.format(cluster_name), + meta=dp_cluster.__dict__ + ) + self._cluster_id = cluster_id + self._cluster_node = cluster_node + + def _init_pools(self): + pools = self._osd_maps.get('pools', []) + cluster_id = self._cluster_id + for pool in pools: + osds = [] + pgs = self._ceph.get_pgs_up_by_poolid(int(pool.get('pool', -1))) + for pg_id, osd_id in pgs.items(): + for o_id in osd_id: + if o_id not in osds: + osds.append(str(o_id)) + dp_pool = MGRDpPool( + fsid=cluster_id, + size=pool.get('size'), + pool_name=pool.get('pool_name'), + pool_id=pool.get('pool'), + type=pool.get('type'), + min_size=pool.get('min_szie'), + pg_num=pool.get('pg_num'), + pgp_num=pool.get('pg_placement_num'), + created_time=pool.get('create_time'), + pgids=','.join(pgs.keys()), + osd_ids=','.join(osds), + tiers=','.join(str(x) for x in pool.get('tiers', [])), + cache_mode=pool.get('cache_mode', ''), + erasure_code_profile=str(pool.get('erasure_code_profile', '')), + tier_of=str(pool.get('tier_of', -1))) + # create pool node + pool_node = NodeInfo( + label='CephPool', + domain_id='{}_pool_{}'.format(cluster_id, pool.get('pool')), + name=pool.get('pool_name'), + meta=dp_pool.__dict__ + ) + self._pool_nodes[str(pool.get('pool'))] = pool_node + + def _init_rbds(self): + cluster_id = self._cluster_id + for p_id, p_node in self._pool_nodes.items(): + rbds = self._ceph.get_rbd_list(p_node.name) + self._rbd_nodes[str(p_id)] = [] + for rbd in rbds: + dp_rbd = MGRDpRBD( + fsid=cluster_id, + _id=rbd['id'], + name=rbd['name'], + pool_name=rbd['pool_name'], + pool_id=p_id, + ) + # create pool node + rbd_node = NodeInfo( + label='CephRBD', + domain_id='{}_rbd_{}'.format(cluster_id, rbd['id']), + name=rbd['name'], + meta=dp_rbd.__dict__, + ) + self._rbd_nodes[str(p_id)].append(rbd_node) + + def _init_fs(self): + # _fields = ['fsid', '_id', 'name', 'metadata_pool', 'data_pool', 'mds_nodes'] + cluster_id = self._cluster_id + file_systems = self._fs_maps.get('filesystems', []) + for fs in file_systems: + mdsmap = fs.get('mdsmap', {}) + mds_hostnames = [] + for m, md in mdsmap.get('info', {}).items(): + if md.get('name') not in mds_hostnames: + mds_hostnames.append(md.get('name')) + dp_fs = MGRDpFS( + fsid=cluster_id, + _id=fs.get('id'), + name=mdsmap.get('fs_name'), + metadata_pool=str(mdsmap.get('metadata_pool', -1)), + data_pools=','.join(str(i) for i in mdsmap.get('data_pools', [])), + mds_nodes=','.join(mds_hostnames), + ) + fs_node = NodeInfo( + label='CephFS', + domain_id='{}_fs_{}'.format(cluster_id, fs.get('id')), + name=mdsmap.get('fs_name'), + meta=dp_fs.__dict__, + ) + self._fs_nodes[str(fs.get('id'))] = fs_node + + def _cluster_contains_host(self): + cluster_id = self._cluster_id + cluster_node = self._cluster_node + + # create node relation + for h_id, h_node in self._host_nodes.items(): + data = DBRelay() + # add osd node relationship + cypher_cmd = CypherOP.add_link( + cluster_node, + h_node, + 'CephClusterContainsHost' + ) + cluster_host = socket.gethostname() + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _host_contains_mon(self): + for m_name, m_node in self._mon_nodes.items(): + host_node = self._host_nodes.get(m_name) + if not host_node: + continue + data = DBRelay() + # add mon node relationship + cypher_cmd = CypherOP.add_link( + host_node, + m_node, + 'HostContainsMon' + ) + cluster_host = socket.gethostname() + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = self._cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _host_contains_osd(self): + cluster_id = self._cluster_id + for o_id, o_node in self._osd_nodes.items(): + host_node = self._host_nodes.get(o_node.meta.get('host')) + if not host_node: + continue + data = DBRelay() + # add osd node relationship + cypher_cmd = CypherOP.add_link( + host_node, + o_node, + 'HostContainsOsd' + ) + cluster_host = socket.gethostname() + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id, data + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _host_contains_mds(self): + cluster_id = self._cluster_id + for m_name, mds_node in self._mds_nodes.items(): + data = DBRelay() + host_node = self._host_nodes.get(mds_node.meta.get('host')) + if not host_node: + continue + # add osd node relationship + cypher_cmd = CypherOP.add_link( + host_node, + mds_node, + 'HostContainsMds' + ) + cluster_host = socket.gethostname() + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _osd_contains_disk(self): + cluster_id = self._cluster_id + cluster_host = socket.gethostname() + for d_name, d_node in self._dev_nodes.items(): + keys = {'data_osd': 'DataDiskOfOSD', + 'fs_journal_osd': 'FsJournalDiskOfOSD', + 'bs_db_osd': 'BsDBDiskOfOSD', + 'bs_wal_osd': 'BsWalDiskOfOSD'} + for k, v in keys.items(): + if not d_node.meta.get(k): + continue + for osdid in d_node.meta.get(k, '').split(','): + data = DBRelay() + osd_node = self._osd_nodes.get(str(osdid)) + if not osd_node: + continue + # add disk node relationship + cypher_cmd = CypherOP.add_link( + osd_node, + d_node, + v) + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + hostname = d_node.meta.get('host', '') + if not hostname: + continue + host_node = self._host_nodes.get(hostname) + if not host_node: + continue + # add osd node relationship + data = DBRelay() + cypher_cmd = CypherOP.add_link( + host_node, + d_node, + 'VmHostContainsVmDisk' + ) + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _pool_contains_osd(self): + cluster_id = self._cluster_id + cluster_host = socket.gethostname() + for p_id, p_node in self._pool_nodes.items(): + for o_id in p_node.meta.get('osd_ids', '').split(','): + osd_node = self._osd_nodes.get(str(o_id)) + if not osd_node: + continue + data = DBRelay() + cypher_cmd = CypherOP.add_link( + osd_node, + p_node, + 'OsdContainsPool' + ) + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _pool_contains_rbd(self): + cluster_id = self._cluster_id + cluster_host = socket.gethostname() + for p_id, p_node in self._pool_nodes.items(): + for rbd_node in self._rbd_nodes.get(str(p_id), []): + if not rbd_node: + continue + data = DBRelay() + cypher_cmd = CypherOP.add_link( + p_node, + rbd_node, + 'PoolContainsRBD' + ) + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _pool_contains_fs(self): + cluster_id = self._cluster_id + cluster_host = socket.gethostname() + for fs_id, fs_node in self._fs_nodes.items(): + pool_attrs = ['metadata_pool', 'data_pools'] + for p_attr in pool_attrs: + pools_id = fs_node.meta.get(p_attr).split(',') + for p_id in pools_id: + p_node = self._pool_nodes.get(str(p_id)) + if p_node: + data = DBRelay() + cypher_cmd = CypherOP.add_link( + p_node, + fs_node, + 'MetadataPoolContainsFS' if p_attr == 'metadata_pool' else 'DataPoolContainsFS' + ) + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + for mds_name in fs_node.meta.get('mds_nodes', '').split(','): + mds_node = self._mds_nodes.get(mds_name) + if not mds_node: + continue + data = DBRelay() + cypher_cmd = CypherOP.add_link( + mds_node, + fs_node, + 'MDSContainsFS' + ) + data.fields['agenthost'] = cluster_host + data.tags['agenthost_domain_id'] = cluster_id + data.tags['host'] = cluster_host + data.fields['cmd'] = str(cypher_cmd) + self.data.append(data) + + def _collect_data(self): + if not self._module_inst: + return + job_name = ['cluster_contains_host', 'host_contains_mon', 'host_contains_mds', 'host_contains_osd', 'osd_contains_disk', + 'pool_contains_osd', 'pool_contains_rbd', 'pool_contains_fs'] + for job in job_name: + fn = getattr(self, '_%s' % job) + if not fn: + continue + try: + fn() + except Exception as e: + self._module_inst.log.error('dbrelay - execute function {} fail, due to {}'.format(job, str(e))) + continue diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_agent.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_agent.py new file mode 100644 index 00000000..81fbdf96 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_agent.py @@ -0,0 +1,70 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +from __future__ import absolute_import + +import socket +import time + +from . import AGENT_VERSION, MetricsAgent, MetricsField +from ...common import DP_MGR_STAT_FAILED, DP_MGR_STAT_WARNING +from ...common.clusterdata import ClusterAPI + + +class SAIAgentFields(MetricsField): + """ SAI DiskSmart structure """ + measurement = 'sai_agent' + + def __init__(self): + super(SAIAgentFields, self).__init__() + self.tags['agenthost_domain_id'] = None + self.fields['agent_type'] = str('ceph') + self.fields['agent_version'] = str(AGENT_VERSION) + self.fields['agenthost'] = '' + self.fields['cluster_domain_id'] = '' + self.fields['heartbeat_interval'] = '' + self.fields['host_ip'] = '' + self.fields['host_name'] = '' + self.fields['is_error'] = False + self.fields['is_ceph_error'] = False + self.fields['needs_warning'] = False + self.fields['send'] = None + + +class SAIAgent(MetricsAgent): + measurement = 'sai_agent' + + def _collect_data(self): + mgr_id = [] + c_data = SAIAgentFields() + obj_api = ClusterAPI(self._module_inst) + svc_data = obj_api.get_server(socket.gethostname()) + cluster_state = obj_api.get_health_status() + if not svc_data: + raise Exception('unable to get %s service info' % socket.gethostname()) + # Filter mgr id + for s in svc_data.get('services', []): + if s.get('type', '') == 'mgr': + mgr_id.append(s.get('id')) + + for _id in mgr_id: + mgr_meta = obj_api.get_mgr_metadata(_id) + cluster_id = obj_api.get_cluster_id() + c_data.fields['cluster_domain_id'] = str(cluster_id) + c_data.fields['agenthost'] = str(socket.gethostname()) + c_data.tags['agenthost_domain_id'] = cluster_id + c_data.fields['heartbeat_interval'] = \ + int(obj_api.get_configuration('diskprediction_upload_metrics_interval')) + c_data.fields['host_ip'] = str(mgr_meta.get('addr', '127.0.0.1')) + c_data.fields['host_name'] = str(socket.gethostname()) + if obj_api.module.status.get('status', '') in [DP_MGR_STAT_WARNING, DP_MGR_STAT_FAILED]: + c_data.fields['is_error'] = bool(True) + else: + c_data.fields['is_error'] = bool(False) + if cluster_state in ['HEALTH_ERR', 'HEALTH_WARN']: + c_data.fields['is_ceph_error'] = bool(True) + c_data.fields['needs_warning'] = bool(True) + c_data.fields['is_error'] = bool(True) + c_data.fields['problems'] = str(obj_api.get_health_checks()) + else: + c_data.fields['is_ceph_error'] = bool(False) + c_data.fields['send'] = int(time.time() * 1000) + self.data.append(c_data) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_cluster.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_cluster.py new file mode 100644 index 00000000..d444f9a2 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_cluster.py @@ -0,0 +1,35 @@ +from __future__ import absolute_import + +import socket + +from . import AGENT_VERSION, MetricsAgent, MetricsField +from ...common.clusterdata import ClusterAPI + + +class SAIClusterFields(MetricsField): + """ SAI Host structure """ + measurement = 'sai_cluster' + + def __init__(self): + super(SAIClusterFields, self).__init__() + self.tags['domain_id'] = None + self.fields['agenthost'] = None + self.fields['agenthost_domain_id'] = None + self.fields['name'] = None + self.fields['agent_version'] = str(AGENT_VERSION) + + +class SAICluserAgent(MetricsAgent): + measurement = 'sai_cluster' + + def _collect_data(self): + c_data = SAIClusterFields() + obj_api = ClusterAPI(self._module_inst) + cluster_id = obj_api.get_cluster_id() + + c_data.tags['domain_id'] = str(cluster_id) + c_data.tags['host_domain_id'] = '%s_%s' % (str(cluster_id), str(socket.gethostname())) + c_data.fields['agenthost'] = str(socket.gethostname()) + c_data.tags['agenthost_domain_id'] = cluster_id + c_data.fields['name'] = 'Ceph mgr plugin' + self.data.append(c_data) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk.py new file mode 100644 index 00000000..3b177e69 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk.py @@ -0,0 +1,175 @@ +from __future__ import absolute_import + +import socket + +from . import AGENT_VERSION, MetricsAgent, MetricsField +from ...common import get_human_readable +from ...common.clusterdata import ClusterAPI + + +class SAIDiskFields(MetricsField): + """ SAI Disk structure """ + measurement = 'sai_disk' + + def __init__(self): + super(SAIDiskFields, self).__init__() + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.tags['disk_domain_id'] = None + self.tags['disk_name'] = None + self.tags['disk_wwn'] = None + self.tags['primary_key'] = None + self.fields['cluster_domain_id'] = None + self.fields['host_domain_id'] = None + self.fields['model'] = None + self.fields['serial_number'] = None + self.fields['size'] = None + self.fields['vendor'] = None + self.fields['agent_version'] = str(AGENT_VERSION) + + """disk_status + 0: unknown 1: good 2: failure + """ + self.fields['disk_status'] = 0 + + """disk_type + 0: unknown 1: HDD 2: SSD 3: SSD NVME + 4: SSD SAS 5: SSD SATA 6: HDD SAS 7: HDD SATA + """ + self.fields['disk_type'] = 0 + + +class SAIDiskAgent(MetricsAgent): + measurement = 'sai_disk' + + @staticmethod + def _convert_disk_type(is_ssd, sata_version, protocol): + """ return type: + 0: "Unknown', 1: 'HDD', + 2: 'SSD", 3: "SSD NVME", + 4: "SSD SAS", 5: "SSD SATA", + 6: "HDD SAS", 7: "HDD SATA" + """ + if is_ssd: + if sata_version and not protocol: + disk_type = 5 + elif 'SCSI'.lower() in protocol.lower(): + disk_type = 4 + elif 'NVMe'.lower() in protocol.lower(): + disk_type = 3 + else: + disk_type = 2 + else: + if sata_version and not protocol: + disk_type = 7 + elif 'SCSI'.lower() in protocol.lower(): + disk_type = 6 + else: + disk_type = 1 + return disk_type + + def _collect_data(self): + # process data and save to 'self.data' + obj_api = ClusterAPI(self._module_inst) + cluster_id = obj_api.get_cluster_id() + osds = obj_api.get_osds() + for osd in osds: + if osd.get('osd') is None: + continue + if not osd.get('in'): + continue + osds_meta = obj_api.get_osd_metadata(osd.get('osd')) + if not osds_meta: + continue + osds_smart = obj_api.get_osd_smart(osd.get('osd')) + if not osds_smart: + continue + for dev_name, s_val in osds_smart.items(): + d_data = SAIDiskFields() + d_data.tags['disk_name'] = str(dev_name) + d_data.fields['cluster_domain_id'] = str(cluster_id) + d_data.tags['host_domain_id'] = \ + str('%s_%s' + % (cluster_id, osds_meta.get('hostname', 'None'))) + d_data.fields['agenthost'] = str(socket.gethostname()) + d_data.tags['agenthost_domain_id'] = cluster_id + serial_number = s_val.get('serial_number') + wwn = s_val.get('wwn', {}) + wwpn = '' + if wwn: + wwpn = '%06X%X' % (wwn.get('oui', 0), wwn.get('id', 0)) + for k in wwn.keys(): + if k in ['naa', 't10', 'eui', 'iqn']: + wwpn = ('%X%s' % (wwn[k], wwpn)).lower() + break + + if wwpn: + d_data.tags['disk_domain_id'] = str(dev_name) + d_data.tags['disk_wwn'] = str(wwpn) + if serial_number: + d_data.fields['serial_number'] = str(serial_number) + else: + d_data.fields['serial_number'] = str(wwpn) + elif serial_number: + d_data.tags['disk_domain_id'] = str(dev_name) + d_data.fields['serial_number'] = str(serial_number) + if wwpn: + d_data.tags['disk_wwn'] = str(wwpn) + else: + d_data.tags['disk_wwn'] = str(serial_number) + else: + d_data.tags['disk_domain_id'] = str(dev_name) + d_data.tags['disk_wwn'] = str(dev_name) + d_data.fields['serial_number'] = str(dev_name) + d_data.tags['primary_key'] = \ + str('%s%s%s' + % (cluster_id, d_data.tags['host_domain_id'], + d_data.tags['disk_domain_id'])) + d_data.fields['disk_status'] = int(1) + is_ssd = True if s_val.get('rotation_rate') == 0 else False + vendor = s_val.get('vendor', None) + model = s_val.get('model_name', None) + if s_val.get('sata_version', {}).get('string'): + sata_version = s_val['sata_version']['string'] + else: + sata_version = '' + if s_val.get('device', {}).get('protocol'): + protocol = s_val['device']['protocol'] + else: + protocol = '' + d_data.fields['disk_type'] = \ + self._convert_disk_type(is_ssd, sata_version, protocol) + d_data.fields['firmware_version'] = \ + str(s_val.get('firmware_version')) + if model: + d_data.fields['model'] = str(model) + if vendor: + d_data.fields['vendor'] = str(vendor) + if sata_version: + d_data.fields['sata_version'] = str(sata_version) + if s_val.get('logical_block_size'): + d_data.fields['sector_size'] = \ + str(str(s_val['logical_block_size'])) + d_data.fields['transport_protocol'] = str('') + d_data.fields['vendor'] = \ + str(s_val.get('model_family', '')).replace('\"', '\'') + try: + if isinstance(s_val.get('user_capacity'), dict): + if isinstance(s_val['user_capacity'].get('bytes'), dict): + user_capacity = \ + s_val['user_capacity'].get('bytes', {}).get('n', 0) + else: + user_capacity = s_val['user_capacity'].get('bytes') + else: + user_capacity = s_val.get('user_capacity', 0) + except ValueError: + user_capacity = 0 + if str(user_capacity).isdigit(): + d_data.fields['size'] = get_human_readable(int(user_capacity), 0) + else: + d_data.fields['size'] = str(user_capacity) + if s_val.get('smart_status', {}).get('passed'): + d_data.fields['smart_health_status'] = 'PASSED' + else: + d_data.fields['smart_health_status'] = 'FAILED' + self.data.append(d_data) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk_smart.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk_smart.py new file mode 100644 index 00000000..1ad34784 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_disk_smart.py @@ -0,0 +1,182 @@ +from __future__ import absolute_import + +import datetime +import json +import _strptime +import socket +import time + +from . import AGENT_VERSION, MetricsAgent, MetricsField +from ...common.clusterdata import ClusterAPI + + +class SAIDiskSmartFields(MetricsField): + """ SAI DiskSmart structure """ + measurement = 'sai_disk_smart' + + def __init__(self): + super(SAIDiskSmartFields, self).__init__() + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.tags['disk_domain_id'] = None + self.tags['disk_name'] = None + self.tags['disk_wwn'] = None + self.tags['primary_key'] = None + self.fields['cluster_domain_id'] = None + self.fields['host_domain_id'] = None + self.fields['agent_version'] = str(AGENT_VERSION) + + +class SAIDiskSmartAgent(MetricsAgent): + measurement = 'sai_disk_smart' + + def _collect_data(self): + # process data and save to 'self.data' + obj_api = ClusterAPI(self._module_inst) + cluster_id = obj_api.get_cluster_id() + osds = obj_api.get_osds() + for osd in osds: + if osd.get('osd') is None: + continue + if not osd.get('in'): + continue + osds_meta = obj_api.get_osd_metadata(osd.get('osd')) + if not osds_meta: + continue + devs_info = obj_api.get_osd_device_id(osd.get('osd')) + if devs_info: + for dev_name, dev_info in devs_info.items(): + osds_smart = obj_api.get_device_health(dev_info['dev_id']) + if not osds_smart: + continue + # Always pass through last smart data record + o_key = sorted(osds_smart.keys(), reverse=True)[0] + if o_key: + s_date = o_key + s_val = osds_smart[s_date] + smart_data = SAIDiskSmartFields() + smart_data.tags['disk_name'] = str(dev_name) + smart_data.fields['cluster_domain_id'] = str(cluster_id) + smart_data.tags['host_domain_id'] = \ + str('%s_%s' + % (cluster_id, osds_meta.get('hostname', 'None'))) + smart_data.fields['agenthost'] = str(socket.gethostname()) + smart_data.tags['agenthost_domain_id'] = cluster_id + # parse attributes + protocol = s_val.get('device', {}).get('protocol', '') + if str(protocol).lower() == 'nvme': + nvme_info = s_val.get('nvme_smart_health_information_log', {}) + smart_data['CriticalWarniing_raw'] = int(nvme_info.get('critical_warning', 0)) + smart_data['CurrentDriveTemperature_raw'] = int(nvme_info.get('temperature', 0)) + smart_data['AvailableSpare_raw'] = int(nvme_info.get('available_spare', 0)) + smart_data['AvailableSpareThreshold_raw'] = int(nvme_info.get('available_spare_threshold', 0)) + smart_data['PercentageUsed_raw'] = int(nvme_info.get('percentage_used', 0)) + smart_data['DataUnitsRead_raw'] = int(nvme_info.get('data_units_read', 0)) + smart_data['DataUnitsRead'] = int(nvme_info.get('data_units_written', 0)) + smart_data['HostReadCommands_raw'] = int(nvme_info.get('host_reads', 0)) + smart_data['HostWriteCommands_raw'] = int(nvme_info.get('host_writes', 0)) + smart_data['ControllerBusyTime_raw'] = int(nvme_info.get('controller_busy_time', 0)) + smart_data['PowerCycles_raw'] = int(nvme_info.get('power_cycles', 0)) + smart_data['PowerOnHours_raw'] = int(nvme_info.get('power_on_hours', 0)) + smart_data['UnsafeShutdowns_raw'] = int(nvme_info.get('unsafe_shutdowns', 0)) + smart_data['MediaandDataIntegrityErrors_raw'] = int(nvme_info.get('media_errors', 0)) + smart_data['ErrorInformationLogEntries'] = int(nvme_info.get('num_err_log_entries')) + nvme_addition = s_val.get('nvme_smart_health_information_add_log', {}) + for k, v in nvme_addition.get("Device stats", {}).items(): + if v.get('raw') is None: + continue + if isinstance(v.get('raw'), int): + smart_data[k] = int(v['raw']) + else: + smart_data[k] = str(v.get('raw')) + else: + ata_smart = s_val.get('ata_smart_attributes', {}) + for attr in ata_smart.get('table', []): + if attr.get('raw', {}).get('string'): + if str(attr.get('raw', {}).get('string', '0')).isdigit(): + smart_data.fields['%s_raw' % attr.get('id')] = \ + int(attr.get('raw', {}).get('string', '0')) + else: + if str(attr.get('raw', {}).get('string', '0')).split(' ')[0].isdigit(): + smart_data.fields['%s_raw' % attr.get('id')] = \ + int(attr.get('raw', {}).get('string', '0').split(' ')[0]) + else: + smart_data.fields['%s_raw' % attr.get('id')] = \ + attr.get('raw', {}).get('value', 0) + smart_data.fields['raw_data'] = str(json.dumps(osds_smart[s_date]).replace("\"", "\'")) + if s_val.get('temperature', {}).get('current') is not None: + smart_data.fields['CurrentDriveTemperature_raw'] = \ + int(s_val['temperature']['current']) + if s_val.get('temperature', {}).get('drive_trip') is not None: + smart_data.fields['DriveTripTemperature_raw'] = \ + int(s_val['temperature']['drive_trip']) + if s_val.get('elements_grown_list') is not None: + smart_data.fields['ElementsInGrownDefectList_raw'] = int(s_val['elements_grown_list']) + if s_val.get('power_on_time', {}).get('hours') is not None: + smart_data.fields['9_raw'] = int(s_val['power_on_time']['hours']) + if s_val.get('scsi_percentage_used_endurance_indicator') is not None: + smart_data.fields['PercentageUsedEnduranceIndicator_raw'] = \ + int(s_val['scsi_percentage_used_endurance_indicator']) + if s_val.get('scsi_error_counter_log') is not None: + s_err_counter = s_val['scsi_error_counter_log'] + for s_key in s_err_counter.keys(): + if s_key.lower() in ['read', 'write']: + for s1_key in s_err_counter[s_key].keys(): + if s1_key.lower() == 'errors_corrected_by_eccfast': + smart_data.fields['ErrorsCorrectedbyECCFast%s_raw' % s_key.capitalize()] = \ + int(s_err_counter[s_key]['errors_corrected_by_eccfast']) + elif s1_key.lower() == 'errors_corrected_by_eccdelayed': + smart_data.fields['ErrorsCorrectedbyECCDelayed%s_raw' % s_key.capitalize()] = \ + int(s_err_counter[s_key]['errors_corrected_by_eccdelayed']) + elif s1_key.lower() == 'errors_corrected_by_rereads_rewrites': + smart_data.fields['ErrorCorrectedByRereadsRewrites%s_raw' % s_key.capitalize()] = \ + int(s_err_counter[s_key]['errors_corrected_by_rereads_rewrites']) + elif s1_key.lower() == 'total_errors_corrected': + smart_data.fields['TotalErrorsCorrected%s_raw' % s_key.capitalize()] = \ + int(s_err_counter[s_key]['total_errors_corrected']) + elif s1_key.lower() == 'correction_algorithm_invocations': + smart_data.fields['CorrectionAlgorithmInvocations%s_raw' % s_key.capitalize()] = \ + int(s_err_counter[s_key]['correction_algorithm_invocations']) + elif s1_key.lower() == 'gigabytes_processed': + smart_data.fields['GigaBytesProcessed%s_raw' % s_key.capitalize()] = \ + float(s_err_counter[s_key]['gigabytes_processed']) + elif s1_key.lower() == 'total_uncorrected_errors': + smart_data.fields['TotalUncorrectedErrors%s_raw' % s_key.capitalize()] = \ + int(s_err_counter[s_key]['total_uncorrected_errors']) + + serial_number = s_val.get('serial_number') + wwn = s_val.get('wwn', {}) + wwpn = '' + if wwn: + wwpn = '%06X%X' % (wwn.get('oui', 0), wwn.get('id', 0)) + for k in wwn.keys(): + if k in ['naa', 't10', 'eui', 'iqn']: + wwpn = ('%X%s' % (wwn[k], wwpn)).lower() + break + if wwpn: + smart_data.tags['disk_domain_id'] = str(dev_info['dev_id']) + smart_data.tags['disk_wwn'] = str(wwpn) + if serial_number: + smart_data.fields['serial_number'] = str(serial_number) + else: + smart_data.fields['serial_number'] = str(wwpn) + elif serial_number: + smart_data.tags['disk_domain_id'] = str(dev_info['dev_id']) + smart_data.fields['serial_number'] = str(serial_number) + if wwpn: + smart_data.tags['disk_wwn'] = str(wwpn) + else: + smart_data.tags['disk_wwn'] = str(serial_number) + else: + smart_data.tags['disk_domain_id'] = str(dev_info['dev_id']) + smart_data.tags['disk_wwn'] = str(dev_name) + smart_data.fields['serial_number'] = str(dev_name) + smart_data.tags['primary_key'] = \ + str('%s%s%s' + % (cluster_id, + smart_data.tags['host_domain_id'], + smart_data.tags['disk_domain_id'])) + smart_data.timestamp = \ + time.mktime(datetime.datetime.strptime( + s_date, '%Y%m%d-%H%M%S').timetuple()) + self.data.append(smart_data) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_host.py b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_host.py new file mode 100644 index 00000000..0f3698ad --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/metrics/sai_host.py @@ -0,0 +1,105 @@ +from __future__ import absolute_import + +import socket + +from . import AGENT_VERSION, MetricsAgent, MetricsField +from ...common.clusterdata import ClusterAPI + + +class SAIHostFields(MetricsField): + """ SAI Host structure """ + measurement = 'sai_host' + + def __init__(self): + super(SAIHostFields, self).__init__() + self.tags['domain_id'] = None + self.fields['agenthost'] = None + self.tags['agenthost_domain_id'] = None + self.fields['cluster_domain_id'] = None + self.fields['name'] = None + self.fields['host_ip'] = None + self.fields['host_ipv6'] = None + self.fields['host_uuid'] = None + self.fields['os_type'] = str('ceph') + self.fields['os_name'] = None + self.fields['os_version'] = None + self.fields['agent_version'] = str(AGENT_VERSION) + + +class SAIHostAgent(MetricsAgent): + measurement = 'sai_host' + + def _collect_data(self): + db = ClusterAPI(self._module_inst) + cluster_id = db.get_cluster_id() + + hosts = set() + + # Parse osd's host + osd_data = db.get_osds() + for _data in osd_data: + osd_id = _data['osd'] + if not _data.get('in'): + continue + osd_addr = _data['public_addr'].split(':')[0] + osd_metadata = db.get_osd_metadata(osd_id) + if osd_metadata: + osd_host = osd_metadata.get('hostname', 'None') + if osd_host not in hosts: + data = SAIHostFields() + data.fields['agenthost'] = str(socket.gethostname()) + data.tags['agenthost_domain_id'] = cluster_id + data.tags['domain_id'] = \ + str('%s_%s' % (cluster_id, osd_host)) + data.fields['cluster_domain_id'] = str(cluster_id) + data.fields['host_ip'] = osd_addr + data.fields['host_uuid'] = \ + str('%s_%s' % (cluster_id, osd_host)) + data.fields['os_name'] = \ + osd_metadata.get('ceph_release', '') + data.fields['os_version'] = \ + osd_metadata.get('ceph_version_short', '') + data.fields['name'] = 'osd_{}'.format(osd_host) + hosts.add(osd_host) + self.data.append(data) + + # Parse mon node host + mons = db.get_mons() + for _data in mons: + mon_host = _data['name'] + mon_addr = _data['public_addr'].split(':')[0] + if mon_host not in hosts: + data = SAIHostFields() + data.fields['agenthost'] = str(socket.gethostname()) + data.tags['agenthost_domain_id'] = cluster_id + data.tags['domain_id'] = \ + str('%s_%s' % (cluster_id, mon_host)) + data.fields['cluster_domain_id'] = str(cluster_id) + data.fields['host_ip'] = mon_addr + data.fields['host_uuid'] = \ + str('%s_%s' % (cluster_id, mon_host)) + data.fields['name'] = 'mon_{}'.format(mon_host) + hosts.add((mon_host, mon_addr)) + self.data.append(data) + + # Parse fs host + file_systems = db.get_file_systems() + for _data in file_systems: + mds_info = _data.get('mdsmap').get('info') + for _gid in mds_info: + mds_data = mds_info[_gid] + mds_addr = mds_data.get('addr').split(':')[0] + mds_host = mds_data.get('name') + if mds_host not in hosts: + data = SAIHostFields() + data.fields['agenthost'] = str(socket.gethostname()) + data.tags['agenthost_domain_id'] = cluster_id + data.tags['domain_id'] = \ + str('%s_%s' % (cluster_id, mds_host)) + data.fields['cluster_domain_id'] = str(cluster_id) + data.fields['host_ip'] = mds_addr + data.fields['host_uuid'] = \ + str('%s_%s' % (cluster_id, mds_host)) + data.fields['name'] = 'mds_{}'.format(mds_host) + hosts.add((mds_host, mds_addr)) + self.data.append(data) diff --git a/src/pybind/mgr/diskprediction_cloud/agent/predictor.py b/src/pybind/mgr/diskprediction_cloud/agent/predictor.py new file mode 100644 index 00000000..1fdea46d --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/agent/predictor.py @@ -0,0 +1,48 @@ +from __future__ import absolute_import + + +class PredictAgent(object): + + measurement = 'predictor' + + def __init__(self, mgr_module, obj_sender, timeout=30): + self.data = [] + self._client = None + self._client = obj_sender + self._logger = mgr_module.log + self._module_inst = mgr_module + self._timeout = timeout + + def __nonzero__(self): + if not self._module_inst: + return False + else: + return True + + def run(self): + result = self._module_inst.get('devices') + cluster_id = self._module_inst.get('mon_map').get('fsid') + if not result: + return -1, '', 'unable to get all devices for prediction' + for dev in result.get('devices', []): + for location in dev.get('location', []): + host = location.get('host') + host_domain_id = '{}_{}'.format(cluster_id, host) + prediction_data = self._get_cloud_prediction_result(host_domain_id, dev.get('devid')) + if prediction_data: + self._module_inst.prediction_result[dev.get('devid')] = prediction_data + + def _get_cloud_prediction_result(self, host_domain_id, disk_domain_id): + result = {} + try: + query_info = self._client.query_info(host_domain_id, disk_domain_id, 'sai_disk_prediction') + status_code = query_info.status_code + if status_code == 200: + result = query_info.json() + else: + resp = query_info.json() + if resp.get('error'): + self._logger.error(str(resp['error'])) + except Exception as e: + self._logger.error('failed to get %s prediction result %s' % (disk_domain_id, str(e))) + return result diff --git a/src/pybind/mgr/diskprediction_cloud/common/__init__.py b/src/pybind/mgr/diskprediction_cloud/common/__init__.py new file mode 100644 index 00000000..ce5131b8 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/common/__init__.py @@ -0,0 +1,61 @@ +from __future__ import absolute_import +import errno +from functools import wraps +import os +import signal + + +DP_MGR_STAT_OK = 'OK' +DP_MGR_STAT_WARNING = 'WARNING' +DP_MGR_STAT_FAILED = 'FAILED' +DP_MGR_STAT_DISABLED = 'DISABLED' +DP_MGR_STAT_ENABLED = 'ENABLED' + + +class DummyResonse: + def __init__(self): + self.resp_json = dict() + self.content = 'DummyResponse' + self.status_code = 404 + + def json(self): + return self.resp_json + + def __str__(self): + return '{}'.format({'resp': self.resp_json, 'content': self.content, 'status_code': self.status_code}) + + +class TimeoutError(Exception): + pass + + +def timeout(seconds=10, error_message=os.strerror(errno.ETIME)): + def decorator(func): + def _handle_timeout(signum, frame): + raise TimeoutError(error_message) + + def wrapper(*args, **kwargs): + if hasattr(args[0], '_timeout') is not None: + seconds = args[0]._timeout + signal.signal(signal.SIGALRM, _handle_timeout) + signal.alarm(seconds) + try: + result = func(*args, **kwargs) + finally: + signal.alarm(0) + return result + + return wraps(func)(wrapper) + + return decorator + + +def get_human_readable(size, precision=2): + suffixes = ['B', 'KB', 'MB', 'GB', 'TB'] + suffix_index = 0 + while size > 1000 and suffix_index < 4: + # increment the index of the suffix + suffix_index += 1 + # apply the division + size = size/1000.0 + return '%.*d %s' % (precision, size, suffixes[suffix_index]) diff --git a/src/pybind/mgr/diskprediction_cloud/common/client_pb2.py b/src/pybind/mgr/diskprediction_cloud/common/client_pb2.py new file mode 100644 index 00000000..9f65c731 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/common/client_pb2.py @@ -0,0 +1,1775 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: mainServer.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='mainServer.proto', + package='proto', + syntax='proto3', + serialized_pb=_b('\n\x10mainServer.proto\x12\x05proto\x1a\x1cgoogle/api/annotations.proto\"\x07\n\x05\x45mpty\"#\n\x10GeneralMsgOutput\x12\x0f\n\x07message\x18\x01 \x01(\t\")\n\x16GeneralHeartbeatOutput\x12\x0f\n\x07message\x18\x01 \x01(\t\"\x1d\n\nPingOutout\x12\x0f\n\x07message\x18\x01 \x01(\t\"*\n\tTestInput\x12\x1d\n\x06people\x18\x01 \x03(\x0b\x32\r.proto.Person\"\xbe\x01\n\nTestOutput\x12\x10\n\x08strArray\x18\x01 \x03(\t\x12\x31\n\x08mapValue\x18\x02 \x03(\x0b\x32\x1f.proto.TestOutput.MapValueEntry\x12\x19\n\x02pn\x18\x04 \x01(\x0b\x32\r.proto.Person\x12\x1f\n\x07profile\x18\x03 \x03(\x0b\x32\x0e.proto.Profile\x1a/\n\rMapValueEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xcf\x01\n\x06Person\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x03\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12)\n\x06phones\x18\x04 \x03(\x0b\x32\x19.proto.Person.PhoneNumber\x1a\x44\n\x0bPhoneNumber\x12\x0e\n\x06number\x18\x01 \x01(\t\x12%\n\x04type\x18\x02 \x01(\x0e\x32\x17.proto.Person.PhoneType\"+\n\tPhoneType\x12\n\n\x06MOBILE\x10\x00\x12\x08\n\x04HOME\x10\x01\x12\x08\n\x04WORK\x10\x02\"\xa9\x01\n\x07Profile\x12%\n\x08\x66ileInfo\x18\x01 \x01(\x0b\x32\x13.proto.Profile.File\x1aw\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\ttypeInt32\x18\x02 \x01(\x05\x12\x11\n\ttypeInt64\x18\x03 \x01(\x03\x12\x11\n\ttypeFloat\x18\x04 \x01(\x02\x12\x12\n\ntypeDouble\x18\x05 \x01(\x01\x12\x14\n\x0c\x62ooleanValue\x18\x06 \x01(\x08\"4\n\x15GetUsersByStatusInput\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\":\n\x16GetUsersByStatusOutput\x12 \n\x05users\x18\x01 \x03(\x0b\x32\x11.proto.UserOutput\")\n\x16\x41\x63\x63ountHeartbeatOutput\x12\x0f\n\x07message\x18\x01 \x01(\t\"-\n\nLoginInput\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x10\n\x08password\x18\x02 \x01(\t\"\xf2\x01\n\nUserOutput\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\r\n\x05phone\x18\x04 \x01(\t\x12\x11\n\tfirstName\x18\x05 \x01(\t\x12\x10\n\x08lastName\x18\x06 \x01(\t\x12\x13\n\x0b\x63reatedTime\x18\x07 \x01(\t\x12\x11\n\tnamespace\x18\x08 \x01(\t\x12\x12\n\ndomainName\x18\t \x01(\t\x12\x0f\n\x07\x63ompany\x18\n \x01(\t\x12\x0b\n\x03url\x18\x0b \x01(\t\x12\x14\n\x0c\x61gentAccount\x18\x0c \x01(\t\x12\x15\n\ragentPassword\x18\r \x01(\t\"s\n\x0bSingupInput\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\r\n\x05phone\x18\x02 \x01(\t\x12\x11\n\tfirstName\x18\x03 \x01(\t\x12\x10\n\x08lastName\x18\x04 \x01(\t\x12\x10\n\x08password\x18\x05 \x01(\t\x12\x0f\n\x07\x63ompany\x18\x06 \x01(\t\"\x1f\n\x0cSingupOutput\x12\x0f\n\x07message\x18\x01 \x01(\t\"-\n\x0f\x44\x65leteUserInput\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"C\n\x15UpdateUserStatusInput\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x03 \x01(\t\"\'\n\x16ResendConfirmCodeInput\x12\r\n\x05\x65mail\x18\x01 \x01(\t\"+\n\x0c\x43onfirmInput\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\"$\n\x11\x44PHeartbeatOutput\x12\x0f\n\x07message\x18\x01 \x01(\t\"n\n\x17\x44PGetPhysicalDisksInput\x12\x0f\n\x07hostIds\x18\x01 \x01(\t\x12\x0b\n\x03ids\x18\x02 \x01(\t\x12\r\n\x05limit\x18\x03 \x01(\x03\x12\x0c\n\x04page\x18\x04 \x01(\x03\x12\x0c\n\x04\x66rom\x18\x05 \x01(\t\x12\n\n\x02to\x18\x06 \x01(\t\"{\n\x19\x44PGetDisksPredictionInput\x12\x17\n\x0fphysicalDiskIds\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\x12\r\n\x05limit\x18\x03 \x01(\x03\x12\x0c\n\x04page\x18\x04 \x01(\x03\x12\x0c\n\x04\x66rom\x18\x05 \x01(\t\x12\n\n\x02to\x18\x06 \x01(\t\"\x1e\n\x0e\x44PBinaryOutput\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\",\n\x19\x43ollectionHeartbeatOutput\x12\x0f\n\x07message\x18\x01 \x01(\t\"\"\n\x10PostMetricsInput\x12\x0e\n\x06points\x18\x01 \x03(\t\" \n\x10PostDBRelayInput\x12\x0c\n\x04\x63mds\x18\x01 \x03(\t\":\n\x17\x43ollectionMessageOutput\x12\x0e\n\x06status\x18\x01 \x01(\x03\x12\x0f\n\x07message\x18\x02 \x01(\t2\x85\x02\n\x07General\x12\x63\n\x10GeneralHeartbeat\x12\x0c.proto.Empty\x1a\x1d.proto.GeneralHeartbeatOutput\"\"\x82\xd3\xe4\x93\x02\x1c\x12\x1a/apis/v2/general/heartbeat\x12\x46\n\x04Ping\x12\x0c.proto.Empty\x1a\x11.proto.PingOutout\"\x1d\x82\xd3\xe4\x93\x02\x17\x12\x15/apis/v2/general/ping\x12M\n\x04Test\x12\x10.proto.TestInput\x1a\x11.proto.TestOutput\" \x82\xd3\xe4\x93\x02\x1a\"\x15/apis/v2/general/test:\x01*2\xa4\x06\n\x07\x41\x63\x63ount\x12\x63\n\x10\x41\x63\x63ountHeartbeat\x12\x0c.proto.Empty\x1a\x1d.proto.AccountHeartbeatOutput\"\"\x82\xd3\xe4\x93\x02\x1c\x12\x1a/apis/v2/account/heartbeat\x12N\n\x05Login\x12\x11.proto.LoginInput\x1a\x11.proto.UserOutput\"\x1f\x82\xd3\xe4\x93\x02\x19\"\x14/apis/v2/users/login:\x01*\x12S\n\x06Signup\x12\x12.proto.SingupInput\x1a\x13.proto.SingupOutput\" \x82\xd3\xe4\x93\x02\x1a\"\x15/apis/v2/users/signup:\x01*\x12r\n\x11ResendConfirmCode\x12\x1d.proto.ResendConfirmCodeInput\x1a\x17.proto.GeneralMsgOutput\"%\x82\xd3\xe4\x93\x02\x1f\"\x1a/apis/v2/users/confirmcode:\x01*\x12_\n\x07\x43onfirm\x12\x13.proto.ConfirmInput\x1a\x17.proto.GeneralMsgOutput\"&\x82\xd3\xe4\x93\x02 \"\x1b/apis/v2/users/confirmation:\x01*\x12g\n\x10GetUsersByStatus\x12\x1c.proto.GetUsersByStatusInput\x1a\x1d.proto.GetUsersByStatusOutput\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/apis/v2/users\x12\x63\n\nDeleteUser\x12\x16.proto.DeleteUserInput\x1a\x17.proto.GeneralMsgOutput\"$\x82\xd3\xe4\x93\x02\x1e*\x1c/apis/v2/users/{email}/{key}\x12l\n\x10UpdateUserStatus\x12\x1c.proto.UpdateUserStatusInput\x1a\x17.proto.GeneralMsgOutput\"!\x82\xd3\xe4\x93\x02\x1b\x1a\x16/apis/v2/users/{email}:\x01*2\xcf\x02\n\x0b\x44iskprophet\x12T\n\x0b\x44PHeartbeat\x12\x0c.proto.Empty\x1a\x18.proto.DPHeartbeatOutput\"\x1d\x82\xd3\xe4\x93\x02\x17\x12\x15/apis/v2/dp/heartbeat\x12l\n\x12\x44PGetPhysicalDisks\x12\x1e.proto.DPGetPhysicalDisksInput\x1a\x15.proto.DPBinaryOutput\"\x1f\x82\xd3\xe4\x93\x02\x19\x12\x17/apis/v2/physical-disks\x12|\n\x14\x44PGetDisksPrediction\x12 .proto.DPGetDisksPredictionInput\x1a\x15.proto.DPBinaryOutput\"+\x82\xd3\xe4\x93\x02%\x12#/apis/v2/physical-disks/predictions2\xdb\x02\n\nCollection\x12l\n\x13\x43ollectionHeartbeat\x12\x0c.proto.Empty\x1a .proto.CollectionHeartbeatOutput\"%\x82\xd3\xe4\x93\x02\x1f\x12\x1d/apis/v2/collection/heartbeat\x12o\n\x0bPostDBRelay\x12\x17.proto.PostDBRelayInput\x1a\x1e.proto.CollectionMessageOutput\"\'\x82\xd3\xe4\x93\x02!\"\x1c/apis/v2/collection/relation:\x01*\x12n\n\x0bPostMetrics\x12\x17.proto.PostMetricsInput\x1a\x1e.proto.CollectionMessageOutput\"&\x82\xd3\xe4\x93\x02 \"\x1b/apis/v2/collection/metrics:\x01*b\x06proto3') + , + dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,]) + + + +_PERSON_PHONETYPE = _descriptor.EnumDescriptor( + name='PhoneType', + full_name='proto.Person.PhoneType', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='MOBILE', index=0, number=0, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='HOME', index=1, number=1, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='WORK', index=2, number=2, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=579, + serialized_end=622, +) +_sym_db.RegisterEnumDescriptor(_PERSON_PHONETYPE) + + +_EMPTY = _descriptor.Descriptor( + name='Empty', + full_name='proto.Empty', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=57, + serialized_end=64, +) + + +_GENERALMSGOUTPUT = _descriptor.Descriptor( + name='GeneralMsgOutput', + full_name='proto.GeneralMsgOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='proto.GeneralMsgOutput.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=66, + serialized_end=101, +) + + +_GENERALHEARTBEATOUTPUT = _descriptor.Descriptor( + name='GeneralHeartbeatOutput', + full_name='proto.GeneralHeartbeatOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='proto.GeneralHeartbeatOutput.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=103, + serialized_end=144, +) + + +_PINGOUTOUT = _descriptor.Descriptor( + name='PingOutout', + full_name='proto.PingOutout', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='proto.PingOutout.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=146, + serialized_end=175, +) + + +_TESTINPUT = _descriptor.Descriptor( + name='TestInput', + full_name='proto.TestInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='people', full_name='proto.TestInput.people', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=177, + serialized_end=219, +) + + +_TESTOUTPUT_MAPVALUEENTRY = _descriptor.Descriptor( + name='MapValueEntry', + full_name='proto.TestOutput.MapValueEntry', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='proto.TestOutput.MapValueEntry.key', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='value', full_name='proto.TestOutput.MapValueEntry.value', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')), + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=365, + serialized_end=412, +) + +_TESTOUTPUT = _descriptor.Descriptor( + name='TestOutput', + full_name='proto.TestOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='strArray', full_name='proto.TestOutput.strArray', index=0, + number=1, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='mapValue', full_name='proto.TestOutput.mapValue', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='pn', full_name='proto.TestOutput.pn', index=2, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='profile', full_name='proto.TestOutput.profile', index=3, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[_TESTOUTPUT_MAPVALUEENTRY, ], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=222, + serialized_end=412, +) + + +_PERSON_PHONENUMBER = _descriptor.Descriptor( + name='PhoneNumber', + full_name='proto.Person.PhoneNumber', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='number', full_name='proto.Person.PhoneNumber.number', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='type', full_name='proto.Person.PhoneNumber.type', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=509, + serialized_end=577, +) + +_PERSON = _descriptor.Descriptor( + name='Person', + full_name='proto.Person', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='proto.Person.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='id', full_name='proto.Person.id', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='email', full_name='proto.Person.email', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='phones', full_name='proto.Person.phones', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[_PERSON_PHONENUMBER, ], + enum_types=[ + _PERSON_PHONETYPE, + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=415, + serialized_end=622, +) + + +_PROFILE_FILE = _descriptor.Descriptor( + name='File', + full_name='proto.Profile.File', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='proto.Profile.File.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='typeInt32', full_name='proto.Profile.File.typeInt32', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='typeInt64', full_name='proto.Profile.File.typeInt64', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='typeFloat', full_name='proto.Profile.File.typeFloat', index=3, + number=4, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='typeDouble', full_name='proto.Profile.File.typeDouble', index=4, + number=5, type=1, cpp_type=5, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='booleanValue', full_name='proto.Profile.File.booleanValue', index=5, + number=6, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=675, + serialized_end=794, +) + +_PROFILE = _descriptor.Descriptor( + name='Profile', + full_name='proto.Profile', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='fileInfo', full_name='proto.Profile.fileInfo', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[_PROFILE_FILE, ], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=625, + serialized_end=794, +) + + +_GETUSERSBYSTATUSINPUT = _descriptor.Descriptor( + name='GetUsersByStatusInput', + full_name='proto.GetUsersByStatusInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='status', full_name='proto.GetUsersByStatusInput.status', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key', full_name='proto.GetUsersByStatusInput.key', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=796, + serialized_end=848, +) + + +_GETUSERSBYSTATUSOUTPUT = _descriptor.Descriptor( + name='GetUsersByStatusOutput', + full_name='proto.GetUsersByStatusOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='users', full_name='proto.GetUsersByStatusOutput.users', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=850, + serialized_end=908, +) + + +_ACCOUNTHEARTBEATOUTPUT = _descriptor.Descriptor( + name='AccountHeartbeatOutput', + full_name='proto.AccountHeartbeatOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='proto.AccountHeartbeatOutput.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=910, + serialized_end=951, +) + + +_LOGININPUT = _descriptor.Descriptor( + name='LoginInput', + full_name='proto.LoginInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='email', full_name='proto.LoginInput.email', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='password', full_name='proto.LoginInput.password', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=953, + serialized_end=998, +) + + +_USEROUTPUT = _descriptor.Descriptor( + name='UserOutput', + full_name='proto.UserOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='proto.UserOutput.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='email', full_name='proto.UserOutput.email', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='status', full_name='proto.UserOutput.status', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='phone', full_name='proto.UserOutput.phone', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='firstName', full_name='proto.UserOutput.firstName', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='lastName', full_name='proto.UserOutput.lastName', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='createdTime', full_name='proto.UserOutput.createdTime', index=6, + number=7, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='namespace', full_name='proto.UserOutput.namespace', index=7, + number=8, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='domainName', full_name='proto.UserOutput.domainName', index=8, + number=9, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='company', full_name='proto.UserOutput.company', index=9, + number=10, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='url', full_name='proto.UserOutput.url', index=10, + number=11, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='agentAccount', full_name='proto.UserOutput.agentAccount', index=11, + number=12, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='agentPassword', full_name='proto.UserOutput.agentPassword', index=12, + number=13, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1001, + serialized_end=1243, +) + + +_SINGUPINPUT = _descriptor.Descriptor( + name='SingupInput', + full_name='proto.SingupInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='email', full_name='proto.SingupInput.email', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='phone', full_name='proto.SingupInput.phone', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='firstName', full_name='proto.SingupInput.firstName', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='lastName', full_name='proto.SingupInput.lastName', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='password', full_name='proto.SingupInput.password', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='company', full_name='proto.SingupInput.company', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1245, + serialized_end=1360, +) + + +_SINGUPOUTPUT = _descriptor.Descriptor( + name='SingupOutput', + full_name='proto.SingupOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='proto.SingupOutput.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1362, + serialized_end=1393, +) + + +_DELETEUSERINPUT = _descriptor.Descriptor( + name='DeleteUserInput', + full_name='proto.DeleteUserInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='email', full_name='proto.DeleteUserInput.email', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key', full_name='proto.DeleteUserInput.key', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1395, + serialized_end=1440, +) + + +_UPDATEUSERSTATUSINPUT = _descriptor.Descriptor( + name='UpdateUserStatusInput', + full_name='proto.UpdateUserStatusInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='email', full_name='proto.UpdateUserStatusInput.email', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key', full_name='proto.UpdateUserStatusInput.key', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='status', full_name='proto.UpdateUserStatusInput.status', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1442, + serialized_end=1509, +) + + +_RESENDCONFIRMCODEINPUT = _descriptor.Descriptor( + name='ResendConfirmCodeInput', + full_name='proto.ResendConfirmCodeInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='email', full_name='proto.ResendConfirmCodeInput.email', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1511, + serialized_end=1550, +) + + +_CONFIRMINPUT = _descriptor.Descriptor( + name='ConfirmInput', + full_name='proto.ConfirmInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='email', full_name='proto.ConfirmInput.email', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='code', full_name='proto.ConfirmInput.code', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1552, + serialized_end=1595, +) + + +_DPHEARTBEATOUTPUT = _descriptor.Descriptor( + name='DPHeartbeatOutput', + full_name='proto.DPHeartbeatOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='proto.DPHeartbeatOutput.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1597, + serialized_end=1633, +) + + +_DPGETPHYSICALDISKSINPUT = _descriptor.Descriptor( + name='DPGetPhysicalDisksInput', + full_name='proto.DPGetPhysicalDisksInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='hostIds', full_name='proto.DPGetPhysicalDisksInput.hostIds', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='ids', full_name='proto.DPGetPhysicalDisksInput.ids', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='limit', full_name='proto.DPGetPhysicalDisksInput.limit', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='page', full_name='proto.DPGetPhysicalDisksInput.page', index=3, + number=4, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='from', full_name='proto.DPGetPhysicalDisksInput.from', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='to', full_name='proto.DPGetPhysicalDisksInput.to', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1635, + serialized_end=1745, +) + + +_DPGETDISKSPREDICTIONINPUT = _descriptor.Descriptor( + name='DPGetDisksPredictionInput', + full_name='proto.DPGetDisksPredictionInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='physicalDiskIds', full_name='proto.DPGetDisksPredictionInput.physicalDiskIds', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='status', full_name='proto.DPGetDisksPredictionInput.status', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='limit', full_name='proto.DPGetDisksPredictionInput.limit', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='page', full_name='proto.DPGetDisksPredictionInput.page', index=3, + number=4, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='from', full_name='proto.DPGetDisksPredictionInput.from', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='to', full_name='proto.DPGetDisksPredictionInput.to', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1747, + serialized_end=1870, +) + + +_DPBINARYOUTPUT = _descriptor.Descriptor( + name='DPBinaryOutput', + full_name='proto.DPBinaryOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='data', full_name='proto.DPBinaryOutput.data', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1872, + serialized_end=1902, +) + + +_COLLECTIONHEARTBEATOUTPUT = _descriptor.Descriptor( + name='CollectionHeartbeatOutput', + full_name='proto.CollectionHeartbeatOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='proto.CollectionHeartbeatOutput.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1904, + serialized_end=1948, +) + + +_POSTMETRICSINPUT = _descriptor.Descriptor( + name='PostMetricsInput', + full_name='proto.PostMetricsInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='points', full_name='proto.PostMetricsInput.points', index=0, + number=1, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1950, + serialized_end=1984, +) + + +_POSTDBRELAYINPUT = _descriptor.Descriptor( + name='PostDBRelayInput', + full_name='proto.PostDBRelayInput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='cmds', full_name='proto.PostDBRelayInput.cmds', index=0, + number=1, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1986, + serialized_end=2018, +) + + +_COLLECTIONMESSAGEOUTPUT = _descriptor.Descriptor( + name='CollectionMessageOutput', + full_name='proto.CollectionMessageOutput', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='status', full_name='proto.CollectionMessageOutput.status', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='message', full_name='proto.CollectionMessageOutput.message', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2020, + serialized_end=2078, +) + +_TESTINPUT.fields_by_name['people'].message_type = _PERSON +_TESTOUTPUT_MAPVALUEENTRY.containing_type = _TESTOUTPUT +_TESTOUTPUT.fields_by_name['mapValue'].message_type = _TESTOUTPUT_MAPVALUEENTRY +_TESTOUTPUT.fields_by_name['pn'].message_type = _PERSON +_TESTOUTPUT.fields_by_name['profile'].message_type = _PROFILE +_PERSON_PHONENUMBER.fields_by_name['type'].enum_type = _PERSON_PHONETYPE +_PERSON_PHONENUMBER.containing_type = _PERSON +_PERSON.fields_by_name['phones'].message_type = _PERSON_PHONENUMBER +_PERSON_PHONETYPE.containing_type = _PERSON +_PROFILE_FILE.containing_type = _PROFILE +_PROFILE.fields_by_name['fileInfo'].message_type = _PROFILE_FILE +_GETUSERSBYSTATUSOUTPUT.fields_by_name['users'].message_type = _USEROUTPUT +DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY +DESCRIPTOR.message_types_by_name['GeneralMsgOutput'] = _GENERALMSGOUTPUT +DESCRIPTOR.message_types_by_name['GeneralHeartbeatOutput'] = _GENERALHEARTBEATOUTPUT +DESCRIPTOR.message_types_by_name['PingOutout'] = _PINGOUTOUT +DESCRIPTOR.message_types_by_name['TestInput'] = _TESTINPUT +DESCRIPTOR.message_types_by_name['TestOutput'] = _TESTOUTPUT +DESCRIPTOR.message_types_by_name['Person'] = _PERSON +DESCRIPTOR.message_types_by_name['Profile'] = _PROFILE +DESCRIPTOR.message_types_by_name['GetUsersByStatusInput'] = _GETUSERSBYSTATUSINPUT +DESCRIPTOR.message_types_by_name['GetUsersByStatusOutput'] = _GETUSERSBYSTATUSOUTPUT +DESCRIPTOR.message_types_by_name['AccountHeartbeatOutput'] = _ACCOUNTHEARTBEATOUTPUT +DESCRIPTOR.message_types_by_name['LoginInput'] = _LOGININPUT +DESCRIPTOR.message_types_by_name['UserOutput'] = _USEROUTPUT +DESCRIPTOR.message_types_by_name['SingupInput'] = _SINGUPINPUT +DESCRIPTOR.message_types_by_name['SingupOutput'] = _SINGUPOUTPUT +DESCRIPTOR.message_types_by_name['DeleteUserInput'] = _DELETEUSERINPUT +DESCRIPTOR.message_types_by_name['UpdateUserStatusInput'] = _UPDATEUSERSTATUSINPUT +DESCRIPTOR.message_types_by_name['ResendConfirmCodeInput'] = _RESENDCONFIRMCODEINPUT +DESCRIPTOR.message_types_by_name['ConfirmInput'] = _CONFIRMINPUT +DESCRIPTOR.message_types_by_name['DPHeartbeatOutput'] = _DPHEARTBEATOUTPUT +DESCRIPTOR.message_types_by_name['DPGetPhysicalDisksInput'] = _DPGETPHYSICALDISKSINPUT +DESCRIPTOR.message_types_by_name['DPGetDisksPredictionInput'] = _DPGETDISKSPREDICTIONINPUT +DESCRIPTOR.message_types_by_name['DPBinaryOutput'] = _DPBINARYOUTPUT +DESCRIPTOR.message_types_by_name['CollectionHeartbeatOutput'] = _COLLECTIONHEARTBEATOUTPUT +DESCRIPTOR.message_types_by_name['PostMetricsInput'] = _POSTMETRICSINPUT +DESCRIPTOR.message_types_by_name['PostDBRelayInput'] = _POSTDBRELAYINPUT +DESCRIPTOR.message_types_by_name['CollectionMessageOutput'] = _COLLECTIONMESSAGEOUTPUT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), dict( + DESCRIPTOR = _EMPTY, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.Empty) + )) +_sym_db.RegisterMessage(Empty) + +GeneralMsgOutput = _reflection.GeneratedProtocolMessageType('GeneralMsgOutput', (_message.Message,), dict( + DESCRIPTOR = _GENERALMSGOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.GeneralMsgOutput) + )) +_sym_db.RegisterMessage(GeneralMsgOutput) + +GeneralHeartbeatOutput = _reflection.GeneratedProtocolMessageType('GeneralHeartbeatOutput', (_message.Message,), dict( + DESCRIPTOR = _GENERALHEARTBEATOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.GeneralHeartbeatOutput) + )) +_sym_db.RegisterMessage(GeneralHeartbeatOutput) + +PingOutout = _reflection.GeneratedProtocolMessageType('PingOutout', (_message.Message,), dict( + DESCRIPTOR = _PINGOUTOUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.PingOutout) + )) +_sym_db.RegisterMessage(PingOutout) + +TestInput = _reflection.GeneratedProtocolMessageType('TestInput', (_message.Message,), dict( + DESCRIPTOR = _TESTINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.TestInput) + )) +_sym_db.RegisterMessage(TestInput) + +TestOutput = _reflection.GeneratedProtocolMessageType('TestOutput', (_message.Message,), dict( + + MapValueEntry = _reflection.GeneratedProtocolMessageType('MapValueEntry', (_message.Message,), dict( + DESCRIPTOR = _TESTOUTPUT_MAPVALUEENTRY, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.TestOutput.MapValueEntry) + )) + , + DESCRIPTOR = _TESTOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.TestOutput) + )) +_sym_db.RegisterMessage(TestOutput) +_sym_db.RegisterMessage(TestOutput.MapValueEntry) + +Person = _reflection.GeneratedProtocolMessageType('Person', (_message.Message,), dict( + + PhoneNumber = _reflection.GeneratedProtocolMessageType('PhoneNumber', (_message.Message,), dict( + DESCRIPTOR = _PERSON_PHONENUMBER, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.Person.PhoneNumber) + )) + , + DESCRIPTOR = _PERSON, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.Person) + )) +_sym_db.RegisterMessage(Person) +_sym_db.RegisterMessage(Person.PhoneNumber) + +Profile = _reflection.GeneratedProtocolMessageType('Profile', (_message.Message,), dict( + + File = _reflection.GeneratedProtocolMessageType('File', (_message.Message,), dict( + DESCRIPTOR = _PROFILE_FILE, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.Profile.File) + )) + , + DESCRIPTOR = _PROFILE, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.Profile) + )) +_sym_db.RegisterMessage(Profile) +_sym_db.RegisterMessage(Profile.File) + +GetUsersByStatusInput = _reflection.GeneratedProtocolMessageType('GetUsersByStatusInput', (_message.Message,), dict( + DESCRIPTOR = _GETUSERSBYSTATUSINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.GetUsersByStatusInput) + )) +_sym_db.RegisterMessage(GetUsersByStatusInput) + +GetUsersByStatusOutput = _reflection.GeneratedProtocolMessageType('GetUsersByStatusOutput', (_message.Message,), dict( + DESCRIPTOR = _GETUSERSBYSTATUSOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.GetUsersByStatusOutput) + )) +_sym_db.RegisterMessage(GetUsersByStatusOutput) + +AccountHeartbeatOutput = _reflection.GeneratedProtocolMessageType('AccountHeartbeatOutput', (_message.Message,), dict( + DESCRIPTOR = _ACCOUNTHEARTBEATOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.AccountHeartbeatOutput) + )) +_sym_db.RegisterMessage(AccountHeartbeatOutput) + +LoginInput = _reflection.GeneratedProtocolMessageType('LoginInput', (_message.Message,), dict( + DESCRIPTOR = _LOGININPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.LoginInput) + )) +_sym_db.RegisterMessage(LoginInput) + +UserOutput = _reflection.GeneratedProtocolMessageType('UserOutput', (_message.Message,), dict( + DESCRIPTOR = _USEROUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.UserOutput) + )) +_sym_db.RegisterMessage(UserOutput) + +SingupInput = _reflection.GeneratedProtocolMessageType('SingupInput', (_message.Message,), dict( + DESCRIPTOR = _SINGUPINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.SingupInput) + )) +_sym_db.RegisterMessage(SingupInput) + +SingupOutput = _reflection.GeneratedProtocolMessageType('SingupOutput', (_message.Message,), dict( + DESCRIPTOR = _SINGUPOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.SingupOutput) + )) +_sym_db.RegisterMessage(SingupOutput) + +DeleteUserInput = _reflection.GeneratedProtocolMessageType('DeleteUserInput', (_message.Message,), dict( + DESCRIPTOR = _DELETEUSERINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.DeleteUserInput) + )) +_sym_db.RegisterMessage(DeleteUserInput) + +UpdateUserStatusInput = _reflection.GeneratedProtocolMessageType('UpdateUserStatusInput', (_message.Message,), dict( + DESCRIPTOR = _UPDATEUSERSTATUSINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.UpdateUserStatusInput) + )) +_sym_db.RegisterMessage(UpdateUserStatusInput) + +ResendConfirmCodeInput = _reflection.GeneratedProtocolMessageType('ResendConfirmCodeInput', (_message.Message,), dict( + DESCRIPTOR = _RESENDCONFIRMCODEINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.ResendConfirmCodeInput) + )) +_sym_db.RegisterMessage(ResendConfirmCodeInput) + +ConfirmInput = _reflection.GeneratedProtocolMessageType('ConfirmInput', (_message.Message,), dict( + DESCRIPTOR = _CONFIRMINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.ConfirmInput) + )) +_sym_db.RegisterMessage(ConfirmInput) + +DPHeartbeatOutput = _reflection.GeneratedProtocolMessageType('DPHeartbeatOutput', (_message.Message,), dict( + DESCRIPTOR = _DPHEARTBEATOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.DPHeartbeatOutput) + )) +_sym_db.RegisterMessage(DPHeartbeatOutput) + +DPGetPhysicalDisksInput = _reflection.GeneratedProtocolMessageType('DPGetPhysicalDisksInput', (_message.Message,), dict( + DESCRIPTOR = _DPGETPHYSICALDISKSINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.DPGetPhysicalDisksInput) + )) +_sym_db.RegisterMessage(DPGetPhysicalDisksInput) + +DPGetDisksPredictionInput = _reflection.GeneratedProtocolMessageType('DPGetDisksPredictionInput', (_message.Message,), dict( + DESCRIPTOR = _DPGETDISKSPREDICTIONINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.DPGetDisksPredictionInput) + )) +_sym_db.RegisterMessage(DPGetDisksPredictionInput) + +DPBinaryOutput = _reflection.GeneratedProtocolMessageType('DPBinaryOutput', (_message.Message,), dict( + DESCRIPTOR = _DPBINARYOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.DPBinaryOutput) + )) +_sym_db.RegisterMessage(DPBinaryOutput) + +CollectionHeartbeatOutput = _reflection.GeneratedProtocolMessageType('CollectionHeartbeatOutput', (_message.Message,), dict( + DESCRIPTOR = _COLLECTIONHEARTBEATOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.CollectionHeartbeatOutput) + )) +_sym_db.RegisterMessage(CollectionHeartbeatOutput) + +PostMetricsInput = _reflection.GeneratedProtocolMessageType('PostMetricsInput', (_message.Message,), dict( + DESCRIPTOR = _POSTMETRICSINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.PostMetricsInput) + )) +_sym_db.RegisterMessage(PostMetricsInput) + +PostDBRelayInput = _reflection.GeneratedProtocolMessageType('PostDBRelayInput', (_message.Message,), dict( + DESCRIPTOR = _POSTDBRELAYINPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.PostDBRelayInput) + )) +_sym_db.RegisterMessage(PostDBRelayInput) + +CollectionMessageOutput = _reflection.GeneratedProtocolMessageType('CollectionMessageOutput', (_message.Message,), dict( + DESCRIPTOR = _COLLECTIONMESSAGEOUTPUT, + __module__ = 'mainServer_pb2' + # @@protoc_insertion_point(class_scope:proto.CollectionMessageOutput) + )) +_sym_db.RegisterMessage(CollectionMessageOutput) + + +_TESTOUTPUT_MAPVALUEENTRY.has_options = True +_TESTOUTPUT_MAPVALUEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')) + +_GENERAL = _descriptor.ServiceDescriptor( + name='General', + full_name='proto.General', + file=DESCRIPTOR, + index=0, + options=None, + serialized_start=2081, + serialized_end=2342, + methods=[ + _descriptor.MethodDescriptor( + name='GeneralHeartbeat', + full_name='proto.General.GeneralHeartbeat', + index=0, + containing_service=None, + input_type=_EMPTY, + output_type=_GENERALHEARTBEATOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\034\022\032/apis/v2/general/heartbeat')), + ), + _descriptor.MethodDescriptor( + name='Ping', + full_name='proto.General.Ping', + index=1, + containing_service=None, + input_type=_EMPTY, + output_type=_PINGOUTOUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\027\022\025/apis/v2/general/ping')), + ), + _descriptor.MethodDescriptor( + name='Test', + full_name='proto.General.Test', + index=2, + containing_service=None, + input_type=_TESTINPUT, + output_type=_TESTOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\032\"\025/apis/v2/general/test:\001*')), + ), +]) +_sym_db.RegisterServiceDescriptor(_GENERAL) + +DESCRIPTOR.services_by_name['General'] = _GENERAL + + +_ACCOUNT = _descriptor.ServiceDescriptor( + name='Account', + full_name='proto.Account', + file=DESCRIPTOR, + index=1, + options=None, + serialized_start=2345, + serialized_end=3149, + methods=[ + _descriptor.MethodDescriptor( + name='AccountHeartbeat', + full_name='proto.Account.AccountHeartbeat', + index=0, + containing_service=None, + input_type=_EMPTY, + output_type=_ACCOUNTHEARTBEATOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\034\022\032/apis/v2/account/heartbeat')), + ), + _descriptor.MethodDescriptor( + name='Login', + full_name='proto.Account.Login', + index=1, + containing_service=None, + input_type=_LOGININPUT, + output_type=_USEROUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\031\"\024/apis/v2/users/login:\001*')), + ), + _descriptor.MethodDescriptor( + name='Signup', + full_name='proto.Account.Signup', + index=2, + containing_service=None, + input_type=_SINGUPINPUT, + output_type=_SINGUPOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\032\"\025/apis/v2/users/signup:\001*')), + ), + _descriptor.MethodDescriptor( + name='ResendConfirmCode', + full_name='proto.Account.ResendConfirmCode', + index=3, + containing_service=None, + input_type=_RESENDCONFIRMCODEINPUT, + output_type=_GENERALMSGOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\037\"\032/apis/v2/users/confirmcode:\001*')), + ), + _descriptor.MethodDescriptor( + name='Confirm', + full_name='proto.Account.Confirm', + index=4, + containing_service=None, + input_type=_CONFIRMINPUT, + output_type=_GENERALMSGOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002 \"\033/apis/v2/users/confirmation:\001*')), + ), + _descriptor.MethodDescriptor( + name='GetUsersByStatus', + full_name='proto.Account.GetUsersByStatus', + index=5, + containing_service=None, + input_type=_GETUSERSBYSTATUSINPUT, + output_type=_GETUSERSBYSTATUSOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\020\022\016/apis/v2/users')), + ), + _descriptor.MethodDescriptor( + name='DeleteUser', + full_name='proto.Account.DeleteUser', + index=6, + containing_service=None, + input_type=_DELETEUSERINPUT, + output_type=_GENERALMSGOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\036*\034/apis/v2/users/{email}/{key}')), + ), + _descriptor.MethodDescriptor( + name='UpdateUserStatus', + full_name='proto.Account.UpdateUserStatus', + index=7, + containing_service=None, + input_type=_UPDATEUSERSTATUSINPUT, + output_type=_GENERALMSGOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\033\032\026/apis/v2/users/{email}:\001*')), + ), +]) +_sym_db.RegisterServiceDescriptor(_ACCOUNT) + +DESCRIPTOR.services_by_name['Account'] = _ACCOUNT + + +_DISKPROPHET = _descriptor.ServiceDescriptor( + name='Diskprophet', + full_name='proto.Diskprophet', + file=DESCRIPTOR, + index=2, + options=None, + serialized_start=3152, + serialized_end=3487, + methods=[ + _descriptor.MethodDescriptor( + name='DPHeartbeat', + full_name='proto.Diskprophet.DPHeartbeat', + index=0, + containing_service=None, + input_type=_EMPTY, + output_type=_DPHEARTBEATOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\027\022\025/apis/v2/dp/heartbeat')), + ), + _descriptor.MethodDescriptor( + name='DPGetPhysicalDisks', + full_name='proto.Diskprophet.DPGetPhysicalDisks', + index=1, + containing_service=None, + input_type=_DPGETPHYSICALDISKSINPUT, + output_type=_DPBINARYOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\031\022\027/apis/v2/physical-disks')), + ), + _descriptor.MethodDescriptor( + name='DPGetDisksPrediction', + full_name='proto.Diskprophet.DPGetDisksPrediction', + index=2, + containing_service=None, + input_type=_DPGETDISKSPREDICTIONINPUT, + output_type=_DPBINARYOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002%\022#/apis/v2/physical-disks/predictions')), + ), +]) +_sym_db.RegisterServiceDescriptor(_DISKPROPHET) + +DESCRIPTOR.services_by_name['Diskprophet'] = _DISKPROPHET + + +_COLLECTION = _descriptor.ServiceDescriptor( + name='Collection', + full_name='proto.Collection', + file=DESCRIPTOR, + index=3, + options=None, + serialized_start=3490, + serialized_end=3837, + methods=[ + _descriptor.MethodDescriptor( + name='CollectionHeartbeat', + full_name='proto.Collection.CollectionHeartbeat', + index=0, + containing_service=None, + input_type=_EMPTY, + output_type=_COLLECTIONHEARTBEATOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002\037\022\035/apis/v2/collection/heartbeat')), + ), + _descriptor.MethodDescriptor( + name='PostDBRelay', + full_name='proto.Collection.PostDBRelay', + index=1, + containing_service=None, + input_type=_POSTDBRELAYINPUT, + output_type=_COLLECTIONMESSAGEOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002!\"\034/apis/v2/collection/relation:\001*')), + ), + _descriptor.MethodDescriptor( + name='PostMetrics', + full_name='proto.Collection.PostMetrics', + index=2, + containing_service=None, + input_type=_POSTMETRICSINPUT, + output_type=_COLLECTIONMESSAGEOUTPUT, + options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\202\323\344\223\002 \"\033/apis/v2/collection/metrics:\001*')), + ), +]) +_sym_db.RegisterServiceDescriptor(_COLLECTION) + +DESCRIPTOR.services_by_name['Collection'] = _COLLECTION + +# @@protoc_insertion_point(module_scope) diff --git a/src/pybind/mgr/diskprediction_cloud/common/client_pb2_grpc.py b/src/pybind/mgr/diskprediction_cloud/common/client_pb2_grpc.py new file mode 100644 index 00000000..c1c32178 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/common/client_pb2_grpc.py @@ -0,0 +1,395 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import client_pb2 as mainServer__pb2 + + +class GeneralStub(object): + """-------------------------- General ------------------------------------- + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GeneralHeartbeat = channel.unary_unary( + '/proto.General/GeneralHeartbeat', + request_serializer=mainServer__pb2.Empty.SerializeToString, + response_deserializer=mainServer__pb2.GeneralHeartbeatOutput.FromString, + ) + self.Ping = channel.unary_unary( + '/proto.General/Ping', + request_serializer=mainServer__pb2.Empty.SerializeToString, + response_deserializer=mainServer__pb2.PingOutout.FromString, + ) + self.Test = channel.unary_unary( + '/proto.General/Test', + request_serializer=mainServer__pb2.TestInput.SerializeToString, + response_deserializer=mainServer__pb2.TestOutput.FromString, + ) + + +class GeneralServicer(object): + """-------------------------- General ------------------------------------- + """ + + def GeneralHeartbeat(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Ping(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Test(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GeneralServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GeneralHeartbeat': grpc.unary_unary_rpc_method_handler( + servicer.GeneralHeartbeat, + request_deserializer=mainServer__pb2.Empty.FromString, + response_serializer=mainServer__pb2.GeneralHeartbeatOutput.SerializeToString, + ), + 'Ping': grpc.unary_unary_rpc_method_handler( + servicer.Ping, + request_deserializer=mainServer__pb2.Empty.FromString, + response_serializer=mainServer__pb2.PingOutout.SerializeToString, + ), + 'Test': grpc.unary_unary_rpc_method_handler( + servicer.Test, + request_deserializer=mainServer__pb2.TestInput.FromString, + response_serializer=mainServer__pb2.TestOutput.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'proto.General', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + +class AccountStub(object): + """-------------------------- SERVER ACCOUNT ------------------------------ + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.AccountHeartbeat = channel.unary_unary( + '/proto.Account/AccountHeartbeat', + request_serializer=mainServer__pb2.Empty.SerializeToString, + response_deserializer=mainServer__pb2.AccountHeartbeatOutput.FromString, + ) + self.Login = channel.unary_unary( + '/proto.Account/Login', + request_serializer=mainServer__pb2.LoginInput.SerializeToString, + response_deserializer=mainServer__pb2.UserOutput.FromString, + ) + self.Signup = channel.unary_unary( + '/proto.Account/Signup', + request_serializer=mainServer__pb2.SingupInput.SerializeToString, + response_deserializer=mainServer__pb2.SingupOutput.FromString, + ) + self.ResendConfirmCode = channel.unary_unary( + '/proto.Account/ResendConfirmCode', + request_serializer=mainServer__pb2.ResendConfirmCodeInput.SerializeToString, + response_deserializer=mainServer__pb2.GeneralMsgOutput.FromString, + ) + self.Confirm = channel.unary_unary( + '/proto.Account/Confirm', + request_serializer=mainServer__pb2.ConfirmInput.SerializeToString, + response_deserializer=mainServer__pb2.GeneralMsgOutput.FromString, + ) + self.GetUsersByStatus = channel.unary_unary( + '/proto.Account/GetUsersByStatus', + request_serializer=mainServer__pb2.GetUsersByStatusInput.SerializeToString, + response_deserializer=mainServer__pb2.GetUsersByStatusOutput.FromString, + ) + self.DeleteUser = channel.unary_unary( + '/proto.Account/DeleteUser', + request_serializer=mainServer__pb2.DeleteUserInput.SerializeToString, + response_deserializer=mainServer__pb2.GeneralMsgOutput.FromString, + ) + self.UpdateUserStatus = channel.unary_unary( + '/proto.Account/UpdateUserStatus', + request_serializer=mainServer__pb2.UpdateUserStatusInput.SerializeToString, + response_deserializer=mainServer__pb2.GeneralMsgOutput.FromString, + ) + + +class AccountServicer(object): + """-------------------------- SERVER ACCOUNT ------------------------------ + """ + + def AccountHeartbeat(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Login(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Signup(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ResendConfirmCode(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Confirm(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetUsersByStatus(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DeleteUser(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def UpdateUserStatus(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_AccountServicer_to_server(servicer, server): + rpc_method_handlers = { + 'AccountHeartbeat': grpc.unary_unary_rpc_method_handler( + servicer.AccountHeartbeat, + request_deserializer=mainServer__pb2.Empty.FromString, + response_serializer=mainServer__pb2.AccountHeartbeatOutput.SerializeToString, + ), + 'Login': grpc.unary_unary_rpc_method_handler( + servicer.Login, + request_deserializer=mainServer__pb2.LoginInput.FromString, + response_serializer=mainServer__pb2.UserOutput.SerializeToString, + ), + 'Signup': grpc.unary_unary_rpc_method_handler( + servicer.Signup, + request_deserializer=mainServer__pb2.SingupInput.FromString, + response_serializer=mainServer__pb2.SingupOutput.SerializeToString, + ), + 'ResendConfirmCode': grpc.unary_unary_rpc_method_handler( + servicer.ResendConfirmCode, + request_deserializer=mainServer__pb2.ResendConfirmCodeInput.FromString, + response_serializer=mainServer__pb2.GeneralMsgOutput.SerializeToString, + ), + 'Confirm': grpc.unary_unary_rpc_method_handler( + servicer.Confirm, + request_deserializer=mainServer__pb2.ConfirmInput.FromString, + response_serializer=mainServer__pb2.GeneralMsgOutput.SerializeToString, + ), + 'GetUsersByStatus': grpc.unary_unary_rpc_method_handler( + servicer.GetUsersByStatus, + request_deserializer=mainServer__pb2.GetUsersByStatusInput.FromString, + response_serializer=mainServer__pb2.GetUsersByStatusOutput.SerializeToString, + ), + 'DeleteUser': grpc.unary_unary_rpc_method_handler( + servicer.DeleteUser, + request_deserializer=mainServer__pb2.DeleteUserInput.FromString, + response_serializer=mainServer__pb2.GeneralMsgOutput.SerializeToString, + ), + 'UpdateUserStatus': grpc.unary_unary_rpc_method_handler( + servicer.UpdateUserStatus, + request_deserializer=mainServer__pb2.UpdateUserStatusInput.FromString, + response_serializer=mainServer__pb2.GeneralMsgOutput.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'proto.Account', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + +class DiskprophetStub(object): + """------------------------ SERVER DISKPROPHET --------------------------- + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.DPHeartbeat = channel.unary_unary( + '/proto.Diskprophet/DPHeartbeat', + request_serializer=mainServer__pb2.Empty.SerializeToString, + response_deserializer=mainServer__pb2.DPHeartbeatOutput.FromString, + ) + self.DPGetPhysicalDisks = channel.unary_unary( + '/proto.Diskprophet/DPGetPhysicalDisks', + request_serializer=mainServer__pb2.DPGetPhysicalDisksInput.SerializeToString, + response_deserializer=mainServer__pb2.DPBinaryOutput.FromString, + ) + self.DPGetDisksPrediction = channel.unary_unary( + '/proto.Diskprophet/DPGetDisksPrediction', + request_serializer=mainServer__pb2.DPGetDisksPredictionInput.SerializeToString, + response_deserializer=mainServer__pb2.DPBinaryOutput.FromString, + ) + + +class DiskprophetServicer(object): + """------------------------ SERVER DISKPROPHET --------------------------- + """ + + def DPHeartbeat(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DPGetPhysicalDisks(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DPGetDisksPrediction(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_DiskprophetServicer_to_server(servicer, server): + rpc_method_handlers = { + 'DPHeartbeat': grpc.unary_unary_rpc_method_handler( + servicer.DPHeartbeat, + request_deserializer=mainServer__pb2.Empty.FromString, + response_serializer=mainServer__pb2.DPHeartbeatOutput.SerializeToString, + ), + 'DPGetPhysicalDisks': grpc.unary_unary_rpc_method_handler( + servicer.DPGetPhysicalDisks, + request_deserializer=mainServer__pb2.DPGetPhysicalDisksInput.FromString, + response_serializer=mainServer__pb2.DPBinaryOutput.SerializeToString, + ), + 'DPGetDisksPrediction': grpc.unary_unary_rpc_method_handler( + servicer.DPGetDisksPrediction, + request_deserializer=mainServer__pb2.DPGetDisksPredictionInput.FromString, + response_serializer=mainServer__pb2.DPBinaryOutput.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'proto.Diskprophet', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + +class CollectionStub(object): + """------------------------ SERVER Collection --------------------------- + + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.CollectionHeartbeat = channel.unary_unary( + '/proto.Collection/CollectionHeartbeat', + request_serializer=mainServer__pb2.Empty.SerializeToString, + response_deserializer=mainServer__pb2.CollectionHeartbeatOutput.FromString, + ) + self.PostDBRelay = channel.unary_unary( + '/proto.Collection/PostDBRelay', + request_serializer=mainServer__pb2.PostDBRelayInput.SerializeToString, + response_deserializer=mainServer__pb2.CollectionMessageOutput.FromString, + ) + self.PostMetrics = channel.unary_unary( + '/proto.Collection/PostMetrics', + request_serializer=mainServer__pb2.PostMetricsInput.SerializeToString, + response_deserializer=mainServer__pb2.CollectionMessageOutput.FromString, + ) + + +class CollectionServicer(object): + """------------------------ SERVER Collection --------------------------- + + """ + + def CollectionHeartbeat(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PostDBRelay(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PostMetrics(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_CollectionServicer_to_server(servicer, server): + rpc_method_handlers = { + 'CollectionHeartbeat': grpc.unary_unary_rpc_method_handler( + servicer.CollectionHeartbeat, + request_deserializer=mainServer__pb2.Empty.FromString, + response_serializer=mainServer__pb2.CollectionHeartbeatOutput.SerializeToString, + ), + 'PostDBRelay': grpc.unary_unary_rpc_method_handler( + servicer.PostDBRelay, + request_deserializer=mainServer__pb2.PostDBRelayInput.FromString, + response_serializer=mainServer__pb2.CollectionMessageOutput.SerializeToString, + ), + 'PostMetrics': grpc.unary_unary_rpc_method_handler( + servicer.PostMetrics, + request_deserializer=mainServer__pb2.PostMetricsInput.FromString, + response_serializer=mainServer__pb2.CollectionMessageOutput.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'proto.Collection', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/src/pybind/mgr/diskprediction_cloud/common/clusterdata.py b/src/pybind/mgr/diskprediction_cloud/common/clusterdata.py new file mode 100644 index 00000000..45add693 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/common/clusterdata.py @@ -0,0 +1,464 @@ +""" +Ceph database API + +""" +from __future__ import absolute_import + +import json +import rbd +from mgr_module import CommandResult + +GB = 1024 * 1024 * 1024 + + +RBD_FEATURES_NAME_MAPPING = { + rbd.RBD_FEATURE_LAYERING: 'layering', + rbd.RBD_FEATURE_STRIPINGV2: 'striping', + rbd.RBD_FEATURE_EXCLUSIVE_LOCK: 'exclusive-lock', + rbd.RBD_FEATURE_OBJECT_MAP: 'object-map', + rbd.RBD_FEATURE_FAST_DIFF: 'fast-diff', + rbd.RBD_FEATURE_DEEP_FLATTEN: 'deep-flatten', + rbd.RBD_FEATURE_JOURNALING: 'journaling', + rbd.RBD_FEATURE_DATA_POOL: 'data-pool', + rbd.RBD_FEATURE_OPERATIONS: 'operations', +} + + +def differentiate(data1, data2): + """ + # >>> times = [0, 2] + # >>> values = [100, 101] + # >>> differentiate(*zip(times, values)) + 0.5 + """ + return (data2[1] - data1[1]) / float(data2[0] - data1[0]) + + +class ClusterAPI(object): + + def __init__(self, module_obj): + self.module = module_obj + + @staticmethod + def format_bitmask(features): + """ + Formats the bitmask: + # >>> format_bitmask(45) + ['deep-flatten', 'exclusive-lock', 'layering', 'object-map'] + """ + names = [val for key, val in RBD_FEATURES_NAME_MAPPING.items() + if key & features == key] + return sorted(names) + + def _open_connection(self, pool_name='device_health_metrics'): + pools = self.module.rados.list_pools() + is_pool = False + for pool in pools: + if pool == pool_name: + is_pool = True + break + if not is_pool: + self.module.log.debug('create %s pool' % pool_name) + # create pool + result = CommandResult('') + self.module.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd pool create', + 'format': 'json', + 'pool': pool_name, + 'pg_num': 1, + }), '') + r, outb, outs = result.wait() + assert r == 0 + + # set pool application + result = CommandResult('') + self.module.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd pool application enable', + 'format': 'json', + 'pool': pool_name, + 'app': 'mgr_devicehealth', + }), '') + r, outb, outs = result.wait() + assert r == 0 + + ioctx = self.module.rados.open_ioctx(pool_name) + return ioctx + + @classmethod + def _rbd_disk_usage(cls, image, snaps, whole_object=True): + class DUCallback(object): + def __init__(self): + self.used_size = 0 + + def __call__(self, offset, length, exists): + if exists: + self.used_size += length + snap_map = {} + prev_snap = None + total_used_size = 0 + for _, size, name in snaps: + image.set_snap(name) + du_callb = DUCallback() + image.diff_iterate(0, size, prev_snap, du_callb, + whole_object=whole_object) + snap_map[name] = du_callb.used_size + total_used_size += du_callb.used_size + prev_snap = name + return total_used_size, snap_map + + def _rbd_image(self, ioctx, pool_name, image_name): + with rbd.Image(ioctx, image_name) as img: + stat = img.stat() + stat['name'] = image_name + stat['id'] = img.id() + stat['pool_name'] = pool_name + features = img.features() + stat['features'] = features + stat['features_name'] = self.format_bitmask(features) + + # the following keys are deprecated + del stat['parent_pool'] + del stat['parent_name'] + stat['timestamp'] = '{}Z'.format(img.create_timestamp() + .isoformat()) + stat['stripe_count'] = img.stripe_count() + stat['stripe_unit'] = img.stripe_unit() + stat['data_pool'] = None + try: + parent_info = img.parent_info() + stat['parent'] = { + 'pool_name': parent_info[0], + 'image_name': parent_info[1], + 'snap_name': parent_info[2] + } + except rbd.ImageNotFound: + # no parent image + stat['parent'] = None + # snapshots + stat['snapshots'] = [] + for snap in img.list_snaps(): + snap['timestamp'] = '{}Z'.format( + img.get_snap_timestamp(snap['id']).isoformat()) + snap['is_protected'] = img.is_protected_snap(snap['name']) + snap['used_bytes'] = None + snap['children'] = [] + img.set_snap(snap['name']) + for child_pool_name, child_image_name in img.list_children(): + snap['children'].append({ + 'pool_name': child_pool_name, + 'image_name': child_image_name + }) + stat['snapshots'].append(snap) + # disk usage + if 'fast-diff' in stat['features_name']: + snaps = [(s['id'], s['size'], s['name']) + for s in stat['snapshots']] + snaps.sort(key=lambda s: s[0]) + snaps += [(snaps[-1][0]+1 if snaps else 0, stat['size'], None)] + total_prov_bytes, snaps_prov_bytes = self._rbd_disk_usage( + img, snaps, True) + stat['total_disk_usage'] = total_prov_bytes + for snap, prov_bytes in snaps_prov_bytes.items(): + if snap is None: + stat['disk_usage'] = prov_bytes + continue + for ss in stat['snapshots']: + if ss['name'] == snap: + ss['disk_usage'] = prov_bytes + break + else: + stat['total_disk_usage'] = None + stat['disk_usage'] = None + return stat + + def get_rbd_list(self, pool_name=None): + if pool_name: + pools = [pool_name] + else: + pools = [] + for data in self.get_osd_pools(): + pools.append(data['pool_name']) + result = [] + for pool in pools: + rbd_inst = rbd.RBD() + with self._open_connection(str(pool)) as ioctx: + names = rbd_inst.list(ioctx) + for name in names: + try: + stat = self._rbd_image(ioctx, pool_name, name) + except rbd.ImageNotFound: + continue + result.append(stat) + return result + + def get_object_pg_info(self, pool_name, object_name): + result = CommandResult('') + data_jaon = {} + self.module.send_command( + result, 'mon', '', json.dumps({ + 'prefix': 'osd map', + 'format': 'json', + 'pool': pool_name, + 'object': object_name, + }), '') + ret, outb, outs = result.wait() + try: + if outb: + data_jaon = json.loads(outb) + else: + self.module.log.error('unable to get %s pg info' % pool_name) + except Exception as e: + self.module.log.error( + 'unable to get %s pg, error: %s' % (pool_name, str(e))) + return data_jaon + + @staticmethod + def _list_objects(ioctx, image_id): + objects = [] + object_iterator = ioctx.list_objects() + while True: + try: + rados_object = object_iterator.next() + if image_id is None: + objects.append(str(rados_object.key)) + else: + v = str(rados_object.key).split('.') + if len(v) >= 2 and v[1] == image_id: + objects.append(str(rados_object.key)) + except StopIteration: + break + return objects + + def get_rbd_info(self, pool_name, image_name): + with self._open_connection(pool_name) as ioctx: + try: + stat = self._rbd_image(ioctx, pool_name, image_name) + if stat.get('id'): + objects = self._list_objects(ioctx, stat.get('id')) + if objects: + stat['objects'] = objects + stat['pgs'] = list() + for obj_name in objects: + pgs_data = self.get_object_pg_info(pool_name, obj_name) + stat['pgs'].extend([pgs_data]) + except rbd.ImageNotFound: + stat = {} + return stat + + def get_pool_objects(self, pool_name, image_id=None): + # list_objects + try: + with self._open_connection(pool_name) as ioctx: + objects = self._list_objects(ioctx, image_id) + except: + objects = [] + return objects + + def get_ceph_df_state(self): + ceph_stats = self.module.get('df').get('stats', {}) + if not ceph_stats: + return {'total_size': 0, 'avail_size': 0, 'raw_used_size': 0, 'raw_used_percent': 0} + total_size = round(float(ceph_stats.get('total_bytes', 0)) / GB) + avail_size = round(float(ceph_stats.get('total_avail_bytes', 0)) / GB, 2) + raw_used_size = round(float(ceph_stats.get('total_used_bytes', 0)) / GB, 2) + if total_size != 0: + raw_used_percent = round(float(raw_used_size) / float(total_size) * 100, 2) + else: + raw_used_percent = 0 + return {'total_size': total_size, 'avail_size': avail_size, 'raw_used_size': raw_used_size, + 'used_percent': raw_used_percent} + + def get_osd_metadata(self, osd_id=None): + if osd_id is not None: + return self.module.get('osd_metadata')[str(osd_id)] + return self.module.get('osd_metadata') + + def get_mgr_metadata(self, mgr_id): + return self.module.get_metadata('mgr', mgr_id) + + def get_osd_epoch(self): + return self.module.get('osd_map').get('epoch', 0) + + def get_osds(self): + return self.module.get('osd_map').get('osds', []) + + def get_max_osd(self): + return self.module.get('osd_map').get('max_osd', '') + + def get_osd_pools(self): + return self.module.get('osd_map').get('pools', []) + + def get_pool_bytes_used(self, pool_id): + bytes_used = None + pools = self.module.get('df').get('pools', []) + for pool in pools: + if pool_id == pool['id']: + bytes_used = pool['stats']['bytes_used'] + return bytes_used + + def get_cluster_id(self): + return self.module.get('mon_map').get('fsid') + + def get_health_status(self): + health = json.loads(self.module.get('health')['json']) + return health.get('status') + + def get_health_checks(self): + health = json.loads(self.module.get('health')['json']) + if health.get('checks'): + message = '' + checks = health['checks'] + for key in checks.keys(): + if message: + message += ';' + if checks[key].get('summary', {}).get('message', ''): + message += checks[key]['summary']['message'] + return message + else: + return '' + + def get_mons(self): + return self.module.get('mon_map').get('mons', []) + + def get_mon_status(self): + mon_status = json.loads(self.module.get('mon_status')['json']) + return mon_status + + def get_osd_smart(self, osd_id, device_id=None): + osd_devices = [] + osd_smart = {} + devices = self.module.get('devices') + for dev in devices.get('devices', []): + osd = '' + daemons = dev.get('daemons', []) + for daemon in daemons: + if daemon[4:] != str(osd_id): + continue + osd = daemon + if not osd: + continue + if dev.get('devid') and dev.get('devid') not in osd_devices: + osd_devices.append(dev.get('devid')) + for dev_id in osd_devices: + o_key = '' + if device_id and dev_id != device_id: + continue + smart_data = self.get_device_health(dev_id) + if smart_data: + o_key = sorted(smart_data.keys(), reverse=True)[0] + if o_key and smart_data and smart_data.values(): + dev_smart = smart_data[o_key] + if dev_smart: + osd_smart[dev_id] = dev_smart + return osd_smart + + def get_device_health(self, devid): + health_data = {} + try: + r, outb, outs = self.module.remote('devicehealth', 'show_device_metrics', devid=devid, sample='') + if r != 0: + self.module.log.error('failed to get device %s health', devid) + health_data = {} + else: + health_data = json.loads(outb) + except Exception as e: + self.module.log.error('failed to get device %s health data due to %s', devid, str(e)) + return health_data + + def get_osd_hostname(self, osd_id): + result = '' + osd_metadata = self.get_osd_metadata(osd_id) + if osd_metadata: + osd_host = osd_metadata.get('hostname', 'None') + result = osd_host + return result + + def get_osd_device_id(self, osd_id): + result = {} + if not str(osd_id).isdigit(): + if str(osd_id)[0:4] == 'osd.': + osdid = osd_id[4:] + else: + raise Exception('not a valid id or number') + else: + osdid = osd_id + osd_metadata = self.get_osd_metadata(osdid) + if osd_metadata: + osd_device_ids = osd_metadata.get('device_ids', '') + if osd_device_ids: + result = {} + for osd_device_id in osd_device_ids.split(','): + dev_name = '' + if len(str(osd_device_id).split('=')) >= 2: + dev_name = osd_device_id.split('=')[0] + dev_id = osd_device_id.split('=')[1] + else: + dev_id = osd_device_id + if dev_name: + result[dev_name] = {'dev_id': dev_id} + return result + + def get_file_systems(self): + return self.module.get('fs_map').get('filesystems', []) + + def set_device_life_expectancy(self, device_id, from_date, to_date=None): + result = CommandResult('') + + if to_date is None: + self.module.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'device set-life-expectancy', + 'devid': device_id, + 'from': from_date + }), '') + else: + self.module.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'device set-life-expectancy', + 'devid': device_id, + 'from': from_date, + 'to': to_date + }), '') + ret, outb, outs = result.wait() + if ret != 0: + self.module.log.error( + 'failed to set device life expectancy, %s' % outs) + return ret + + def reset_device_life_expectancy(self, device_id): + result = CommandResult('') + self.module.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'device rm-life-expectancy', + 'devid': device_id + }), '') + ret, outb, outs = result.wait() + if ret != 0: + self.module.log.error( + 'failed to reset device life expectancy, %s' % outs) + return ret + + def get_server(self, hostname): + return self.module.get_server(hostname) + + def get_configuration(self, key): + return self.module.get_configuration(key) + + def get_rate(self, svc_type, svc_name, path): + """returns most recent rate""" + data = self.module.get_counter(svc_type, svc_name, path)[path] + + if data and len(data) > 1: + return differentiate(*data[-2:]) + return 0.0 + + def get_latest(self, daemon_type, daemon_name, counter): + return self.module.get_latest(daemon_type, daemon_name, counter) + + def get_pgs_up_by_poolid(self, poolid): + pgs = {} + try: + osd_map = self.module.get_osdmap() + if not osd_map: + return {} + pgs = osd_map.map_pool_pgs_up(int(poolid)) + return pgs + except: + return {} diff --git a/src/pybind/mgr/diskprediction_cloud/common/cypher.py b/src/pybind/mgr/diskprediction_cloud/common/cypher.py new file mode 100644 index 00000000..7b7b60e5 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/common/cypher.py @@ -0,0 +1,71 @@ +from __future__ import absolute_import + +import time + + +class NodeInfo(object): + """ Neo4j Node information """ + def __init__(self, label, domain_id, name, meta): + self.label = label + self.domain_id = domain_id + self.name = name + self.meta = meta + + +class CypherOP(object): + """ Cypher Operation """ + + @staticmethod + def update(node, key, value, timestamp=int(time.time()*(1000**3))): + result = '' + if isinstance(node, NodeInfo): + if key != 'time': + cy_value = '\'%s\'' % value + else: + cy_value = value + result = \ + 'set %s.%s=case when %s.time >= %s then %s.%s ELSE %s end' % ( + node.label, key, node.label, timestamp, node.label, key, + cy_value) + return result + + @staticmethod + def create_or_merge(node, timestamp=int(time.time()*(1000**3))): + result = '' + if isinstance(node, NodeInfo): + meta_list = [] + if isinstance(node.meta, dict): + for key, value in node.meta.items(): + meta_list.append(CypherOP.update(node, key, value, timestamp)) + domain_id = '{domainId:\'%s\'}' % node.domain_id + if meta_list: + result = 'merge (%s:%s %s) %s %s %s' % ( + node.label, node.label, + domain_id, + CypherOP.update(node, 'name', node.name, timestamp), + ' '.join(meta_list), + CypherOP.update(node, 'time', timestamp, timestamp)) + else: + result = 'merge (%s:%s %s) %s %s' % ( + node.label, node.label, + domain_id, + CypherOP.update(node, 'name', node.name, timestamp), + CypherOP.update(node, 'time', timestamp, timestamp)) + return result + + @staticmethod + def add_link(snode, dnode, relationship, timestamp=None): + result = '' + if timestamp is None: + timestamp = int(time.time()*(1000**3)) + if isinstance(snode, NodeInfo) and isinstance(dnode, NodeInfo): + cy_snode = CypherOP.create_or_merge(snode, timestamp) + cy_dnode = CypherOP.create_or_merge(dnode, timestamp) + target = snode.label + dnode.label + link = 'merge (%s)-[%s:%s]->(%s) set %s.time=case when %s.time >= %s then %s.time ELSE %s end' % ( + snode.label, target, relationship, + dnode.label, target, + target, timestamp, + target, timestamp) + result = '%s %s %s' % (cy_snode, cy_dnode, link) + return result diff --git a/src/pybind/mgr/diskprediction_cloud/common/grpcclient.py b/src/pybind/mgr/diskprediction_cloud/common/grpcclient.py new file mode 100644 index 00000000..5a1d5e7e --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/common/grpcclient.py @@ -0,0 +1,242 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +import grpc +import json +from logging import getLogger +import time + +from . import DummyResonse +from . import client_pb2 +from . import client_pb2_grpc + + +def gen_configuration(**kwargs): + configuration = { + 'host': kwargs.get('host', 'api.diskprophet.com'), + 'user': kwargs.get('user'), + 'password': kwargs.get('password'), + 'port': kwargs.get('port', 31400), + 'mgr_inst': kwargs.get('mgr_inst', None), + 'cert_context': kwargs.get('cert_context'), + 'ssl_target_name': kwargs.get('ssl_target_name', 'api.diskprophet.com'), + 'default_authority': kwargs.get('default_authority', 'api.diskprophet.com')} + return configuration + + +class GRPcClient(object): + + def __init__(self, configuration): + self.auth = None + self.host = configuration.get('host') + self.port = configuration.get('port') + if configuration.get('user') and configuration.get('password'): + self.auth = ( + ('account', configuration.get('user')), + ('password', configuration.get('password'))) + self.cert_context = configuration.get('cert_context') + self.ssl_target_name = configuration.get('ssl_target_name') + self.default_authority = configuration.get('default_authority') + self.mgr_inst = configuration.get('mgr_inst') + if self.mgr_inst: + self._logger = self.mgr_inst.log + else: + self._logger = getLogger() + self._client = self._get_channel() + + def close(self): + if self._client: + self._client.close() + + @staticmethod + def connectivity_update(connectivity): + pass + + def _get_channel(self): + try: + creds = grpc.ssl_channel_credentials( + root_certificates=self.cert_context) + channel = \ + grpc.secure_channel('{}:{}'.format( + self.host, self.port), creds, + options=(('grpc.ssl_target_name_override', self.ssl_target_name,), + ('grpc.default_authority', self.default_authority),)) + channel.subscribe(self.connectivity_update, try_to_connect=True) + return channel + except Exception as e: + self._logger.error( + 'failed to create connection exception: {}'.format( + ';'.join(str(e).split('\n\t')))) + return None + + def test_connection(self): + try: + stub_accout = client_pb2_grpc.AccountStub(self._client) + result = stub_accout.AccountHeartbeat(client_pb2.Empty()) + self._logger.debug('text connection result: {}'.format(str(result))) + if result and "is alive" in str(result.message): + return True + else: + return False + except Exception as e: + self._logger.error( + 'failed to test connection exception: {}'.format( + ';'.join(str(e).split('\n\t')))) + return False + + def _send_metrics(self, data, measurement): + status_info = dict() + status_info['measurement'] = None + status_info['success_count'] = 0 + status_info['failure_count'] = 0 + for dp_data in data: + d_measurement = dp_data.measurement + if not d_measurement: + status_info['measurement'] = measurement + else: + status_info['measurement'] = d_measurement + tag_list = [] + field_list = [] + for name in dp_data.tags: + tag = '{}={}'.format(name, dp_data.tags[name]) + tag_list.append(tag) + for name in dp_data.fields: + if dp_data.fields[name] is None: + continue + if isinstance(dp_data.fields[name], str): + field = '{}=\"{}\"'.format(name, dp_data.fields[name]) + elif isinstance(dp_data.fields[name], bool): + field = '{}={}'.format(name, + str(dp_data.fields[name]).lower()) + elif (isinstance(dp_data.fields[name], int) or + isinstance(dp_data.fields[name], long)): + field = '{}={}i'.format(name, dp_data.fields[name]) + else: + field = '{}={}'.format(name, dp_data.fields[name]) + field_list.append(field) + data = '{},{} {} {}'.format( + status_info['measurement'], + ','.join(tag_list), + ','.join(field_list), + int(time.time() * 1000 * 1000 * 1000)) + try: + resp = self._send_info(data=[data], measurement=status_info['measurement']) + status_code = resp.status_code + if 200 <= status_code < 300: + self._logger.debug( + '{} send diskprediction api success(ret: {})'.format( + status_info['measurement'], status_code)) + status_info['success_count'] += 1 + else: + self._logger.error( + 'return code: {}, content: {}'.format( + status_code, resp.content)) + status_info['failure_count'] += 1 + except Exception as e: + status_info['failure_count'] += 1 + self._logger.error(str(e)) + return status_info + + def _send_db_relay(self, data, measurement): + status_info = dict() + status_info['measurement'] = measurement + status_info['success_count'] = 0 + status_info['failure_count'] = 0 + for dp_data in data: + try: + resp = self._send_info( + data=[dp_data.fields['cmd']], measurement=measurement) + status_code = resp.status_code + if 200 <= status_code < 300: + self._logger.debug( + '{} send diskprediction api success(ret: {})'.format( + measurement, status_code)) + status_info['success_count'] += 1 + else: + self._logger.error( + 'return code: {}, content: {}'.format( + status_code, resp.content)) + status_info['failure_count'] += 1 + except Exception as e: + status_info['failure_count'] += 1 + self._logger.error(str(e)) + return status_info + + def send_info(self, data, measurement): + """ + :param data: data structure + :param measurement: data measurement class name + :return: + status_info = { + 'success_count': , + 'failure_count': + } + """ + if measurement == 'db_relay': + return self._send_db_relay(data, measurement) + else: + return self._send_metrics(data, measurement) + + def _send_info(self, data, measurement): + resp = DummyResonse() + try: + stub_collection = client_pb2_grpc.CollectionStub(self._client) + if measurement == 'db_relay': + result = stub_collection.PostDBRelay( + client_pb2.PostDBRelayInput(cmds=data), metadata=self.auth) + else: + result = stub_collection.PostMetrics( + client_pb2.PostMetricsInput(points=data), metadata=self.auth) + if result and 'success' in str(result.message).lower(): + resp.status_code = 200 + resp.content = '' + else: + resp.status_code = 400 + resp.content = ';'.join(str(result).split('\n\t')) + self._logger.error( + 'failed to send info: {}'.format(resp.content)) + except Exception as e: + resp.status_code = 400 + resp.content = ';'.join(str(e).split('\n\t')) + self._logger.error( + 'failed to send info exception: {}'.format(resp.content)) + return resp + + def query_info(self, host_domain_id, disk_domain_id, measurement): + resp = DummyResonse() + try: + stub_dp = client_pb2_grpc.DiskprophetStub(self._client) + predicted = stub_dp.DPGetDisksPrediction( + client_pb2.DPGetDisksPredictionInput( + physicalDiskIds=disk_domain_id), + metadata=self.auth) + if predicted and hasattr(predicted, 'data'): + resp.status_code = 200 + resp.content = '' + resp_json = json.loads(predicted.data) + rc = resp_json.get('results', []) + if rc: + series = rc[0].get('series', []) + if series: + values = series[0].get('values', []) + if not values: + resp.resp_json = {} + else: + columns = series[0].get('columns', []) + for item in values: + # get prediction key and value from server. + for name, value in zip(columns, item): + # process prediction data + resp.resp_json[name] = value + self._logger.debug("query {}:{} result:{}".format(host_domain_id, disk_domain_id, resp)) + return resp + else: + resp.status_code = 400 + resp.content = '' + resp.resp_json = {'error': ';'.join(str(predicted).split('\n\t'))} + self._logger.debug("query {}:{} result:{}".format(host_domain_id, disk_domain_id, resp)) + return resp + except Exception as e: + resp.status_code = 400 + resp.content = ';'.join(str(e).split('\n\t')) + resp.resp_json = {'error': resp.content} + self._logger.debug("query {}:{} result:{}".format(host_domain_id, disk_domain_id, resp)) + return resp diff --git a/src/pybind/mgr/diskprediction_cloud/common/server.crt b/src/pybind/mgr/diskprediction_cloud/common/server.crt new file mode 100644 index 00000000..d72c9d2f --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/common/server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZoCCQCKLjrHOzCTrDANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBBh +cGkuZmVkZXJhdG9yLmFpMB4XDTE4MDgwMjA2NDg0N1oXDTI4MDczMDA2NDg0N1ow +GzEZMBcGA1UEAwwQYXBpLmZlZGVyYXRvci5haTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAJkDL/VoLbI+Rc1GXkZwpN8n4e7HhIk1iK98yhXegoH8g6ZZ +uVVlUW/zNO0V5W9IgiSBqEWOEf9heWj7mIbbxl437W1LpR4V0LKR2dbY7ZMwlB3L +ZJYxtziZYu1g4Fn9hDnVJIXVmXFpF62wHd2ZSY7FyUF/OGetxLSfoOMkTHY8A8HB +92vQfoFjgx1e23lLgTO2VpucmU/qXiF+xI/K6kkrMnGJi4xBL29i3aKRRNktVUHf +Zs6JhBKl4sbvkW5m5AECW4c0XxVJotTLoPUjx4rxp0k5S1aQSYSS+0z96eVY0w8J +ungiWEj7lLqwEGKjOzfjDLsczZIcZZcQSQwb3qcCAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEADwfBrHsvPmUD8CTx8lpVcqrOlHc7ftW3hb11vWwwfJw4fBiJ8DoB496x +SAP2CJyDnSLdyvVueKLjiRFBm96W76nbMeP9+CkktGRUbLjkByv/v+7WSxRrukDC +yR6IXqQJe4ADcYkVYoUMx3frBQzFtS7hni0FPvl3AN55TvTXqed61CdN9zdw9Ezn +yn0oy3BbT5h/zNHefTQBzgQhW62C5YdTRtS6VVWV/k1kLz0GVG1eMtAqueUCxFeM +g1mXYz2/Cm5C8pszZfiP+a/QV1z/3QgRUp0i0yVLiteqNDCPv6bc767VQEuXok9p +NDuKElVxdA0WD9cbnBXiyfeMOQnjQw== +-----END CERTIFICATE----- diff --git a/src/pybind/mgr/diskprediction_cloud/module.py b/src/pybind/mgr/diskprediction_cloud/module.py new file mode 100644 index 00000000..5052d55e --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/module.py @@ -0,0 +1,454 @@ +""" +diskprediction with cloud predictor +""" +from __future__ import absolute_import + +import base64 +from datetime import datetime +import errno +import json +from mgr_module import MgrModule +import os +from threading import Event + +try: + from string import maketrans +except ImportError: + maketrans = str.maketrans + +from .common import DP_MGR_STAT_ENABLED, DP_MGR_STAT_DISABLED +from .task import MetricsRunner, SmartRunner, PredictRunner, TestRunner + +TIME_DAYS = 24*60*60 +TIME_WEEK = TIME_DAYS * 7 +DP_AGENTS = [MetricsRunner, SmartRunner, PredictRunner] +CUSTOMER_ALPHABET = "ABCDEFG&HIJKLMN@OQRS.TUV(WXYZabcd)efghijlmn-opqrstu*vwxyz0123=45" +ORIGIN_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + + +def get_transtable(): + transtable = maketrans(ORIGIN_ALPHABET, CUSTOMER_ALPHABET) + return transtable + + +def get_reverse_transtable(): + transtable = maketrans(CUSTOMER_ALPHABET, ORIGIN_ALPHABET) + return transtable + + +def encode_string(value): + if len(value) == 0: + return "" + transtable = get_transtable() + e = str((base64.b64encode(str(value).encode())).decode("utf-8")) + e = e.rstrip("=") + return e.translate(transtable) + + +class Module(MgrModule): + + MODULE_OPTIONS = [ + { + 'name': 'diskprediction_server', + 'default': '' + }, + { + 'name': 'diskprediction_port', + 'default': '31400' + }, + { + 'name': 'diskprediction_user', + 'default': '' + }, + { + 'name': 'diskprediction_password', + 'default': '' + }, + { + 'name': 'diskprediction_upload_metrics_interval', + 'default': '600' + }, + { + 'name': 'diskprediction_upload_smart_interval', + 'default': '43200' + }, + { + 'name': 'diskprediction_retrieve_prediction_interval', + 'default': '43200' + }, + { + 'name': 'diskprediction_cert_context', + 'default': '' + }, + { + 'name': 'diskprediction_ssl_target_name_override', + 'default': 'localhost' + }, + { + 'name': 'diskprediction_default_authority', + 'default': 'localhost' + }, + { + 'name': 'sleep_interval', + 'default': str(600), + } + ] + + COMMANDS = [ + { + 'cmd': 'device show-prediction-config', + 'desc': 'Prints diskprediction configuration', + 'perm': 'r' + }, + { + 'cmd': 'device set-cloud-prediction-config ' + 'name=server,type=CephString,req=true ' + 'name=user,type=CephString,req=true ' + 'name=password,type=CephString,req=true ' + 'name=certfile,type=CephString,req=true ' + 'name=port,type=CephString,req=false ', + 'desc': 'Configure Disk Prediction service', + 'perm': 'rw' + }, + { + 'cmd': 'device debug metrics-forced', + 'desc': 'Run metrics agent forced', + 'perm': 'r' + }, + { + 'cmd': 'device debug smart-forced', + 'desc': 'Run smart agent forced', + 'perm': 'r' + }, + { + 'cmd': 'diskprediction_cloud status', + 'desc': 'Check diskprediction_cloud status', + 'perm': 'r' + } + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.status = {'status': DP_MGR_STAT_DISABLED} + self._event = Event() + self._predict_event = Event() + self._agents = [] + self._activated_cloud = False + self.prediction_result = {} + self.config = dict() + self._run = True + + def config_notify(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name'])) + if not self._activated_cloud and self.get_ceph_option('device_failure_prediction_mode') == 'cloud': + self._event.set() + if self._activated_cloud and self.get_ceph_option('device_failure_prediction_mode') != 'cloud': + self._event.set() + + @property + def config_keys(self): + return dict((o['name'], o.get('default', None)) for o in self.MODULE_OPTIONS) + + def set_config_option(self, option, value): + if option not in self.config_keys.keys(): + raise RuntimeError('{0} is a unknown configuration ' + 'option'.format(option)) + + if option in ['diskprediction_port', + 'diskprediction_upload_metrics_interval', + 'diskprediction_upload_smart_interval', + 'diskprediction_retrieve_prediction_interval']: + if not str(value).isdigit(): + raise RuntimeError('invalid {} configured. Please specify ' + 'a valid integer {}'.format(option, value)) + + self.log.debug('Setting in-memory config option %s to: %s', option, + value) + self.set_module_option(option, value) + self.config[option] = value + + return True + + def get_configuration(self, key): + return self.get_module_option(key, self.config_keys[key]) + + @staticmethod + def _convert_timestamp(predicted_timestamp, life_expectancy_day): + """ + :param predicted_timestamp: unit is nanoseconds + :param life_expectancy_day: unit is seconds + :return: + date format '%Y-%m-%d' ex. 2018-01-01 + """ + return datetime.fromtimestamp( + predicted_timestamp / (1000 ** 3) + life_expectancy_day).strftime('%Y-%m-%d') + + def _show_prediction_config(self, cmd): + self.show_module_config() + return 0, json.dumps(self.config, indent=4), '' + + def _set_ssl_target_name(self, cmd): + str_ssl_target = cmd.get('ssl_target_name', '') + try: + self.set_module_option('diskprediction_ssl_target_name_override', str_ssl_target) + return (0, + 'success to config ssl target name', 0) + except Exception as e: + return -errno.EINVAL, '', str(e) + + def _set_ssl_default_authority(self, cmd): + str_ssl_authority = cmd.get('ssl_authority', '') + try: + self.set_module_option('diskprediction_default_authority', str_ssl_authority) + return 0, 'success to config ssl default authority', 0 + except Exception as e: + return -errno.EINVAL, '', str(e) + + def _set_cloud_prediction_config(self, cmd): + str_cert_path = cmd.get('certfile', '') + if os.path.exists(str_cert_path): + with open(str_cert_path, 'rb') as f: + trusted_certs = f.read() + self.set_config_option( + 'diskprediction_cert_context', trusted_certs) + for _agent in self._agents: + _agent.event.set() + self.set_module_option('diskprediction_server', cmd['server']) + self.set_module_option('diskprediction_user', cmd['user']) + self.set_module_option('diskprediction_password', encode_string(cmd['password'])) + if cmd.get('port'): + self.set_module_option('diskprediction_port', cmd['port']) + return 0, 'succeed to config cloud mode connection', '' + else: + return -errno.EINVAL, '', 'certification file not existed' + + def _debug_metrics_forced(self, cmd): + msg = '' + for _agent in self._agents: + if isinstance(_agent, MetricsRunner): + msg = 'run metrics agent successfully' + _agent.event.set() + return 0, msg, '' + + def _debug_smart_forced(self, cmd): + msg = ' ' + for _agent in self._agents: + if isinstance(_agent, SmartRunner): + msg = 'run smart agent successfully' + _agent.event.set() + return 0, msg, '' + + def refresh_config(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name'])) + + def _status(self, cmd): + return 0, json.dumps(self.status), '' + + def _refresh_cloud_prediction_result(self): + for _agent in self._agents: + if isinstance(_agent, PredictRunner): + self._predict_event.clear() + _agent.event.set() + self._predict_event.wait(300) + if self._predict_event.is_set(): + self._predict_event.clear() + break + + def predict_life_expectancy(self, devid): + assert devid + result = self.get('device {}'.format(devid)) + if not result: + return -1, '', 'device {} not found'.format(devid) + dev_info = result.get('device', {}) + if not dev_info: + return -1, '', 'device {} not found'.format(devid) + self._refresh_cloud_prediction_result() + prediction_data = self.prediction_result.get(devid) + if not prediction_data: + return -1, '', 'device {} prediction data not ready'.format(devid) + elif prediction_data.get('near_failure', '').lower() == 'good': + return 0, '>6w', '' + elif prediction_data.get('near_failure', '').lower() == 'warning': + return 0, '>=2w and <=6w', '' + elif prediction_data.get('near_failure', '').lower() == 'bad': + return 0, '<2w', '' + else: + return 0, 'unknown', '' + + def _update_device_life_expectancy_day(self, devid, prediction): + # Update osd life-expectancy + from .common.clusterdata import ClusterAPI + predicted = None + life_expectancy_day_min = None + life_expectancy_day_max = None + if prediction.get('predicted'): + predicted = int(prediction['predicted']) + if prediction.get('near_failure'): + if prediction['near_failure'].lower() == 'good': + life_expectancy_day_min = (TIME_WEEK * 6) + TIME_DAYS + life_expectancy_day_max = None + elif prediction['near_failure'].lower() == 'warning': + life_expectancy_day_min = (TIME_WEEK * 2) + life_expectancy_day_max = (TIME_WEEK * 6) + elif prediction['near_failure'].lower() == 'bad': + life_expectancy_day_min = 0 + life_expectancy_day_max = (TIME_WEEK * 2) - TIME_DAYS + else: + # Near failure state is unknown. + predicted = None + life_expectancy_day_min = None + life_expectancy_day_max = None + + obj_api = ClusterAPI(self) + if predicted and devid and life_expectancy_day_min is not None: + from_date = None + to_date = None + try: + if life_expectancy_day_min is not None: + from_date = self._convert_timestamp(predicted, life_expectancy_day_min) + + if life_expectancy_day_max is not None: + to_date = self._convert_timestamp(predicted, life_expectancy_day_max) + + obj_api.set_device_life_expectancy(devid, from_date, to_date) + self.log.info( + 'succeed to set device {} life expectancy from: {}, to: {}'.format( + devid, from_date, to_date)) + except Exception as e: + self.log.error( + 'failed to set device {} life expectancy from: {}, to: {}, {}'.format( + devid, from_date, to_date, str(e))) + else: + obj_api.reset_device_life_expectancy(devid) + + def predict_all_devices(self): + if not self._activated_cloud: + return -1, '', 'diskprecition_cloud not ready' + self.refresh_config() + result = self.get('devices') + if not result: + return -1, '', 'unable to get all devices for prediction' + self._refresh_cloud_prediction_result() + for dev in result.get('devices', []): + devid = dev.get('devid') + if not devid: + continue + prediction_data = self.prediction_result.get(devid) + if prediction_data: + break + if not prediction_data: + return -1, '', 'device {} prediction data not ready'.format(dev.get('devid')) + else: + self._update_device_life_expectancy_day(dev.get('devid'), prediction_data) + return 0, '', '' + + def handle_command(self, _, cmd): + for o_cmd in self.COMMANDS: + if cmd['prefix'] == o_cmd['cmd'][:len(cmd['prefix'])]: + fun_name = '' + avgs = o_cmd['cmd'].split(' ') + for avg in avgs: + if avg.lower() == 'diskprediction_cloud': + continue + if avg.lower() == 'device': + continue + if '=' in avg or ',' in avg or not avg: + continue + fun_name += '_%s' % avg.replace('-', '_') + if fun_name: + fun = getattr( + self, fun_name) + if fun: + return fun(cmd) + return -errno.EINVAL, '', 'cmd not found' + + def show_module_config(self): + for key, default in self.config_keys.items(): + self.set_config_option(key, self.get_module_option(key, default)) + + def serve(self): + self.log.info('Starting diskprediction module') + self.config_notify() + self.status = {'status': DP_MGR_STAT_ENABLED} + + while self._run: + self.refresh_config() + mode = self.get_ceph_option('device_failure_prediction_mode') + if mode == 'cloud': + if not self._activated_cloud: + self.start_cloud_disk_prediction() + else: + if self._activated_cloud: + self.stop_disk_prediction() + + # Check agent hang is? + restart_agent = False + try: + for dp_agent in self._agents: + if dp_agent.is_timeout(): + self.log.error('agent name: {] timeout'.format(dp_agent.task_name)) + restart_agent = True + break + except Exception as IOError: + self.log.error('disk prediction plugin failed to started and try to restart') + restart_agent = True + + if restart_agent: + self.stop_disk_prediction() + else: + sleep_interval = int(self.sleep_interval) or 60 + self._event.wait(sleep_interval) + self._event.clear() + self.stop_disk_prediction() + + def _agent_call_back(self): + self.log.debug('notify refresh devices prediction result') + self._predict_event.set() + + def start_cloud_disk_prediction(self): + assert not self._activated_cloud + for dp_agent in DP_AGENTS: + if dp_agent == PredictRunner: + obj_agent = dp_agent(self, 300, self._agent_call_back) + else: + obj_agent = dp_agent(self, 300) + if obj_agent: + obj_agent.start() + else: + raise Exception('failed to start task %s' % obj_agent.task_name) + self._agents.append(obj_agent) + self._activated_cloud = True + self.log.info('start cloud disk prediction') + + def stop_disk_prediction(self): + assert self._activated_cloud + try: + self.status = {'status': DP_MGR_STAT_DISABLED} + while self._agents: + dp_agent = self._agents.pop() + self.log.info('agent name: {}'.format(dp_agent.task_name)) + dp_agent.terminate() + dp_agent.join(5) + del dp_agent + self._activated_cloud = False + self.log.info('stop disk prediction') + except Exception as IOError: + self.log.error('failed to stop disk prediction clould plugin') + + def shutdown(self): + self._run = False + self._event.set() + super(Module, self).shutdown() + + def self_test(self): + obj_test = TestRunner(self) + obj_test.run() + self.log.info('self test completed') diff --git a/src/pybind/mgr/diskprediction_cloud/requirements.txt b/src/pybind/mgr/diskprediction_cloud/requirements.txt new file mode 100644 index 00000000..4abc346a --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/requirements.txt @@ -0,0 +1,12 @@ +google-api-python-client==1.7.3 +google-auth==1.5.0 +google-auth-httplib2==0.0.3 +googleapis-common-protos==1.5.3 +grpc==0.3.post19 +grpc-google-logging-v2==0.8.1 +grpc-google-pubsub-v1==0.8.1 +grpcio==1.14.1 +mock==2.0.0 +numpy==1.15.1 +scikit-learn==0.19.2 +scipy==1.1.0 diff --git a/src/pybind/mgr/diskprediction_cloud/task.py b/src/pybind/mgr/diskprediction_cloud/task.py new file mode 100644 index 00000000..6ed04e60 --- /dev/null +++ b/src/pybind/mgr/diskprediction_cloud/task.py @@ -0,0 +1,181 @@ +from __future__ import absolute_import + +import time +from threading import Event, Thread + +from .agent.predictor import PredictAgent +from .agent.metrics.ceph_cluster import CephClusterAgent +from .agent.metrics.ceph_mon_osd import CephMonOsdAgent +from .agent.metrics.ceph_pool import CephPoolAgent +from .agent.metrics.db_relay import DBRelayAgent +from .agent.metrics.sai_agent import SAIAgent +from .agent.metrics.sai_cluster import SAICluserAgent +from .agent.metrics.sai_disk import SAIDiskAgent +from .agent.metrics.sai_disk_smart import SAIDiskSmartAgent +from .agent.metrics.sai_host import SAIHostAgent +from .common import DP_MGR_STAT_FAILED, DP_MGR_STAT_OK, DP_MGR_STAT_WARNING + + +class AgentRunner(Thread): + + task_name = '' + interval_key = '' + agents = [] + + def __init__(self, mgr_module, agent_timeout=60, call_back=None): + """ + + :param mgr_module: parent ceph mgr module + :param agent_timeout: (unit seconds) agent execute timeout value, default: 60 secs + """ + Thread.__init__(self) + self._agent_timeout = agent_timeout + self._module_inst = mgr_module + self._log = mgr_module.log + self._start_time = time.time() + self._th = None + self._call_back = call_back + self.exit = False + self.event = Event() + self.task_interval = \ + int(self._module_inst.get_configuration(self.interval_key)) + + def terminate(self): + self.exit = True + self.event.set() + self._log.info('PDS terminate %s complete' % self.task_name) + + def run(self): + self._start_time = time.time() + self._log.info( + 'start %s, interval: %s' + % (self.task_name, self.task_interval)) + while not self.exit: + self.run_agents() + if self._call_back: + self._call_back() + if self.event: + self.event.wait(int(self.task_interval)) + self.event.clear() + self._log.info( + 'completed %s(%s)' % (self.task_name, time.time()-self._start_time)) + + def run_agents(self): + obj_sender = None + try: + self._log.debug('run_agents %s' % self.task_name) + from .common.grpcclient import GRPcClient, gen_configuration + conf = gen_configuration( + host=self._module_inst.get_configuration('diskprediction_server'), + user=self._module_inst.get_configuration('diskprediction_user'), + password=self._module_inst.get_configuration( + 'diskprediction_password'), + port=self._module_inst.get_configuration('diskprediction_port'), + cert_context=self._module_inst.get_configuration('diskprediction_cert_context'), + mgr_inst=self._module_inst, + ssl_target_name=self._module_inst.get_configuration('diskprediction_ssl_target_name_override'), + default_authority=self._module_inst.get_configuration('diskprediction_default_authority')) + obj_sender = GRPcClient(conf) + if not obj_sender: + self._log.error('invalid diskprediction sender') + self._module_inst.status = \ + {'status': DP_MGR_STAT_FAILED, + 'reason': 'invalid diskprediction sender'} + raise Exception('invalid diskprediction sender') + if obj_sender.test_connection(): + self._module_inst.status = {'status': DP_MGR_STAT_OK} + self._log.debug('succeed to test connection') + self._run(self._module_inst, obj_sender) + else: + self._log.error('failed to test connection') + self._module_inst.status = \ + {'status': DP_MGR_STAT_FAILED, + 'reason': 'failed to test connection'} + raise Exception('failed to test connection') + except Exception as e: + self._module_inst.status = \ + {'status': DP_MGR_STAT_FAILED, + 'reason': 'failed to start %s agents, %s' + % (self.task_name, str(e))} + self._log.error( + 'failed to start %s agents, %s' % (self.task_name, str(e))) + raise + finally: + if obj_sender: + obj_sender.close() + + def is_timeout(self): + now = time.time() + if (now - self._start_time) > self._agent_timeout: + return True + else: + return False + + def _run(self, module_inst, sender): + self._log.debug('%s run' % self.task_name) + for agent in self.agents: + self._start_time = time.time() + retry_count = 3 + while retry_count: + retry_count -= 1 + try: + obj_agent = agent(module_inst, sender, self._agent_timeout) + obj_agent.run() + del obj_agent + break + except Exception as e: + if str(e).find('configuring') >= 0: + self._log.debug( + 'failed to execute {}, {}, retry again.'.format( + agent.measurement, str(e))) + time.sleep(1) + continue + else: + module_inst.status = \ + {'status': DP_MGR_STAT_WARNING, + 'reason': 'failed to execute {}, {}'.format( + agent.measurement, ';'.join(str(e).split('\n\t')))} + self._log.warning( + 'failed to execute {}, {}'.format( + agent.measurement, ';'.join(str(e).split('\n\t')))) + break + + +class MetricsRunner(AgentRunner): + + task_name = 'Metrics Agent' + interval_key = 'diskprediction_upload_metrics_interval' + agents = [CephClusterAgent, CephMonOsdAgent, CephPoolAgent, + SAICluserAgent, SAIDiskAgent, SAIHostAgent, DBRelayAgent, + SAIAgent] + + +class PredictRunner(AgentRunner): + + task_name = 'Predictor Agent' + interval_key = 'diskprediction_retrieve_prediction_interval' + agents = [PredictAgent] + + +class SmartRunner(AgentRunner): + + task_name = 'Smart data Agent' + interval_key = 'diskprediction_upload_smart_interval' + agents = [SAIDiskSmartAgent] + + +class TestRunner(object): + task_name = 'Test Agent' + interval_key = 'diskprediction_upload_metrics_interval' + agents = [CephClusterAgent, CephMonOsdAgent, CephPoolAgent, + SAICluserAgent, SAIDiskAgent, SAIHostAgent, DBRelayAgent, + SAIAgent, SAIDiskSmartAgent] + + def __init__(self, mgr_module): + self._module_inst = mgr_module + + def run(self): + for agent in self.agents: + obj_agent = agent(self._module_inst, None) + obj_agent.run() + del obj_agent diff --git a/src/pybind/mgr/diskprediction_local/__init__.py b/src/pybind/mgr/diskprediction_local/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/diskprediction_local/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/diskprediction_local/models/config.json b/src/pybind/mgr/diskprediction_local/models/config.json new file mode 100644 index 00000000..9a1485ca --- /dev/null +++ b/src/pybind/mgr/diskprediction_local/models/config.json @@ -0,0 +1,77 @@ +{ +"svm_123.pkl": ["smart_197_raw", "smart_183_raw", "smart_200_raw", "smart_194_raw", "smart_254_raw", "smart_252_raw", "smart_4_raw", "smart_222_raw", "smart_187_raw", "smart_184_raw"], +"svm_105.pkl": ["smart_197_raw", "smart_4_raw", "smart_5_raw", "smart_252_raw", "smart_184_raw", "smart_223_raw", "smart_198_raw", "smart_10_raw", "smart_189_raw", "smart_222_raw"], +"svm_82.pkl":["smart_184_raw", "smart_2_raw", "smart_187_raw", "smart_225_raw", "smart_198_raw", "smart_197_raw", "smart_4_raw", "smart_13_raw", "smart_188_raw", "smart_251_raw"], +"svm_186.pkl":["smart_3_raw", "smart_11_raw", "smart_198_raw", "smart_250_raw", "smart_13_raw", "smart_200_raw", "smart_224_raw", "smart_187_raw", "smart_22_raw", "smart_4_raw", "smart_220_raw"], +"svm_14.pkl":["smart_12_raw", "smart_226_raw", "smart_187_raw", "smart_196_raw", "smart_5_raw", "smart_183_raw", "smart_255_raw", "smart_250_raw", "smart_201_raw", "smart_8_raw"], +"svm_10.pkl":["smart_251_raw", "smart_4_raw", "smart_223_raw", "smart_13_raw", "smart_255_raw", "smart_188_raw", "smart_197_raw", "smart_201_raw", "smart_250_raw", "smart_15_raw"], +"svm_235.pkl":["smart_15_raw", "smart_255_raw", "smart_252_raw", "smart_197_raw", "smart_250_raw", "smart_254_raw", "smart_13_raw", "smart_251_raw", "smart_198_raw", "smart_189_raw", "smart_191_raw"], +"svm_234.pkl":["smart_187_raw", "smart_183_raw", "smart_3_raw", "smart_4_raw", "smart_222_raw", "smart_184_raw", "smart_5_raw", "smart_198_raw", "smart_200_raw", "smart_8_raw", "smart_10_raw"], +"svm_119.pkl":["smart_254_raw", "smart_8_raw", "smart_183_raw", "smart_184_raw", "smart_195_raw", "smart_252_raw", "smart_191_raw", "smart_10_raw", "smart_200_raw", "smart_197_raw"], +"svm_227.pkl":["smart_254_raw", "smart_189_raw", "smart_225_raw", "smart_224_raw", "smart_197_raw", "smart_223_raw", "smart_4_raw", "smart_183_raw", "smart_11_raw", "smart_184_raw", "smart_13_raw"], +"svm_18.pkl":["smart_197_raw", "smart_3_raw", "smart_220_raw", "smart_193_raw", "smart_10_raw", "smart_187_raw", "smart_188_raw", "smart_225_raw", "smart_194_raw", "smart_13_raw"], +"svm_78.pkl":["smart_10_raw", "smart_183_raw", "smart_191_raw", "smart_13_raw", "smart_198_raw", "smart_22_raw", "smart_195_raw", "smart_12_raw", "smart_224_raw", "smart_200_raw"], +"svm_239.pkl":["smart_3_raw", "smart_254_raw", "smart_199_raw", "smart_225_raw", "smart_187_raw", "smart_195_raw", "smart_197_raw", "smart_2_raw", "smart_193_raw", "smart_220_raw", "smart_183_raw"], +"svm_174.pkl":["smart_183_raw", "smart_196_raw", "smart_225_raw", "smart_189_raw", "smart_4_raw", "smart_3_raw", "smart_9_raw", "smart_198_raw", "smart_15_raw", "smart_5_raw", "smart_194_raw"], +"svm_104.pkl":["smart_12_raw", "smart_198_raw", "smart_197_raw", "smart_4_raw", "smart_240_raw", "smart_187_raw", "smart_225_raw", "smart_8_raw", "smart_3_raw", "smart_2_raw"], +"svm_12.pkl":["smart_222_raw", "smart_251_raw", "smart_194_raw", "smart_9_raw", "smart_184_raw", "smart_191_raw", "smart_187_raw", "smart_255_raw", "smart_4_raw", "smart_11_raw"], +"svm_97.pkl":["smart_15_raw", "smart_197_raw", "smart_190_raw", "smart_199_raw", "smart_200_raw", "smart_12_raw", "smart_191_raw", "smart_254_raw", "smart_194_raw", "smart_201_raw"], +"svm_118.pkl":["smart_11_raw", "smart_225_raw", "smart_196_raw", "smart_197_raw", "smart_198_raw", "smart_200_raw", "smart_3_raw", "smart_10_raw", "smart_191_raw", "smart_22_raw"], +"svm_185.pkl":["smart_191_raw", "smart_254_raw", "smart_3_raw", "smart_190_raw", "smart_15_raw", "smart_22_raw", "smart_2_raw", "smart_198_raw", "smart_13_raw", "smart_226_raw", "smart_225_raw"], +"svm_206.pkl":["smart_183_raw", "smart_192_raw", "smart_197_raw", "smart_255_raw", "smart_187_raw", "smart_254_raw", "smart_198_raw", "smart_13_raw", "smart_226_raw", "smart_240_raw", "smart_8_raw"], +"svm_225.pkl":["smart_224_raw", "smart_11_raw", "smart_5_raw", "smart_4_raw", "smart_225_raw", "smart_197_raw", "smart_15_raw", "smart_183_raw", "smart_193_raw", "smart_190_raw", "smart_187_raw"], +"svm_169.pkl":["smart_252_raw", "smart_183_raw", "smart_254_raw", "smart_11_raw", "smart_193_raw", "smart_22_raw", "smart_226_raw", "smart_189_raw", "smart_225_raw", "smart_198_raw", "smart_200_raw"], +"svm_79.pkl":["smart_184_raw", "smart_196_raw", "smart_4_raw", "smart_226_raw", "smart_199_raw", "smart_187_raw", "smart_193_raw", "smart_188_raw", "smart_12_raw", "smart_250_raw"], +"svm_69.pkl":["smart_187_raw", "smart_9_raw", "smart_200_raw", "smart_11_raw", "smart_252_raw", "smart_189_raw", "smart_4_raw", "smart_188_raw", "smart_255_raw", "smart_201_raw"], +"svm_201.pkl":["smart_224_raw", "smart_8_raw", "smart_250_raw", "smart_2_raw", "smart_198_raw", "smart_15_raw", "smart_193_raw", "smart_223_raw", "smart_3_raw", "smart_11_raw", "smart_191_raw"], +"svm_114.pkl":["smart_226_raw", "smart_188_raw", "smart_2_raw", "smart_11_raw", "smart_4_raw", "smart_193_raw", "smart_184_raw", "smart_194_raw", "smart_198_raw", "smart_13_raw"], +"svm_219.pkl":["smart_12_raw", "smart_22_raw", "smart_8_raw", "smart_191_raw", "smart_197_raw", "smart_254_raw", "smart_15_raw", "smart_193_raw", "smart_199_raw", "smart_225_raw", "smart_192_raw"], +"svm_168.pkl":["smart_255_raw", "smart_191_raw", "smart_193_raw", "smart_220_raw", "smart_5_raw", "smart_3_raw", "smart_222_raw", "smart_223_raw", "smart_197_raw", "smart_196_raw", "smart_22_raw"], +"svm_243.pkl":["smart_11_raw", "smart_255_raw", "smart_10_raw", "smart_189_raw", "smart_225_raw", "smart_240_raw", "smart_222_raw", "smart_197_raw", "smart_183_raw", "smart_198_raw", "smart_12_raw"], +"svm_195.pkl":["smart_183_raw", "smart_5_raw", "smart_11_raw", "smart_197_raw", "smart_15_raw", "smart_9_raw", "smart_4_raw", "smart_220_raw", "smart_12_raw", "smart_192_raw", "smart_240_raw"], +"svm_222.pkl":["smart_10_raw", "smart_13_raw", "smart_188_raw", "smart_15_raw", "smart_192_raw", "smart_224_raw", "smart_225_raw", "smart_187_raw", "smart_222_raw", "smart_220_raw", "smart_252_raw"], +"svm_62.pkl":["smart_196_raw", "smart_251_raw", "smart_187_raw", "smart_224_raw", "smart_11_raw", "smart_12_raw", "smart_8_raw", "smart_199_raw", "smart_220_raw", "smart_195_raw"], +"svm_151.pkl":["smart_187_raw", "smart_223_raw", "smart_200_raw", "smart_189_raw", "smart_251_raw", "smart_255_raw", "smart_222_raw", "smart_192_raw", "smart_12_raw", "smart_183_raw", "smart_22_raw"], +"svm_125.pkl":["smart_9_raw", "smart_252_raw", "smart_197_raw", "smart_251_raw", "smart_11_raw", "smart_12_raw", "smart_188_raw", "smart_240_raw", "smart_10_raw", "smart_223_raw"], +"svm_124.pkl":["smart_193_raw", "smart_187_raw", "smart_183_raw", "smart_11_raw", "smart_10_raw", "smart_8_raw", "smart_194_raw", "smart_189_raw", "smart_222_raw", "smart_191_raw"], +"svm_67.pkl":["smart_2_raw", "smart_8_raw", "smart_225_raw", "smart_240_raw", "smart_13_raw", "smart_5_raw", "smart_187_raw", "smart_198_raw", "smart_199_raw", "smart_3_raw"], +"svm_115.pkl":["smart_222_raw", "smart_193_raw", "smart_223_raw", "smart_195_raw", "smart_252_raw", "smart_189_raw", "smart_199_raw", "smart_187_raw", "smart_15_raw", "smart_184_raw"], +"svm_1.pkl":["smart_201_raw", "smart_8_raw", "smart_200_raw", "smart_252_raw", "smart_251_raw", "smart_187_raw", "smart_9_raw", "smart_188_raw", "smart_15_raw", "smart_184_raw"], +"svm_112.pkl":["smart_220_raw", "smart_197_raw", "smart_10_raw", "smart_188_raw", "smart_12_raw", "smart_4_raw", "smart_196_raw", "smart_3_raw", "smart_240_raw", "smart_225_raw"], +"svm_138.pkl":["smart_183_raw", "smart_10_raw", "smart_191_raw", "smart_195_raw", "smart_223_raw", "smart_189_raw", "smart_187_raw", "smart_255_raw", "smart_226_raw", "smart_8_raw"], +"svm_229.pkl":["smart_224_raw", "smart_8_raw", "smart_192_raw", "smart_220_raw", "smart_195_raw", "smart_183_raw", "smart_250_raw", "smart_187_raw", "smart_225_raw", "smart_4_raw", "smart_252_raw"], +"svm_145.pkl":["smart_190_raw", "smart_8_raw", "smart_226_raw", "smart_184_raw", "smart_225_raw", "smart_220_raw", "smart_193_raw", "smart_183_raw", "smart_201_raw", "smart_187_raw", "smart_2_raw"], +"svm_59.pkl":["smart_188_raw", "smart_11_raw", "smart_184_raw", "smart_2_raw", "smart_220_raw", "smart_198_raw", "smart_225_raw", "smart_240_raw", "smart_197_raw", "smart_251_raw"], +"svm_204.pkl":["smart_15_raw", "smart_240_raw", "smart_225_raw", "smart_223_raw", "smart_252_raw", "smart_22_raw", "smart_200_raw", "smart_13_raw", "smart_220_raw", "smart_198_raw", "smart_191_raw"], +"svm_88.pkl":["smart_198_raw", "smart_3_raw", "smart_8_raw", "smart_225_raw", "smart_251_raw", "smart_222_raw", "smart_188_raw", "smart_10_raw", "smart_240_raw", "smart_189_raw"], +"svm_182.pkl":["smart_10_raw", "smart_190_raw", "smart_250_raw", "smart_15_raw", "smart_193_raw", "smart_22_raw", "smart_200_raw", "smart_8_raw", "smart_4_raw", "smart_187_raw", "smart_9_raw"], +"svm_61.pkl":["smart_5_raw", "smart_12_raw", "smart_9_raw", "smart_198_raw", "smart_195_raw", "smart_252_raw", "smart_15_raw", "smart_240_raw", "smart_255_raw", "smart_224_raw"], +"svm_50.pkl":["smart_220_raw", "smart_5_raw", "smart_194_raw", "smart_250_raw", "smart_15_raw", "smart_240_raw", "smart_8_raw", "smart_198_raw", "smart_224_raw", "smart_191_raw"], +"svm_210.pkl":["smart_8_raw", "smart_15_raw", "smart_195_raw", "smart_224_raw", "smart_5_raw", "smart_191_raw", "smart_198_raw", "smart_225_raw", "smart_200_raw", "smart_251_raw", "smart_240_raw"], +"svm_16.pkl":["smart_222_raw", "smart_10_raw", "smart_250_raw", "smart_189_raw", "smart_191_raw", "smart_2_raw", "smart_5_raw", "smart_193_raw", "smart_9_raw", "smart_187_raw"], +"svm_85.pkl":["smart_252_raw", "smart_184_raw", "smart_9_raw", "smart_5_raw", "smart_254_raw", "smart_3_raw", "smart_195_raw", "smart_10_raw", "smart_12_raw", "smart_222_raw"], +"svm_36.pkl":["smart_201_raw", "smart_251_raw", "smart_184_raw", "smart_3_raw", "smart_5_raw", "smart_183_raw", "smart_194_raw", "smart_195_raw", "smart_224_raw", "smart_2_raw"], +"svm_33.pkl":["smart_223_raw", "smart_254_raw", "smart_225_raw", "smart_9_raw", "smart_199_raw", "smart_5_raw", "smart_189_raw", "smart_194_raw", "smart_240_raw", "smart_4_raw"], +"svm_3.pkl":["smart_225_raw", "smart_194_raw", "smart_3_raw", "smart_189_raw", "smart_9_raw", "smart_254_raw", "smart_240_raw", "smart_5_raw", "smart_255_raw", "smart_223_raw"], +"svm_93.pkl":["smart_8_raw", "smart_188_raw", "smart_5_raw", "smart_10_raw", "smart_222_raw", "smart_2_raw", "smart_254_raw", "smart_12_raw", "smart_193_raw", "smart_224_raw"], +"svm_120.pkl":["smart_189_raw", "smart_224_raw", "smart_222_raw", "smart_193_raw", "smart_5_raw", "smart_201_raw", "smart_8_raw", "smart_254_raw", "smart_194_raw", "smart_22_raw"], +"svm_128.pkl":["smart_195_raw", "smart_184_raw", "smart_251_raw", "smart_8_raw", "smart_5_raw", "smart_196_raw", "smart_10_raw", "smart_4_raw", "smart_225_raw", "smart_191_raw"], +"svm_212.pkl":["smart_225_raw", "smart_192_raw", "smart_10_raw", "smart_12_raw", "smart_222_raw", "smart_184_raw", "smart_13_raw", "smart_226_raw", "smart_5_raw", "smart_201_raw", "smart_22_raw"], +"svm_221.pkl":["smart_255_raw", "smart_2_raw", "smart_224_raw", "smart_192_raw", "smart_252_raw", "smart_13_raw", "smart_183_raw", "smart_193_raw", "smart_15_raw", "smart_199_raw", "smart_200_raw"], +"svm_223.pkl":["smart_4_raw", "smart_194_raw", "smart_9_raw", "smart_255_raw", "smart_188_raw", "smart_201_raw", "smart_3_raw", "smart_226_raw", "smart_192_raw", "smart_251_raw", "smart_191_raw"], +"svm_44.pkl":["smart_255_raw", "smart_11_raw", "smart_200_raw", "smart_3_raw", "smart_195_raw", "smart_201_raw", "smart_4_raw", "smart_5_raw", "smart_10_raw", "smart_191_raw"], +"svm_213.pkl":["smart_22_raw", "smart_191_raw", "smart_183_raw", "smart_4_raw", "smart_194_raw", "smart_255_raw", "smart_254_raw", "smart_193_raw", "smart_11_raw", "smart_10_raw", "smart_220_raw"], +"svm_131.pkl":["smart_22_raw", "smart_194_raw", "smart_184_raw", "smart_250_raw", "smart_10_raw", "smart_189_raw", "smart_183_raw", "smart_240_raw", "smart_12_raw", "smart_252_raw"], +"svm_6.pkl":["smart_194_raw", "smart_250_raw", "smart_223_raw", "smart_224_raw", "smart_184_raw", "smart_191_raw", "smart_201_raw", "smart_9_raw", "smart_252_raw", "smart_3_raw"], +"svm_161.pkl":["smart_255_raw", "smart_222_raw", "smart_226_raw", "smart_254_raw", "smart_183_raw", "smart_22_raw", "smart_12_raw", "smart_190_raw", "smart_11_raw", "smart_192_raw", "smart_251_raw"], +"svm_72.pkl":["smart_13_raw", "smart_184_raw", "smart_223_raw", "smart_240_raw", "smart_250_raw", "smart_251_raw", "smart_201_raw", "smart_196_raw", "smart_5_raw", "smart_4_raw"], +"svm_27.pkl":["smart_189_raw", "smart_188_raw", "smart_255_raw", "smart_251_raw", "smart_240_raw", "smart_15_raw", "smart_9_raw", "smart_191_raw", "smart_226_raw", "smart_10_raw"], +"svm_141.pkl":["smart_9_raw", "smart_191_raw", "smart_2_raw", "smart_226_raw", "smart_13_raw", "smart_22_raw", "smart_193_raw", "smart_222_raw", "smart_220_raw", "smart_225_raw", "smart_3_raw"], +"svm_57.pkl":["smart_12_raw", "smart_252_raw", "smart_190_raw", "smart_226_raw", "smart_10_raw", "smart_189_raw", "smart_193_raw", "smart_2_raw", "smart_9_raw", "smart_223_raw"], +"svm_236.pkl":["smart_200_raw", "smart_189_raw", "smart_226_raw", "smart_252_raw", "smart_250_raw", "smart_193_raw", "smart_13_raw", "smart_2_raw", "smart_254_raw", "smart_22_raw", "smart_9_raww"], +"svm_208.pkl":["smart_223_raw", "smart_15_raw", "smart_251_raw", "smart_5_raw", "smart_198_raw", "smart_252_raw", "smart_4_raw", "smart_8_raw", "smart_220_raw", "smart_254_raw", "smart_193_raw"], +"svm_230.pkl":["smart_184_raw", "smart_5_raw", "smart_191_raw", "smart_198_raw", "smart_11_raw", "smart_255_raw", "smart_189_raw", "smart_254_raw", "smart_196_raw", "smart_199_raw", "smart_223_raw"], +"svm_134.pkl":["smart_8_raw", "smart_194_raw", "smart_4_raw", "smart_189_raw", "smart_223_raw", "smart_5_raw", "smart_187_raw", "smart_9_raw", "smart_192_raw", "smart_220_raw"], +"svm_71.pkl":["smart_220_raw", "smart_13_raw", "smart_194_raw", "smart_197_raw", "smart_192_raw", "smart_22_raw", "smart_184_raw", "smart_199_raw", "smart_222_raw", "smart_183_raw"], +"svm_109.pkl":["smart_224_raw", "smart_252_raw", "smart_2_raw", "smart_200_raw", "smart_5_raw", "smart_194_raw", "smart_222_raw", "smart_198_raw", "smart_4_raw", "smart_13_raw"] +} diff --git a/src/pybind/mgr/diskprediction_local/models/svm_1.pkl b/src/pybind/mgr/diskprediction_local/models/svm_1.pkl new file mode 100644 index 00000000..5eb30f30 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_1.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_10.pkl b/src/pybind/mgr/diskprediction_local/models/svm_10.pkl new file mode 100644 index 00000000..9259c1e7 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_10.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_104.pkl b/src/pybind/mgr/diskprediction_local/models/svm_104.pkl new file mode 100644 index 00000000..d5d5cf5b Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_104.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_105.pkl b/src/pybind/mgr/diskprediction_local/models/svm_105.pkl new file mode 100644 index 00000000..4aadc3cf Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_105.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_109.pkl b/src/pybind/mgr/diskprediction_local/models/svm_109.pkl new file mode 100644 index 00000000..c99c353b Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_109.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_112.pkl b/src/pybind/mgr/diskprediction_local/models/svm_112.pkl new file mode 100644 index 00000000..367a3304 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_112.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_114.pkl b/src/pybind/mgr/diskprediction_local/models/svm_114.pkl new file mode 100644 index 00000000..946d5cef Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_114.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_115.pkl b/src/pybind/mgr/diskprediction_local/models/svm_115.pkl new file mode 100644 index 00000000..ff834929 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_115.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_118.pkl b/src/pybind/mgr/diskprediction_local/models/svm_118.pkl new file mode 100644 index 00000000..eec8689e Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_118.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_119.pkl b/src/pybind/mgr/diskprediction_local/models/svm_119.pkl new file mode 100644 index 00000000..6a26c050 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_119.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_12.pkl b/src/pybind/mgr/diskprediction_local/models/svm_12.pkl new file mode 100644 index 00000000..5cbe9775 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_12.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_120.pkl b/src/pybind/mgr/diskprediction_local/models/svm_120.pkl new file mode 100644 index 00000000..d2041c26 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_120.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_123.pkl b/src/pybind/mgr/diskprediction_local/models/svm_123.pkl new file mode 100644 index 00000000..0ab6187e Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_123.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_124.pkl b/src/pybind/mgr/diskprediction_local/models/svm_124.pkl new file mode 100644 index 00000000..8f9ea4ec Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_124.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_125.pkl b/src/pybind/mgr/diskprediction_local/models/svm_125.pkl new file mode 100644 index 00000000..4d49900f Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_125.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_128.pkl b/src/pybind/mgr/diskprediction_local/models/svm_128.pkl new file mode 100644 index 00000000..6a18726d Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_128.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_131.pkl b/src/pybind/mgr/diskprediction_local/models/svm_131.pkl new file mode 100644 index 00000000..e6a55dca Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_131.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_134.pkl b/src/pybind/mgr/diskprediction_local/models/svm_134.pkl new file mode 100644 index 00000000..51171e00 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_134.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_138.pkl b/src/pybind/mgr/diskprediction_local/models/svm_138.pkl new file mode 100644 index 00000000..bc98e0c7 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_138.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_14.pkl b/src/pybind/mgr/diskprediction_local/models/svm_14.pkl new file mode 100644 index 00000000..c4547dc6 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_14.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_141.pkl b/src/pybind/mgr/diskprediction_local/models/svm_141.pkl new file mode 100644 index 00000000..86d9f38d Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_141.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_145.pkl b/src/pybind/mgr/diskprediction_local/models/svm_145.pkl new file mode 100644 index 00000000..24ff9623 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_145.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_151.pkl b/src/pybind/mgr/diskprediction_local/models/svm_151.pkl new file mode 100644 index 00000000..92bfd3f1 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_151.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_16.pkl b/src/pybind/mgr/diskprediction_local/models/svm_16.pkl new file mode 100644 index 00000000..11664b3d Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_16.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_161.pkl b/src/pybind/mgr/diskprediction_local/models/svm_161.pkl new file mode 100644 index 00000000..2d421685 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_161.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_168.pkl b/src/pybind/mgr/diskprediction_local/models/svm_168.pkl new file mode 100644 index 00000000..12a811cf Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_168.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_169.pkl b/src/pybind/mgr/diskprediction_local/models/svm_169.pkl new file mode 100644 index 00000000..0c51446c Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_169.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_174.pkl b/src/pybind/mgr/diskprediction_local/models/svm_174.pkl new file mode 100644 index 00000000..d2945ce9 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_174.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_18.pkl b/src/pybind/mgr/diskprediction_local/models/svm_18.pkl new file mode 100644 index 00000000..d05520cc Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_18.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_182.pkl b/src/pybind/mgr/diskprediction_local/models/svm_182.pkl new file mode 100644 index 00000000..7fcfb3cb Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_182.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_185.pkl b/src/pybind/mgr/diskprediction_local/models/svm_185.pkl new file mode 100644 index 00000000..785301c1 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_185.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_186.pkl b/src/pybind/mgr/diskprediction_local/models/svm_186.pkl new file mode 100644 index 00000000..4ea83da7 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_186.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_195.pkl b/src/pybind/mgr/diskprediction_local/models/svm_195.pkl new file mode 100644 index 00000000..12273f7c Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_195.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_201.pkl b/src/pybind/mgr/diskprediction_local/models/svm_201.pkl new file mode 100644 index 00000000..c866cf00 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_201.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_204.pkl b/src/pybind/mgr/diskprediction_local/models/svm_204.pkl new file mode 100644 index 00000000..8cf1c3aa Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_204.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_206.pkl b/src/pybind/mgr/diskprediction_local/models/svm_206.pkl new file mode 100644 index 00000000..cba64e80 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_206.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_208.pkl b/src/pybind/mgr/diskprediction_local/models/svm_208.pkl new file mode 100644 index 00000000..ba0df0ab Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_208.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_210.pkl b/src/pybind/mgr/diskprediction_local/models/svm_210.pkl new file mode 100644 index 00000000..6b5bee21 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_210.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_212.pkl b/src/pybind/mgr/diskprediction_local/models/svm_212.pkl new file mode 100644 index 00000000..11eafc64 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_212.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_213.pkl b/src/pybind/mgr/diskprediction_local/models/svm_213.pkl new file mode 100644 index 00000000..0b8475c5 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_213.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_219.pkl b/src/pybind/mgr/diskprediction_local/models/svm_219.pkl new file mode 100644 index 00000000..4a248c14 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_219.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_221.pkl b/src/pybind/mgr/diskprediction_local/models/svm_221.pkl new file mode 100644 index 00000000..e37c6b4f Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_221.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_222.pkl b/src/pybind/mgr/diskprediction_local/models/svm_222.pkl new file mode 100644 index 00000000..e5430386 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_222.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_223.pkl b/src/pybind/mgr/diskprediction_local/models/svm_223.pkl new file mode 100644 index 00000000..8b208f4e Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_223.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_225.pkl b/src/pybind/mgr/diskprediction_local/models/svm_225.pkl new file mode 100644 index 00000000..3f2b6298 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_225.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_227.pkl b/src/pybind/mgr/diskprediction_local/models/svm_227.pkl new file mode 100644 index 00000000..5e4fb56f Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_227.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_229.pkl b/src/pybind/mgr/diskprediction_local/models/svm_229.pkl new file mode 100644 index 00000000..1e9c3359 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_229.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_230.pkl b/src/pybind/mgr/diskprediction_local/models/svm_230.pkl new file mode 100644 index 00000000..36f8205c Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_230.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_234.pkl b/src/pybind/mgr/diskprediction_local/models/svm_234.pkl new file mode 100644 index 00000000..199f9ba5 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_234.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_235.pkl b/src/pybind/mgr/diskprediction_local/models/svm_235.pkl new file mode 100644 index 00000000..d986526e Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_235.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_236.pkl b/src/pybind/mgr/diskprediction_local/models/svm_236.pkl new file mode 100644 index 00000000..160e22fa Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_236.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_239.pkl b/src/pybind/mgr/diskprediction_local/models/svm_239.pkl new file mode 100644 index 00000000..8d98572a Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_239.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_243.pkl b/src/pybind/mgr/diskprediction_local/models/svm_243.pkl new file mode 100644 index 00000000..4fca95e1 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_243.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_27.pkl b/src/pybind/mgr/diskprediction_local/models/svm_27.pkl new file mode 100644 index 00000000..011974ed Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_27.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_3.pkl b/src/pybind/mgr/diskprediction_local/models/svm_3.pkl new file mode 100644 index 00000000..e5e97a88 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_3.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_33.pkl b/src/pybind/mgr/diskprediction_local/models/svm_33.pkl new file mode 100644 index 00000000..e709d7b4 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_33.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_36.pkl b/src/pybind/mgr/diskprediction_local/models/svm_36.pkl new file mode 100644 index 00000000..3d87b8bd Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_36.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_44.pkl b/src/pybind/mgr/diskprediction_local/models/svm_44.pkl new file mode 100644 index 00000000..9abcece9 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_44.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_50.pkl b/src/pybind/mgr/diskprediction_local/models/svm_50.pkl new file mode 100644 index 00000000..b7ce5eda Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_50.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_57.pkl b/src/pybind/mgr/diskprediction_local/models/svm_57.pkl new file mode 100644 index 00000000..fe783289 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_57.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_59.pkl b/src/pybind/mgr/diskprediction_local/models/svm_59.pkl new file mode 100644 index 00000000..76217777 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_59.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_6.pkl b/src/pybind/mgr/diskprediction_local/models/svm_6.pkl new file mode 100644 index 00000000..4fb09d37 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_6.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_61.pkl b/src/pybind/mgr/diskprediction_local/models/svm_61.pkl new file mode 100644 index 00000000..319fc5f4 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_61.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_62.pkl b/src/pybind/mgr/diskprediction_local/models/svm_62.pkl new file mode 100644 index 00000000..25b21aed Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_62.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_67.pkl b/src/pybind/mgr/diskprediction_local/models/svm_67.pkl new file mode 100644 index 00000000..1e6e7383 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_67.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_69.pkl b/src/pybind/mgr/diskprediction_local/models/svm_69.pkl new file mode 100644 index 00000000..22d349a7 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_69.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_71.pkl b/src/pybind/mgr/diskprediction_local/models/svm_71.pkl new file mode 100644 index 00000000..e0760add Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_71.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_72.pkl b/src/pybind/mgr/diskprediction_local/models/svm_72.pkl new file mode 100644 index 00000000..5096aa8e Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_72.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_78.pkl b/src/pybind/mgr/diskprediction_local/models/svm_78.pkl new file mode 100644 index 00000000..7958f3b6 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_78.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_79.pkl b/src/pybind/mgr/diskprediction_local/models/svm_79.pkl new file mode 100644 index 00000000..2ed3a0fe Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_79.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_82.pkl b/src/pybind/mgr/diskprediction_local/models/svm_82.pkl new file mode 100644 index 00000000..2e188409 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_82.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_85.pkl b/src/pybind/mgr/diskprediction_local/models/svm_85.pkl new file mode 100644 index 00000000..88161af5 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_85.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_88.pkl b/src/pybind/mgr/diskprediction_local/models/svm_88.pkl new file mode 100644 index 00000000..71563398 Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_88.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_93.pkl b/src/pybind/mgr/diskprediction_local/models/svm_93.pkl new file mode 100644 index 00000000..703429fe Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_93.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/models/svm_97.pkl b/src/pybind/mgr/diskprediction_local/models/svm_97.pkl new file mode 100644 index 00000000..9653d20f Binary files /dev/null and b/src/pybind/mgr/diskprediction_local/models/svm_97.pkl differ diff --git a/src/pybind/mgr/diskprediction_local/module.py b/src/pybind/mgr/diskprediction_local/module.py new file mode 100644 index 00000000..7339c603 --- /dev/null +++ b/src/pybind/mgr/diskprediction_local/module.py @@ -0,0 +1,266 @@ +""" +diskprediction with local predictor +""" +import json +import datetime +import _strptime +from threading import Event +import time + +from mgr_module import MgrModule, CommandResult + + +TIME_FORMAT = '%Y%m%d-%H%M%S' +TIME_DAYS = 24*60*60 +TIME_WEEK = TIME_DAYS * 7 + + +class Module(MgrModule): + MODULE_OPTIONS = [ + { + 'name': 'sleep_interval', + 'default': str(600), + }, + { + 'name': 'predict_interval', + 'default': str(86400), + }, + ] + + COMMANDS = [] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + # options + for opt in self.MODULE_OPTIONS: + setattr(self, opt['name'], opt['default']) + # other + self._run = True + self._event = Event() + + def config_notify(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name'])) + if self.get_ceph_option('device_failure_prediction_mode') == 'local': + self._event.set() + + def refresh_config(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name'])) + + def handle_command(self, _, cmd): + self.log.debug('handle_command cmd: %s', cmd) + raise NotImplementedError(cmd['prefix']) + + def self_test(self): + ret, out, err = self.predict_all_devices() + assert ret == 0 + return 0, 'self test succeed', '' + + def serve(self): + self.log.info('Starting diskprediction local module') + self.config_notify() + last_predicted = None + ls = self.get_store('last_predicted') + if ls: + try: + last_predicted = datetime.datetime.strptime(ls, TIME_FORMAT) + except ValueError: + pass + self.log.debug('Last predicted %s', last_predicted) + + while self._run: + self.refresh_config() + mode = self.get_ceph_option('device_failure_prediction_mode') + if mode == 'local': + now = datetime.datetime.utcnow() + if not last_predicted: + next_predicted = now + else: + predicted_frequency = int(self.predict_interval) or 86400 + seconds = (last_predicted - datetime.datetime.utcfromtimestamp(0)).total_seconds() + seconds -= seconds % predicted_frequency + seconds += predicted_frequency + next_predicted = datetime.datetime.utcfromtimestamp(seconds) + if last_predicted: + self.log.debug('Last scrape %s, next scrape due %s', + last_predicted.strftime(TIME_FORMAT), + next_predicted.strftime(TIME_FORMAT)) + else: + self.log.debug('Last scrape never, next scrape due %s', + next_predicted.strftime(TIME_FORMAT)) + if now >= next_predicted: + self.predict_all_devices() + last_predicted = now + self.set_store('last_predicted', last_predicted.strftime(TIME_FORMAT)) + + sleep_interval = int(self.sleep_interval) or 60 + self.log.debug('Sleeping for %d seconds', sleep_interval) + self._event.wait(sleep_interval) + self._event.clear() + + def shutdown(self): + self.log.info('Stopping') + self._run = False + self._event.set() + + @staticmethod + def _convert_timestamp(predicted_timestamp, life_expectancy_day): + """ + :param predicted_timestamp: unit is nanoseconds + :param life_expectancy_day: unit is seconds + :return: + date format '%Y-%m-%d' ex. 2018-01-01 + """ + return datetime.datetime.fromtimestamp( + predicted_timestamp / (1000 ** 3) + life_expectancy_day).strftime('%Y-%m-%d') + + def _predict_life_expentancy(self, devid): + predicted_result = '' + from .predictor import get_diskfailurepredictor_path, DiskFailurePredictor + health_data = {} + predict_datas = [] + try: + r, outb, outs = self.remote('devicehealth', 'show_device_metrics', devid=devid, sample='') + if r != 0: + self.log.error('failed to get device %s health', devid) + health_data = {} + else: + health_data = json.loads(outb) + except Exception as e: + self.log.error('failed to get device %s health data due to %s', devid, str(e)) + + obj_predictor = DiskFailurePredictor() + obj_predictor.initialize("{}/models".format(get_diskfailurepredictor_path())) + + if len(health_data) >= 6: + o_keys = sorted(health_data.keys(), reverse=True) + for o_key in o_keys: + dev_smart = {} + s_val = health_data[o_key] + ata_smart = s_val.get('ata_smart_attributes', {}) + for attr in ata_smart.get('table', []): + if attr.get('raw', {}).get('string'): + if str(attr.get('raw', {}).get('string', '0')).isdigit(): + dev_smart['smart_%s_raw' % attr.get('id')] = \ + int(attr.get('raw', {}).get('string', '0')) + else: + if str(attr.get('raw', {}).get('string', '0')).split(' ')[0].isdigit(): + dev_smart['smart_%s_raw' % attr.get('id')] = \ + int(attr.get('raw', {}).get('string', + '0').split(' ')[0]) + else: + dev_smart['smart_%s_raw' % attr.get('id')] = \ + attr.get('raw', {}).get('value', 0) + if s_val.get('power_on_time', {}).get('hours') is not None: + dev_smart['smart_9_raw'] = int(s_val['power_on_time']['hours']) + if dev_smart: + predict_datas.append(dev_smart) + if len(predict_datas) >= 12: + break + else: + self.log.error('unable to predict device due to health data records less than 6 days') + + if len(predict_datas) >= 6: + predicted_result = obj_predictor.predict(predict_datas) + return predicted_result + + def predict_life_expectancy(self, devid): + result = self._predict_life_expentancy(devid) + if result.lower() == 'good': + return 0, '>6w', '' + elif result.lower() == 'warning': + return 0, '>=2w and <=6w', '' + elif result.lower() == 'bad': + return 0, '<2w', '' + else: + return 0, 'unknown', '' + + def _reset_device_life_expectancy(self, device_id): + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'device rm-life-expectancy', + 'devid': device_id + }), '') + ret, _, outs = result.wait() + if ret != 0: + self.log.error( + 'failed to reset device life expectancy, %s' % outs) + return ret + + def _set_device_life_expectancy(self, device_id, from_date, to_date=None): + result = CommandResult('') + + if to_date is None: + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'device set-life-expectancy', + 'devid': device_id, + 'from': from_date + }), '') + else: + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'device set-life-expectancy', + 'devid': device_id, + 'from': from_date, + 'to': to_date + }), '') + ret, _, outs = result.wait() + if ret != 0: + self.log.error( + 'failed to set device life expectancy, %s' % outs) + return ret + + def predict_all_devices(self): + devices = self.get('devices').get('devices', []) + for devInfo in devices: + if not devInfo.get('daemons'): + continue + if not devInfo.get('devid'): + continue + result = self._predict_life_expentancy(devInfo['devid']) + if result == 'unknown': + self._reset_device_life_expectancy(devInfo['devid']) + continue + predicted = int(time.time() * (1000 ** 3)) + + if result.lower() == 'good': + life_expectancy_day_min = (TIME_WEEK * 6) + TIME_DAYS + life_expectancy_day_max = None + elif result.lower() == 'warning': + life_expectancy_day_min = (TIME_WEEK * 2) + life_expectancy_day_max = (TIME_WEEK * 6) + elif result.lower() == 'bad': + life_expectancy_day_min = 0 + life_expectancy_day_max = (TIME_WEEK * 2) - TIME_DAYS + else: + predicted = None + life_expectancy_day_min = None + life_expectancy_day_max = None + + if predicted and devInfo['devid'] and life_expectancy_day_min: + from_date = None + to_date = None + try: + if life_expectancy_day_min: + from_date = self._convert_timestamp(predicted, life_expectancy_day_min) + + if life_expectancy_day_max: + to_date = self._convert_timestamp(predicted, life_expectancy_day_max) + + self._set_device_life_expectancy(devInfo['devid'], from_date, to_date) + self._logger.info( + 'succeed to set device {} life expectancy from: {}, to: {}'.format( + devInfo['devid'], from_date, to_date)) + except Exception as e: + self._logger.error( + 'failed to set device {} life expectancy from: {}, to: {}, {}'.format( + devInfo['devid'], from_date, to_date, str(e))) + else: + self._reset_device_life_expectancy(devInfo['devid']) + return 0, 'succeed to predicted all devices', '' diff --git a/src/pybind/mgr/diskprediction_local/predictor.py b/src/pybind/mgr/diskprediction_local/predictor.py new file mode 100644 index 00000000..bf9b0d7d --- /dev/null +++ b/src/pybind/mgr/diskprediction_local/predictor.py @@ -0,0 +1,265 @@ +"""Sample code for disk failure prediction. + +This sample code is a community version for anyone who is interested in Machine +Learning and care about disk failure. + +This class provides a disk failure prediction module. Given models dirpath to +initialize a predictor instance and then use 6 days data to predict. Predict +function will return a string to indicate disk failure status: "Good", +"Warning", "Bad", or "Unknown". + +An example code is as follows: + +>>> model = disk_failure_predictor.DiskFailurePredictor() +>>> status = model.initialize("./models") +>>> if status: +>>> model.predict(disk_days) +'Bad' + + +Provided by ProphetStor Data Services Inc. +http://www.prophetstor.com/ + +""" + +from __future__ import print_function +import os +import json +import pickle + + +def get_diskfailurepredictor_path(): + path = os.path.abspath(__file__) + dir_path = os.path.dirname(path) + return dir_path + + +class DiskFailurePredictor(object): + """Disk failure prediction + + This class implements a disk failure prediction module. + """ + + CONFIG_FILE = "config.json" + EXCLUDED_ATTRS = ['smart_9_raw', 'smart_241_raw', 'smart_242_raw'] + + def __init__(self): + """ + This function may throw exception due to wrong file operation. + """ + + self.model_dirpath = "" + self.model_context = {} + + def initialize(self, model_dirpath): + """ + Initialize all models. + + Args: None + + Returns: + Error message. If all goes well, return an empty string. + + Raises: + """ + + config_path = os.path.join(model_dirpath, self.CONFIG_FILE) + if not os.path.isfile(config_path): + return "Missing config file: " + config_path + else: + with open(config_path) as f_conf: + self.model_context = json.load(f_conf) + + for model_name in self.model_context: + model_path = os.path.join(model_dirpath, model_name) + + if not os.path.isfile(model_path): + return "Missing model file: " + model_path + + self.model_dirpath = model_dirpath + + def __preprocess(self, disk_days): + """ + Preprocess disk attributes. + + Args: + disk_days: Refer to function predict(...). + + Returns: + new_disk_days: Processed disk days. + """ + + req_attrs = [] + new_disk_days = [] + + attr_list = set.intersection(*[set(disk_day.keys()) + for disk_day in disk_days]) + for attr in attr_list: + if (attr.startswith('smart_') and attr.endswith('_raw')) and \ + attr not in self.EXCLUDED_ATTRS: + req_attrs.append(attr) + + for disk_day in disk_days: + new_disk_day = {} + for attr in req_attrs: + if float(disk_day[attr]) >= 0.0: + new_disk_day[attr] = disk_day[attr] + + new_disk_days.append(new_disk_day) + + return new_disk_days + + @staticmethod + def __get_diff_attrs(disk_days): + """ + Get 5 days differential attributes. + + Args: + disk_days: Refer to function predict(...). + + Returns: + attr_list: All S.M.A.R.T. attributes used in given disk. Here we + use intersection set of all disk days. + + diff_disk_days: A list struct comprises 5 dictionaries, each + dictionary contains differential attributes. + + Raises: + Exceptions of wrong list/dict operations. + """ + + all_attrs = [set(disk_day.keys()) for disk_day in disk_days] + attr_list = list(set.intersection(*all_attrs)) + attr_list = disk_days[0].keys() + prev_days = disk_days[:-1] + curr_days = disk_days[1:] + diff_disk_days = [] + + for prev, cur in zip(prev_days, curr_days): + diff_disk_days.append({attr:(int(cur[attr]) - int(prev[attr])) + for attr in attr_list}) + + return attr_list, diff_disk_days + + def __get_best_models(self, attr_list): + """ + Find the best model from model list according to given attribute list. + + Args: + attr_list: All S.M.A.R.T. attributes used in given disk. + + Returns: + modelpath: The best model for the given attribute list. + model_attrlist: 'Ordered' attribute list of the returned model. + Must be aware that SMART attributes is in order. + + Raises: + """ + + models = self.model_context.keys() + + scores = [] + for model_name in models: + scores.append(sum(attr in attr_list + for attr in self.model_context[model_name])) + max_score = max(scores) + + # Skip if too few matched attributes. + if max_score < 3: + print("Too few matched attributes") + return None + + best_models = {} + best_model_indices = [idx for idx, score in enumerate(scores) + if score > max_score - 2] + for model_idx in best_model_indices: + model_name = list(models)[model_idx] + model_path = os.path.join(self.model_dirpath, model_name) + model_attrlist = self.model_context[model_name] + best_models[model_path] = model_attrlist + + return best_models + # return os.path.join(self.model_dirpath, model_name), model_attrlist + + @staticmethod + def __get_ordered_attrs(disk_days, model_attrlist): + """ + Return ordered attributes of given disk days. + + Args: + disk_days: Unordered disk days. + model_attrlist: Model's ordered attribute list. + + Returns: + ordered_attrs: Ordered disk days. + + Raises: None + """ + + ordered_attrs = [] + + for one_day in disk_days: + one_day_attrs = [] + + for attr in model_attrlist: + if attr in one_day: + one_day_attrs.append(one_day[attr]) + else: + one_day_attrs.append(0) + + ordered_attrs.append(one_day_attrs) + + return ordered_attrs + + def predict(self, disk_days): + """ + Predict using given 6-days disk S.M.A.R.T. attributes. + + Args: + disk_days: A list struct comprises 6 dictionaries. These + dictionaries store 'consecutive' days of disk SMART + attributes. + Returns: + A string indicates prediction result. One of following four strings + will be returned according to disk failure status: + (1) Good : Disk is health + (2) Warning : Disk has some symptoms but may not fail immediately + (3) Bad : Disk is in danger and data backup is highly recommended + (4) Unknown : Not enough data for prediction. + + Raises: + Pickle exceptions + """ + + all_pred = [] + + proc_disk_days = self.__preprocess(disk_days) + attr_list, diff_data = DiskFailurePredictor.__get_diff_attrs(proc_disk_days) + modellist = self.__get_best_models(attr_list) + if modellist is None: + return "Unknown" + + for modelpath in modellist: + model_attrlist = modellist[modelpath] + ordered_data = DiskFailurePredictor.__get_ordered_attrs( + diff_data, model_attrlist) + + try: + with open(modelpath, 'rb') as f_model: + clf = pickle.load(f_model) + + except UnicodeDecodeError: + # Compatibility for python3 + with open(modelpath, 'rb') as f_model: + clf = pickle.load(f_model, encoding='latin1') + + pred = clf.predict(ordered_data) + + all_pred.append(1 if any(pred) else 0) + + score = 2 ** sum(all_pred) - len(modellist) + if score > 10: + return "Bad" + if score > 4: + return "Warning" + return "Good" diff --git a/src/pybind/mgr/hello/__init__.py b/src/pybind/mgr/hello/__init__.py new file mode 100644 index 00000000..129920c0 --- /dev/null +++ b/src/pybind/mgr/hello/__init__.py @@ -0,0 +1 @@ +from .module import Hello diff --git a/src/pybind/mgr/hello/module.py b/src/pybind/mgr/hello/module.py new file mode 100644 index 00000000..94d532ee --- /dev/null +++ b/src/pybind/mgr/hello/module.py @@ -0,0 +1,82 @@ + +""" +A hello world module + +See doc/mgr/hello.rst for more info. +""" + +from mgr_module import MgrModule, HandleCommandResult +from threading import Event + + +class Hello(MgrModule): + # these are CLI commands we implement + COMMANDS = [ + { + "cmd": "hello " + "name=person_name,type=CephString,req=false", + "desc": "Prints hello world to mgr.x.log", + "perm": "r" + }, + ] + + # these are module options we understand. These can be set with + # 'ceph config set global mgr/hello/ '. e.g., + # 'ceph config set global mgr/hello/place Earth' + MODULE_OPTIONS = [ + { + 'name': 'place', + 'default': 'world', + }, + { + 'name': 'emphatic', + 'type': 'bool', + 'default': True, + }, + ] + + def __init__(self, *args, **kwargs): + super(Hello, self).__init__(*args, **kwargs) + + # set up some members to enable the serve() method and shutdown + self.run = True + self.event = Event() + + def handle_command(self, inbuf, cmd): + self.log.info("hello_world_info") + self.log.debug("hello_world_debug") + self.log.error("hello_world_error") + + status_code = 0 + output_buffer = "Output buffer is for data results" + output_string = "Output string is for informative text" + if 'person_name' in cmd: + message = "Hello, " + cmd['person_name'] + else: + message = "Hello " + self.get_module_option('place') + if self.get_module_option('emphatic'): + message += '!' + + return HandleCommandResult(retval=status_code, stdout=output_buffer, + stderr=message + "\n" + output_string) + + def serve(self): + """ + This method is called by the mgr when the module starts and can be + used for any background activity. + """ + self.log.info("Starting") + while self.run: + sleep_interval = 5 + self.log.debug('Sleeping for %d seconds', sleep_interval) + ret = self.event.wait(sleep_interval) + self.event.clear() + + def shutdown(self): + """ + This method is called by the mgr when the module needs to shut + down (i.e., when the serve() function needs to exit. + """ + self.log.info('Stopping') + self.run = False + self.event.set() diff --git a/src/pybind/mgr/influx/__init__.py b/src/pybind/mgr/influx/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/influx/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/influx/module.py b/src/pybind/mgr/influx/module.py new file mode 100644 index 00000000..f3b80041 --- /dev/null +++ b/src/pybind/mgr/influx/module.py @@ -0,0 +1,489 @@ +from contextlib import contextmanager +from datetime import datetime +from threading import Event, Thread +from itertools import chain +from six import next +from six.moves import queue +from six.moves import xrange as range +import json +import errno +import six +import time + +from mgr_module import MgrModule + +try: + from influxdb import InfluxDBClient + from influxdb.exceptions import InfluxDBClientError + from requests.exceptions import RequestException +except ImportError: + InfluxDBClient = None + + +class Module(MgrModule): + MODULE_OPTIONS = [ + { + 'name': 'hostname', + 'default': None + }, + { + 'name': 'port', + 'default': 8086 + }, + { + 'name': 'database', + 'default': 'ceph' + }, + { + 'name': 'username', + 'default': None + }, + { + 'name': 'password', + 'default': None + }, + { + 'name': 'interval', + 'default': 30 + }, + { + 'name': 'ssl', + 'default': 'false' + }, + { + 'name': 'verify_ssl', + 'default': 'true' + }, + { + 'name': 'threads', + 'default': 5 + }, + { + 'name': 'batch_size', + 'default': 5000 + } + ] + + @property + def config_keys(self): + return dict((o['name'], o.get('default', None)) + for o in self.MODULE_OPTIONS) + + COMMANDS = [ + { + "cmd": "influx config-set name=key,type=CephString " + "name=value,type=CephString", + "desc": "Set a configuration value", + "perm": "rw" + }, + { + "cmd": "influx config-show", + "desc": "Show current configuration", + "perm": "r" + }, + { + "cmd": "influx send", + "desc": "Force sending data to Influx", + "perm": "rw" + } + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.event = Event() + self.run = True + self.config = dict() + self.workers = list() + self.queue = queue.Queue(maxsize=100) + self.health_checks = dict() + + def get_fsid(self): + return self.get('mon_map')['fsid'] + + @staticmethod + def can_run(): + if InfluxDBClient is not None: + return True, "" + else: + return False, "influxdb python module not found" + + @staticmethod + def get_timestamp(): + return datetime.utcnow().isoformat() + 'Z' + + @staticmethod + def chunk(l, n): + try: + while True: + xs = [] + for _ in range(n): + xs.append(next(l)) + yield xs + except StopIteration: + yield xs + + def queue_worker(self): + while True: + try: + points = self.queue.get() + if points is None: + self.log.debug('Worker shutting down') + break + + start = time.time() + with self.get_influx_client() as client: + client.write_points(points, time_precision='ms') + runtime = time.time() - start + self.log.debug('Writing points %d to Influx took %.3f seconds', + len(points), runtime) + except RequestException as e: + self.log.exception("Failed to connect to Influx host %s:%d", + self.config['hostname'], self.config['port']) + self.health_checks.update({ + 'MGR_INFLUX_SEND_FAILED': { + 'severity': 'warning', + 'summary': 'Failed to send data to InfluxDB server ' + 'at %s:%d due to an connection error' + % (self.config['hostname'], + self.config['port']), + 'detail': [str(e)] + } + }) + except InfluxDBClientError as e: + self.health_checks.update({ + 'MGR_INFLUX_SEND_FAILED': { + 'severity': 'warning', + 'summary': 'Failed to send data to InfluxDB', + 'detail': [str(e)] + } + }) + self.log.exception('Failed to send data to InfluxDB') + except queue.Empty: + continue + except: + self.log.exception('Unhandled Exception while sending to Influx') + finally: + self.queue.task_done() + + def get_latest(self, daemon_type, daemon_name, stat): + data = self.get_counter(daemon_type, daemon_name, stat)[stat] + if data: + return data[-1][1] + + return 0 + + def get_df_stats(self, now): + df = self.get("df") + data = [] + pool_info = {} + + df_types = [ + 'stored', + 'kb_used', + 'dirty', + 'rd', + 'rd_bytes', + 'stored_raw', + 'wr', + 'wr_bytes', + 'objects', + 'max_avail', + 'quota_objects', + 'quota_bytes' + ] + + for df_type in df_types: + for pool in df['pools']: + point = { + "measurement": "ceph_pool_stats", + "tags": { + "pool_name": pool['name'], + "pool_id": pool['id'], + "type_instance": df_type, + "fsid": self.get_fsid() + }, + "time": now, + "fields": { + "value": pool['stats'][df_type], + } + } + data.append(point) + pool_info.update({str(pool['id']):pool['name']}) + return data, pool_info + + def get_pg_summary_osd(self, pool_info, now): + pg_sum = self.get('pg_summary') + osd_sum = pg_sum['by_osd'] + for osd_id, stats in six.iteritems(osd_sum): + metadata = self.get_metadata('osd', "%s" % osd_id) + if not metadata: + continue + + for stat in stats: + yield { + "measurement": "ceph_pg_summary_osd", + "tags": { + "ceph_daemon": "osd." + str(osd_id), + "type_instance": stat, + "host": metadata['hostname'] + }, + "time" : now, + "fields" : { + "value": stats[stat] + } + } + + def get_pg_summary_pool(self, pool_info, now): + pool_sum = self.get('pg_summary')['by_pool'] + for pool_id, stats in six.iteritems(pool_sum): + for stat in stats: + yield { + "measurement": "ceph_pg_summary_pool", + "tags": { + "pool_name" : pool_info[pool_id], + "pool_id" : pool_id, + "type_instance" : stat, + }, + "time" : now, + "fields": { + "value" : stats[stat], + } + } + + def get_daemon_stats(self, now): + for daemon, counters in six.iteritems(self.get_all_perf_counters()): + svc_type, svc_id = daemon.split(".", 1) + metadata = self.get_metadata(svc_type, svc_id) + + for path, counter_info in counters.items(): + if counter_info['type'] & self.PERFCOUNTER_HISTOGRAM: + continue + + value = counter_info['value'] + + yield { + "measurement": "ceph_daemon_stats", + "tags": { + "ceph_daemon": daemon, + "type_instance": path, + "host": metadata['hostname'], + "fsid": self.get_fsid() + }, + "time": now, + "fields": { + "value": value + } + } + + def set_config_option(self, option, value): + if option not in self.config_keys.keys(): + raise RuntimeError('{0} is a unknown configuration ' + 'option'.format(option)) + + if option in ['port', 'interval', 'threads', 'batch_size']: + try: + value = int(value) + except (ValueError, TypeError): + raise RuntimeError('invalid {0} configured. Please specify ' + 'a valid integer'.format(option)) + + if option == 'interval' and value < 5: + raise RuntimeError('interval should be set to at least 5 seconds') + + if option in ['ssl', 'verify_ssl']: + value = value.lower() == 'true' + + if option == 'threads': + if 1 > value > 32: + raise RuntimeError('threads should be in range 1-32') + + self.config[option] = value + + def init_module_config(self): + self.config['hostname'] = \ + self.get_module_option("hostname", default=self.config_keys['hostname']) + self.config['port'] = \ + int(self.get_module_option("port", default=self.config_keys['port'])) + self.config['database'] = \ + self.get_module_option("database", default=self.config_keys['database']) + self.config['username'] = \ + self.get_module_option("username", default=self.config_keys['username']) + self.config['password'] = \ + self.get_module_option("password", default=self.config_keys['password']) + self.config['interval'] = \ + int(self.get_module_option("interval", + default=self.config_keys['interval'])) + self.config['threads'] = \ + int(self.get_module_option("threads", + default=self.config_keys['threads'])) + self.config['batch_size'] = \ + int(self.get_module_option("batch_size", + default=self.config_keys['batch_size'])) + ssl = self.get_module_option("ssl", default=self.config_keys['ssl']) + self.config['ssl'] = ssl.lower() == 'true' + verify_ssl = \ + self.get_module_option("verify_ssl", default=self.config_keys['verify_ssl']) + self.config['verify_ssl'] = verify_ssl.lower() == 'true' + + def gather_statistics(self): + now = self.get_timestamp() + df_stats, pools = self.get_df_stats(now) + return chain(df_stats, self.get_daemon_stats(now), + self.get_pg_summary_osd(pools, now), + self.get_pg_summary_pool(pools, now)) + + @contextmanager + def get_influx_client(self): + client = InfluxDBClient(self.config['hostname'], + self.config['port'], + self.config['username'], + self.config['password'], + self.config['database'], + self.config['ssl'], + self.config['verify_ssl']) + try: + yield client + finally: + try: + client.close() + except AttributeError: + # influxdb older than v5.0.0 + pass + + def send_to_influx(self): + if not self.config['hostname']: + self.log.error("No Influx server configured, please set one using: " + "ceph influx config-set hostname ") + + self.set_health_checks({ + 'MGR_INFLUX_NO_SERVER': { + 'severity': 'warning', + 'summary': 'No InfluxDB server configured', + 'detail': ['Configuration option hostname not set'] + } + }) + return False + + self.health_checks = dict() + + self.log.debug("Sending data to Influx host: %s", + self.config['hostname']) + try: + with self.get_influx_client() as client: + databases = client.get_list_database() + if {'name': self.config['database']} not in databases: + self.log.info("Database '%s' not found, trying to create " + "(requires admin privs). You can also create " + "manually and grant write privs to user " + "'%s'", self.config['database'], + self.config['database']) + client.create_database(self.config['database']) + client.create_retention_policy(name='8_weeks', + duration='8w', + replication='1', + default=True, + database=self.config['database']) + + self.log.debug('Gathering statistics') + points = self.gather_statistics() + for chunk in self.chunk(points, self.config['batch_size']): + self.queue.put(chunk, block=False) + + self.log.debug('Queue currently contains %d items', + self.queue.qsize()) + except queue.Full: + self.health_checks.update({ + 'MGR_INFLUX_QUEUE_FULL': { + 'severity': 'warning', + 'summary': 'Failed to chunk to InfluxDB Queue', + 'detail': ['Queue is full. InfluxDB might be slow with ' + 'processing data'] + } + }) + self.log.error('Queue is full, failed to add chunk') + except (RequestException, InfluxDBClientError) as e: + self.health_checks.update({ + 'MGR_INFLUX_DB_LIST_FAILED': { + 'severity': 'warning', + 'summary': 'Failed to list/create InfluxDB database', + 'detail': [str(e)] + } + }) + self.log.exception('Failed to list/create InfluxDB database') + return False + finally: + self.set_health_checks(self.health_checks) + + def shutdown(self): + self.log.info('Stopping influx module') + self.run = False + self.event.set() + self.log.debug('Shutting down queue workers') + + for _ in self.workers: + self.queue.put(None) + + self.queue.join() + + for worker in self.workers: + worker.join() + + def self_test(self): + now = self.get_timestamp() + daemon_stats = list(self.get_daemon_stats(now)) + assert len(daemon_stats) + df_stats, pools = self.get_df_stats(now) + + result = { + 'daemon_stats': daemon_stats, + 'df_stats': df_stats + } + + return json.dumps(result, indent=2) + + def handle_command(self, inbuf, cmd): + if cmd['prefix'] == 'influx config-show': + return 0, json.dumps(self.config), '' + elif cmd['prefix'] == 'influx config-set': + key = cmd['key'] + value = cmd['value'] + if not value: + return -errno.EINVAL, '', 'Value should not be empty or None' + + self.log.debug('Setting configuration option %s to %s', key, value) + self.set_config_option(key, value) + self.set_module_option(key, value) + return 0, 'Configuration option {0} updated'.format(key), '' + elif cmd['prefix'] == 'influx send': + self.send_to_influx() + return 0, 'Sending data to Influx', '' + + return (-errno.EINVAL, '', + "Command not found '{0}'".format(cmd['prefix'])) + + def serve(self): + if InfluxDBClient is None: + self.log.error("Cannot transmit statistics: influxdb python " + "module not found. Did you install it?") + return + + self.log.info('Starting influx module') + self.init_module_config() + self.run = True + + self.log.debug('Starting %d queue worker threads', + self.config['threads']) + for i in range(self.config['threads']): + worker = Thread(target=self.queue_worker, args=()) + worker.setDaemon(True) + worker.start() + self.workers.append(worker) + + while self.run: + start = time.time() + self.send_to_influx() + runtime = time.time() - start + self.log.debug('Finished sending data to Influx in %.3f seconds', + runtime) + self.log.debug("Sleeping for %d seconds", self.config['interval']) + self.event.wait(self.config['interval']) diff --git a/src/pybind/mgr/insights/CMakeLists.txt b/src/pybind/mgr/insights/CMakeLists.txt new file mode 100644 index 00000000..00722a99 --- /dev/null +++ b/src/pybind/mgr/insights/CMakeLists.txt @@ -0,0 +1,7 @@ +set(MGR_INSIGHTS_VIRTUALENV ${CEPH_BUILD_VIRTUALENV}/mgr-insights-virtualenv) + +add_custom_target(mgr-insights-test-venv + COMMAND ${CMAKE_SOURCE_DIR}/src/tools/setup-virtualenv.sh --python=${MGR_PYTHON_EXECUTABLE} ${MGR_INSIGHTS_VIRTUALENV} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/insights + COMMENT "insights tests virtualenv is being created") +add_dependencies(tests mgr-insights-test-venv) diff --git a/src/pybind/mgr/insights/__init__.py b/src/pybind/mgr/insights/__init__.py new file mode 100644 index 00000000..ea61a12f --- /dev/null +++ b/src/pybind/mgr/insights/__init__.py @@ -0,0 +1,9 @@ +from __future__ import absolute_import +import os + +if 'UNITTEST' not in os.environ: + from .module import Module +else: + import sys + import mock + sys.modules['ceph_module'] = mock.Mock() diff --git a/src/pybind/mgr/insights/health.py b/src/pybind/mgr/insights/health.py new file mode 100644 index 00000000..5235ca84 --- /dev/null +++ b/src/pybind/mgr/insights/health.py @@ -0,0 +1,191 @@ +import json +import six +from collections import defaultdict +import datetime + +# freq to write cached state to disk +PERSIST_PERIOD = datetime.timedelta(seconds = 10) +# on disk key prefix +HEALTH_HISTORY_KEY_PREFIX = "health_history/" +# apply on offset to "now": used for testing +NOW_OFFSET = None + +class HealthEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, set): + return list(obj) + return json.JSONEncoder.default(self, obj) + +class HealthCheckAccumulator(object): + """ + Deuplicated storage of health checks. + """ + def __init__(self, init_checks = None): + # check : severity : { summary, detail } + # summary and detail are deduplicated + self._checks = defaultdict(lambda: + defaultdict(lambda: { + "summary": set(), + "detail": set() + })) + + if init_checks: + self._update(init_checks) + + def __str__(self): + return "check count {}".format(len(self._checks)) + + def add(self, checks): + """ + Add health checks to the current state + + Returns: + bool: True if the state changed, False otherwise. + """ + changed = False + + for check, info in six.iteritems(checks): + + # only keep the icky stuff + severity = info["severity"] + if severity == "HEALTH_OK": + continue + + summary = info["summary"]["message"] + details = map(lambda d: d["message"], info["detail"]) + + if self._add_check(check, severity, [summary], details): + changed = True + + return changed + + def checks(self): + return self._checks + + def merge(self, other): + assert isinstance(other, HealthCheckAccumulator) + self._update(other._checks) + + def _update(self, checks): + """Merge checks with same structure. Does not set dirty bit""" + for check in checks: + for severity in checks[check]: + summaries = set(checks[check][severity]["summary"]) + details = set(checks[check][severity]["detail"]) + self._add_check(check, severity, summaries, details) + + def _add_check(self, check, severity, summaries, details): + changed = False + + for summary in summaries: + if summary not in self._checks[check][severity]["summary"]: + changed = True + self._checks[check][severity]["summary"].add(summary) + + for detail in details: + if detail not in self._checks[check][severity]["detail"]: + changed = True + self._checks[check][severity]["detail"].add(detail) + + return changed + +class HealthHistorySlot(object): + """ + Manage the life cycle of a health history time slot. + + A time slot is a fixed slice of wall clock time (e.g. every hours, from :00 + to :59), and all health updates that occur during this time are deduplicated + together. A slot is initially in a clean state, and becomes dirty when a new + health check is observed. The state of a slot should be persisted when + need_flush returns true. Once the state has been flushed, reset the dirty + bit by calling mark_flushed. + """ + def __init__(self, init_health = dict()): + self._checks = HealthCheckAccumulator(init_health.get("checks")) + self._slot = self._curr_slot() + self._next_flush = None + + def __str__(self): + return "key {} next flush {} checks {}".format( + self.key(), self._next_flush, self._checks) + + def health(self): + return dict(checks = self._checks.checks()) + + def key(self): + """Identifier in the persist store""" + return self._key(self._slot) + + def expired(self): + """True if this slot is the current slot, False otherwise""" + return self._slot != self._curr_slot() + + def need_flush(self): + """True if this slot needs to be flushed, False otherwise""" + now = HealthHistorySlot._now() + if self._next_flush is not None: + if self._next_flush <= now or self.expired(): + return True + return False + + def mark_flushed(self): + """Reset the dirty bit. Caller persists state""" + assert self._next_flush + self._next_flush = None + + def add(self, health): + """ + Add health to the underlying health accumulator. When the slot + transitions from clean to dirty a target flush time is computed. + """ + changed = self._checks.add(health["checks"]) + if changed and not self._next_flush: + self._next_flush = HealthHistorySlot._now() + PERSIST_PERIOD + return changed + + def merge(self, other): + assert isinstance(other, HealthHistorySlot) + self._checks.merge(other._checks) + + @staticmethod + def key_range(hours): + """Return the time slot keys for the past N hours""" + def inner(curr, hours): + slot = curr - datetime.timedelta(hours = hours) + return HealthHistorySlot._key(slot) + curr = HealthHistorySlot._curr_slot() + return map(lambda i: inner(curr, i), range(hours)) + + @staticmethod + def curr_key(): + """Key for the current UTC time slot""" + return HealthHistorySlot._key(HealthHistorySlot._curr_slot()) + + @staticmethod + def key_to_time(key): + """Return key converted into datetime""" + timestr = key[len(HEALTH_HISTORY_KEY_PREFIX):] + return datetime.datetime.strptime(timestr, "%Y-%m-%d_%H") + + @staticmethod + def _key(dt): + """Key format. Example: health_2018_11_05_00""" + return HEALTH_HISTORY_KEY_PREFIX + dt.strftime("%Y-%m-%d_%H") + + @staticmethod + def _now(): + """Control now time for easier testing""" + now = datetime.datetime.utcnow() + if NOW_OFFSET is not None: + now = now + NOW_OFFSET + return now + + @staticmethod + def _curr_slot(): + """Slot for the current UTC time""" + dt = HealthHistorySlot._now() + return datetime.datetime( + year = dt.year, + month = dt.month, + day = dt.day, + hour = dt.hour) diff --git a/src/pybind/mgr/insights/module.py b/src/pybind/mgr/insights/module.py new file mode 100644 index 00000000..052295a1 --- /dev/null +++ b/src/pybind/mgr/insights/module.py @@ -0,0 +1,322 @@ +import datetime +import json +import re +import threading +import six +from mgr_module import MgrModule, CommandResult +from . import health as health_util + +# hours of crash history to report +CRASH_HISTORY_HOURS = 24 +# hours of health history to report +HEALTH_HISTORY_HOURS = 24 +# how many hours of health history to keep +HEALTH_RETENTION_HOURS = 30 +# health check name for insights health +INSIGHTS_HEALTH_CHECK = "MGR_INSIGHTS_WARNING" +# version tag for persistent data format +ON_DISK_VERSION = 1 + +class Module(MgrModule): + COMMANDS = [ + { + "cmd": "insights", + "desc": "Retrieve insights report", + "perm": "r", + "poll": "false", + }, + { + 'cmd': 'insights prune-health name=hours,type=CephString', + 'desc': 'Remove health history older than hours', + 'perm': 'rw', + "poll": "false", + }, + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + + self._shutdown = False + self._evt = threading.Event() + + # health history tracking + self._pending_health = [] + self._health_slot = None + + def notify(self, ttype, ident): + """Queue updates for processing""" + if ttype == "health": + self.log.info("Received health check update {} pending".format( + len(self._pending_health))) + health = json.loads(self.get("health")["json"]) + self._pending_health.append(health) + self._evt.set() + + def serve(self): + self._health_reset() + while True: + self._evt.wait(health_util.PERSIST_PERIOD.total_seconds()) + self._evt.clear() + if self._shutdown: + break + + # when the current health slot expires, finalize it by flushing it to + # the store, and initializing a new empty slot. + if self._health_slot.expired(): + self.log.info("Health history slot expired {}".format( + self._health_slot)) + self._health_maybe_flush() + self._health_reset() + self._health_prune_history(HEALTH_RETENTION_HOURS) + + # fold in pending health snapshots and flush + self.log.info("Applying {} health updates to slot {}".format( + len(self._pending_health), self._health_slot)) + for health in self._pending_health: + self._health_slot.add(health) + self._pending_health = [] + self._health_maybe_flush() + + def shutdown(self): + self._shutdown = True + self._evt.set() + + def _health_reset(self): + """Initialize the current health slot + + The slot will be initialized with any state found to have already been + persisted, otherwise the slot will start empty. + """ + key = health_util.HealthHistorySlot.curr_key() + data = self.get_store(key) + if data: + init_health = json.loads(data) + self._health_slot = health_util.HealthHistorySlot(init_health) + else: + self._health_slot = health_util.HealthHistorySlot() + self.log.info("Reset curr health slot {}".format(self._health_slot)) + + def _health_maybe_flush(self): + """Store the health for the current time slot if needed""" + + self.log.info("Maybe flushing slot {} needed {}".format( + self._health_slot, self._health_slot.need_flush())) + + if self._health_slot.need_flush(): + key = self._health_slot.key() + + # build store data entry + slot = self._health_slot.health() + assert "version" not in slot + slot.update(dict(version = ON_DISK_VERSION)) + data = json.dumps(slot, cls=health_util.HealthEncoder) + + self.log.debug("Storing health key {} data {}".format( + key, json.dumps(slot, indent=2, cls=health_util.HealthEncoder))) + + self.set_store(key, data) + self._health_slot.mark_flushed() + + def _health_filter(self, f): + """Filter hourly health reports timestamp""" + matches = filter( + lambda t: f(health_util.HealthHistorySlot.key_to_time(t[0])), + six.iteritems(self.get_store_prefix(health_util.HEALTH_HISTORY_KEY_PREFIX))) + return map(lambda t: t[0], matches) + + def _health_prune_history(self, hours): + """Prune old health entries""" + cutoff = datetime.datetime.utcnow() - datetime.timedelta(hours = hours) + for key in self._health_filter(lambda ts: ts <= cutoff): + self.log.info("Removing old health slot key {}".format(key)) + self.set_store(key, None) + if not hours: + self._health_slot = health_util.HealthHistorySlot() + + def _health_report(self, hours): + """ + Report a consolidated health report for the past N hours. + """ + # roll up the past N hours of health info + collector = health_util.HealthHistorySlot() + keys = health_util.HealthHistorySlot.key_range(hours) + for key in keys: + data = self.get_store(key) + self.log.info("Reporting health key {} found {}".format( + key, bool(data))) + health = json.loads(data) if data else {} + slot = health_util.HealthHistorySlot(health) + collector.merge(slot) + + # include history that hasn't yet been flushed + collector.merge(self._health_slot) + + return dict( + current = json.loads(self.get("health")["json"]), + history = collector.health() + ) + + def _version_parse(self, version): + """ + Return the components of a Ceph version string. + + This returns nothing when the version string cannot be parsed into its + constituent components, such as when Ceph has been built with + ENABLE_GIT_VERSION=OFF. + """ + r = r"ceph version (?P\d+)\.(?P\d+)\.(?P\d+)" + m = re.match(r, version) + ver = {} if not m else { + "release": m.group("release"), + "major": m.group("major"), + "minor": m.group("minor") + } + return { k:int(v) for k,v in six.iteritems(ver) } + + def _crash_history(self, hours): + """ + Load crash history for the past N hours from the crash module. + """ + params = dict( + prefix = "crash json_report", + hours = hours + ) + + result = dict( + summary = {}, + hours = params["hours"], + ) + + health_check_details = [] + + try: + _, _, crashes = self.remote("crash", "handle_command", "", params) + result["summary"] = json.loads(crashes) + except Exception as e: + errmsg = "failed to invoke crash module" + self.log.warning("{}: {}".format(errmsg, str(e))) + health_check_details.append(errmsg) + else: + self.log.debug("Crash module invocation succeeded {}".format( + json.dumps(result["summary"], indent=2))) + + return result, health_check_details + + def _apply_osd_stats(self, osd_map): + # map from osd id to its index in the map structure + osd_id_to_idx = {} + for idx in range(len(osd_map["osds"])): + osd_id_to_idx[osd_map["osds"][idx]["osd"]] = idx + + # include stats, including space utilization performance counters. + # adapted from dashboard api controller + for s in self.get('osd_stats')['osd_stats']: + try: + idx = osd_id_to_idx[s["osd"]] + osd_map["osds"][idx].update({'osd_stats': s}) + except KeyError as e: + self.log.warning("inconsistent api state: {}".format(str(e))) + + for osd in osd_map["osds"]: + osd['stats'] = {} + for s in ['osd.numpg', 'osd.stat_bytes', 'osd.stat_bytes_used']: + osd['stats'][s.split('.')[1]] = self.get_latest('osd', str(osd["osd"]), s) + + + def _config_dump(self): + """Report cluster configuration + + This report is the standard `config dump` report. It does not include + configuration defaults; these can be inferred from the version number. + """ + result = CommandResult("") + args = dict(prefix = "config dump", format = "json") + self.send_command(result, "mon", "", json.dumps(args), "") + ret, outb, outs = result.wait() + if ret == 0: + return json.loads(outb), [] + else: + self.log.warning("send_command 'config dump' failed. \ + ret={}, outs=\"{}\"".format(ret, outs)) + return [], ["Failed to read monitor config dump"] + + def do_report(self, inbuf, command): + health_check_details = [] + report = {} + + report.update({ + "version": dict(full = self.version, + **self._version_parse(self.version)) + }) + + # crash history + crashes, health_details = self._crash_history(CRASH_HISTORY_HOURS) + report["crashes"] = crashes + health_check_details.extend(health_details) + + # health history + report["health"] = self._health_report(HEALTH_HISTORY_HOURS) + + # cluster configuration + config, health_details = self._config_dump() + report["config"] = config + health_check_details.extend(health_details) + + osd_map = self.get("osd_map") + del osd_map['pg_temp'] + self._apply_osd_stats(osd_map) + report["osd_dump"] = osd_map + + report["df"] = self.get("df") + report["osd_tree"] = self.get("osd_map_tree") + report["fs_map"] = self.get("fs_map") + report["crush_map"] = self.get("osd_map_crush") + report["mon_map"] = self.get("mon_map") + report["service_map"] = self.get("service_map") + report["manager_map"] = self.get("mgr_map") + report["mon_status"] = json.loads(self.get("mon_status")["json"]) + report["pg_summary"] = self.get("pg_summary") + report["osd_metadata"] = self.get("osd_metadata") + + report.update({ + "errors": health_check_details + }) + + if health_check_details: + self.set_health_checks({ + INSIGHTS_HEALTH_CHECK: { + "severity": "warning", + "summary": "Generated incomplete Insights report", + "detail": health_check_details + } + }) + + return 0, json.dumps(report, indent=2, cls=health_util.HealthEncoder), "" + + def do_prune_health(self, inbuf, command): + try: + hours = int(command['hours']) + except ValueError: + return errno.EINVAL, '', 'hours argument must be integer' + + self._health_prune_history(hours) + + return 0, "", "" + + def testing_set_now_time_offset(self, hours): + """ + Control what "now" time it is by applying an offset. This is called from + the selftest module to manage testing scenarios related to tracking + health history. + """ + hours = long(hours) + health_util.NOW_OFFSET = datetime.timedelta(hours = hours) + self.log.warning("Setting now time offset {}".format(health_util.NOW_OFFSET)) + + def handle_command(self, inbuf, command): + if command["prefix"] == "insights": + return self.do_report(inbuf, command) + elif command["prefix"] == "insights prune-health": + return self.do_prune_health(inbuf, command) + else: + raise NotImplementedError(cmd["prefix"]) diff --git a/src/pybind/mgr/insights/run-tox.sh b/src/pybind/mgr/insights/run-tox.sh new file mode 100644 index 00000000..7d621450 --- /dev/null +++ b/src/pybind/mgr/insights/run-tox.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +function dump_envvars { + echo "WITH_PYTHON2: ->$WITH_PYTHON2<-" + echo "WITH_PYTHON3: ->$WITH_PYTHON3<-" + echo "TOX_PATH: ->$TOX_PATH<-" + echo "ENV_LIST: ->$ENV_LIST<-" +} + +# run from ./ or from ../ +: ${MGR_INSIGHTS_VIRTUALENV:=$CEPH_BUILD_DIR/mgr-insights-virtualenv} +: ${WITH_PYTHON2:=ON} +: ${WITH_PYTHON3:=3} +: ${CEPH_BUILD_DIR:=$PWD/.tox} +test -d insights && cd insights + +if [ -e tox.ini ]; then + TOX_PATH=$(readlink -f tox.ini) +else + TOX_PATH=$(readlink -f $(dirname $0)/tox.ini) +fi + +# tox.ini will take care of this. +unset PYTHONPATH +export CEPH_BUILD_DIR=$CEPH_BUILD_DIR + +source ${MGR_INSIGHTS_VIRTUALENV}/bin/activate + +if [ "$WITH_PYTHON2" = "ON" ]; then + ENV_LIST+="py27," +fi +# WITH_PYTHON3 might be set to "ON" or to the python3 RPM version number +# prevailing on the system - e.g. "3", "36" +if [[ "$WITH_PYTHON3" =~ (^3|^ON) ]]; then + ENV_LIST+="py3," +fi +# use bash string manipulation to strip off any trailing comma +ENV_LIST=${ENV_LIST%,} + +tox -c "${TOX_PATH}" -e "${ENV_LIST}" "$@" +TOX_STATUS="$?" +test "$TOX_STATUS" -ne "0" && dump_envvars +exit $TOX_STATUS diff --git a/src/pybind/mgr/insights/tests/__init__.py b/src/pybind/mgr/insights/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/pybind/mgr/insights/tests/test_health.py b/src/pybind/mgr/insights/tests/test_health.py new file mode 100644 index 00000000..9b34786d --- /dev/null +++ b/src/pybind/mgr/insights/tests/test_health.py @@ -0,0 +1,273 @@ +import unittest +import mock +from ..health import * + +class HealthChecksTest(unittest.TestCase): + def test_check_accum_empty(self): + # health checks accum initially empty reports empty + h = HealthCheckAccumulator() + self.assertEqual(h.checks(), {}) + + h = HealthCheckAccumulator({}) + self.assertEqual(h.checks(), {}) + + def _get_init_checks(self): + return HealthCheckAccumulator({ + "C0": { + "S0": { + "summary": ["s0", "s1"], + "detail": ("d0", "d1") + } + } + }) + + def test_check_init(self): + # initialization with lists and tuples is OK + h = self._get_init_checks() + self.assertEqual(h.checks(), { + "C0": { + "S0": { + "summary": set(["s0", "s1"]), + "detail": set(["d0", "d1"]) + } + } + }) + + def _get_merged_checks(self): + h = self._get_init_checks() + h.merge(HealthCheckAccumulator({ + "C0": { + "S0": { + "summary": ["s0", "s1", "s2"], + "detail": ("d2",) + }, + "S1": { + "summary": ["s0", "s1", "s2"], + "detail": () + } + }, + "C1": { + "S0": { + "summary": [], + "detail": ("d0", "d1", "d2") + } + } + })) + return h + + def test_check_merge(self): + # merging combines and de-duplicates + h = self._get_merged_checks() + self.assertEqual(h.checks(), { + "C0": { + "S0": { + "summary": set(["s0", "s1", "s2"]), + "detail": set(["d0", "d1", "d2"]) + }, + "S1": { + "summary": set(["s0", "s1", "s2"]), + "detail": set([]) + } + }, + "C1": { + "S0": { + "summary": set([]), + "detail": set(["d0", "d1", "d2"]) + } + } + }) + + def test_check_add_no_change(self): + # returns false when nothing changes + h = self._get_merged_checks() + + self.assertFalse(h.add({})) + + self.assertFalse(h.add({ + "C0": { + "severity": "S0", + "summary": { "message": "s0" }, + "detail": [] + } + })) + + self.assertFalse(h.add({ + "C0": { + "severity": "S0", + "summary": { "message": "s1" }, + "detail": [{ "message": "d1" }] + } + })) + + self.assertFalse(h.add({ + "C0": { + "severity": "S0", + "summary": { "message": "s0" }, + "detail": [{ "message": "d1" }, { "message": "d2" }] + } + })) + + def test_check_add_changed(self): + # new checks report change + h = self._get_merged_checks() + + self.assertTrue(h.add({ + "C0": { + "severity": "S0", + "summary": { "message": "s3" }, + "detail": [] + } + })) + + self.assertTrue(h.add({ + "C0": { + "severity": "S0", + "summary": { "message": "s1" }, + "detail": [{ "message": "d4" }] + } + })) + + self.assertTrue(h.add({ + "C0": { + "severity": "S2", + "summary": { "message": "s0" }, + "detail": [{ "message": "d0" }] + } + })) + + self.assertTrue(h.add({ + "C2": { + "severity": "S0", + "summary": { "message": "s0" }, + "detail": [{ "message": "d0" }, { "message": "d1" }] + } + })) + + self.assertEqual(h.checks(), { + "C0": { + "S0": { + "summary": set(["s0", "s1", "s2", "s3"]), + "detail": set(["d0", "d1", "d2", "d4"]) + }, + "S1": { + "summary": set(["s0", "s1", "s2"]), + "detail": set([]) + }, + "S2": { + "summary": set(["s0"]), + "detail": set(["d0"]) + } + }, + "C1": { + "S0": { + "summary": set([]), + "detail": set(["d0", "d1", "d2"]) + } + }, + "C2": { + "S0": { + "summary": set(["s0"]), + "detail": set(["d0", "d1"]) + } + } + }) + +class HealthHistoryTest(unittest.TestCase): + def _now(self): + # return some time truncated at 30 minutes past the hour. this lets us + # fiddle with time offsets without worrying about accidentally landing + # on exactly the top of the hour which is the edge of a time slot for + # tracking health history. + dt = datetime.datetime.utcnow() + return datetime.datetime( + year = dt.year, + month = dt.month, + day = dt.day, + hour = dt.hour, + minute = 30) + + def test_empty_slot(self): + now = self._now() + + HealthHistorySlot._now = mock.Mock(return_value=now) + h = HealthHistorySlot() + + # reports no historical checks + self.assertEqual(h.health(), { "checks": {} }) + + # an empty slot doesn't need to be flushed + self.assertFalse(h.need_flush()) + + def test_expires(self): + now = self._now() + + HealthHistorySlot._now = mock.Mock(return_value=now) + h = HealthHistorySlot() + self.assertFalse(h.expired()) + + # an hour from now it would be expired + future = now + datetime.timedelta(hours = 1) + HealthHistorySlot._now = mock.Mock(return_value=future) + self.assertTrue(h.expired()) + + def test_need_flush(self): + now = self._now() + + HealthHistorySlot._now = mock.Mock(return_value=now) + h = HealthHistorySlot() + self.assertFalse(h.need_flush()) + + self.assertTrue(h.add(dict(checks = { + "C0": { + "severity": "S0", + "summary": { "message": "s0" }, + "detail": [{ "message": "d0" }] + } + }))) + # no flush needed, yet... + self.assertFalse(h.need_flush()) + + # after persist period time elapses, a flush is needed + future = now + PERSIST_PERIOD + HealthHistorySlot._now = mock.Mock(return_value=future) + self.assertTrue(h.need_flush()) + + # mark flush resets + h.mark_flushed() + self.assertFalse(h.need_flush()) + + def test_need_flush_edge(self): + # test needs flush is true because it has expired, not because it has + # been dirty for the persistence period + dt = datetime.datetime.utcnow() + now = datetime.datetime( + year = dt.year, + month = dt.month, + day = dt.day, + hour = dt.hour, + minute = 59, + second = 59) + HealthHistorySlot._now = mock.Mock(return_value=now) + h = HealthHistorySlot() + self.assertFalse(h.expired()) + self.assertFalse(h.need_flush()) + + # now it is dirty, but it doesn't need a flush + self.assertTrue(h.add(dict(checks = { + "C0": { + "severity": "S0", + "summary": { "message": "s0" }, + "detail": [{ "message": "d0" }] + } + }))) + self.assertFalse(h.expired()) + self.assertFalse(h.need_flush()) + + # advance time past the hour so it expires, but not past the persistence + # period deadline for the last event that set the dirty bit + self.assertTrue(PERSIST_PERIOD.total_seconds() > 5) + future = now + datetime.timedelta(seconds = 5) + HealthHistorySlot._now = mock.Mock(return_value=future) + + self.assertTrue(h.expired()) + self.assertTrue(h.need_flush()) diff --git a/src/pybind/mgr/insights/tox.ini b/src/pybind/mgr/insights/tox.ini new file mode 100644 index 00000000..c02393af --- /dev/null +++ b/src/pybind/mgr/insights/tox.ini @@ -0,0 +1,17 @@ +[tox] +envlist = py27,py3 +skipsdist = true +toxworkdir = {env:CEPH_BUILD_DIR}/insights +minversion = 2.8.1 + +[testenv] +deps = + pytest + mock + six>=1.14.0 +setenv= + UNITTEST = true + py27: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.2 + py3: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.3 +commands= + {envbindir}/py.test tests/ diff --git a/src/pybind/mgr/iostat/__init__.py b/src/pybind/mgr/iostat/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/iostat/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/iostat/module.py b/src/pybind/mgr/iostat/module.py new file mode 100644 index 00000000..f5c3179d --- /dev/null +++ b/src/pybind/mgr/iostat/module.py @@ -0,0 +1,73 @@ + +from mgr_module import MgrModule + + +class Module(MgrModule): + COMMANDS = [ + { + "cmd": "iostat", + "desc": "Get IO rates", + "perm": "r", + "poll": "true" + }, + ] + + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + + def self_test(self): + r = self.get('io_rate') + assert('pg_stats_delta' in r) + assert('stamp_delta' in r['pg_stats_delta']) + assert('stat_sum' in r['pg_stats_delta']) + assert('num_read_kb' in r['pg_stats_delta']['stat_sum']) + assert('num_write_kb' in r['pg_stats_delta']['stat_sum']) + assert('num_write' in r['pg_stats_delta']['stat_sum']) + assert('num_read' in r['pg_stats_delta']['stat_sum']) + + def handle_command(self, inbuf, command): + rd = 0 + wr = 0 + total = 0 + rd_ops = 0 + wr_ops = 0 + total_ops = 0 + ret = '' + + if command['prefix'] == 'iostat': + r = self.get('io_rate') + + stamp_delta = float(r['pg_stats_delta']['stamp_delta']) + if (stamp_delta > 0): + rd = int(r['pg_stats_delta']['stat_sum']['num_read_kb']) / stamp_delta + wr = int(r['pg_stats_delta']['stat_sum']['num_write_kb']) / stamp_delta + # The values are in kB, but to_pretty_iec() requires them to be in bytes + rd = int(rd) << 10 + wr = int(wr) << 10 + total = rd + wr + + rd_ops = int(r['pg_stats_delta']['stat_sum']['num_read']) / stamp_delta + wr_ops = int(r['pg_stats_delta']['stat_sum']['num_write']) / stamp_delta + total_ops = rd_ops + wr_ops + + if 'width' in command: + width = command['width'] + else: + width = 80 + + if command.get('print_header', False): + elems = ['Read', 'Write', 'Total', 'Read IOPS', 'Write IOPS', 'Total IOPS'] + ret += self.get_pretty_header(elems, width) + + elems = [ + self.to_pretty_iec(rd) + 'B/s', + self.to_pretty_iec(wr) + 'B/s', + self.to_pretty_iec(total) + 'B/s', + int(rd_ops), + int(wr_ops), + int(total_ops) + ] + ret += self.get_pretty_row(elems, width) + + return 0, '', ret diff --git a/src/pybind/mgr/k8sevents/README.md b/src/pybind/mgr/k8sevents/README.md new file mode 100644 index 00000000..7398096e --- /dev/null +++ b/src/pybind/mgr/k8sevents/README.md @@ -0,0 +1,81 @@ +# Testing + +## To test the k8sevents module +enable the module with `ceph mgr module enable k8sevents` +check that it's working `ceph k8sevents status`, you should see something like this; +``` +[root@ceph-mgr ~]# ceph k8sevents status +Kubernetes +- Hostname : https://localhost:30443 +- Namespace: ceph +Tracker Health +- EventProcessor : OK +- CephConfigWatcher : OK +- NamespaceWatcher : OK +Tracked Events +- namespace : 5 +- ceph events: 0 + +``` +Now run some commands to generate healthchecks and admin level events; +- ```ceph osd set noout``` +- ```ceph osd unset noout``` +- ```ceph osd pool create mypool 4 4 replicated``` +- ```ceph osd pool delete mypool mypool --yes-i-really-really-mean-it``` + +In addition to tracking audit, healthchecks and configuration changes if you have the environment up for >1 hr you should also see and event that shows the clusters health and configuration overview. + +As well as status, you can use k8sevents to see event activity in the target kubernetes namespace +``` +[root@rhcs4-3 kube]# ceph k8sevents ls +Last Seen (UTC) Type Count Message Event Object Name +2019/09/20 04:33:00 Normal 1 Pool 'mypool' has been removed from the cluster mgr.ConfigurationChangeql2hj +2019/09/20 04:32:55 Normal 1 Client 'client.admin' issued: ceph osd pool delete mgr.audit.osd_pool_delete_ +2019/09/20 04:13:23 Normal 2 Client 'mds.rhcs4-2' issued: ceph osd blacklist mgr.audit.osd_blacklist_ +2019/09/20 04:08:28 Normal 1 Ceph log -> event tracking started mgr.k8sevents-moduleq74k7 +Total : 4 +``` +or, focus on the ceph specific events(audit & healthcheck) that are being tracked by the k8sevents module. +``` +[root@rhcs4-3 kube]# ceph k8sevents ceph +Last Seen (UTC) Type Count Message Event Object Name +2019/09/20 04:32:55 Normal 1 Client 'client.admin' issued: ceph osd pool delete mgr.audit.osd_pool_delete_ +2019/09/20 04:13:23 Normal 2 Client 'mds.rhcs4-2' issued: ceph osd blacklist mgr.audit.osd_blacklist_ +Total : 2 +``` + +## Sending events from a standalone Ceph cluster to remote Kubernetes cluster +To test interaction from a standalone ceph cluster to a kubernetes environment, you need to make changes on the kubernetes cluster **and** on one of the mgr hosts. +### kubernetes (minikube) +We need some basic RBAC in place to define a serviceaccount(and token) that we can use to push events into kubernetes. The `rbac_sample.yaml` file provides a quick means to create the required resources. Create them with `kubectl create -f rbac_sample.yaml` + +Once the resources are defined inside kubernetes, we need a couple of things copied over to the Ceph mgr's filesystem. +### ceph admin host +We need to run some commands against the cluster, so you'll needs access to a ceph admin host. If you don't have a dedicated admin host, you can use a mon or mgr machine. We'll need the root ca.crt of the kubernetes API, and the token associated with the service account we're using to access the kubernetes API. + +1. Download/fetch the root ca.crt for the kubernetes cluster (on minikube this can be found at ~/minikube/ca.crt) +2. Copy the ca.crt to your ceph admin host +3. Extract the token from the service account we're going to use +``` +kubectl -n ceph get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='ceph-mgr')].data.token}"|base64 -d > mytoken +``` +4. Copy the token to your ceph admin host +5. On the ceph admin host, enable the module with `ceph mgr module enable k8sevents` +6. Set up the configuration +``` +ceph k8sevents set-access cacrt -i +ceph k8sevents set-access token -i +ceph k8sevents set-config server https://: +ceph k8sevents set-config namespace ceph +``` +7. Restart the module with `ceph mgr module disable k8sevents && ceph mgr module enable k8sevents` +8. Check state with the `ceph k8sevents status` command +9. Remove the ca.crt and mytoken files from your admin host + +To remove the configuration keys used for external kubernetes access, run the following command +``` +ceph k8sevents clear-config +``` + +## Networking +You can use the above approach with a minikube based target from a standalone ceph cluster, but you'll need to have a tunnel/routing defined from the mgr host(s) to the minikube machine to make the kubernetes API accessible to the mgr/k8sevents module. This can just be a simple ssh tunnel. diff --git a/src/pybind/mgr/k8sevents/__init__.py b/src/pybind/mgr/k8sevents/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/k8sevents/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/k8sevents/module.py b/src/pybind/mgr/k8sevents/module.py new file mode 100644 index 00000000..e6568269 --- /dev/null +++ b/src/pybind/mgr/k8sevents/module.py @@ -0,0 +1,1460 @@ +# Integrate with the kubernetes events API. +# This module sends events to Kubernetes, and also captures/tracks all events +# in the rook-ceph namespace so kubernetes activity like pod restarts, +# imagepulls etc can be seen from within the ceph cluster itself. +# +# To interact with the events API, the mgr service to access needs to be +# granted additional permissions +# e.g. kubectl -n rook-ceph edit clusterrole rook-ceph-mgr-cluster-rules +# +# These are the changes needed; +# - apiGroups: +# - "" +# resources: +# - events +# verbs: +# - create +# - patch +# - list +# - get +# - watch + + +import os +import re +import sys +import time +import json +import yaml +import errno +import socket +import base64 +import logging +import tempfile +import threading + +try: + # python 3 + from urllib.parse import urlparse +except ImportError: + # python 2 fallback + from urlparse import urlparse + +from datetime import tzinfo, datetime, timedelta + +from urllib3.exceptions import MaxRetryError,ProtocolError +from collections import OrderedDict + +import rados +from mgr_module import MgrModule +from mgr_util import verify_cacrt, ServerConfigException + +try: + import queue +except ImportError: + # python 2.7.5 + import Queue as queue +finally: + # python 2.7.15 or python3 + event_queue = queue.Queue() + +try: + from kubernetes import client, config, watch + from kubernetes.client.rest import ApiException +except ImportError: + kubernetes_imported = False + client = None + config = None + watch = None +else: + kubernetes_imported = True + + # The watch.Watch.stream method can provide event objects that have involved_object = None + # which causes an exception in the generator. A workaround is discussed for a similar issue + # in https://github.com/kubernetes-client/python/issues/376 which has been used here + # pylint: disable=no-member + from kubernetes.client.models.v1_event import V1Event + def local_involved_object(self, involved_object): + if involved_object is None: + involved_object = client.V1ObjectReference(api_version="1") + self._involved_object = involved_object + V1Event.involved_object = V1Event.involved_object.setter(local_involved_object) + +log = logging.getLogger(__name__) + +# use a simple local class to represent UTC +# datetime pkg modules vary between python2 and 3 and pytz is not available on older +# ceph container images, so taking a pragmatic approach! +class UTC(tzinfo): + def utcoffset(self, dt): + return timedelta(0) + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return timedelta(0) + + +def text_suffix(num): + """Define a text suffix based on a value i.e. turn host into hosts""" + return '' if num == 1 else 's' + + +def create_temp_file(fname, content, suffix=".tmp"): + """Create a temp file + + Attempt to create an temporary file containing the given content + + Returns: + str .. full path to the temporary file + + Raises: + OSError: problems creating the file + + """ + + if content is not None: + file_name = os.path.join(tempfile.gettempdir(), fname + suffix) + + try: + with open(file_name, "w") as f: + f.write(content) + except OSError as e: + raise OSError("Unable to create temporary file : {}".format(str(e))) + + return file_name + + +class HealthCheck(object): + """Transform a healthcheck msg into it's component parts""" + + def __init__(self, msg, msg_level): + + # msg looks like + # + # Health check failed: Reduced data availability: 100 pgs inactive (PG_AVAILABILITY) + # Health check cleared: OSDMAP_FLAGS (was: nodown flag(s) set) + # Health check failed: nodown flag(s) set (OSDMAP_FLAGS) + # + self.msg = None + self.name = None + self.text = None + self.valid = False + + if msg.lower().startswith('health check'): + + self.valid = True + self.msg = msg + msg_tokens = self.msg.split() + + if msg_level == 'INF': + self.text = ' '.join(msg_tokens[3:]) + self.name = msg_tokens[3] # health check name e.g. OSDMAP_FLAGS + else: # WRN or ERR + self.text = ' '.join(msg_tokens[3:-1]) + self.name = msg_tokens[-1][1:-1] + + +class LogEntry(object): + """Generic 'log' object""" + + reason_map = { + "audit": "Audit", + "cluster": "HealthCheck", + "config": "ClusterChange", + "heartbeat":"Heartbeat", + "startup": "Started" + } + + def __init__(self, source, msg, msg_type, level, tstamp=None): + + self.source = source + self.msg = msg + self.msg_type = msg_type + self.level = level + self.tstamp = tstamp + self.healthcheck = None + + if 'health check ' in self.msg.lower(): + self.healthcheck = HealthCheck(self.msg, self.level) + + + def __str__(self): + return "source={}, msg_type={}, msg={}, level={}, tstamp={}".format(self.source, + self.msg_type, + self.msg, + self.level, + self.tstamp) + + @property + def cmd(self): + """Look at the msg string and extract the command content""" + + # msg looks like 'from=\'client.205306 \' entity=\'client.admin\' cmd=\'[{"prefix": "osd set", "key": "nodown"}]\': finished' + if self.msg_type != 'audit': + return None + else: + _m=self.msg[:-10].replace("\'","").split("cmd=") + _s='"cmd":{}'.format(_m[1]) + cmds_list = json.loads('{' + _s + '}')['cmd'] + + # TODO. Assuming only one command was issued for now + _c = cmds_list[0] + return "{} {}".format(_c['prefix'], _c.get('key', '')) + + @property + def event_type(self): + return 'Normal' if self.level == 'INF' else 'Warning' + + @property + def event_reason(self): + return self.reason_map[self.msg_type] + + @property + def event_name(self): + if self.msg_type == 'heartbeat': + return 'mgr.Heartbeat' + elif self.healthcheck: + return 'mgr.health.{}'.format(self.healthcheck.name) + elif self.msg_type == 'audit': + return 'mgr.audit.{}'.format(self.cmd).replace(' ', '_') + elif self.msg_type == 'config': + return 'mgr.ConfigurationChange' + elif self.msg_type == 'startup': + return "mgr.k8sevents-module" + else: + return None + + @property + def event_entity(self): + if self.msg_type == 'audit': + return self.msg.replace("\'","").split('entity=')[1].split(' ')[0] + else: + return None + + @property + def event_msg(self): + if self.msg_type == 'audit': + return "Client '{}' issued: ceph {}".format(self.event_entity, self.cmd) + + elif self.healthcheck: + return self.healthcheck.text + else: + return self.msg + + +class BaseThread(threading.Thread): + health = 'OK' + reported = False + daemon = True + + +def clean_event(event): + """ clean an event record """ + if not event.first_timestamp: + log.error("first_timestamp is empty") + if event.metadata.creation_timestamp: + log.error("setting first_timestamp to the creation timestamp") + event.first_timestamp = event.metadata.creation_timestamp + else: + log.error("defaulting event first timestamp to current datetime") + event.first_timestamp = datetime.datetime.now() + + if not event.last_timestamp: + log.error("setting event last timestamp to {}".format(event.first_timestamp)) + event.last_timestamp = event.first_timestamp + + if not event.count: + event.count = 1 + + return event + + +class NamespaceWatcher(BaseThread): + """Watch events in a given namespace + + Using the watch package we can listen to event traffic in the namespace to + get an idea of what kubernetes related events surround the ceph cluster. The + thing to bear in mind is that events have a TTL enforced by the kube-apiserver + so this stream will only really show activity inside this retention window. + """ + + def __init__(self, api_client_config, namespace=None): + super(NamespaceWatcher, self).__init__() + + if api_client_config: + self.api = client.CoreV1Api(api_client_config) + else: + self.api = client.CoreV1Api() + + self.namespace = namespace + + self.events = OrderedDict() + self.lock = threading.Lock() + self.active = None + self.resource_version = None + + def fetch(self): + # clear the cache on every call to fetch + self.events.clear() + try: + resp = self.api.list_namespaced_event(self.namespace) + # TODO - Perhaps test for auth problem to be more specific in the except clause? + except: + self.active = False + self.health = "Unable to access events API (list_namespaced_event call failed)" + log.warning(self.health) + else: + self.active = True + self.resource_version = resp.metadata.resource_version + + for item in resp.items: + self.events[item.metadata.name] = clean_event(item) + log.info('Added {} events'.format(len(resp.items))) + + def run(self): + self.fetch() + func = getattr(self.api, "list_namespaced_event") + + if self.active: + log.info("Namespace event watcher started") + + + while True: + + try: + w = watch.Watch() + # execute generator to continually watch resource for changes + for item in w.stream(func, namespace=self.namespace, resource_version=self.resource_version, watch=True): + obj = item['object'] + + with self.lock: + + if item['type'] in ['ADDED', 'MODIFIED']: + self.events[obj.metadata.name] = clean_event(obj) + + elif item['type'] == 'DELETED': + del self.events[obj.metadata.name] + + # TODO test the exception for auth problem (403?) + + # Attribute error is generated when urllib3 on the system is old and doesn't have a + # read_chunked method + except AttributeError as e: + self.health = ("Error: Unable to 'watch' events API in namespace '{}' - " + "urllib3 too old? ({})".format(self.namespace, e)) + self.active = False + log.warning(self.health) + break + + except ApiException as e: + # refresh the resource_version & watcher + log.warning("API exception caught in watcher ({})".format(e)) + log.warning("Restarting namespace watcher") + self.fetch() + + except ProtocolError as e: + log.warning("Namespace watcher hit protocolerror ({}) - restarting".format(e)) + self.fetch() + + except Exception: + self.health = "{} Exception at {}".format( + sys.exc_info()[0].__name__, + datetime.strftime(datetime.now(),"%Y/%m/%d %H:%M:%S") + ) + log.exception(self.health) + self.active = False + break + + log.warning("Namespace event watcher stopped") + + +class KubernetesEvent(object): + + def __init__(self, log_entry, unique_name=True, api_client_config=None, namespace=None): + + if api_client_config: + self.api = client.CoreV1Api(api_client_config) + else: + self.api = client.CoreV1Api() + + self.namespace = namespace + + self.event_name = log_entry.event_name + self.message = log_entry.event_msg + self.event_type = log_entry.event_type + self.event_reason = log_entry.event_reason + self.unique_name = unique_name + + self.host = os.environ.get('NODE_NAME', os.environ.get('HOSTNAME', 'UNKNOWN')) + + self.api_status = 200 + self.count = 1 + self.first_timestamp = None + self.last_timestamp = None + + @property + def type(self): + """provide a type property matching a V1Event object""" + return self.event_type + + @property + def event_body(self): + if self.unique_name: + obj_meta = client.V1ObjectMeta(name="{}".format(self.event_name)) + else: + obj_meta = client.V1ObjectMeta(generate_name="{}".format(self.event_name)) + + # field_path is needed to prevent problems in the namespacewatcher when + # deleted event are received + obj_ref = client.V1ObjectReference(kind="CephCluster", + field_path='spec.containers{mgr}', + name=self.event_name, + namespace=self.namespace) + + event_source = client.V1EventSource(component="ceph-mgr", + host=self.host) + return client.V1Event( + involved_object=obj_ref, + metadata=obj_meta, + message=self.message, + count=self.count, + type=self.event_type, + reason=self.event_reason, + source=event_source, + first_timestamp=self.first_timestamp, + last_timestamp=self.last_timestamp + ) + + def write(self): + + now=datetime.now(UTC()) + + self.first_timestamp = now + self.last_timestamp = now + + try: + self.api.create_namespaced_event(self.namespace, self.event_body) + except (OSError, ProtocolError): + # unable to reach to the API server + log.error("Unable to reach API server") + self.api_status = 400 + except MaxRetryError: + # k8s config has not be defined properly + log.error("multiple attempts to connect to the API have failed") + self.api_status = 403 # Forbidden + except ApiException as e: + log.debug("event.write status:{}".format(e.status)) + self.api_status = e.status + if e.status == 409: + log.debug("attempting event update for an existing event") + # 409 means the event is there already, so read it back (v1Event object returned) + # this could happen if the event has been created, and then the k8sevent module + # disabled and reenabled - i.e. the internal event tracking no longer matches k8s + response = self.api.read_namespaced_event(self.event_name, self.namespace) + # + # response looks like + # + # {'action': None, + # 'api_version': 'v1', + # 'count': 1, + # 'event_time': None, + # 'first_timestamp': datetime.datetime(2019, 7, 18, 5, 24, 59, tzinfo=tzlocal()), + # 'involved_object': {'api_version': None, + # 'field_path': None, + # 'kind': 'CephCluster', + # 'name': 'ceph-mgr.k8sevent-module', + # 'namespace': 'rook-ceph', + # 'resource_version': None, + # 'uid': None}, + # 'kind': 'Event', + # 'last_timestamp': datetime.datetime(2019, 7, 18, 5, 24, 59, tzinfo=tzlocal()), + # 'message': 'Ceph log -> event tracking started', + # 'metadata': {'annotations': None, + # 'cluster_name': None, + # 'creation_timestamp': datetime.datetime(2019, 7, 18, 5, 24, 59, tzinfo=tzlocal()), + # 'deletion_grace_period_seconds': None, + # 'deletion_timestamp': None, + # 'finalizers': None, + # 'generate_name': 'ceph-mgr.k8sevent-module', + # 'generation': None, + # 'initializers': None, + # 'labels': None, + # 'name': 'ceph-mgr.k8sevent-module5z7kq', + # 'namespace': 'rook-ceph', + # 'owner_references': None, + # 'resource_version': '1195832', + # 'self_link': '/api/v1/namespaces/rook-ceph/events/ceph-mgr.k8sevent-module5z7kq', + # 'uid': '62fde5f1-a91c-11e9-9c80-6cde63a9debf'}, + # 'reason': 'Started', + # 'related': None, + # 'reporting_component': '', + # 'reporting_instance': '', + # 'series': None, + # 'source': {'component': 'ceph-mgr', 'host': 'minikube'}, + # 'type': 'Normal'} + + # conflict event already exists + # read it + # update : count and last_timestamp and msg + + self.count = response.count + 1 + self.first_timestamp = response.first_timestamp + try: + self.api.patch_namespaced_event(self.event_name, self.namespace, self.event_body) + except ApiException as e: + log.error("event.patch failed for {} with status code:{}".format(self.event_name, e.status)) + self.api_status = e.status + else: + log.debug("event {} patched".format(self.event_name)) + self.api_status = 200 + + else: + log.debug("event {} created successfully".format(self.event_name)) + self.api_status = 200 + + @property + def api_success(self): + return self.api_status == 200 + + def update(self, log_entry): + self.message = log_entry.event_msg + self.event_type = log_entry.event_type + self.last_timestamp = datetime.now(UTC()) + self.count += 1 + log.debug("performing event update for {}".format(self.event_name)) + + try: + self.api.patch_namespaced_event(self.event_name, self.namespace, self.event_body) + except ApiException as e: + log.error("event patch call failed: {}".format(e.status)) + if e.status == 404: + # tried to patch, but hit a 404. The event's TTL must have been reached, and + # pruned by the kube-apiserver + log.debug("event not found, so attempting to create it") + try: + self.api.create_namespaced_event(self.namespace, self.event_body) + except ApiException as e: + log.error("unable to create the event: {}".format(e.status)) + self.api_status = e.status + else: + log.debug("event {} created successfully".format(self.event_name)) + self.api_status = 200 + else: + log.debug("event {} updated".format(self.event_name)) + self.api_status = 200 + + +class EventProcessor(BaseThread): + """Handle a global queue used to track events we want to send/update to kubernetes""" + + can_run = True + + def __init__(self, config_watcher, event_retention_days, api_client_config, namespace): + super(EventProcessor, self).__init__() + + self.events = dict() + self.config_watcher = config_watcher + self.event_retention_days = event_retention_days + self.api_client_config = api_client_config + self.namespace = namespace + + def startup(self): + """Log an event to show we're active""" + + event = KubernetesEvent( + LogEntry( + source='self', + msg='Ceph log -> event tracking started', + msg_type='startup', + level='INF', + tstamp=None + ), + unique_name=False, + api_client_config=self.api_client_config, + namespace=self.namespace + ) + + event.write() + return event.api_success + + @property + def ok(self): + return self.startup() + + def prune_events(self): + log.debug("prune_events - looking for old events to remove from cache") + oldest = datetime.now(UTC()) - timedelta(days=self.event_retention_days) + local_events = dict(self.events) + + for event_name in sorted(local_events, + key = lambda name: local_events[name].last_timestamp): + event = local_events[event_name] + if event.last_timestamp >= oldest: + break + else: + # drop this event + log.debug("prune_events - removing old event : {}".format(event_name)) + del self.events[event_name] + + def process(self, log_object): + + log.debug("log entry being processed : {}".format(str(log_object))) + + event_out = False + unique_name = True + + if log_object.msg_type == 'audit': + # audit traffic : operator commands + if log_object.msg.endswith('finished'): + log.debug("K8sevents received command finished msg") + event_out = True + else: + # NO OP - ignoring 'dispatch' log records + return + + elif log_object.msg_type == 'cluster': + # cluster messages : health checks + if log_object.event_name: + event_out = True + + elif log_object.msg_type == 'config': + # configuration checker messages + event_out = True + unique_name = False + + elif log_object.msg_type == 'heartbeat': + # hourly health message summary from Ceph + event_out = True + unique_name = False + log_object.msg = str(self.config_watcher) + + else: + log.warning("K8sevents received unknown msg_type - {}".format(log_object.msg_type)) + + if event_out: + log.debug("k8sevents sending event to kubernetes") + # we don't cache non-unique events like heartbeats or config changes + if not unique_name or log_object.event_name not in self.events.keys(): + event = KubernetesEvent(log_entry=log_object, + unique_name=unique_name, + api_client_config=self.api_client_config, + namespace=self.namespace) + event.write() + log.debug("event(unique={}) creation ended : {}".format(unique_name, event.api_status)) + if event.api_success and unique_name: + self.events[log_object.event_name] = event + else: + event = self.events[log_object.event_name] + event.update(log_object) + log.debug("event update ended : {}".format(event.api_status)) + + self.prune_events() + + else: + log.debug("K8sevents ignored message : {}".format(log_object.msg)) + + def run(self): + log.info("Ceph event processing thread started, " + "event retention set to {} days".format(self.event_retention_days)) + + while True: + + try: + log_object = event_queue.get(block=False) + except queue.Empty: + pass + else: + try: + self.process(log_object) + except Exception: + self.health = "{} Exception at {}".format( + sys.exc_info()[0].__name__, + datetime.strftime(datetime.now(),"%Y/%m/%d %H:%M:%S") + ) + log.exception(self.health) + break + + if not self.can_run: + break + + time.sleep(0.5) + + log.warning("Ceph event processing thread stopped") + + +class ListDiff(object): + def __init__(self, before, after): + self.before = set(before) + self.after = set(after) + + @property + def removed(self): + return list(self.before - self.after) + + @property + def added(self): + return list(self.after - self.before) + + @property + def is_equal(self): + return self.before == self.after + + +class CephConfigWatcher(BaseThread): + """Detect configuration changes within the cluster and generate human readable events""" + + def __init__(self, mgr): + super(CephConfigWatcher, self).__init__() + self.mgr = mgr + self.server_map = dict() + self.osd_map = dict() + self.pool_map = dict() + self.service_map = dict() + + self.config_check_secs = mgr.config_check_secs + + @property + def raw_capacity(self): + # Note. if the osd's are not online the capacity field will be 0 + return sum([self.osd_map[osd]['capacity'] for osd in self.osd_map]) + + @property + def num_servers(self): + return len(self.server_map.keys()) + + @property + def num_osds(self): + return len(self.osd_map.keys()) + + @property + def num_pools(self): + return len(self.pool_map.keys()) + + def __str__(self): + s = '' + + s += "{} : {:>3} host{}, {} pool{}, {} OSDs. Raw Capacity {}B".format( + json.loads(self.mgr.get('health')['json'])['status'], + self.num_servers, + text_suffix(self.num_servers), + self.num_pools, + text_suffix(self.num_pools), + self.num_osds, + MgrModule.to_pretty_iec(self.raw_capacity)) + return s + + def fetch_servers(self): + """Return a server summary, and service summary""" + servers = self.mgr.list_servers() + server_map = dict() # host -> services + service_map = dict() # service -> host + for server_info in servers: + services = dict() + for svc in server_info['services']: + if svc.get('type') in services.keys(): + services[svc.get('type')].append(svc.get('id')) + else: + services[svc.get('type')] = list([svc.get('id')]) + # maintain the service xref map service -> host and version + service_map[(svc.get('type'), str(svc.get('id')))] = server_info.get('hostname', '') + server_map[server_info.get('hostname')] = services + + return server_map, service_map + + def fetch_pools(self): + interesting = ["type", "size", "min_size"] + # pools = [{'pool': 1, 'pool_name': 'replicapool', 'flags': 1, 'flags_names': 'hashpspool', + # 'type': 1, 'size': 3, 'min_size': 1, 'crush_rule': 1, 'object_hash': 2, 'pg_autoscale_mode': 'warn', + # 'pg_num': 100, 'pg_placement_num': 100, 'pg_placement_num_target': 100, 'pg_num_target': 100, 'pg_num_pending': 100, + # 'last_pg_merge_meta': {'ready_epoch': 0, 'last_epoch_started': 0, 'last_epoch_clean': 0, 'source_pgid': '0.0', + # 'source_version': "0'0", 'target_version': "0'0"}, 'auid': 0, 'snap_mode': 'selfmanaged', 'snap_seq': 0, 'snap_epoch': 0, + # 'pool_snaps': [], 'quota_max_bytes': 0, 'quota_max_objects': 0, 'tiers': [], 'tier_of': -1, 'read_tier': -1, + # 'write_tier': -1, 'cache_mode': 'none', 'target_max_bytes': 0, 'target_max_objects': 0, + # 'cache_target_dirty_ratio_micro': 400000, 'cache_target_dirty_high_ratio_micro': 600000, + # 'cache_target_full_ratio_micro': 800000, 'cache_min_flush_age': 0, 'cache_min_evict_age': 0, + # 'erasure_code_profile': '', 'hit_set_params': {'type': 'none'}, 'hit_set_period': 0, 'hit_set_count': 0, + # 'use_gmt_hitset': True, 'min_read_recency_for_promote': 0, 'min_write_recency_for_promote': 0, + # 'hit_set_grade_decay_rate': 0, 'hit_set_search_last_n': 0, 'grade_table': [], 'stripe_width': 0, + # 'expected_num_objects': 0, 'fast_read': False, 'options': {}, 'application_metadata': {'rbd': {}}, + # 'create_time': '2019-08-02 02:23:01.618519', 'last_change': '19', 'last_force_op_resend': '0', + # 'last_force_op_resend_prenautilus': '0', 'last_force_op_resend_preluminous': '0', 'removed_snaps': '[]'}] + pools = self.mgr.get('osd_map')['pools'] + pool_map = dict() + for pool in pools: + pool_map[pool.get('pool_name')] = {k:pool.get(k) for k in interesting} + return pool_map + + + def fetch_osd_map(self, service_map): + """Create an osd map""" + stats = self.mgr.get('osd_stats') + + osd_map = dict() + + devices = self.mgr.get('osd_map_crush')['devices'] + for dev in devices: + osd_id = str(dev['id']) + osd_map[osd_id] = dict( + deviceclass=dev.get('class'), + capacity=0, + hostname=service_map['osd', osd_id] + ) + + for osd_stat in stats['osd_stats']: + osd_id = str(osd_stat.get('osd')) + osd_map[osd_id]['capacity'] = osd_stat['statfs']['total'] + + return osd_map + + def push_events(self, changes): + """Add config change to the global queue to generate an event in kubernetes""" + log.debug("{} events will be generated") + for change in changes: + event_queue.put(change) + + def _generate_config_logentry(self, msg): + return LogEntry( + source="config", + msg_type="config", + msg=msg, + level='INF', + tstamp=None + ) + + def _check_hosts(self, server_map): + log.debug("K8sevents checking host membership") + changes = list() + servers = ListDiff(self.server_map.keys(), server_map.keys()) + if servers.is_equal: + # no hosts have been added or removed + pass + else: + # host changes detected, find out what + host_msg = "Host '{}' has been {} the cluster" + for new_server in servers.added: + changes.append(self._generate_config_logentry( + msg=host_msg.format(new_server, 'added to')) + ) + + for removed_server in servers.removed: + changes.append(self._generate_config_logentry( + msg=host_msg.format(removed_server, 'removed from')) + ) + + return changes + + def _check_osds(self,server_map, osd_map): + log.debug("K8sevents checking OSD configuration") + changes = list() + before_osds = list() + for svr in self.server_map: + before_osds.extend(self.server_map[svr].get('osd',[])) + + after_osds = list() + for svr in server_map: + after_osds.extend(server_map[svr].get('osd',[])) + + if set(before_osds) == set(after_osds): + # no change in osd id's + pass + else: + # osd changes detected + osd_msg = "Ceph OSD '{}' ({} @ {}B) has been {} host {}" + + osds = ListDiff(before_osds, after_osds) + for new_osd in osds.added: + changes.append(self._generate_config_logentry( + msg=osd_msg.format( + new_osd, + osd_map[new_osd]['deviceclass'], + MgrModule.to_pretty_iec(osd_map[new_osd]['capacity']), + 'added to', + osd_map[new_osd]['hostname'])) + ) + + for removed_osd in osds.removed: + changes.append(self._generate_config_logentry( + msg=osd_msg.format( + removed_osd, + osd_map[removed_osd]['deviceclass'], + MgrModule.to_pretty_iec(osd_map[removed_osd]['capacity']), + 'removed from', + osd_map[removed_osd]['hostname'])) + ) + + return changes + + def _check_pools(self, pool_map): + changes = list() + log.debug("K8sevents checking pool configurations") + if self.pool_map.keys() == pool_map.keys(): + # no pools added/removed + pass + else: + # Pool changes + pools = ListDiff(self.pool_map.keys(), pool_map.keys()) + pool_msg = "Pool '{}' has been {} the cluster" + for new_pool in pools.added: + changes.append(self._generate_config_logentry( + msg=pool_msg.format(new_pool, 'added to')) + ) + + for removed_pool in pools.removed: + changes.append(self._generate_config_logentry( + msg=pool_msg.format(removed_pool, 'removed from')) + ) + + # check pool configuration changes + for pool_name in pool_map: + if not self.pool_map.get(pool_name, dict()): + # pool didn't exist before so just skip the checks + continue + + if pool_map[pool_name] == self.pool_map[pool_name]: + # no changes - dicts match in key and value + continue + else: + # determine the change and add it to the change list + size_diff = pool_map[pool_name]['size'] - self.pool_map[pool_name]['size'] + if size_diff != 0: + if size_diff < 0: + msg = "Data protection level of pool '{}' reduced to {} copies".format(pool_name, + pool_map[pool_name]['size']) + level = 'WRN' + else: + msg = "Data protection level of pool '{}' increased to {} copies".format(pool_name, + pool_map[pool_name]['size']) + level = 'INF' + + changes.append(LogEntry(source="config", + msg_type="config", + msg=msg, + level=level, + tstamp=None) + ) + + if pool_map[pool_name]['min_size'] != self.pool_map[pool_name]['min_size']: + changes.append(LogEntry(source="config", + msg_type="config", + msg="Minimum acceptable number of replicas in pool '{}' has changed".format(pool_name), + level='WRN', + tstamp=None) + ) + + return changes + + def get_changes(self, server_map, osd_map, pool_map): + """Detect changes in maps between current observation and the last""" + + changes = list() + + changes.extend(self._check_hosts(server_map)) + changes.extend(self._check_osds(server_map, osd_map)) + changes.extend(self._check_pools(pool_map)) + + # FUTURE + # Could generate an event if a ceph daemon has moved hosts + # (assumes the ceph metadata host information is valid though!) + + return changes + + def run(self): + log.info("Ceph configuration watcher started, interval set to {}s".format(self.config_check_secs)) + + self.server_map, self.service_map = self.fetch_servers() + self.pool_map = self.fetch_pools() + + self.osd_map = self.fetch_osd_map(self.service_map) + + while True: + + try: + start_time = time.time() + server_map, service_map = self.fetch_servers() + pool_map = self.fetch_pools() + osd_map = self.fetch_osd_map(service_map) + + changes = self.get_changes(server_map, osd_map, pool_map) + if changes: + self.push_events(changes) + + self.osd_map = osd_map + self.pool_map = pool_map + self.server_map = server_map + self.service_map = service_map + + checks_duration = int(time.time() - start_time) + + # check that the time it took to run the checks fits within the + # interval, and if not extend the interval and emit a log message + # to show that the runtime for the checks exceeded the desired + # interval + if checks_duration > self.config_check_secs: + new_interval = self.config_check_secs * 2 + log.warning("K8sevents check interval warning. " + "Current checks took {}s, interval was {}s. " + "Increasing interval to {}s".format(int(checks_duration), + self.config_check_secs, + new_interval)) + self.config_check_secs = new_interval + + time.sleep(self.config_check_secs) + + except Exception: + self.health = "{} Exception at {}".format( + sys.exc_info()[0].__name__, + datetime.strftime(datetime.now(),"%Y/%m/%d %H:%M:%S") + ) + log.exception(self.health) + break + + log.warning("Ceph configuration watcher stopped") + + +class Module(MgrModule): + COMMANDS = [ + { + "cmd": "k8sevents status", + "desc": "Show the status of the data gathering threads", + "perm": "r" + }, + { + "cmd": "k8sevents ls", + "desc": "List all current Kuberenetes events from the Ceph namespace", + "perm": "r" + }, + { + "cmd": "k8sevents ceph", + "desc": "List Ceph events tracked & sent to the kubernetes cluster", + "perm": "r" + }, + { + "cmd": "k8sevents set-access name=key,type=CephString", + "desc": "Set kubernetes access credentials. must be cacrt or token and use -i syntax.\ne.g. ceph k8sevents set-access cacrt -i /root/ca.crt", + "perm": "rw" + }, + { + "cmd": "k8sevents set-config name=key,type=CephString name=value,type=CephString", + "desc": "Set kubernetes config paramters. must be server or namespace.\ne.g. ceph k8sevents set-config server https://localhost:30433", + "perm": "rw" + }, + { + "cmd": "k8sevents clear-config", + "desc": "Clear external kubernetes configuration settings", + "perm": "rw" + }, + ] + MODULE_OPTIONS = [ + {'name': 'config_check_secs', + 'type': 'int', + 'default': 10, + 'min': 10, + 'desc': "interval (secs) to check for cluster configuration changes"}, + {'name': 'ceph_event_retention_days', + 'type': 'int', + 'default': 7, + 'desc': "Days to hold ceph event information within local cache"} + ] + + def __init__(self, *args, **kwargs): + self.run = True + self.kubernetes_control = 'POD_NAME' in os.environ + self.event_processor = None + self.config_watcher = None + self.ns_watcher = None + self.trackers = list() + self.error_msg = None + self._api_client_config = None + self._namespace = None + + # Declare the module options we accept + self.config_check_secs = None + self.ceph_event_retention_days = None + + self.k8s_config = dict( + cacrt = None, + token = None, + server = None, + namespace = None + ) + + super(Module, self).__init__(*args, **kwargs) + + def k8s_ready(self): + """Validate the k8s_config dict + + Returns: + - bool .... indicating whether the config is ready to use + - string .. variables that need to be defined before the module will function + + """ + missing = list() + ready = True + for k in self.k8s_config: + if not self.k8s_config[k]: + missing.append(k) + ready = False + return ready, missing + + def config_notify(self): + """Apply runtime module options, and defaults from the modules KV store""" + self.log.debug("applying runtime module option settings") + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + + if not self.kubernetes_control: + # Populate the config + self.log.debug("loading config from KV store") + for k in self.k8s_config: + self.k8s_config[k] = self.get_store(k, default=None) + + def fetch_events(self, limit=None): + """Interface to expose current events to another mgr module""" + # FUTURE: Implement this to provide k8s events to the dashboard? + raise NotImplementedError + + def process_clog(self, log_message): + """Add log message to the event queue + + :param log_message: dict from the cluster log (audit/cluster channels) + """ + required_fields = ['channel', 'message', 'priority', 'stamp'] + _message_attrs = log_message.keys() + if all(_field in _message_attrs for _field in required_fields): + self.log.debug("clog entry received - adding to the queue") + if log_message.get('message').startswith('overall HEALTH'): + m_type = 'heartbeat' + else: + m_type = log_message.get('channel') + + event_queue.put( + LogEntry( + source='log', + msg_type=m_type, + msg=log_message.get('message'), + level=log_message.get('priority')[1:-1], + tstamp=log_message.get('stamp') + ) + ) + + else: + self.log.warning("Unexpected clog message format received - skipped: {}".format(log_message)) + + def notify(self, notify_type, notify_id): + """ + Called by the ceph-mgr service to notify the Python plugin + that new state is available. + + :param notify_type: string indicating what kind of notification, + such as osd_map, mon_map, fs_map, mon_status, + health, pg_summary, command, service_map + :param notify_id: string (may be empty) that optionally specifies + which entity is being notified about. With + "command" notifications this is set to the tag + ``from send_command``. + """ + + # only interested in cluster log (clog) messages for now + if notify_type == 'clog': + self.log.debug("received a clog entry from mgr.notify") + if isinstance(notify_id, dict): + # create a log object to process + self.process_clog(notify_id) + else: + self.log.warning("Expected a 'dict' log record format, received {}".format(type(notify_type))) + + def _show_events(self, events): + + max_msg_length = max([len(events[k].message) for k in events]) + fmt = "{:<20} {:<8} {:>5} {:<" + str(max_msg_length) + "} {}\n" + s = fmt.format("Last Seen (UTC)", "Type", "Count", "Message", "Event Object Name") + + for event_name in sorted(events, + key = lambda name: events[name].last_timestamp, + reverse=True): + + event = events[event_name] + + s += fmt.format( + datetime.strftime(event.last_timestamp,"%Y/%m/%d %H:%M:%S"), + str(event.type), + str(event.count), + str(event.message), + str(event_name) + ) + s += "Total : {:>3}\n".format(len(events)) + return s + + def show_events(self, events): + """Show events we're holding from the ceph namespace - most recent 1st""" + + if len(events): + return 0, "", self._show_events(events) + else: + return 0, "", "No events emitted yet, local cache is empty" + + def show_status(self): + s = "Kubernetes\n" + s += "- Hostname : {}\n".format(self.k8s_config['server']) + s += "- Namespace : {}\n".format(self._namespace) + s += "Tracker Health\n" + for t in self.trackers: + s += "- {:<20} : {}\n".format(t.__class__.__name__, t.health) + s += "Tracked Events\n" + s += "- namespace : {:>3}\n".format(len(self.ns_watcher.events)) + s += "- ceph events : {:>3}\n".format(len(self.event_processor.events)) + return 0, "", s + + def _valid_server(self, server): + # must be a valid server url format + server = server.strip() + + res = urlparse(server) + port = res.netloc.split(":")[-1] + + if res.scheme != 'https': + return False, "Server URL must use https" + + elif not res.hostname: + return False, "Invalid server URL format" + + elif res.hostname: + try: + socket.gethostbyname(res.hostname) + except socket.gaierror: + return False, "Unresolvable server URL" + + if not port.isdigit(): + return False, "Server URL must end in a port number" + + return True, "" + + def _valid_cacrt(self, cacrt_data): + """use mgr_util.verify_cacrt to validate the CA file""" + + cacrt_fname = create_temp_file("ca_file", cacrt_data) + + try: + verify_cacrt(cacrt_fname) + except ServerConfigException as e: + return False, "Invalid CA certificate: {}".format(str(e)) + else: + return True, "" + + def _valid_token(self, token_data): + """basic checks on the token""" + if not token_data: + return False, "Token file is empty" + + pattern = re.compile(r"[a-zA-Z0-9\-\.\_]+$") + if not pattern.match(token_data): + return False, "Token contains invalid characters" + + return True, "" + + def _valid_namespace(self, namespace): + # Simple check - name must be a string <= 253 in length, alphanumeric with '.' and '-' symbols + + if len(namespace) > 253: + return False, "Name too long" + if namespace.isdigit(): + return False, "Invalid name - must be alphanumeric" + + pattern = re.compile(r"^[a-z][a-z0-9\-\.]+$") + if not pattern.match(namespace): + return False, "Invalid characters in the name" + + return True, "" + + def _config_set(self, key, val): + """Attempt to validate the content, then save to KV store""" + + val = val.rstrip() # remove any trailing whitespace/newline + + try: + checker = getattr(self, "_valid_" + key) + except AttributeError: + # no checker available, just let it pass + self.log.warning("Unable to validate '{}' parameter - checker not implemented".format(key)) + valid = True + else: + valid, reason = checker(val) + + if valid: + self.set_store(key, val) + self.log.info("Updated config KV Store item: " + key) + return 0, "", "Config updated for parameter '{}'".format(key) + else: + return -22, "", "Invalid value for '{}' :{}".format(key, reason) + + def clear_config_settings(self): + for k in self.k8s_config: + self.set_store(k, None) + return 0,"","{} configuration keys removed".format(len(self.k8s_config.keys())) + + def handle_command(self, inbuf, cmd): + + access_options = ['cacrt', 'token'] + config_options = ['server', 'namespace'] + + if cmd['prefix'] == 'k8sevents clear-config': + return self.clear_config_settings() + + if cmd['prefix'] == 'k8sevents set-access': + if cmd['key'] not in access_options: + return -errno.EINVAL, "", "Unknown access option. Must be one of; {}".format(','.join(access_options)) + + if inbuf: + return self._config_set(cmd['key'], inbuf) + else: + return -errno.EINVAL, "", "Command must specify -i " + + if cmd['prefix'] == 'k8sevents set-config': + + if cmd['key'] not in config_options: + return -errno.EINVAL, "", "Unknown config option. Must be one of; {}".format(','.join(config_options)) + + return self._config_set(cmd['key'], cmd['value']) + + # At this point the command is trying to interact with k8sevents, so intercept if the configuration is + # not ready + if self.error_msg: + _msg = "k8sevents unavailable: " + self.error_msg + ready, _ = self.k8s_ready() + if not self.kubernetes_control and not ready: + _msg += "\nOnce all variables have been defined, you must restart the k8sevents module for the changes to take effect" + return -errno.ENODATA, "", _msg + + if cmd["prefix"] == "k8sevents status": + return self.show_status() + + elif cmd["prefix"] == "k8sevents ls": + return self.show_events(self.ns_watcher.events) + + elif cmd["prefix"] == "k8sevents ceph": + return self.show_events(self.event_processor.events) + + else: + raise NotImplementedError(cmd["prefix"]) + + @staticmethod + def can_run(): + """Determine whether the pre-reqs for the module are in place""" + + if not kubernetes_imported: + return False, "kubernetes python client is not available" + return True, "" + + def load_kubernetes_config(self): + """Load configuration for remote kubernetes API using KV store values + + Attempt to create an API client configuration from settings stored in + KV store. + + Returns: + client.ApiClient: kubernetes API client object + + Raises: + OSError: unable to create the cacrt file + """ + + # the kubernetes setting Configuration.ssl_ca_cert is a path, so we have to create a + # temporary file containing the cert for the client to load from + try: + ca_crt_file = create_temp_file('cacrt', self.k8s_config['cacrt']) + except OSError as e: + self.log.error("Unable to create file to hold cacrt: {}".format(str(e))) + raise OSError(str(e)) + else: + self.log.debug("CA certificate from KV store, written to {}".format(ca_crt_file)) + + configuration = client.Configuration() + configuration.host = self.k8s_config['server'] + configuration.ssl_ca_cert = ca_crt_file + configuration.api_key = { "authorization": "Bearer " + self.k8s_config['token'] } + api_client = client.ApiClient(configuration) + self.log.info("API client created for remote kubernetes access using cacrt and token from KV store") + + return api_client + + def serve(self): + # apply options set by CLI to this module + self.config_notify() + + if not kubernetes_imported: + self.error_msg = "Unable to start : python kubernetes package is missing" + else: + if self.kubernetes_control: + # running under rook-ceph + config.load_incluster_config() + self.k8s_config['server'] = "https://{}:{}".format(os.environ.get('KUBERNETES_SERVICE_HOST', 'UNKNOWN'), + os.environ.get('KUBERNETES_SERVICE_PORT_HTTPS', 'UNKNOWN')) + self._api_client_config = None + self._namespace = os.environ.get("POD_NAMESPACE", "rook-ceph") + else: + # running outside of rook-ceph, so we need additional settings to tell us + # how to connect to the kubernetes cluster + ready, errors = self.k8s_ready() + if not ready: + self.error_msg = "Required settings missing. Use ceph k8sevents set-access | set-config to define {}".format(",".join(errors)) + else: + try: + self._api_client_config = self.load_kubernetes_config() + except OSError as e: + self.error_msg = str(e) + else: + self._namespace = self.k8s_config['namespace'] + self.log.info("k8sevents configuration loaded from KV store") + + if self.error_msg: + self.log.error(self.error_msg) + return + + # All checks have passed + self.config_watcher = CephConfigWatcher(self) + + self.event_processor = EventProcessor(self.config_watcher, + self.ceph_event_retention_days, + self._api_client_config, + self._namespace) + + self.ns_watcher = NamespaceWatcher(api_client_config=self._api_client_config, + namespace=self._namespace) + + if self.event_processor.ok: + log.info("Ceph Log processor thread starting") + self.event_processor.start() # start log consumer thread + log.info("Ceph config watcher thread starting") + self.config_watcher.start() + log.info("Rook-ceph namespace events watcher starting") + self.ns_watcher.start() + + self.trackers.extend([self.event_processor, self.config_watcher, self.ns_watcher]) + + while True: + # stay alive + time.sleep(1) + + trackers = self.trackers + for t in trackers: + if not t.is_alive() and not t.reported: + log.error("K8sevents tracker thread '{}' stopped: {}".format(t.__class__.__name__, t.health)) + t.reported = True + + else: + self.error_msg = "Unable to access kubernetes API. Is it accessible? Are RBAC rules for our token valid?" + log.warning(self.error_msg) + log.warning("k8sevents module exiting") + self.run = False + + def shutdown(self): + self.run = False + log.info("Shutting down k8sevents module") + self.event_processor.can_run = False + + if self._rados: + self._rados.shutdown() diff --git a/src/pybind/mgr/k8sevents/rbac_sample.yaml b/src/pybind/mgr/k8sevents/rbac_sample.yaml new file mode 100644 index 00000000..56392202 --- /dev/null +++ b/src/pybind/mgr/k8sevents/rbac_sample.yaml @@ -0,0 +1,45 @@ +--- +# Create a namespace to receive our test events +apiVersion: v1 +kind: Namespace +metadata: + name: ceph +--- +# Define the access rules to open the events API to k8sevents +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: ceph-mgr-events-rules +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list + - watch + - patch + - get +--- +# Define a service account to associate with our event stream +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ceph-mgr + namespace: ceph +--- +# Allow the ceph-mgr service account access to the events api +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: ceph-mgr + namespace: ceph +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ceph-mgr-events-rules +subjects: +- kind: ServiceAccount + name: ceph-mgr + namespace: ceph diff --git a/src/pybind/mgr/localpool/__init__.py b/src/pybind/mgr/localpool/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/localpool/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/localpool/module.py b/src/pybind/mgr/localpool/module.py new file mode 100644 index 00000000..23ffeaa1 --- /dev/null +++ b/src/pybind/mgr/localpool/module.py @@ -0,0 +1,136 @@ +from mgr_module import MgrModule, CommandResult +import json +import threading + +class Module(MgrModule): + + MODULE_OPTIONS = [ + { + 'name': 'subtree', + 'type': 'str', + 'default': 'rack', + 'desc': 'CRUSH level for which to create a local pool', + 'runtime': True, + }, + { + 'name': 'failure_domain', + 'type': 'str', + 'default': 'host', + 'desc': 'failure domain for any created local pool', + 'runtime': True, + }, + { + 'name': 'min_size', + 'type': 'int', + 'desc': 'default min_size for any created local pool', + 'runtime': True, + }, + { + 'name': 'num_rep', + 'type': 'int', + 'default': 3, + 'desc': 'default replica count for any created local pool', + 'runtime': True, + }, + { + 'name': 'pg_num', + 'type': 'int', + 'default': 128, + 'desc': 'default pg_num for any created local pool', + 'runtime': True, + }, + { + 'name': 'prefix', + 'type': 'str', + 'default': '', + 'desc': 'name prefix for any created local pool', + 'runtime': True, + }, + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.serve_event = threading.Event() + + def notify(self, notify_type, notify_id): + if notify_type == 'osd_map': + self.handle_osd_map() + + def handle_osd_map(self): + """ + Check pools on each OSDMap change + """ + subtree_type = self.get_module_option('subtree') + failure_domain = self.get_module_option('failure_domain') + pg_num = self.get_module_option('pg_num') + num_rep = self.get_module_option('num_rep') + min_size = self.get_module_option('min_size') + prefix = self.get_module_option('prefix') or 'by-' + subtree_type + '-' + + osdmap = self.get("osd_map") + lpools = [] + for pool in osdmap['pools']: + if pool['pool_name'].find(prefix) == 0: + lpools.append(pool['pool_name']) + + self.log.debug('localized pools = %s', lpools) + subtrees = [] + tree = self.get('osd_map_tree') + for node in tree['nodes']: + if node['type'] == subtree_type: + subtrees.append(node['name']) + pool_name = prefix + node['name'] + if pool_name not in lpools: + self.log.info('Creating localized pool %s', pool_name) + # + result = CommandResult("") + self.send_command(result, "mon", "", json.dumps({ + "prefix": "osd crush rule create-replicated", + "format": "json", + "name": pool_name, + "root": node['name'], + "type": failure_domain, + }), "") + r, outb, outs = result.wait() + + result = CommandResult("") + self.send_command(result, "mon", "", json.dumps({ + "prefix": "osd pool create", + "format": "json", + "pool": pool_name, + 'rule': pool_name, + "pool_type": 'replicated', + 'pg_num': pg_num, + }), "") + r, outb, outs = result.wait() + + result = CommandResult("") + self.send_command(result, "mon", "", json.dumps({ + "prefix": "osd pool set", + "format": "json", + "pool": pool_name, + 'var': 'size', + "val": str(num_rep), + }), "") + r, outb, outs = result.wait() + + if min_size: + result = CommandResult("") + self.send_command(result, "mon", "", json.dumps({ + "prefix": "osd pool set", + "format": "json", + "pool": pool_name, + 'var': 'min_size', + "val": str(min_size), + }), "") + r, outb, outs = result.wait() + + # TODO remove pools for hosts that don't exist? + + def serve(self): + self.handle_osd_map() + self.serve_event.wait() + self.serve_event.clear() + + def shutdown(self): + self.serve_event.set() diff --git a/src/pybind/mgr/mgr_module.py b/src/pybind/mgr/mgr_module.py new file mode 100644 index 00000000..79cbc950 --- /dev/null +++ b/src/pybind/mgr/mgr_module.py @@ -0,0 +1,1504 @@ +import ceph_module # noqa + +try: + from typing import Set, Tuple, Iterator, Any +except ImportError: + # just for type checking + pass +import errno +import logging +import json +import six +import threading +from collections import defaultdict, namedtuple +import rados +import re +import time + +ERROR_MSG_EMPTY_INPUT_FILE = 'Empty content: please add a password/secret to the file.' +ERROR_MSG_NO_INPUT_FILE = 'Please specify the file containing the password/secret with "-i" option.' +# Full list of strings in "osd_types.cc:pg_state_string()" +PG_STATES = [ + "active", + "clean", + "down", + "recovery_unfound", + "backfill_unfound", + "scrubbing", + "degraded", + "inconsistent", + "peering", + "repair", + "recovering", + "forced_recovery", + "backfill_wait", + "incomplete", + "stale", + "remapped", + "deep", + "backfilling", + "forced_backfill", + "backfill_toofull", + "recovery_wait", + "recovery_toofull", + "undersized", + "activating", + "peered", + "snaptrim", + "snaptrim_wait", + "snaptrim_error", + "creating", + "unknown", + "premerge", + "failed_repair", +] + + +class CPlusPlusHandler(logging.Handler): + def __init__(self, module_inst): + super(CPlusPlusHandler, self).__init__() + self._module = module_inst + + def emit(self, record): + if record.levelno <= logging.DEBUG: + ceph_level = 20 + elif record.levelno <= logging.INFO: + ceph_level = 4 + elif record.levelno <= logging.WARNING: + ceph_level = 1 + else: + ceph_level = 0 + + self._module._ceph_log(ceph_level, self.format(record)) + + +def configure_logger(module_inst, module_name): + """ + Create and configure the logger with the specified module. + + A handler will be added to the root logger which will redirect + the messages from all loggers (incl. 3rd party libraries) to the + Ceph log. + + :param module_inst: The module instance. + :type module_inst: instance + :param module_name: The module name. + :type module_name: str + :return: Return the logger with the specified name. + """ + logger = logging.getLogger(module_name) + # Don't filter any logs at the python level, leave it to C++. + # FIXME: We should learn the log level from C++ land, and then + # avoid calling the C++ level log when we know a message + # is of an insufficient level to be ultimately output. + logger.setLevel(logging.DEBUG) # Don't use NOTSET + + root_logger = logging.getLogger() + # Add handler to the root logger, thus this module and all + # 3rd party libraries will log their messages to the Ceph log. + root_logger.addHandler(CPlusPlusHandler(module_inst)) + # Set the log level to ``ERROR`` to ensure that we only get + # those message from 3rd party libraries (only effective if + # they use the default log level ``NOTSET``). + # Check https://docs.python.org/3/library/logging.html#logging.Logger.setLevel + # for more information about how the effective log level is + # determined. + root_logger.setLevel(logging.ERROR) + + return logger + + +def unconfigure_logger(module_name=None): + """ + :param module_name: The module name. Defaults to ``None``. + :type module_name: str or None + """ + logger = logging.getLogger(module_name) + rm_handlers = [ + h for h in logger.handlers if isinstance(h, CPlusPlusHandler)] + for h in rm_handlers: + logger.removeHandler(h) + + +class CommandResult(object): + """ + Use with MgrModule.send_command + """ + + def __init__(self, tag=None): + self.ev = threading.Event() + self.outs = "" + self.outb = "" + self.r = 0 + + # This is just a convenience for notifications from + # C++ land, to avoid passing addresses around in messages. + self.tag = tag if tag else "" + + def complete(self, r, outb, outs): + self.r = r + self.outb = outb + self.outs = outs + self.ev.set() + + def wait(self): + self.ev.wait() + return self.r, self.outb, self.outs + + +class HandleCommandResult(namedtuple('HandleCommandResult', ['retval', 'stdout', 'stderr'])): + def __new__(cls, retval=0, stdout="", stderr=""): + """ + Tuple containing the result of `handle_command()` + + Only write to stderr if there is an error, or in extraordinary circumstances + + Avoid having `ceph foo bar` commands say "did foo bar" on success unless there + is critical information to include there. + + Everything programmatically consumable should be put on stdout + + :param retval: return code. E.g. 0 or -errno.EINVAL + :type retval: int + :param stdout: data of this result. + :type stdout: str + :param stderr: Typically used for error messages. + :type stderr: str + """ + return super(HandleCommandResult, cls).__new__(cls, retval, stdout, stderr) + + +class MonCommandFailed(RuntimeError): pass + + +class OSDMap(ceph_module.BasePyOSDMap): + def get_epoch(self): + return self._get_epoch() + + def get_crush_version(self): + return self._get_crush_version() + + def dump(self): + return self._dump() + + def get_pools(self): + # FIXME: efficient implementation + d = self._dump() + return dict([(p['pool'], p) for p in d['pools']]) + + def get_pools_by_name(self): + # FIXME: efficient implementation + d = self._dump() + return dict([(p['pool_name'], p) for p in d['pools']]) + + def new_incremental(self): + return self._new_incremental() + + def apply_incremental(self, inc): + return self._apply_incremental(inc) + + def get_crush(self): + return self._get_crush() + + def get_pools_by_take(self, take): + return self._get_pools_by_take(take).get('pools', []) + + def calc_pg_upmaps(self, inc, + max_deviation=.01, max_iterations=10, pools=None): + if pools is None: + pools = [] + return self._calc_pg_upmaps( + inc, + max_deviation, max_iterations, pools) + + def map_pool_pgs_up(self, poolid): + return self._map_pool_pgs_up(poolid) + + def pg_to_up_acting_osds(self, pool_id, ps): + return self._pg_to_up_acting_osds(pool_id, ps) + + def pool_raw_used_rate(self, pool_id): + return self._pool_raw_used_rate(pool_id) + + def get_ec_profile(self, name): + # FIXME: efficient implementation + d = self._dump() + return d['erasure_code_profiles'].get(name, None) + + +class OSDMapIncremental(ceph_module.BasePyOSDMapIncremental): + def get_epoch(self): + return self._get_epoch() + + def dump(self): + return self._dump() + + def set_osd_reweights(self, weightmap): + """ + weightmap is a dict, int to float. e.g. { 0: .9, 1: 1.0, 3: .997 } + """ + return self._set_osd_reweights(weightmap) + + def set_crush_compat_weight_set_weights(self, weightmap): + """ + weightmap is a dict, int to float. devices only. e.g., + { 0: 3.4, 1: 3.3, 2: 3.334 } + """ + return self._set_crush_compat_weight_set_weights(weightmap) + + +class CRUSHMap(ceph_module.BasePyCRUSH): + ITEM_NONE = 0x7fffffff + DEFAULT_CHOOSE_ARGS = '-1' + + def dump(self): + return self._dump() + + def get_item_weight(self, item): + return self._get_item_weight(item) + + def get_item_name(self, item): + return self._get_item_name(item) + + def find_takes(self): + return self._find_takes().get('takes', []) + + def get_take_weight_osd_map(self, root): + uglymap = self._get_take_weight_osd_map(root) + return {int(k): v for k, v in six.iteritems(uglymap.get('weights', {}))} + + @staticmethod + def have_default_choose_args(dump): + return CRUSHMap.DEFAULT_CHOOSE_ARGS in dump.get('choose_args', {}) + + @staticmethod + def get_default_choose_args(dump): + return dump.get('choose_args').get(CRUSHMap.DEFAULT_CHOOSE_ARGS, []) + + def get_rule(self, rule_name): + # TODO efficient implementation + for rule in self.dump()['rules']: + if rule_name == rule['rule_name']: + return rule + + return None + + def get_rule_by_id(self, rule_id): + for rule in self.dump()['rules']: + if rule['rule_id'] == rule_id: + return rule + + return None + + def get_rule_root(self, rule_name): + rule = self.get_rule(rule_name) + if rule is None: + return None + + try: + first_take = [s for s in rule['steps'] if s['op'] == 'take'][0] + except IndexError: + self.log.warn("CRUSH rule '{0}' has no 'take' step".format( + rule_name)) + return None + else: + return first_take['item'] + + def get_osds_under(self, root_id): + # TODO don't abuse dump like this + d = self.dump() + buckets = dict([(b['id'], b) for b in d['buckets']]) + + osd_list = [] + + def accumulate(b): + for item in b['items']: + if item['id'] >= 0: + osd_list.append(item['id']) + else: + try: + accumulate(buckets[item['id']]) + except KeyError: + pass + + accumulate(buckets[root_id]) + + return osd_list + + def device_class_counts(self): + result = defaultdict(int) + # TODO don't abuse dump like this + d = self.dump() + for device in d['devices']: + cls = device.get('class', None) + result[cls] += 1 + + return dict(result) + + +class CLICommand(object): + COMMANDS = {} + + def __init__(self, prefix, args="", desc="", perm="rw"): + self.prefix = prefix + self.args = args + self.args_dict = {} + self.desc = desc + self.perm = perm + self.func = None + self._parse_args() + + def _parse_args(self): + if not self.args: + return + args = self.args.split(" ") + for arg in args: + arg_desc = arg.strip().split(",") + arg_d = {} + for kv in arg_desc: + k, v = kv.split("=") + if k != "name": + arg_d[k] = v + else: + self.args_dict[v] = arg_d + + def __call__(self, func): + self.func = func + self.COMMANDS[self.prefix] = self + return self.func + + def call(self, mgr, cmd_dict, inbuf): + kwargs = {} + for a, d in self.args_dict.items(): + if 'req' in d and d['req'] == "false" and a not in cmd_dict: + continue + kwargs[a.replace("-", "_")] = cmd_dict[a] + if inbuf: + kwargs['inbuf'] = inbuf + return self.func(mgr, **kwargs) + + @classmethod + def dump_cmd_list(cls): + return [{ + 'cmd': '{} {}'.format(cmd.prefix, cmd.args), + 'desc': cmd.desc, + 'perm': cmd.perm + } for _, cmd in cls.COMMANDS.items()] + + +def CLIReadCommand(prefix, args="", desc=""): + return CLICommand(prefix, args, desc, "r") + + +def CLIWriteCommand(prefix, args="", desc=""): + return CLICommand(prefix, args, desc, "w") + + +def CLICheckNonemptyFileInput(func): + def check(*args, **kwargs): + if not 'inbuf' in kwargs: + return -errno.EINVAL, '', ERROR_MSG_NO_INPUT_FILE + if isinstance(kwargs['inbuf'], str): + # Delete new line separator at EOF (it may have been added by a text editor). + kwargs['inbuf'] = kwargs['inbuf'].rstrip('\r\n').rstrip('\n') + if not kwargs['inbuf']: + return -errno.EINVAL, '', ERROR_MSG_EMPTY_INPUT_FILE + return func(*args, **kwargs) + return check + + +def _get_localized_key(prefix, key): + return '{}/{}'.format(prefix, key) + + +class Option(dict): + """ + Helper class to declare options for MODULE_OPTIONS list. + + Caveat: it uses argument names matching Python keywords (type, min, max), + so any further processing should happen in a separate method. + + TODO: type validation. + """ + + def __init__( + self, name, + default=None, + type='str', + desc=None, longdesc=None, + min=None, max=None, + enum_allowed=None, + see_also=None, + tags=None, + runtime=False, + ): + super(Option, self).__init__( + (k, v) for k, v in vars().items() + if k != 'self' and v is not None) + +class Command(dict): + """ + Helper class to declare options for COMMANDS list. + + It also allows to specify prefix and args separately, as well as storing a + handler callable. + + Usage: + >>> Command(prefix="example", + ... args="name=arg,type=CephInt", + ... perm='w', + ... desc="Blah") + {'poll': False, 'cmd': 'example name=arg,type=CephInt', 'perm': 'w', 'desc': 'Blah'} + """ + + def __init__( + self, + prefix, + args=None, + perm="rw", + desc=None, + poll=False, + handler=None + ): + super(Command, self).__init__( + cmd=prefix + (' ' + args if args else ''), + perm=perm, + desc=desc, + poll=poll) + self.prefix = prefix + self.args = args + self.handler = handler + + def register(self, instance=False): + """ + Register a CLICommand handler. It allows an instance to register bound + methods. In that case, the mgr instance is not passed, and it's expected + to be available in the class instance. + It also uses HandleCommandResult helper to return a wrapped a tuple of 3 + items. + """ + return CLICommand( + prefix=self.prefix, + args=self.args, + desc=self['desc'], + perm=self['perm'] + )( + func=lambda mgr, *args, **kwargs: HandleCommandResult(*self.handler( + *((instance or mgr,) + args), **kwargs)) + ) + + +class MgrStandbyModule(ceph_module.BaseMgrStandbyModule): + """ + Standby modules only implement a serve and shutdown method, they + are not permitted to implement commands and they do not receive + any notifications. + + They only have access to the mgrmap (for accessing service URI info + from their active peer), and to configuration settings (read only). + """ + + MODULE_OPTIONS = [] + MODULE_OPTION_DEFAULTS = {} + + def __init__(self, module_name, capsule): + super(MgrStandbyModule, self).__init__(capsule) + self.module_name = module_name + self._logger = configure_logger(self, module_name) + # see also MgrModule.__init__() + for o in self.MODULE_OPTIONS: + if 'default' in o: + if 'type' in o: + self.MODULE_OPTION_DEFAULTS[o['name']] = o['default'] + else: + self.MODULE_OPTION_DEFAULTS[o['name']] = str(o['default']) + + def __del__(self): + unconfigure_logger() + + @property + def log(self): + return self._logger + + def serve(self): + """ + The serve method is mandatory for standby modules. + :return: + """ + raise NotImplementedError() + + def get_mgr_id(self): + return self._ceph_get_mgr_id() + + def get_module_option(self, key, default=None): + """ + Retrieve the value of a persistent configuration setting + + :param str key: + :param default: the default value of the config if it is not found + :return: str + """ + r = self._ceph_get_module_option(key) + if r is None: + return self.MODULE_OPTION_DEFAULTS.get(key, default) + else: + return r + + def get_ceph_option(self, key): + return self._ceph_get_option(key) + + def get_store(self, key): + """ + Retrieve the value of a persistent KV store entry + + :param key: String + :return: Byte string or None + """ + return self._ceph_get_store(key) + + def get_active_uri(self): + return self._ceph_get_active_uri() + + def get_localized_module_option(self, key, default=None): + r = self._ceph_get_module_option(key, self.get_mgr_id()) + if r is None: + return self.MODULE_OPTION_DEFAULTS.get(key, default) + else: + return r + + +class MgrModule(ceph_module.BaseMgrModule): + COMMANDS = [] + MODULE_OPTIONS = [] + MODULE_OPTION_DEFAULTS = {} + + # Priority definitions for perf counters + PRIO_CRITICAL = 10 + PRIO_INTERESTING = 8 + PRIO_USEFUL = 5 + PRIO_UNINTERESTING = 2 + PRIO_DEBUGONLY = 0 + + # counter value types + PERFCOUNTER_TIME = 1 + PERFCOUNTER_U64 = 2 + + # counter types + PERFCOUNTER_LONGRUNAVG = 4 + PERFCOUNTER_COUNTER = 8 + PERFCOUNTER_HISTOGRAM = 0x10 + PERFCOUNTER_TYPE_MASK = ~3 + + # units supported + BYTES = 0 + NONE = 1 + + # Cluster log priorities + CLUSTER_LOG_PRIO_DEBUG = 0 + CLUSTER_LOG_PRIO_INFO = 1 + CLUSTER_LOG_PRIO_SEC = 2 + CLUSTER_LOG_PRIO_WARN = 3 + CLUSTER_LOG_PRIO_ERROR = 4 + + def __init__(self, module_name, py_modules_ptr, this_ptr): + self.module_name = module_name + + # If we're taking over from a standby module, let's make sure + # its logger was unconfigured before we hook ours up + unconfigure_logger() + self._logger = configure_logger(self, module_name) + + super(MgrModule, self).__init__(py_modules_ptr, this_ptr) + + self._version = self._ceph_get_version() + + self._perf_schema_cache = None + + # Keep a librados instance for those that need it. + self._rados = None + + for o in self.MODULE_OPTIONS: + if 'default' in o: + if 'type' in o: + # we'll assume the declared type matches the + # supplied default value's type. + self.MODULE_OPTION_DEFAULTS[o['name']] = o['default'] + else: + # module not declaring it's type, so normalize the + # default value to be a string for consistent behavior + # with default and user-supplied option values. + self.MODULE_OPTION_DEFAULTS[o['name']] = str(o['default']) + + def __del__(self): + unconfigure_logger() + + @classmethod + def _register_commands(cls): + cls.COMMANDS.extend(CLICommand.dump_cmd_list()) + + @property + def log(self): + return self._logger + + def cluster_log(self, channel, priority, message): + """ + :param channel: The log channel. This can be 'cluster', 'audit', ... + :type channel: str + :param priority: The log message priority. This can be + CLUSTER_LOG_PRIO_DEBUG, CLUSTER_LOG_PRIO_INFO, + CLUSTER_LOG_PRIO_SEC, CLUSTER_LOG_PRIO_WARN or + CLUSTER_LOG_PRIO_ERROR. + :type priority: int + :param message: The message to log. + :type message: str + """ + self._ceph_cluster_log(channel, priority, message) + + @property + def version(self): + return self._version + + @property + def release_name(self): + """ + Get the release name of the Ceph version, e.g. 'nautilus' or 'octopus'. + :return: Returns the release name of the Ceph version in lower case. + :rtype: str + """ + return self._ceph_get_release_name() + + def get_context(self): + """ + :return: a Python capsule containing a C++ CephContext pointer + """ + return self._ceph_get_context() + + def notify(self, notify_type, notify_id): + """ + Called by the ceph-mgr service to notify the Python plugin + that new state is available. + + :param notify_type: string indicating what kind of notification, + such as osd_map, mon_map, fs_map, mon_status, + health, pg_summary, command, service_map + :param notify_id: string (may be empty) that optionally specifies + which entity is being notified about. With + "command" notifications this is set to the tag + ``from send_command``. + """ + pass + + def config_notify(self): + """ + Called by the ceph-mgr service to notify the Python plugin + that the configuration may have changed. Modules will want to + refresh any configuration values stored in config variables. + """ + pass + + def serve(self): + """ + Called by the ceph-mgr service to start any server that + is provided by this Python plugin. The implementation + of this function should block until ``shutdown`` is called. + + You *must* implement ``shutdown`` if you implement ``serve`` + """ + pass + + def shutdown(self): + """ + Called by the ceph-mgr service to request that this + module drop out of its serve() function. You do not + need to implement this if you do not implement serve() + + :return: None + """ + if self._rados: + self._rados.shutdown() + + def get(self, data_name): + """ + Called by the plugin to fetch named cluster-wide objects from ceph-mgr. + + :param str data_name: Valid things to fetch are osd_crush_map_text, + osd_map, osd_map_tree, osd_map_crush, config, mon_map, fs_map, + osd_metadata, pg_summary, io_rate, pg_dump, df, osd_stats, + health, mon_status, devices, device , pg_stats, + pool_stats, pg_ready, osd_ping_times. + + Note: + All these structures have their own JSON representations: experiment + or look at the C++ ``dump()`` methods to learn about them. + """ + return self._ceph_get(data_name) + + def _stattype_to_str(self, stattype): + + typeonly = stattype & self.PERFCOUNTER_TYPE_MASK + if typeonly == 0: + return 'gauge' + if typeonly == self.PERFCOUNTER_LONGRUNAVG: + # this lie matches the DaemonState decoding: only val, no counts + return 'counter' + if typeonly == self.PERFCOUNTER_COUNTER: + return 'counter' + if typeonly == self.PERFCOUNTER_HISTOGRAM: + return 'histogram' + + return '' + + def _perfpath_to_path_labels(self, daemon, path): + label_names = ("ceph_daemon",) + labels = (daemon,) + + if daemon.startswith('rbd-mirror.'): + match = re.match( + r'^rbd_mirror_([^/]+)/(?:(?:([^/]+)/)?)(.*)\.(replay(?:_bytes|_latency)?)$', + path + ) + if match: + path = 'rbd_mirror_' + match.group(4) + pool = match.group(1) + namespace = match.group(2) or '' + image = match.group(3) + label_names += ('pool', 'namespace', 'image') + labels += (pool, namespace, image) + + return path, label_names, labels, + + def _perfvalue_to_value(self, stattype, value): + if stattype & self.PERFCOUNTER_TIME: + # Convert from ns to seconds + return value / 1000000000.0 + else: + return value + + def _unit_to_str(self, unit): + if unit == self.NONE: + return "/s" + elif unit == self.BYTES: + return "B/s" + + @staticmethod + def to_pretty_iec(n): + for bits, suffix in [(60, 'Ei'), (50, 'Pi'), (40, 'Ti'), (30, 'Gi'), + (20, 'Mi'), (10, 'Ki')]: + if n > 10 << bits: + return str(n >> bits) + ' ' + suffix + return str(n) + ' ' + + @staticmethod + def get_pretty_row(elems, width): + """ + Takes an array of elements and returns a string with those elements + formatted as a table row. Useful for polling modules. + + :param elems: the elements to be printed + :param width: the width of the terminal + """ + n = len(elems) + column_width = int(width / n) + + ret = '|' + for elem in elems: + ret += '{0:>{w}} |'.format(elem, w=column_width - 2) + + return ret + + def get_pretty_header(self, elems, width): + """ + Like ``get_pretty_row`` but adds dashes, to be used as a table title. + + :param elems: the elements to be printed + :param width: the width of the terminal + """ + n = len(elems) + column_width = int(width / n) + + # dash line + ret = '+' + for i in range(0, n): + ret += '-' * (column_width - 1) + '+' + ret += '\n' + + # title + ret += self.get_pretty_row(elems, width) + ret += '\n' + + # dash line + ret += '+' + for i in range(0, n): + ret += '-' * (column_width - 1) + '+' + ret += '\n' + + return ret + + def get_server(self, hostname): + """ + Called by the plugin to fetch metadata about a particular hostname from + ceph-mgr. + + This is information that ceph-mgr has gleaned from the daemon metadata + reported by daemons running on a particular server. + + :param hostname: a hostname + """ + return self._ceph_get_server(hostname) + + def get_perf_schema(self, svc_type, svc_name): + """ + Called by the plugin to fetch perf counter schema info. + svc_name can be nullptr, as can svc_type, in which case + they are wildcards + + :param str svc_type: + :param str svc_name: + :return: list of dicts describing the counters requested + """ + return self._ceph_get_perf_schema(svc_type, svc_name) + + def get_counter(self, svc_type, svc_name, path): + """ + Called by the plugin to fetch the latest performance counter data for a + particular counter on a particular service. + + :param str svc_type: + :param str svc_name: + :param str path: a period-separated concatenation of the subsystem and the + counter name, for example "mds.inodes". + :return: A list of two-tuples of (timestamp, value) is returned. This may be + empty if no data is available. + """ + return self._ceph_get_counter(svc_type, svc_name, path) + + def get_latest_counter(self, svc_type, svc_name, path): + """ + Called by the plugin to fetch only the newest performance counter data + pointfor a particular counter on a particular service. + + :param str svc_type: + :param str svc_name: + :param str path: a period-separated concatenation of the subsystem and the + counter name, for example "mds.inodes". + :return: A list of two-tuples of (timestamp, value) is returned. This may be + empty if no data is available. + """ + return self._ceph_get_latest_counter(svc_type, svc_name, path) + + def list_servers(self): + """ + Like ``get_server``, but gives information about all servers (i.e. all + unique hostnames that have been mentioned in daemon metadata) + + :return: a list of information about all servers + :rtype: list + """ + return self._ceph_get_server(None) + + def get_metadata(self, svc_type, svc_id, default=None): + """ + Fetch the daemon metadata for a particular service. + + ceph-mgr fetches metadata asynchronously, so are windows of time during + addition/removal of services where the metadata is not available to + modules. ``None`` is returned if no metadata is available. + + :param str svc_type: service type (e.g., 'mds', 'osd', 'mon') + :param str svc_id: service id. convert OSD integer IDs to strings when + calling this + :rtype: dict, or None if no metadata found + """ + metadata = self._ceph_get_metadata(svc_type, svc_id) + if metadata is None: + return default + return metadata + + def get_daemon_status(self, svc_type, svc_id): + """ + Fetch the latest status for a particular service daemon. + + This method may return ``None`` if no status information is + available, for example because the daemon hasn't fully started yet. + + :param svc_type: string (e.g., 'rgw') + :param svc_id: string + :return: dict, or None if the service is not found + """ + return self._ceph_get_daemon_status(svc_type, svc_id) + + def check_mon_command(self, cmd_dict, inbuf=None): + """ + Wrapper around :func:`~mgr_module.MgrModule.mon_command`, but raises, + if ``retval != 0``. + """ + + r = HandleCommandResult(*self.mon_command(cmd_dict, inbuf)) + if r.retval: + raise MonCommandFailed( + '{} failed: {} retval: {}'.format(cmd_dict["prefix"], r.stderr, r.retval) + ) + return r + + def mon_command(self, cmd_dict, inbuf=None): + """ + Helper for modules that do simple, synchronous mon command + execution. + + See send_command for general case. + + :return: status int, out std, err str + """ + + t1 = time.time() + result = CommandResult() + self.send_command(result, "mon", "", json.dumps(cmd_dict), "", inbuf) + r = result.wait() + t2 = time.time() + + self.log.debug("mon_command: '{0}' -> {1} in {2:.3f}s".format( + cmd_dict['prefix'], r[0], t2 - t1 + )) + + return r + + def send_command( + self, + result, + svc_type, + svc_id, + command, + tag, + inbuf=None): + """ + Called by the plugin to send a command to the mon + cluster. + + :param CommandResult result: an instance of the ``CommandResult`` + class, defined in the same module as MgrModule. This acts as a + completion and stores the output of the command. Use + ``CommandResult.wait()`` if you want to block on completion. + :param str svc_type: + :param str svc_id: + :param str command: a JSON-serialized command. This uses the same + format as the ceph command line, which is a dictionary of command + arguments, with the extra ``prefix`` key containing the command + name itself. Consult MonCommands.h for available commands and + their expected arguments. + :param str tag: used for nonblocking operation: when a command + completes, the ``notify()`` callback on the MgrModule instance is + triggered, with notify_type set to "command", and notify_id set to + the tag of the command. + :param str inbuf: input buffer for sending additional data. + """ + self._ceph_send_command(result, svc_type, svc_id, command, tag, inbuf) + + def set_health_checks(self, checks): + """ + Set the module's current map of health checks. Argument is a + dict of check names to info, in this form: + + :: + + { + 'CHECK_FOO': { + 'severity': 'warning', # or 'error' + 'summary': 'summary string', + 'detail': [ 'list', 'of', 'detail', 'strings' ], + }, + 'CHECK_BAR': { + 'severity': 'error', + 'summary': 'bars are bad', + 'detail': [ 'too hard' ], + }, + } + + :param list: dict of health check dicts + """ + self._ceph_set_health_checks(checks) + + def _handle_command(self, inbuf, cmd): + if cmd['prefix'] not in CLICommand.COMMANDS: + return self.handle_command(inbuf, cmd) + return CLICommand.COMMANDS[cmd['prefix']].call(self, cmd, inbuf) + + def handle_command(self, inbuf, cmd): + """ + Called by ceph-mgr to request the plugin to handle one + of the commands that it declared in self.COMMANDS + + Return a status code, an output buffer, and an + output string. The output buffer is for data results, + the output string is for informative text. + + :param inbuf: content of any "-i " supplied to ceph cli + :type inbuf: str + :param cmd: from Ceph's cmdmap_t + :type cmd: dict + + :return: HandleCommandResult or a 3-tuple of (int, str, str) + """ + + # Should never get called if they didn't declare + # any ``COMMANDS`` + raise NotImplementedError() + + def get_mgr_id(self): + """ + Retrieve the name of the manager daemon where this plugin + is currently being executed (i.e. the active manager). + + :return: str + """ + return self._ceph_get_mgr_id() + + def get_ceph_option(self, key): + return self._ceph_get_option(key) + + def _validate_module_option(self, key): + """ + Helper: don't allow get/set config callers to + access config options that they didn't declare + in their schema. + """ + if key not in [o['name'] for o in self.MODULE_OPTIONS]: + raise RuntimeError("Config option '{0}' is not in {1}.MODULE_OPTIONS". + format(key, self.__class__.__name__)) + + def _get_module_option(self, key, default, localized_prefix=""): + r = self._ceph_get_module_option(self.module_name, key, + localized_prefix) + if r is None: + return self.MODULE_OPTION_DEFAULTS.get(key, default) + else: + return r + + def get_module_option(self, key, default=None): + """ + Retrieve the value of a persistent configuration setting + + :param str key: + :param str default: + :return: str + """ + self._validate_module_option(key) + return self._get_module_option(key, default) + + def get_module_option_ex(self, module, key, default=None): + """ + Retrieve the value of a persistent configuration setting + for the specified module. + + :param str module: The name of the module, e.g. 'dashboard' + or 'telemetry'. + :param str key: The configuration key, e.g. 'server_addr'. + :param str,None default: The default value to use when the + returned value is ``None``. Defaults to ``None``. + :return: str,int,bool,float,None + """ + if module == self.module_name: + self._validate_module_option(key) + r = self._ceph_get_module_option(module, key) + return default if r is None else r + + def get_store_prefix(self, key_prefix): + """ + Retrieve a dict of KV store keys to values, where the keys + have the given prefix + + :param str key_prefix: + :return: str + """ + return self._ceph_get_store_prefix(key_prefix) + + def _set_localized(self, key, val, setter): + return setter(_get_localized_key(self.get_mgr_id(), key), val) + + def get_localized_module_option(self, key, default=None): + """ + Retrieve localized configuration for this ceph-mgr instance + :param str key: + :param str default: + :return: str + """ + self._validate_module_option(key) + return self._get_module_option(key, default, self.get_mgr_id()) + + def _set_module_option(self, key, val): + return self._ceph_set_module_option(self.module_name, key, + None if val is None else str(val)) + + def set_module_option(self, key, val): + """ + Set the value of a persistent configuration setting + + :param str key: + :type val: str | None + """ + self._validate_module_option(key) + return self._set_module_option(key, val) + + def set_module_option_ex(self, module, key, val): + """ + Set the value of a persistent configuration setting + for the specified module. + + :param str module: + :param str key: + :param str val: + """ + if module == self.module_name: + self._validate_module_option(key) + return self._ceph_set_module_option(module, key, str(val)) + + def set_localized_module_option(self, key, val): + """ + Set localized configuration for this ceph-mgr instance + :param str key: + :param str val: + :return: str + """ + self._validate_module_option(key) + return self._set_localized(key, val, self._set_module_option) + + def set_store(self, key, val): + """ + Set a value in this module's persistent key value store. + If val is None, remove key from store + + :param str key: + :param str val: + """ + self._ceph_set_store(key, val) + + def get_store(self, key, default=None): + """ + Get a value from this module's persistent key value store + """ + r = self._ceph_get_store(key) + if r is None: + return default + else: + return r + + def get_localized_store(self, key, default=None): + r = self._ceph_get_store(_get_localized_key(self.get_mgr_id(), key)) + if r is None: + r = self._ceph_get_store(key) + if r is None: + r = default + return r + + def set_localized_store(self, key, val): + return self._set_localized(key, val, self.set_store) + + def self_test(self): + """ + Run a self-test on the module. Override this function and implement + a best as possible self-test for (automated) testing of the module + + Indicate any failures by raising an exception. This does not have + to be pretty, it's mainly for picking up regressions during + development, rather than use in the field. + + :return: None, or an advisory string for developer interest, such + as a json dump of some state. + """ + pass + + def get_osdmap(self): + """ + Get a handle to an OSDMap. If epoch==0, get a handle for the latest + OSDMap. + :return: OSDMap + """ + return self._ceph_get_osdmap() + + def get_latest(self, daemon_type, daemon_name, counter): + data = self.get_latest_counter( + daemon_type, daemon_name, counter)[counter] + if data: + return data[1] + else: + return 0 + + def get_latest_avg(self, daemon_type, daemon_name, counter): + data = self.get_latest_counter( + daemon_type, daemon_name, counter)[counter] + if data: + return data[1], data[2] + else: + return 0, 0 + + def get_all_perf_counters(self, prio_limit=PRIO_USEFUL, + services=("mds", "mon", "osd", + "rbd-mirror", "rgw", "tcmu-runner")): + """ + Return the perf counters currently known to this ceph-mgr + instance, filtered by priority equal to or greater than `prio_limit`. + + The result is a map of string to dict, associating services + (like "osd.123") with their counters. The counter + dict for each service maps counter paths to a counter + info structure, which is the information from + the schema, plus an additional "value" member with the latest + value. + """ + + result = defaultdict(dict) + + for server in self.list_servers(): + for service in server['services']: + if service['type'] not in services: + continue + + schema = self.get_perf_schema(service['type'], service['id']) + if not schema: + self.log.warn("No perf counter schema for {0}.{1}".format( + service['type'], service['id'] + )) + continue + + # Value is returned in a potentially-multi-service format, + # get just the service we're asking about + svc_full_name = "{0}.{1}".format( + service['type'], service['id']) + schema = schema[svc_full_name] + + # Populate latest values + for counter_path, counter_schema in schema.items(): + # self.log.debug("{0}: {1}".format( + # counter_path, json.dumps(counter_schema) + # )) + if counter_schema['priority'] < prio_limit: + continue + + counter_info = dict(counter_schema) + + # Also populate count for the long running avgs + if counter_schema['type'] & self.PERFCOUNTER_LONGRUNAVG: + v, c = self.get_latest_avg( + service['type'], + service['id'], + counter_path + ) + counter_info['value'], counter_info['count'] = v, c + result[svc_full_name][counter_path] = counter_info + else: + counter_info['value'] = self.get_latest( + service['type'], + service['id'], + counter_path + ) + + result[svc_full_name][counter_path] = counter_info + + self.log.debug("returning {0} counter".format(len(result))) + + return result + + def set_uri(self, uri): + """ + If the module exposes a service, then call this to publish the + address once it is available. + + :return: a string + """ + return self._ceph_set_uri(uri) + + def have_mon_connection(self): + """ + Check whether this ceph-mgr daemon has an open connection + to a monitor. If it doesn't, then it's likely that the + information we have about the cluster is out of date, + and/or the monitor cluster is down. + """ + + return self._ceph_have_mon_connection() + + def update_progress_event(self, evid, desc, progress): + return self._ceph_update_progress_event(str(evid), str(desc), float(progress)) + + def complete_progress_event(self, evid): + return self._ceph_complete_progress_event(str(evid)) + + def clear_all_progress_events(self): + return self._ceph_clear_all_progress_events() + + @property + def rados(self): + """ + A librados instance to be shared by any classes within + this mgr module that want one. + """ + if self._rados: + return self._rados + + ctx_capsule = self.get_context() + self._rados = rados.Rados(context=ctx_capsule) + self._rados.connect() + + return self._rados + + @staticmethod + def can_run(): + """ + Implement this function to report whether the module's dependencies + are met. For example, if the module needs to import a particular + dependency to work, then use a try/except around the import at + file scope, and then report here if the import failed. + + This will be called in a blocking way from the C++ code, so do not + do any I/O that could block in this function. + + :return a 2-tuple consisting of a boolean and explanatory string + """ + + return True, "" + + def remote(self, module_name, method_name, *args, **kwargs): + """ + Invoke a method on another module. All arguments, and the return + value from the other module must be serializable. + + Limitation: Do not import any modules within the called method. + Otherwise you will get an error in Python 2:: + + RuntimeError('cannot unmarshal code objects in restricted execution mode',) + + + + :param module_name: Name of other module. If module isn't loaded, + an ImportError exception is raised. + :param method_name: Method name. If it does not exist, a NameError + exception is raised. + :param args: Argument tuple + :param kwargs: Keyword argument dict + :raises RuntimeError: **Any** error raised within the method is converted to a RuntimeError + :raises ImportError: No such module + """ + return self._ceph_dispatch_remote(module_name, method_name, + args, kwargs) + + def add_osd_perf_query(self, query): + """ + Register an OSD perf query. Argument is a + dict of the query parameters, in this form: + + :: + + { + 'key_descriptor': [ + {'type': subkey_type, 'regex': regex_pattern}, + ... + ], + 'performance_counter_descriptors': [ + list, of, descriptor, types + ], + 'limit': {'order_by': performance_counter_type, 'max_count': n}, + } + + Valid subkey types: + 'client_id', 'client_address', 'pool_id', 'namespace', 'osd_id', + 'pg_id', 'object_name', 'snap_id' + Valid performance counter types: + 'ops', 'write_ops', 'read_ops', 'bytes', 'write_bytes', 'read_bytes', + 'latency', 'write_latency', 'read_latency' + + :param object query: query + :rtype: int (query id) + """ + return self._ceph_add_osd_perf_query(query) + + def remove_osd_perf_query(self, query_id): + """ + Unregister an OSD perf query. + + :param int query_id: query ID + """ + return self._ceph_remove_osd_perf_query(query_id) + + def get_osd_perf_counters(self, query_id): + """ + Get stats collected for an OSD perf query. + + :param int query_id: query ID + """ + return self._ceph_get_osd_perf_counters(query_id) + + def is_authorized(self, arguments): + """ + Verifies that the current session caps permit executing the py service + or current module with the provided arguments. This provides a generic + way to allow modules to restrict by more fine-grained controls (e.g. + pools). + + :param arguments: dict of key/value arguments to test + """ + return self._ceph_is_authorized(arguments) + + +class PersistentStoreDict(object): + def __init__(self, mgr, prefix): + # type: (MgrModule, str) -> None + self.mgr = mgr + self.prefix = prefix + '.' + + def _mk_store_key(self, key): + return self.prefix + key + + def __missing__(self, key): + # KeyError won't work for the `in` operator. + # https://docs.python.org/3/reference/expressions.html#membership-test-details + raise IndexError('PersistentStoreDict: "{}" not found'.format(key)) + + def clear(self): + # Don't make any assumptions about the content of the values. + for item in six.iteritems(self.mgr.get_store_prefix(self.prefix)): + k, _ = item + self.mgr.set_store(k, None) + + def __getitem__(self, item): + # type: (str) -> Any + key = self._mk_store_key(item) + try: + val = self.mgr.get_store(key) + if val is None: + self.__missing__(key) + return json.loads(val) + except (KeyError, AttributeError, IndexError, ValueError, TypeError): + logging.getLogger(__name__).exception('failed to deserialize') + self.mgr.set_store(key, None) + raise + + def __setitem__(self, item, value): + # type: (str, Any) -> None + """ + value=None is not allowed, as it will remove the key. + """ + key = self._mk_store_key(item) + self.mgr.set_store(key, json.dumps(value) if value is not None else None) + + def __delitem__(self, item): + self[item] = None + + def __len__(self): + return len(self.keys()) + + def items(self): + # type: () -> Iterator[Tuple[str, Any]] + prefix_len = len(self.prefix) + try: + for item in six.iteritems(self.mgr.get_store_prefix(self.prefix)): + k, v = item + yield k[prefix_len:], json.loads(v) + except (KeyError, AttributeError, IndexError, ValueError, TypeError): + logging.getLogger(__name__).exception('failed to deserialize') + self.clear() + + def keys(self): + # type: () -> Set[str] + return {item[0] for item in self.items()} + + def __iter__(self): + return iter(self.keys()) diff --git a/src/pybind/mgr/mgr_util.py b/src/pybind/mgr/mgr_util.py new file mode 100644 index 00000000..e337a618 --- /dev/null +++ b/src/pybind/mgr/mgr_util.py @@ -0,0 +1,300 @@ +import contextlib +import os +import socket +import logging + +( + BLACK, + RED, + GREEN, + YELLOW, + BLUE, + MAGENTA, + CYAN, + GRAY +) = range(8) + +RESET_SEQ = "\033[0m" +COLOR_SEQ = "\033[1;%dm" +COLOR_DARK_SEQ = "\033[0;%dm" +BOLD_SEQ = "\033[1m" +UNDERLINE_SEQ = "\033[4m" + +logger = logging.getLogger(__name__) + + +def colorize(msg, color, dark=False): + """ + Decorate `msg` with escape sequences to give the requested color + """ + return (COLOR_DARK_SEQ if dark else COLOR_SEQ) % (30 + color) \ + + msg + RESET_SEQ + + +def bold(msg): + """ + Decorate `msg` with escape sequences to make it appear bold + """ + return BOLD_SEQ + msg + RESET_SEQ + + +def format_units(n, width, colored, decimal): + """ + Format a number without units, so as to fit into `width` characters, substituting + an appropriate unit suffix. + + Use decimal for dimensionless things, use base 2 (decimal=False) for byte sizes/rates. + """ + + factor = 1000 if decimal else 1024 + units = [' ', 'k', 'M', 'G', 'T', 'P', 'E'] + unit = 0 + while len("%s" % (int(n) // (factor**unit))) > width - 1: + unit += 1 + + if unit > 0: + truncated_float = ("%f" % (n / (float(factor) ** unit)))[0:width - 1] + if truncated_float[-1] == '.': + truncated_float = " " + truncated_float[0:-1] + else: + truncated_float = "%{wid}d".format(wid=width - 1) % n + formatted = "%s%s" % (truncated_float, units[unit]) + + if colored: + if n == 0: + color = BLACK, False + else: + color = YELLOW, False + return bold(colorize(formatted[0:-1], color[0], color[1])) \ + + bold(colorize(formatted[-1], BLACK, False)) + else: + return formatted + + +def format_dimless(n, width, colored=False): + return format_units(n, width, colored, decimal=True) + + +def format_bytes(n, width, colored=False): + return format_units(n, width, colored, decimal=False) + + +def merge_dicts(*args): + # type: (dict) -> dict + """ + >>> assert merge_dicts({1:2}, {3:4}) == {1:2, 3:4} + You can also overwrite keys: + >>> assert merge_dicts({1:2}, {1:4}) == {1:4} + :rtype: dict[str, Any] + """ + ret = {} + for arg in args: + ret.update(arg) + return ret + + +def get_default_addr(): + def is_ipv6_enabled(): + try: + sock = socket.socket(socket.AF_INET6) + with contextlib.closing(sock): + sock.bind(("::1", 0)) + return True + except (AttributeError, socket.error) as e: + return False + + try: + return get_default_addr.result + except AttributeError: + result = '::' if is_ipv6_enabled() else '0.0.0.0' + get_default_addr.result = result + return result + + +class ServerConfigException(Exception): + pass + +def verify_cacrt(cert_fname): + """Basic validation of a ca cert""" + + if not cert_fname: + raise ServerConfigException("CA cert not configured") + if not os.path.isfile(cert_fname): + raise ServerConfigException("Certificate {} does not exist".format(cert_fname)) + + from OpenSSL import crypto + try: + with open(cert_fname) as f: + x509 = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) + if x509.has_expired(): + logger.warning( + 'Certificate {} has expired'.format(cert_fname)) + except (ValueError, crypto.Error) as e: + raise ServerConfigException( + 'Invalid certificate {}: {}'.format(cert_fname, str(e))) + + +def verify_tls_files(cert_fname, pkey_fname): + """Basic checks for TLS certificate and key files + + Do some validations to the private key and certificate: + - Check the type and format + - Check the certificate expiration date + - Check the consistency of the private key + - Check that the private key and certificate match up + + :param cert_fname: Name of the certificate file + :param pkey_fname: name of the certificate public key file + + :raises ServerConfigException: An error with a message + + """ + + if not cert_fname or not pkey_fname: + raise ServerConfigException('no certificate configured') + + verify_cacrt(cert_fname) + + if not os.path.isfile(pkey_fname): + raise ServerConfigException('private key %s does not exist' % pkey_fname) + + from OpenSSL import crypto, SSL + + try: + with open(pkey_fname) as f: + pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) + pkey.check() + except (ValueError, crypto.Error) as e: + raise ServerConfigException( + 'Invalid private key {}: {}'.format(pkey_fname, str(e))) + try: + context = SSL.Context(SSL.TLSv1_METHOD) + context.use_certificate_file(cert_fname, crypto.FILETYPE_PEM) + context.use_privatekey_file(pkey_fname, crypto.FILETYPE_PEM) + context.check_privatekey() + except crypto.Error as e: + logger.warning( + 'Private key {} and certificate {} do not match up: {}'.format( + pkey_fname, cert_fname, str(e))) + +def get_most_recent_rate(rates): + """ Get most recent rate from rates + + :param rates: The derivative between all time series data points [time in seconds, value] + :type rates: list[tuple[int, float]] + + :return: The last derivative or 0.0 if none exists + :rtype: float + + >>> get_most_recent_rate(None) + 0.0 + >>> get_most_recent_rate([]) + 0.0 + >>> get_most_recent_rate([(1, -2.0)]) + -2.0 + >>> get_most_recent_rate([(1, 2.0), (2, 1.5), (3, 5.0)]) + 5.0 + """ + if not rates: + return 0.0 + return rates[-1][1] + +def get_time_series_rates(data): + """ Rates from time series data + + :param data: Time series data [time in seconds, value] + :type data: list[tuple[int, float]] + + :return: The derivative between all time series data points [time in seconds, value] + :rtype: list[tuple[int, float]] + + >>> logger.debug = lambda s,x,y: print(s % (x,y)) + >>> get_time_series_rates([]) + [] + >>> get_time_series_rates([[0, 1], [1, 3]]) + [(1, 2.0)] + >>> get_time_series_rates([[0, 2], [0, 3], [0, 1], [1, 2], [1, 3]]) + Duplicate timestamp in time series data: [0, 2], [0, 3] + Duplicate timestamp in time series data: [0, 3], [0, 1] + Duplicate timestamp in time series data: [1, 2], [1, 3] + [(1, 2.0)] + >>> get_time_series_rates([[1, 1], [2, 3], [4, 11], [5, 16], [6, 22]]) + [(2, 2.0), (4, 4.0), (5, 5.0), (6, 6.0)] + """ + data = _filter_time_series(data) + if not data: + return [] + return [(data2[0], _derivative(data1, data2)) for data1, data2 in + _pairwise(data)] + +def _filter_time_series(data): + """ Filters time series data + + Filters out samples with the same timestamp in given time series data. + It also enforces the list to contain at least two samples. + + All filtered values will be shown in the debug log. If values were filtered it's a bug in the + time series data collector, please report it. + + :param data: Time series data [time in seconds, value] + :type data: list[tuple[int, float]] + + :return: Filtered time series data [time in seconds, value] + :rtype: list[tuple[int, float]] + + >>> logger.debug = lambda s,x,y: print(s % (x,y)) + >>> _filter_time_series([]) + [] + >>> _filter_time_series([[1, 42]]) + [] + >>> _filter_time_series([[10, 2], [10, 3]]) + Duplicate timestamp in time series data: [10, 2], [10, 3] + [] + >>> _filter_time_series([[0, 1], [1, 2]]) + [[0, 1], [1, 2]] + >>> _filter_time_series([[0, 2], [0, 3], [0, 1], [1, 2], [1, 3]]) + Duplicate timestamp in time series data: [0, 2], [0, 3] + Duplicate timestamp in time series data: [0, 3], [0, 1] + Duplicate timestamp in time series data: [1, 2], [1, 3] + [[0, 1], [1, 3]] + >>> _filter_time_series([[1, 1], [2, 3], [4, 11], [5, 16], [6, 22]]) + [[1, 1], [2, 3], [4, 11], [5, 16], [6, 22]] + """ + filtered = [] + for i in range(len(data) - 1): + if data[i][0] == data[i + 1][0]: # Same timestamp + logger.debug("Duplicate timestamp in time series data: %s, %s", data[i], data[i + 1]) + continue + filtered.append(data[i]) + if not filtered: + return [] + filtered.append(data[-1]) + return filtered + +def _derivative(p1, p2): + """ Derivative between two time series data points + + :param p1: Time series data [time in seconds, value] + :type p1: tuple[int, float] + :param p2: Time series data [time in seconds, value] + :type p2: tuple[int, float] + + :return: Derivative between both points + :rtype: float + + >>> _derivative([0, 0], [2, 1]) + 0.5 + >>> _derivative([0, 1], [2, 0]) + -0.5 + >>> _derivative([0, 0], [3, 1]) + 0.3333333333333333 + """ + return (p2[1] - p1[1]) / float(p2[0] - p1[0]) + +def _pairwise(iterable): + it = iter(iterable) + a = next(it, None) + + for b in it: + yield (a, b) + a = b diff --git a/src/pybind/mgr/orchestrator.py b/src/pybind/mgr/orchestrator.py new file mode 100644 index 00000000..ccf2c86f --- /dev/null +++ b/src/pybind/mgr/orchestrator.py @@ -0,0 +1,1085 @@ + +""" +ceph-mgr orchestrator interface + +Please see the ceph-mgr module developer's guide for more information. +""" +import sys +import time +import fnmatch +import uuid +import datetime + +import six + +from mgr_module import MgrModule, PersistentStoreDict +from mgr_util import format_bytes + +try: + from typing import TypeVar, Generic, List, Optional, Union, Tuple, Iterator + + T = TypeVar('T') + G = Generic[T] +except ImportError: + T, G = object, object + + +class OrchestratorError(Exception): + """ + General orchestrator specific error. + + Used for deployment, configuration or user errors. + + It's not intended for programming errors or orchestrator internal errors. + """ + + +class NoOrchestrator(OrchestratorError): + """ + No orchestrator in configured. + """ + def __init__(self, msg="No orchestrator configured (try `ceph orchestrator set backend`)"): + super(NoOrchestrator, self).__init__(msg) + + +class OrchestratorValidationError(OrchestratorError): + """ + Raised when an orchestrator doesn't support a specific feature. + """ + + +class _Completion(G): + @property + def result(self): + # type: () -> T + """ + Return the result of the operation that we were waited + for. Only valid after calling Orchestrator.wait() on this + completion. + """ + raise NotImplementedError() + + @property + def exception(self): + # type: () -> Optional[Exception] + """ + Holds an exception object. + """ + try: + return self.__exception + except AttributeError: + return None + + @exception.setter + def exception(self, value): + self.__exception = value + + @property + def is_read(self): + # type: () -> bool + raise NotImplementedError() + + @property + def is_complete(self): + # type: () -> bool + raise NotImplementedError() + + @property + def is_errored(self): + # type: () -> bool + """ + Has the completion failed. Default implementation looks for + self.exception. Can be overwritten. + """ + return self.exception is not None + + @property + def should_wait(self): + # type: () -> bool + raise NotImplementedError() + + +def raise_if_exception(c): + # type: (_Completion) -> None + """ + :raises OrchestratorError: Some user error or a config error. + :raises Exception: Some internal error + """ + def copy_to_this_subinterpreter(r_obj): + # This is something like `return pickle.loads(pickle.dumps(r_obj))` + # Without importing anything. + r_cls = r_obj.__class__ + if r_cls.__module__ == '__builtin__': + return r_obj + my_cls = getattr(sys.modules[r_cls.__module__], r_cls.__name__) + if id(my_cls) == id(r_cls): + return r_obj + my_obj = my_cls.__new__(my_cls) + for k,v in r_obj.__dict__.items(): + setattr(my_obj, k, copy_to_this_subinterpreter(v)) + return my_obj + + if c.exception is not None: + raise copy_to_this_subinterpreter(c.exception) + + +class ReadCompletion(_Completion): + """ + ``Orchestrator`` implementations should inherit from this + class to implement their own handles to operations in progress, and + return an instance of their subclass from calls into methods. + """ + + def __init__(self): + pass + + @property + def is_read(self): + return True + + @property + def should_wait(self): + """Could the external operation be deemed as complete, + or should we wait? + We must wait for a read operation only if it is not complete. + """ + return not self.is_complete + + +class TrivialReadCompletion(ReadCompletion): + """ + This is the trivial completion simply wrapping a result. + """ + def __init__(self, result): + super(TrivialReadCompletion, self).__init__() + self._result = result + + @property + def result(self): + return self._result + + @property + def is_complete(self): + return True + + +class WriteCompletion(_Completion): + """ + ``Orchestrator`` implementations should inherit from this + class to implement their own handles to operations in progress, and + return an instance of their subclass from calls into methods. + """ + + def __init__(self): + self.progress_id = str(uuid.uuid4()) + + #: if a orchestrator module can provide a more detailed + #: progress information, it needs to also call ``progress.update()``. + self.progress = 0.5 + + def __str__(self): + """ + ``__str__()`` is used for determining the message for progress events. + """ + return super(WriteCompletion, self).__str__() + + @property + def is_persistent(self): + # type: () -> bool + """ + Has the operation updated the orchestrator's configuration + persistently? Typically this would indicate that an update + had been written to a manifest, but that the update + had not necessarily been pushed out to the cluster. + """ + raise NotImplementedError() + + @property + def is_effective(self): + """ + Has the operation taken effect on the cluster? For example, + if we were adding a service, has it come up and appeared + in Ceph's cluster maps? + """ + raise NotImplementedError() + + @property + def is_complete(self): + return self.is_errored or (self.is_persistent and self.is_effective) + + @property + def is_read(self): + return False + + @property + def should_wait(self): + """Could the external operation be deemed as complete, + or should we wait? + We must wait for a write operation only if we know + it is not persistent yet. + """ + return not self.is_persistent + + +class Orchestrator(object): + """ + Calls in this class may do long running remote operations, with time + periods ranging from network latencies to package install latencies and large + internet downloads. For that reason, all are asynchronous, and return + ``Completion`` objects. + + Implementations are not required to start work on an operation until + the caller waits on the relevant Completion objects. Callers making + multiple updates should not wait on Completions until they're done + sending operations: this enables implementations to batch up a series + of updates when wait() is called on a set of Completion objects. + + Implementations are encouraged to keep reasonably fresh caches of + the status of the system: it is better to serve a stale-but-recent + result read of e.g. device inventory than it is to keep the caller waiting + while you scan hosts every time. + """ + + def is_orchestrator_module(self): + """ + Enable other modules to interrogate this module to discover + whether it's usable as an orchestrator module. + + Subclasses do not need to override this. + """ + return True + + def available(self): + # type: () -> Tuple[bool, str] + """ + Report whether we can talk to the orchestrator. This is the + place to give the user a meaningful message if the orchestrator + isn't running or can't be contacted. + + This method may be called frequently (e.g. every page load + to conditionally display a warning banner), so make sure it's + not too expensive. It's okay to give a slightly stale status + (e.g. based on a periodic background ping of the orchestrator) + if that's necessary to make this method fast. + + ..note:: `True` doesn't mean that the desired functionality + is actually available in the orchestrator. I.e. this + won't work as expected:: + + >>> if OrchestratorClientMixin().available()[0]: # wrong. + ... OrchestratorClientMixin().get_hosts() + + :return: two-tuple of boolean, string + """ + raise NotImplementedError() + + def wait(self, completions): + """ + Given a list of Completion instances, progress any which are + incomplete. Return a true if everything is done. + + Callers should inspect the detail of each completion to identify + partial completion/progress information, and present that information + to the user. + + For fast operations (e.g. reading from a database), implementations + may choose to do blocking IO in this call. + + :rtype: bool + """ + raise NotImplementedError() + + def add_host(self, host): + # type: (str) -> WriteCompletion + """ + Add a host to the orchestrator inventory. + + :param host: hostname + """ + raise NotImplementedError() + + def remove_host(self, host): + # type: (str) -> WriteCompletion + """ + Remove a host from the orchestrator inventory. + + :param host: hostname + """ + raise NotImplementedError() + + def get_hosts(self): + # type: () -> ReadCompletion[List[InventoryNode]] + """ + Report the hosts in the cluster. + + The default implementation is extra slow. + + :return: list of InventoryNodes + """ + return self.get_inventory() + + def get_inventory(self, node_filter=None, refresh=False): + # type: (InventoryFilter, bool) -> ReadCompletion[List[InventoryNode]] + """ + Returns something that was created by `ceph-volume inventory`. + + :return: list of InventoryNode + """ + raise NotImplementedError() + + def describe_service(self, service_type=None, service_id=None, node_name=None, refresh=False): + # type: (Optional[str], Optional[str], Optional[str], bool) -> ReadCompletion[List[ServiceDescription]] + """ + Describe a service (of any kind) that is already configured in + the orchestrator. For example, when viewing an OSD in the dashboard + we might like to also display information about the orchestrator's + view of the service (like the kubernetes pod ID). + + When viewing a CephFS filesystem in the dashboard, we would use this + to display the pods being currently run for MDS daemons. + + :return: list of ServiceDescription objects. + """ + raise NotImplementedError() + + def service_action(self, action, service_type, service_name=None, service_id=None): + # type: (str, str, str, str) -> WriteCompletion + """ + Perform an action (start/stop/reload) on a service. + + Either service_name or service_id must be specified: + + * If using service_name, perform the action on that entire logical + service (i.e. all daemons providing that named service). + * If using service_id, perform the action on a single specific daemon + instance. + + :param action: one of "start", "stop", "reload" + :param service_type: e.g. "mds", "rgw", ... + :param service_name: name of logical service ("cephfs", "us-east", ...) + :param service_id: service daemon instance (usually a short hostname) + :rtype: WriteCompletion + """ + assert action in ["start", "stop", "reload"] + assert service_name or service_id + assert not (service_name and service_id) + raise NotImplementedError() + + def create_osds(self, drive_group, all_hosts): + # type: (DriveGroupSpec, List[str]) -> WriteCompletion + """ + Create one or more OSDs within a single Drive Group. + + The principal argument here is the drive_group member + of OsdSpec: other fields are advisory/extensible for any + finer-grained OSD feature enablement (choice of backing store, + compression/encryption, etc). + + :param drive_group: DriveGroupSpec + :param all_hosts: TODO, this is required because the orchestrator methods are not composable + Probably this parameter can be easily removed because each orchestrator can use + the "get_inventory" method and the "drive_group.host_pattern" attribute + to obtain the list of hosts where to apply the operation + """ + raise NotImplementedError() + + def replace_osds(self, drive_group): + # type: (DriveGroupSpec) -> WriteCompletion + """ + Like create_osds, but the osd_id_claims must be fully + populated. + """ + raise NotImplementedError() + + def remove_osds(self, osd_ids): + # type: (List[str]) -> WriteCompletion + """ + :param osd_ids: list of OSD IDs + + Note that this can only remove OSDs that were successfully + created (i.e. got an OSD ID). + """ + raise NotImplementedError() + + def update_mgrs(self, num, hosts): + # type: (int, List[str]) -> WriteCompletion + """ + Update the number of cluster managers. + + :param num: requested number of managers. + :param hosts: list of hosts (optional) + """ + raise NotImplementedError() + + def update_mons(self, num, hosts): + # type: (int, List[Tuple[str,str]]) -> WriteCompletion + """ + Update the number of cluster monitors. + + :param num: requested number of monitors. + :param hosts: list of hosts + network (optional) + """ + raise NotImplementedError() + + def add_stateless_service(self, service_type, spec): + # type: (str, StatelessServiceSpec) -> WriteCompletion + """ + Installing and adding a completely new service to the cluster. + + This is not about starting services. + """ + raise NotImplementedError() + + def update_stateless_service(self, service_type, spec): + # type: (str, StatelessServiceSpec) -> WriteCompletion + """ + This is about changing / redeploying existing services. Like for + example changing the number of service instances. + + :rtype: WriteCompletion + """ + raise NotImplementedError() + + def remove_stateless_service(self, service_type, id_): + # type: (str, str) -> WriteCompletion + """ + Uninstalls an existing service from the cluster. + + This is not about stopping services. + """ + raise NotImplementedError() + + def upgrade_start(self, upgrade_spec): + # type: (UpgradeSpec) -> WriteCompletion + raise NotImplementedError() + + def upgrade_status(self): + # type: () -> ReadCompletion[UpgradeStatusSpec] + """ + If an upgrade is currently underway, report on where + we are in the process, or if some error has occurred. + + :return: UpgradeStatusSpec instance + """ + raise NotImplementedError() + + def upgrade_available(self): + # type: () -> ReadCompletion[List[str]] + """ + Report on what versions are available to upgrade to + + :return: List of strings + """ + raise NotImplementedError() + + +class UpgradeSpec(object): + # Request to orchestrator to initiate an upgrade to a particular + # version of Ceph + def __init__(self): + self.target_version = None + + +class UpgradeStatusSpec(object): + # Orchestrator's report on what's going on with any ongoing upgrade + def __init__(self): + self.in_progress = False # Is an upgrade underway? + self.services_complete = [] # Which daemon types are fully updated? + self.message = "" # Freeform description + + +class PlacementSpec(object): + """ + For APIs that need to specify a node subset + """ + def __init__(self): + self.label = None + + +class ServiceDescription(object): + """ + For responding to queries about the status of a particular service, + stateful or stateless. + + This is not about health or performance monitoring of services: it's + about letting the orchestrator tell Ceph whether and where a + service is scheduled in the cluster. When an orchestrator tells + Ceph "it's running on node123", that's not a promise that the process + is literally up this second, it's a description of where the orchestrator + has decided the service should run. + """ + + def __init__(self, nodename=None, container_id=None, service=None, service_instance=None, + service_type=None, version=None, rados_config_location=None, + service_url=None, status=None, status_desc=None): + # Node is at the same granularity as InventoryNode + self.nodename = nodename + + # Not everyone runs in containers, but enough people do to + # justify having this field here. + self.container_id = container_id + + # Some services can be deployed in groups. For example, mds's can + # have an active and standby daemons, and nfs-ganesha can run daemons + # in parallel. This tag refers to a group of daemons as a whole. + # + # For instance, a cluster of mds' all service the same fs, and they + # will all have the same service value (which may be the + # Filesystem name in the FSMap). + # + # Single-instance services should leave this set to None + self.service = service + + # The orchestrator will have picked some names for daemons, + # typically either based on hostnames or on pod names. + # This is the in mds., the ID that will appear + # in the FSMap/ServiceMap. + self.service_instance = service_instance + + # The type of service (osd, mon, mgr, etc.) + self.service_type = service_type + + # Service version that was deployed + self.version = version + + # Location of the service configuration when stored in rados + # object. Format: "rados:///[]" + self.rados_config_location = rados_config_location + + # If the service exposes REST-like API, this attribute should hold + # the URL. + self.service_url = service_url + + # Service status: -1 error, 0 stopped, 1 running + self.status = status + + # Service status description when status == -1. + self.status_desc = status_desc + + def to_json(self): + out = { + 'nodename': self.nodename, + 'container_id': self.container_id, + 'service': self.service, + 'service_instance': self.service_instance, + 'service_type': self.service_type, + 'version': self.version, + 'rados_config_location': self.rados_config_location, + 'service_url': self.service_url, + 'status': self.status, + 'status_desc': self.status_desc, + } + return {k: v for (k, v) in out.items() if v is not None} + + @classmethod + def from_json(cls, data): + return cls(**data) + + +class DeviceSelection(object): + """ + Used within :class:`myclass.DriveGroupSpec` to specify the devices + used by the Drive Group. + + Any attributes (even none) can be included in the device + specification structure. + """ + + def __init__(self, paths=None, id_model=None, size=None, rotates=None, count=None): + # type: (List[str], str, str, bool, int) -> None + """ + ephemeral drive group device specification + + TODO: translate from the user interface (Drive Groups) to an actual list of devices. + """ + if paths is None: + paths = [] + + #: List of absolute paths to the devices. + self.paths = paths # type: List[str] + + #: A wildcard string. e.g: "SDD*" + self.id_model = id_model + + #: Size specification of format LOW:HIGH. + #: Can also take the the form :HIGH, LOW: + #: or an exact value (as ceph-volume inventory reports) + self.size = size + + #: is the drive rotating or not + self.rotates = rotates + + #: if this is present limit the number of drives to this number. + self.count = count + self.validate() + + def validate(self): + props = [self.id_model, self.size, self.rotates, self.count] + if self.paths and any(p is not None for p in props): + raise DriveGroupValidationError('DeviceSelection: `paths` and other parameters are mutually exclusive') + if not any(p is not None for p in [self.paths] + props): + raise DriveGroupValidationError('DeviceSelection cannot be empty') + + @classmethod + def from_json(cls, device_spec): + return cls(**device_spec) + + +class DriveGroupValidationError(Exception): + """ + Defining an exception here is a bit problematic, cause you cannot properly catch it, + if it was raised in a different mgr module. + """ + + def __init__(self, msg): + super(DriveGroupValidationError, self).__init__('Failed to validate Drive Group: ' + msg) + +class DriveGroupSpec(object): + """ + Describe a drive group in the same form that ceph-volume + understands. + """ + def __init__(self, host_pattern, data_devices=None, db_devices=None, wal_devices=None, journal_devices=None, + data_directories=None, osds_per_device=None, objectstore='bluestore', encrypted=False, + db_slots=None, wal_slots=None): + # type: (str, Optional[DeviceSelection], Optional[DeviceSelection], Optional[DeviceSelection], Optional[DeviceSelection], Optional[List[str]], int, str, bool, int, int) -> None + + # concept of applying a drive group to a (set) of hosts is tightly + # linked to the drive group itself + # + #: An fnmatch pattern to select hosts. Can also be a single host. + self.host_pattern = host_pattern + + #: A :class:`orchestrator.DeviceSelection` + self.data_devices = data_devices + + #: A :class:`orchestrator.DeviceSelection` + self.db_devices = db_devices + + #: A :class:`orchestrator.DeviceSelection` + self.wal_devices = wal_devices + + #: A :class:`orchestrator.DeviceSelection` + self.journal_devices = journal_devices + + #: Number of osd daemons per "DATA" device. + #: To fully utilize nvme devices multiple osds are required. + self.osds_per_device = osds_per_device + + #: A list of strings, containing paths which should back OSDs + self.data_directories = data_directories + + #: ``filestore`` or ``bluestore`` + self.objectstore = objectstore + + #: ``true`` or ``false`` + self.encrypted = encrypted + + #: How many OSDs per DB device + self.db_slots = db_slots + + #: How many OSDs per WAL device + self.wal_slots = wal_slots + + # FIXME: needs ceph-volume support + #: Optional: mapping of drive to OSD ID, used when the + #: created OSDs are meant to replace previous OSDs on + #: the same node. + self.osd_id_claims = {} + + @classmethod + def from_json(self, json_drive_group): + """ + Initialize 'Drive group' structure + + :param json_drive_group: A valid json string with a Drive Group + specification + """ + args = {k: (DeviceSelection.from_json(v) if k.endswith('_devices') else v) for k, v in + json_drive_group.items()} + return DriveGroupSpec(**args) + + def hosts(self, all_hosts): + return fnmatch.filter(all_hosts, self.host_pattern) + + def validate(self, all_hosts): + if not isinstance(self.host_pattern, six.string_types): + raise DriveGroupValidationError('host_pattern must be of type string') + + specs = [self.data_devices, self.db_devices, self.wal_devices, self.journal_devices] + for s in filter(None, specs): + s.validate() + if self.objectstore not in ('filestore', 'bluestore'): + raise DriveGroupValidationError("objectstore not in ('filestore', 'bluestore')") + if not self.hosts(all_hosts): + raise DriveGroupValidationError( + "host_pattern '{}' does not match any hosts".format(self.host_pattern)) + + +class StatelessServiceSpec(object): + # Request to orchestrator for a group of stateless services + # such as MDS, RGW, nfs gateway, iscsi gateway + """ + Details of stateless service creation. + + This is *not* supposed to contain all the configuration + of the services: it's just supposed to be enough information to + execute the binaries. + """ + + def __init__(self): + self.placement = PlacementSpec() + + # Give this set of statelss services a name: typically it would + # be the name of a CephFS filesystem, RGW zone, etc. Must be unique + # within one ceph cluster. + self.name = "" + + # Count of service instances + self.count = 1 + + # Arbitrary JSON-serializable object. + # Maybe you're using e.g. kubenetes and you want to pass through + # some replicaset special sauce for autoscaling? + self.extended = {} + + +class InventoryFilter(object): + """ + When fetching inventory, use this filter to avoid unnecessarily + scanning the whole estate. + + Typical use: filter by node when presenting UI workflow for configuring + a particular server. + filter by label when not all of estate is Ceph servers, + and we want to only learn about the Ceph servers. + filter by label when we are interested particularly + in e.g. OSD servers. + + """ + def __init__(self, labels=None, nodes=None): + # type: (List[str], List[str]) -> None + self.labels = labels # Optional: get info about nodes matching labels + self.nodes = nodes # Optional: get info about certain named nodes only + + +class InventoryDevice(object): + """ + When fetching inventory, block devices are reported in this format. + + Note on device identifiers: the format of this is up to the orchestrator, + but the same identifier must also work when passed into StatefulServiceSpec. + The identifier should be something meaningful like a device WWID or + stable device node path -- not something made up by the orchestrator. + + "Extended" is for reporting any special configuration that may have + already been done out of band on the block device. For example, if + the device has already been configured for encryption, report that + here so that it can be indicated to the user. The set of + extended properties may differ between orchestrators. An orchestrator + is permitted to support no extended properties (only normal block + devices) + """ + def __init__(self, blank=False, type=None, id=None, size=None, + rotates=False, available=False, dev_id=None, extended=None, + metadata_space_free=None): + # type: (bool, str, str, int, bool, bool, str, dict, bool) -> None + + self.blank = blank + + #: 'ssd', 'hdd', 'nvme' + self.type = type + + #: unique within a node (or globally if you like). + self.id = id + + #: byte integer. + self.size = size + + #: indicates if it is a spinning disk + self.rotates = rotates + + #: can be used to create a new OSD? + self.available = available + + #: vendor/model + self.dev_id = dev_id + + #: arbitrary JSON-serializable object + self.extended = extended if extended is not None else extended + + # If this drive is not empty, but is suitable for appending + # additional journals, wals, or bluestore dbs, then report + # how much space is available. + self.metadata_space_free = metadata_space_free + + def to_json(self): + return dict(type=self.type, blank=self.blank, id=self.id, + size=self.size, rotates=self.rotates, + available=self.available, dev_id=self.dev_id, + extended=self.extended) + + @classmethod + def from_ceph_volume_inventory(cls, data): + # TODO: change InventoryDevice itself to mirror c-v inventory closely! + + dev = InventoryDevice() + dev.id = data["path"] + dev.type = 'hdd' if data["sys_api"]["rotational"] == "1" else 'sdd/nvme' + dev.size = data["sys_api"]["size"] + dev.rotates = data["sys_api"]["rotational"] == "1" + dev.available = data["available"] + dev.dev_id = "%s/%s" % (data["sys_api"]["vendor"], + data["sys_api"]["model"]) + dev.extended = data + return dev + + @classmethod + def from_ceph_volume_inventory_list(cls, datas): + return [cls.from_ceph_volume_inventory(d) for d in datas] + + def pretty_print(self, only_header=False): + """Print a human friendly line with the information of the device + + :param only_header: Print only the name of the device attributes + + Ex:: + + Device Path Type Size Rotates Available Model + /dev/sdc hdd 50.00 GB True True ATA/QEMU + + """ + row_format = " {0:<15} {1:>10} {2:>10} {3:>10} {4:>10} {5:<15}\n" + if only_header: + return row_format.format("Device Path", "Type", "Size", "Rotates", + "Available", "Model") + else: + return row_format.format(str(self.id), self.type if self.type is not None else "", + format_bytes(self.size if self.size is not None else 0, 5, + colored=False), + str(self.rotates), str(self.available), + self.dev_id if self.dev_id is not None else "") + + +class InventoryNode(object): + """ + When fetching inventory, all Devices are groups inside of an + InventoryNode. + """ + def __init__(self, name, devices): + # type: (str, List[InventoryDevice]) -> None + assert isinstance(devices, list) + self.name = name # unique within cluster. For example a hostname. + self.devices = devices + + def to_json(self): + return {'name': self.name, 'devices': [d.to_json() for d in self.devices]} + + @classmethod + def from_nested_items(cls, hosts): + devs = InventoryDevice.from_ceph_volume_inventory_list + return [cls(item[0], devs(item[1].data)) for item in hosts] + + +def _mk_orch_methods(cls): + # Needs to be defined outside of for. + # Otherwise meth is always bound to last key + def shim(method_name): + def inner(self, *args, **kwargs): + completion = self._oremote(method_name, args, kwargs) + self._update_completion_progress(completion, 0) + return completion + return inner + + for meth in Orchestrator.__dict__: + if not meth.startswith('_') and meth not in ['is_orchestrator_module']: + setattr(cls, meth, shim(meth)) + return cls + + +@_mk_orch_methods +class OrchestratorClientMixin(Orchestrator): + """ + A module that inherents from `OrchestratorClientMixin` can directly call + all :class:`Orchestrator` methods without manually calling remote. + + Every interface method from ``Orchestrator`` is converted into a stub method that internally + calls :func:`OrchestratorClientMixin._oremote` + + >>> class MyModule(OrchestratorClientMixin): + ... def func(self): + ... completion = self.add_host('somehost') # calls `_oremote()` + ... self._orchestrator_wait([completion]) + ... self.log.debug(completion.result) + + """ + + def set_mgr(self, mgr): + # type: (MgrModule) -> None + """ + Useable in the Dashbord that uses a global ``mgr`` + """ + + self.__mgr = mgr # Make sure we're not overwriting any other `mgr` properties + + def _oremote(self, meth, args, kwargs): + """ + Helper for invoking `remote` on whichever orchestrator is enabled + + :raises RuntimeError: If the remote method failed. + :raises OrchestratorError: orchestrator failed to perform + :raises ImportError: no `orchestrator_cli` module or backend not found. + """ + try: + mgr = self.__mgr + except AttributeError: + mgr = self + try: + o = mgr._select_orchestrator() + except AttributeError: + o = mgr.remote('orchestrator_cli', '_select_orchestrator') + + if o is None: + raise NoOrchestrator() + + mgr.log.debug("_oremote {} -> {}.{}(*{}, **{})".format(mgr.module_name, o, meth, args, kwargs)) + return mgr.remote(o, meth, *args, **kwargs) + + def _update_completion_progress(self, completion, force_progress=None): + # type: (WriteCompletion, Optional[float]) -> None + try: + progress = force_progress if force_progress is not None else completion.progress + if completion.is_complete: + self.remote("progress", "complete", completion.progress_id) + else: + self.remote("progress", "update", completion.progress_id, str(completion), progress, + ["orchestrator"]) + except AttributeError: + # No WriteCompletion. Ignore. + pass + except ImportError: + # If the progress module is disabled that's fine, + # they just won't see the output. + pass + + def _orchestrator_wait(self, completions): + # type: (List[_Completion]) -> None + """ + Wait for completions to complete (reads) or + become persistent (writes). + + Waits for writes to be *persistent* but not *effective*. + + :param completions: List of Completions + :raises NoOrchestrator: + :raises ImportError: no `orchestrator_cli` module or backend not found. + """ + for c in completions: + self._update_completion_progress(c) + while not self.wait(completions): + if any(c.should_wait for c in completions): + time.sleep(5) + else: + break + for c in completions: + self._update_completion_progress(c) + + +class OutdatableData(object): + DATEFMT = '%Y-%m-%d %H:%M:%S.%f' + + def __init__(self, data=None, last_refresh=None): + # type: (Optional[dict], Optional[datetime.datetime]) -> None + self._data = data + if data is not None and last_refresh is None: + self.last_refresh = datetime.datetime.utcnow() + else: + self.last_refresh = last_refresh + + def json(self): + if self.last_refresh is not None: + timestr = self.last_refresh.strftime(self.DATEFMT) + else: + timestr = None + + return { + "data": self._data, + "last_refresh": timestr, + } + + @property + def data(self): + return self._data + + # @data.setter + # No setter, as it doesn't work as expected: It's not saved in store automatically + + @classmethod + def time_from_string(cls, timestr): + if timestr is None: + return None + # drop the 'Z' timezone indication, it's always UTC + timestr = timestr.rstrip('Z') + return datetime.datetime.strptime(timestr, cls.DATEFMT) + + + @classmethod + def from_json(cls, data): + return cls(data['data'], cls.time_from_string(data['last_refresh'])) + + def outdated(self, timeout_min=None): + if timeout_min is None: + timeout_min = 10 + if self.last_refresh is None: + return True + cutoff = datetime.datetime.utcnow() - datetime.timedelta( + minutes=timeout_min) + return self.last_refresh < cutoff + + def __repr__(self): + return 'OutdatableData(data={}, last_refresh={})'.format(self._data, self.last_refresh) + + +class OutdatableDictMixin(object): + """ + Toolbox for implementing a cache. As every orchestrator has + different needs, we cannot implement any logic here. + """ + + def __getitem__(self, item): + # type: (str) -> OutdatableData + return OutdatableData.from_json(super(OutdatableDictMixin, self).__getitem__(item)) + + def __setitem__(self, key, value): + # type: (str, OutdatableData) -> None + val = None if value is None else value.json() + super(OutdatableDictMixin, self).__setitem__(key, val) + + def items(self): + # type: () -> Iterator[Tuple[str, OutdatableData]] + for item in super(OutdatableDictMixin, self).items(): + k, v = item + yield k, OutdatableData.from_json(v) + + def items_filtered(self, keys=None): + if keys: + return [(host, self[host]) for host in keys] + else: + return list(self.items()) + + def any_outdated(self, timeout=None): + items = self.items() + if not list(items): + return True + return any([i[1].outdated(timeout) for i in items]) + + def remove_outdated(self): + outdated = [item[0] for item in self.items() if item[1].outdated()] + for o in outdated: + del self[o] + +class OutdatablePersistentDict(OutdatableDictMixin, PersistentStoreDict): + pass + +class OutdatableDict(OutdatableDictMixin, dict): + pass diff --git a/src/pybind/mgr/orchestrator_cli/.gitignore b/src/pybind/mgr/orchestrator_cli/.gitignore new file mode 100644 index 00000000..43a2d269 --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/.gitignore @@ -0,0 +1 @@ +wheelhouse* diff --git a/src/pybind/mgr/orchestrator_cli/CMakeLists.txt b/src/pybind/mgr/orchestrator_cli/CMakeLists.txt new file mode 100644 index 00000000..195b79ad --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/CMakeLists.txt @@ -0,0 +1,7 @@ +set(MGR_ORCHESTRATOR_CLI_VIRTUALENV ${CEPH_BUILD_VIRTUALENV}/mgr-orchestrator_cli-virtualenv) + +add_custom_target(mgr-orchestrator_cli-test-venv + COMMAND ${CMAKE_SOURCE_DIR}/src/tools/setup-virtualenv.sh --python=${MGR_PYTHON_EXECUTABLE} ${MGR_ORCHESTRATOR_CLI_VIRTUALENV} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/mgr/orchestrator_cli + COMMENT "orchestrator_cli tests virtualenv is being created") +add_dependencies(tests mgr-orchestrator_cli-test-venv) diff --git a/src/pybind/mgr/orchestrator_cli/README.md b/src/pybind/mgr/orchestrator_cli/README.md new file mode 100644 index 00000000..e4cbcdfc --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/README.md @@ -0,0 +1,16 @@ +# Orchestrator CLI + +See also [../../../doc/mgr/orchestrator_cli.rst](../../../doc/mgr/orchestrator_cli.rst). + +## Running the Teuthology tests + +To run the API tests against a real Ceph cluster, we leverage the Teuthology +framework and the `test_orchestrator` backend. + +``source`` the script and run the tests manually:: + + $ pushd ../dashboard ; source ./run-backend-api-tests.sh ; popd + $ run_teuthology_tests tasks.mgr.test_orchestrator_cli + $ cleanup_teuthology + + \ No newline at end of file diff --git a/src/pybind/mgr/orchestrator_cli/__init__.py b/src/pybind/mgr/orchestrator_cli/__init__.py new file mode 100644 index 00000000..07c29b47 --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/__init__.py @@ -0,0 +1,10 @@ +from __future__ import absolute_import +import os + +if 'UNITTEST' not in os.environ: + from .module import OrchestratorCli +else: + import sys + import mock + sys.path.append("..") + sys.modules['ceph_module'] = mock.Mock() diff --git a/src/pybind/mgr/orchestrator_cli/module.py b/src/pybind/mgr/orchestrator_cli/module.py new file mode 100644 index 00000000..6225b5ad --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/module.py @@ -0,0 +1,437 @@ +import errno +import json + +try: + from typing import Dict, List +except ImportError: + pass # just for type checking. + +from functools import wraps + +from mgr_module import MgrModule, HandleCommandResult, CLICommand + +import orchestrator + + +def handle_exception(prefix, cmd_args, desc, perm, func): + @wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except (orchestrator.OrchestratorError, ImportError) as e: + # Do not print Traceback for expected errors. + return HandleCommandResult(-errno.ENOENT, stderr=str(e)) + except NotImplementedError: + msg = 'This Orchestrator does not support `{}`'.format(prefix) + return HandleCommandResult(-errno.ENOENT, stderr=msg) + + return CLICommand(prefix, cmd_args, desc, perm)(wrapper) + + +def _cli_command(perm): + def inner_cli_command(prefix, cmd_args="", desc=""): + return lambda func: handle_exception(prefix, cmd_args, desc, perm, func) + return inner_cli_command + + +_read_cli = _cli_command('r') +_write_cli = _cli_command('rw') + +class OrchestratorCli(orchestrator.OrchestratorClientMixin, MgrModule): + MODULE_OPTIONS = [ + {'name': 'orchestrator'} + ] + + def _select_orchestrator(self): + return self.get_module_option("orchestrator") + + @_write_cli('orchestrator host add', + "name=host,type=CephString,req=true", + 'Add a host') + def _add_host(self, host): + completion = self.add_host(host) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult(stdout=str(completion.result)) + + @_write_cli('orchestrator host rm', + "name=host,type=CephString,req=true", + 'Remove a host') + def _remove_host(self, host): + completion = self.remove_host(host) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult(stdout=str(completion.result)) + + @_read_cli('orchestrator host ls', + desc='List hosts') + def _get_hosts(self): + completion = self.get_hosts() + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + result = "\n".join(map(lambda node: node.name, completion.result)) + return HandleCommandResult(stdout=result) + + @_read_cli('orchestrator device ls', + "name=host,type=CephString,n=N,req=false " + "name=format,type=CephChoices,strings=json|plain,req=false " + "name=refresh,type=CephBool,req=false", + 'List devices on a node') + def _list_devices(self, host=None, format='plain', refresh=False): + # type: (List[str], str, bool) -> HandleCommandResult + """ + Provide information about storage devices present in cluster hosts + + Note: this does not have to be completely synchronous. Slightly out of + date hardware inventory is fine as long as hardware ultimately appears + in the output of this command. + """ + nf = orchestrator.InventoryFilter(nodes=host) if host else None + + completion = self.get_inventory(node_filter=nf, refresh=refresh) + + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + + if format == 'json': + data = [n.to_json() for n in completion.result] + return HandleCommandResult(stdout=json.dumps(data)) + else: + # Return a human readable version + result = "" + + for inventory_node in completion.result: + result += "Host {0}:\n".format(inventory_node.name) + + if inventory_node.devices: + result += inventory_node.devices[0].pretty_print(only_header=True) + else: + result += "No storage devices found" + + for d in inventory_node.devices: + result += d.pretty_print() + result += "\n" + + return HandleCommandResult(stdout=result) + + @_read_cli('orchestrator service ls', + "name=host,type=CephString,req=false " + "name=svc_type,type=CephChoices,strings=mon|mgr|osd|mds|iscsi|nfs|rgw|rbd-mirror,req=false " + "name=svc_id,type=CephString,req=false " + "name=format,type=CephChoices,strings=json|plain,req=false " + "name=refresh,type=CephBool,req=false", + 'List services known to orchestrator') + def _list_services(self, host=None, svc_type=None, svc_id=None, format='plain', refresh=False): + # XXX this is kind of confusing for people because in the orchestrator + # context the service ID for MDS is the filesystem ID, not the daemon ID + + completion = self.describe_service(svc_type, svc_id, host, refresh=refresh) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + services = completion.result + + # Sort the list for display + services.sort(key=lambda s: (s.service_type, s.nodename, s.service_instance)) + + if len(services) == 0: + return HandleCommandResult(stdout="No services reported") + elif format == 'json': + data = [s.to_json() for s in services] + return HandleCommandResult(stdout=json.dumps(data)) + else: + lines = [] + for s in services: + if s.service == None: + service_id = s.service_instance + else: + service_id = "{0}.{1}".format(s.service, s.service_instance) + + lines.append("{0} {1} {2} {3} {4} {5}".format( + s.service_type, + service_id, + s.nodename, + s.container_id, + s.version, + s.rados_config_location)) + + return HandleCommandResult(stdout="\n".join(lines)) + + @_write_cli('orchestrator osd create', + "name=svc_arg,type=CephString,req=false", + 'Create an OSD service. Either --svc_arg=host:drives or -i ') + def _create_osd(self, svc_arg=None, inbuf=None): + # type: (str, str) -> HandleCommandResult + """Create one or more OSDs""" + + usage = """ +Usage: + ceph orchestrator osd create -i + ceph orchestrator osd create host:device1,device2,... +""" + + if inbuf: + try: + drive_group = orchestrator.DriveGroupSpec.from_json(json.loads(inbuf)) + except ValueError as e: + msg = 'Failed to read JSON input: {}'.format(str(e)) + usage + return HandleCommandResult(-errno.EINVAL, stderr=msg) + + elif svc_arg: + try: + node_name, block_device = svc_arg.split(":") + block_devices = block_device.split(',') + except (TypeError, KeyError, ValueError): + msg = "Invalid host:device spec: '{}'".format(svc_arg) + usage + return HandleCommandResult(-errno.EINVAL, stderr=msg) + + devs = orchestrator.DeviceSelection(paths=block_devices) + drive_group = orchestrator.DriveGroupSpec(node_name, data_devices=devs) + else: + return HandleCommandResult(-errno.EINVAL, stderr=usage) + + # TODO: Remove this and make the orchestrator composable + # Like a future or so. + host_completion = self.get_hosts() + self._orchestrator_wait([host_completion]) + orchestrator.raise_if_exception(host_completion) + all_hosts = [h.name for h in host_completion.result] + + try: + drive_group.validate(all_hosts) + except orchestrator.DriveGroupValidationError as e: + return HandleCommandResult(-errno.EINVAL, stderr=str(e)) + + completion = self.create_osds(drive_group, all_hosts) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + self.log.warning(str(completion.result)) + return HandleCommandResult(stdout=str(completion.result)) + + @_write_cli('orchestrator osd rm', + "name=svc_id,type=CephString,n=N", + 'Remove OSD services') + def _osd_rm(self, svc_id): + # type: (List[str]) -> HandleCommandResult + """ + Remove OSD's + :cmd : Arguments for remove the osd + """ + completion = self.remove_osds(svc_id) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult(stdout=str(completion.result)) + + def _add_stateless_svc(self, svc_type, spec): + completion = self.add_stateless_service(svc_type, spec) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult() + + @_write_cli('orchestrator mds add', + "name=svc_arg,type=CephString", + 'Create an MDS service') + def _mds_add(self, svc_arg): + spec = orchestrator.StatelessServiceSpec() + spec.name = svc_arg + return self._add_stateless_svc("mds", spec) + + @_write_cli('orchestrator rgw add', + "name=svc_arg,type=CephString", + 'Create an RGW service') + def _rgw_add(self, svc_arg): + spec = orchestrator.StatelessServiceSpec() + spec.name = svc_arg + return self._add_stateless_svc("rgw", spec) + + @_write_cli('orchestrator nfs add', + "name=svc_arg,type=CephString " + "name=pool,type=CephString " + "name=namespace,type=CephString,req=false", + 'Create an NFS service') + def _nfs_add(self, svc_arg, pool, namespace=None): + spec = orchestrator.StatelessServiceSpec() + spec.name = svc_arg + spec.extended = { "pool":pool } + if namespace is not None: + spec.extended["namespace"] = namespace + return self._add_stateless_svc("nfs", spec) + + def _rm_stateless_svc(self, svc_type, svc_id): + completion = self.remove_stateless_service(svc_type, svc_id) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult() + + @_write_cli('orchestrator mds rm', + "name=svc_id,type=CephString", + 'Remove an MDS service') + def _mds_rm(self, svc_id): + return self._rm_stateless_svc("mds", svc_id) + + @_write_cli('orchestrator rgw rm', + "name=svc_id,type=CephString", + 'Remove an RGW service') + def _rgw_rm(self, svc_id): + return self._rm_stateless_svc("rgw", svc_id) + + @_write_cli('orchestrator nfs rm', + "name=svc_id,type=CephString", + 'Remove an NFS service') + def _nfs_rm(self, svc_id): + return self._rm_stateless_svc("nfs", svc_id) + + @_write_cli('orchestrator nfs update', + "name=svc_id,type=CephString " + "name=num,type=CephInt", + 'Scale an NFS service') + def _nfs_update(self, svc_id, num): + spec = orchestrator.StatelessServiceSpec() + spec.name = svc_id + spec.count = num + completion = self.update_stateless_service("nfs", spec) + self._orchestrator_wait([completion]) + return HandleCommandResult() + + @_write_cli('orchestrator service', + "name=action,type=CephChoices,strings=start|stop|reload " + "name=svc_type,type=CephString " + "name=svc_name,type=CephString", + 'Start, stop or reload an entire service (i.e. all daemons)') + def _service_action(self, action, svc_type, svc_name): + completion = self.service_action(action, svc_type, service_name=svc_name) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult() + + @_write_cli('orchestrator service-instance', + "name=action,type=CephChoices,strings=start|stop|reload " + "name=svc_type,type=CephString " + "name=svc_id,type=CephString", + 'Start, stop or reload a specific service instance') + def _service_instance_action(self, action, svc_type, svc_id): + completion = self.service_action(action, svc_type, service_id=svc_id) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult() + + @_write_cli('orchestrator mgr update', + "name=num,type=CephInt,req=true " + "name=hosts,type=CephString,n=N,req=false", + 'Update the number of manager instances') + def _update_mgrs(self, num, hosts=None): + hosts = hosts if hosts is not None else [] + + if num <= 0: + return HandleCommandResult(-errno.EINVAL, + stderr="Invalid number of mgrs: require {} > 0".format(num)) + + completion = self.update_mgrs(num, hosts) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult(stdout=str(completion.result)) + + @_write_cli('orchestrator mon update', + "name=num,type=CephInt,req=true " + "name=hosts,type=CephString,n=N,req=false", + 'Update the number of monitor instances') + def _update_mons(self, num, hosts=None): + hosts = hosts if hosts is not None else [] + + if num <= 0: + return HandleCommandResult(-errno.EINVAL, + stderr="Invalid number of mons: require {} > 0".format(num)) + + def split_host(host): + """Split host into host and network parts""" + # TODO: stricter validation + parts = host.split(":") + if len(parts) == 1: + return (parts[0], None) + elif len(parts) == 2: + return (parts[0], parts[1]) + else: + raise RuntimeError("Invalid host specification: " + "'{}'".format(host)) + + if hosts: + try: + hosts = list(map(split_host, hosts)) + except Exception as e: + msg = "Failed to parse host list: '{}': {}".format(hosts, e) + return HandleCommandResult(-errno.EINVAL, stderr=msg) + + completion = self.update_mons(num, hosts) + self._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + return HandleCommandResult(stdout=str(completion.result)) + + @_write_cli('orchestrator set backend', + "name=module_name,type=CephString,req=true", + 'Select orchestrator module backend') + def _set_backend(self, module_name): + """ + We implement a setter command instead of just having the user + modify the setting directly, so that we can validate they're setting + it to a module that really exists and is enabled. + + There isn't a mechanism for ensuring they don't *disable* the module + later, but this is better than nothing. + """ + mgr_map = self.get("mgr_map") + + if module_name is None or module_name == "": + self.set_module_option("orchestrator", None) + return HandleCommandResult() + + for module in mgr_map['available_modules']: + if module['name'] != module_name: + continue + + if not module['can_run']: + continue + + enabled = module['name'] in mgr_map['modules'] + if not enabled: + return HandleCommandResult(-errno.EINVAL, + stderr="Module '{module_name}' is not enabled. \n Run " + "`ceph mgr module enable {module_name}` " + "to enable.".format(module_name=module_name)) + + try: + is_orchestrator = self.remote(module_name, + "is_orchestrator_module") + except NameError: + is_orchestrator = False + + if not is_orchestrator: + return HandleCommandResult(-errno.EINVAL, + stderr="'{0}' is not an orchestrator module".format(module_name)) + + self.set_module_option("orchestrator", module_name) + + return HandleCommandResult() + + return HandleCommandResult(-errno.EINVAL, stderr="Module '{0}' not found".format(module_name)) + + @_read_cli('orchestrator status', + desc='Report configured backend and its status') + def _status(self): + o = self._select_orchestrator() + if o is None: + raise orchestrator.NoOrchestrator() + + avail, why = self.available() + if avail is None: + # The module does not report its availability + return HandleCommandResult(stdout="Backend: {0}".format(o)) + else: + return HandleCommandResult(stdout="Backend: {0}\nAvailable: {1}{2}".format( + o, avail, + " ({0})".format(why) if not avail else "" + )) + + def self_test(self): + old_orch = self._select_orchestrator() + self._set_backend('') + assert self._select_orchestrator() is None + self._set_backend(old_orch) diff --git a/src/pybind/mgr/orchestrator_cli/requirements.txt b/src/pybind/mgr/orchestrator_cli/requirements.txt new file mode 100644 index 00000000..e75b578d --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/requirements.txt @@ -0,0 +1,2 @@ +tox==2.9.1 +importlib_metadata==2.1.0 diff --git a/src/pybind/mgr/orchestrator_cli/run-tox.sh b/src/pybind/mgr/orchestrator_cli/run-tox.sh new file mode 100644 index 00000000..32b24f55 --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/run-tox.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +function dump_envvars { + echo "WITH_PYTHON2: ->$WITH_PYTHON2<-" + echo "WITH_PYTHON3: ->$WITH_PYTHON3<-" + echo "TOX_PATH: ->$TOX_PATH<-" + echo "ENV_LIST: ->$ENV_LIST<-" +} + +# run from ./ or from ../ +: ${MGR_ORCHESTRATOR_CLI_VIRTUALENV:=$CEPH_BUILD_DIR/mgr-orchestrator_cli-virtualenv} +: ${WITH_PYTHON2:=ON} +: ${WITH_PYTHON3:=3} +: ${CEPH_BUILD_DIR:=$PWD/.tox} +test -d orchestrator_cli && cd orchestrator_cli + +if [ -e tox.ini ]; then + TOX_PATH=$(readlink -f tox.ini) +else + TOX_PATH=$(readlink -f $(dirname $0)/tox.ini) +fi + +# tox.ini will take care of this. +unset PYTHONPATH +export CEPH_BUILD_DIR=$CEPH_BUILD_DIR + +if [ -f ${MGR_ORCHESTRATOR_CLI_VIRTUALENV}/bin/activate ] +then + source ${MGR_ORCHESTRATOR_CLI_VIRTUALENV}/bin/activate +fi + +if [ "$WITH_PYTHON2" = "ON" ]; then + ENV_LIST+="py27," +fi +# WITH_PYTHON3 might be set to "ON" or to the python3 RPM version number +# prevailing on the system - e.g. "3", "36" +if [[ "$WITH_PYTHON3" =~ (^3|^ON) ]]; then + ENV_LIST+="py3," +fi +# use bash string manipulation to strip off any trailing comma +ENV_LIST=${ENV_LIST%,} + +tox -c "${TOX_PATH}" -e "${ENV_LIST}" "$@" +TOX_STATUS="$?" +test "$TOX_STATUS" -ne "0" && dump_envvars +exit $TOX_STATUS diff --git a/src/pybind/mgr/orchestrator_cli/test_orchestrator.py b/src/pybind/mgr/orchestrator_cli/test_orchestrator.py new file mode 100644 index 00000000..834cd4d7 --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/test_orchestrator.py @@ -0,0 +1,48 @@ +from __future__ import absolute_import +import pytest + + +from orchestrator import DriveGroupSpec, DeviceSelection, DriveGroupValidationError, \ + InventoryDevice, ReadCompletion, raise_if_exception + + +def test_DriveGroup(): + dg_json = { + 'host_pattern': 'hostname', + 'data_devices': {'paths': ['/dev/sda']} + } + + dg = DriveGroupSpec.from_json(dg_json) + assert dg.hosts(['hostname']) == ['hostname'] + assert dg.data_devices.paths == ['/dev/sda'] + + +def test_DriveGroup_fail(): + with pytest.raises(TypeError): + DriveGroupSpec.from_json({}) + + +def test_drivegroup_pattern(): + dg = DriveGroupSpec('node[1-3]', DeviceSelection()) + assert dg.hosts(['node{}'.format(i) for i in range(10)]) == ['node1', 'node2', 'node3'] + + +def test_drive_selection(): + devs = DeviceSelection(paths=['/dev/sda']) + spec = DriveGroupSpec('node_name', data_devices=devs) + assert spec.data_devices.paths == ['/dev/sda'] + + with pytest.raises(DriveGroupValidationError, match='exclusive'): + DeviceSelection(paths=['/dev/sda'], rotates=False) + +def test_inventory_device(): + i_d = InventoryDevice() + s = i_d.pretty_print() + assert len(s) + + +def test_raise(): + c = ReadCompletion() + c.exception = ZeroDivisionError() + with pytest.raises(ZeroDivisionError): + raise_if_exception(c) diff --git a/src/pybind/mgr/orchestrator_cli/tox.ini b/src/pybind/mgr/orchestrator_cli/tox.ini new file mode 100644 index 00000000..94dd70dd --- /dev/null +++ b/src/pybind/mgr/orchestrator_cli/tox.ini @@ -0,0 +1,18 @@ +[tox] +envlist = py27,py3 +skipsdist = true +toxworkdir = {env:CEPH_BUILD_DIR}/orchestrator_cli +minversion = 2.5 + +[testenv] +deps = + pytest + mock + requests-mock +setenv= + UNITTEST = true + py27: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.2 + py3: PYTHONPATH = {env:CEPH_LIB}/cython_modules/lib.3 + +commands= + {envbindir}/py.test . diff --git a/src/pybind/mgr/osd_perf_query/__init__.py b/src/pybind/mgr/osd_perf_query/__init__.py new file mode 100644 index 00000000..691ef4dd --- /dev/null +++ b/src/pybind/mgr/osd_perf_query/__init__.py @@ -0,0 +1 @@ +from .module import OSDPerfQuery diff --git a/src/pybind/mgr/osd_perf_query/module.py b/src/pybind/mgr/osd_perf_query/module.py new file mode 100644 index 00000000..ee5c8ba8 --- /dev/null +++ b/src/pybind/mgr/osd_perf_query/module.py @@ -0,0 +1,194 @@ + +""" +osd_perf_query module +""" + +from itertools import groupby +from time import time +import errno +import prettytable + +from mgr_module import MgrModule + +def get_human_readable(bytes, precision=2): + suffixes = ['', 'Ki', 'Mi', 'Gi', 'Ti'] + suffix_index = 0 + while bytes > 1024 and suffix_index < 4: + # increment the index of the suffix + suffix_index += 1 + # apply the division + bytes = bytes / 1024.0 + return '%.*f%s' % (precision, bytes, suffixes[suffix_index]) + +class OSDPerfQuery(MgrModule): + COMMANDS = [ + { + "cmd": "osd perf query add " + "name=query,type=CephChoices," + "strings=client_id|rbd_image_id|all_subkeys", + "desc": "add osd perf query", + "perm": "w" + }, + { + "cmd": "osd perf query remove " + "name=query_id,type=CephInt,req=true", + "desc": "remove osd perf query", + "perm": "w" + }, + { + "cmd": "osd perf counters get " + "name=query_id,type=CephInt,req=true", + "desc": "fetch osd perf counters", + "perm": "w" + }, + ] + + CLIENT_ID_QUERY = { + 'key_descriptor': [ + {'type': 'client_id', 'regex': '^(.+)$'}, + ], + 'performance_counter_descriptors': [ + 'bytes', 'write_ops', 'read_ops', 'write_bytes', 'read_bytes', + 'write_latency', 'read_latency', + ], + 'limit': {'order_by': 'bytes', 'max_count': 10}, + } + + RBD_IMAGE_ID_QUERY = { + 'key_descriptor': [ + {'type': 'pool_id', 'regex': '^(.+)$'}, + {'type': 'object_name', + 'regex': '^(?:rbd|journal)_data\.(?:([0-9]+)\.)?([^.]+)\.'}, + ], + 'performance_counter_descriptors': [ + 'bytes', 'write_ops', 'read_ops', 'write_bytes', 'read_bytes', + 'write_latency', 'read_latency', + ], + 'limit': {'order_by': 'bytes', 'max_count': 10}, + } + + ALL_SUBKEYS_QUERY = { + 'key_descriptor': [ + {'type': 'client_id', 'regex': '^(.*)$'}, + {'type': 'client_address', 'regex': '^(.*)$'}, + {'type': 'pool_id', 'regex': '^(.*)$'}, + {'type': 'namespace', 'regex': '^(.*)$'}, + {'type': 'osd_id', 'regex': '^(.*)$'}, + {'type': 'pg_id', 'regex': '^(.*)$'}, + {'type': 'object_name', 'regex': '^(.*)$'}, + {'type': 'snap_id', 'regex': '^(.*)$'}, + ], + 'performance_counter_descriptors': [ + 'write_ops', 'read_ops', + ], + } + + queries = {} + + def handle_command(self, inbuf, cmd): + if cmd['prefix'] == "osd perf query add": + if cmd['query'] == 'rbd_image_id': + query = self.RBD_IMAGE_ID_QUERY + elif cmd['query'] == 'client_id': + query = self.CLIENT_ID_QUERY + else: + query = self.ALL_SUBKEYS_QUERY + query_id = self.add_osd_perf_query(query) + if query_id is None: + return -errno.EINVAL, "", "Invalid query" + self.queries[query_id] = [query, time()] + return 0, str(query_id), "added query " + cmd['query'] + " with id " + str(query_id) + elif cmd['prefix'] == "osd perf query remove": + if cmd['query_id'] not in self.queries: + return -errno.ENOENT, "", "unknown query id " + str(cmd['query_id']) + self.remove_osd_perf_query(cmd['query_id']) + del self.queries[cmd['query_id']] + return 0, "", "removed query with id " + str(cmd['query_id']) + elif cmd['prefix'] == "osd perf counters get": + if cmd['query_id'] not in self.queries: + return -errno.ENOENT, "", "unknown query id " + str(cmd['query_id']) + + query = self.queries[cmd['query_id']][0] + res = self.get_osd_perf_counters(cmd['query_id']) + now = time() + last_update = self.queries[cmd['query_id']][1] + descriptors = query['performance_counter_descriptors'] + + if query == self.RBD_IMAGE_ID_QUERY: + column_names = ["pool_id", "rbd image_id"] + else: + column_names = [sk['type'] for sk in query['key_descriptor']] + for d in descriptors: + desc = d + if d in ['bytes']: + continue + elif d in ['write_bytes', 'read_bytes']: + desc += '/sec' + elif d in ['write_latency', 'read_latency']: + desc += '(msec)' + column_names.append(desc) + + table = prettytable.PrettyTable(tuple(column_names), + hrules=prettytable.FRAME) + + if query == self.RBD_IMAGE_ID_QUERY: + # typical output: + # {'k': [['3'], ['', '16fe5b5a8435e']], + # 'c': [[1024, 0], [1, 0], ...]} + # pool id fixup: if the object_name regex has matched pool id + # use it as the image pool id + for c in res['counters']: + if c['k'][1][0]: + c['k'][0][0] = c['k'][1][0] + # group by (pool_id, image_id) + processed = [] + res['counters'].sort(key=lambda c: [c['k'][0][0], c['k'][1][1]]) + for key, group in groupby(res['counters'], + lambda c: [c['k'][0][0], c['k'][1][1]]): + counters = [[0, 0] for x in descriptors] + for c in group: + for i in range(len(counters)): + counters[i][0] += c['c'][i][0] + counters[i][1] += c['c'][i][1] + processed.append({'k' : key, 'c' : counters}) + else: + # typical output: + # {'k': [['client.94348']], 'c': [[1024, 0], [1, 0], ...]} + processed = res['counters'] + + max_count = len(processed) + if 'limit' in query: + if 'max_count' in query['limit']: + max_count = query['limit']['max_count'] + if 'order_by' in query['limit']: + i = descriptors.index(query['limit']['order_by']) + processed.sort(key=lambda x: x['c'][i][0], reverse=True) + for c in processed[:max_count]: + if query == self.RBD_IMAGE_ID_QUERY: + row = c['k'] + else: + row = [sk[0] for sk in c['k']] + counters = c['c'] + for i in range(len(descriptors)): + if descriptors[i] in ['bytes']: + continue + elif descriptors[i] in ['write_bytes', 'read_bytes']: + bps = counters[i][0] / (now - last_update) + row.append(get_human_readable(bps)) + elif descriptors[i] in ['write_latency', 'read_latency']: + lat = 0 + if counters[i][1] > 0: + lat = 1.0 * counters[i][0] / counters[i][1] / 1000000 + row.append("%.2f" % lat) + else: + row.append("%d" % counters[i][0]) + table.add_row(row) + + msg = "counters for the query id %d for the last %d sec" % \ + (cmd['query_id'], now - last_update) + self.queries[cmd['query_id']][1] = now + + return 0, table.get_string() + "\n", msg + else: + raise NotImplementedError(cmd['prefix']) + diff --git a/src/pybind/mgr/pg_autoscaler/__init__.py b/src/pybind/mgr/pg_autoscaler/__init__.py new file mode 100644 index 00000000..e7c7b8fc --- /dev/null +++ b/src/pybind/mgr/pg_autoscaler/__init__.py @@ -0,0 +1 @@ +from .module import PgAutoscaler diff --git a/src/pybind/mgr/pg_autoscaler/module.py b/src/pybind/mgr/pg_autoscaler/module.py new file mode 100644 index 00000000..3d5d5175 --- /dev/null +++ b/src/pybind/mgr/pg_autoscaler/module.py @@ -0,0 +1,507 @@ +""" +Automatically scale pg_num based on how much data is stored in each pool. +""" + +import errno +import json +import mgr_util +import threading +import uuid +from six import itervalues, iteritems +from collections import defaultdict +from prettytable import PrettyTable, PLAIN_COLUMNS + +from mgr_module import MgrModule + +""" +Some terminology is made up for the purposes of this module: + + - "raw pgs": pg count after applying replication, i.e. the real resource + consumption of a pool. + - "grow/shrink" - increase/decrease the pg_num in a pool + - "crush subtree" - non-overlapping domains in crush hierarchy: used as + units of resource management. +""" + +INTERVAL = 5 + +PG_NUM_MIN = 32 # unless specified on a per-pool basis + +def nearest_power_of_two(n): + v = int(n) + + v -= 1 + v |= v >> 1 + v |= v >> 2 + v |= v >> 4 + v |= v >> 8 + v |= v >> 16 + + # High bound power of two + v += 1 + + # Low bound power of tow + x = v >> 1 + + return x if (v - n) > (n - x) else v + +def effective_target_ratio(target_ratio, total_target_ratio, total_target_bytes, capacity): + """ + Returns the target ratio after normalizing for ratios across pools and + adjusting for capacity reserved by pools that have target_size_bytes set. + """ + target_ratio = float(target_ratio) + if total_target_ratio: + target_ratio = target_ratio / total_target_ratio + + if total_target_bytes and capacity: + fraction_available = 1.0 - min(1.0, float(total_target_bytes) / capacity) + target_ratio *= fraction_available + + return target_ratio + + +class PgAdjustmentProgress(object): + """ + Keeps the initial and target pg_num values + """ + def __init__(self, pg_num, pg_num_target, ev_id, increase_decrease): + self._ev_id = ev_id + self._pg_num = pg_num + self._pg_num_target = pg_num_target + self._increase_decrease = increase_decrease + + +class PgAutoscaler(MgrModule): + """ + PG autoscaler. + """ + COMMANDS = [ + { + "cmd": "osd pool autoscale-status", + "desc": "report on pool pg_num sizing recommendation and intent", + "perm": "r" + }, + ] + + NATIVE_OPTIONS = [ + 'mon_target_pg_per_osd', + 'mon_max_pg_per_osd', + ] + + MODULE_OPTIONS = [ + { + 'name': 'sleep_interval', + 'default': str(60), + }, + ] + + def __init__(self, *args, **kwargs): + super(PgAutoscaler, self).__init__(*args, **kwargs) + self._shutdown = threading.Event() + + # So much of what we do peeks at the osdmap that it's easiest + # to just keep a copy of the pythonized version. + self._osd_map = None + + def config_notify(self): + for opt in self.NATIVE_OPTIONS: + setattr(self, + opt, + self.get_ceph_option(opt)) + self.log.debug(' native option %s = %s', opt, getattr(self, opt)) + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' mgr option %s = %s', + opt['name'], getattr(self, opt['name'])) + + + def handle_command(self, inbuf, cmd): + if cmd['prefix'] == "osd pool autoscale-status": + retval = self._command_autoscale_status(cmd) + else: + assert False # ceph-mgr should never pass us unknown cmds + return retval + + def _command_autoscale_status(self, cmd): + osdmap = self.get_osdmap() + pools = osdmap.get_pools_by_name() + ps, root_map, pool_root = self._get_pool_status(osdmap, pools) + + if cmd.get('format') == 'json' or cmd.get('format') == 'json-pretty': + return 0, json.dumps(ps, indent=2), '' + else: + table = PrettyTable(['POOL', 'SIZE', 'TARGET SIZE', + 'RATE', 'RAW CAPACITY', + 'RATIO', 'TARGET RATIO', + 'EFFECTIVE RATIO', + 'BIAS', + 'PG_NUM', +# 'IDEAL', + 'NEW PG_NUM', 'AUTOSCALE'], + border=False) + table.left_padding_width = 0 + table.right_padding_width = 1 + table.align['POOL'] = 'l' + table.align['SIZE'] = 'r' + table.align['TARGET SIZE'] = 'r' + table.align['RATE'] = 'r' + table.align['RAW CAPACITY'] = 'r' + table.align['RATIO'] = 'r' + table.align['TARGET RATIO'] = 'r' + table.align['EFFECTIVE RATIO'] = 'r' + table.align['BIAS'] = 'r' + table.align['PG_NUM'] = 'r' +# table.align['IDEAL'] = 'r' + table.align['NEW PG_NUM'] = 'r' + table.align['AUTOSCALE'] = 'l' + for p in ps: + if p['would_adjust']: + final = str(p['pg_num_final']) + else: + final = '' + if p['target_bytes'] > 0: + ts = mgr_util.format_bytes(p['target_bytes'], 6) + else: + ts = '' + if p['target_ratio'] > 0.0: + tr = '%.4f' % p['target_ratio'] + else: + tr = '' + if p['effective_target_ratio'] > 0.0: + etr = '%.4f' % p['effective_target_ratio'] + else: + etr = '' + table.add_row([ + p['pool_name'], + mgr_util.format_bytes(p['logical_used'], 6), + ts, + p['raw_used_rate'], + mgr_util.format_bytes(p['subtree_capacity'], 6), + '%.4f' % p['capacity_ratio'], + tr, + etr, + p['bias'], + p['pg_num_target'], +# p['pg_num_ideal'], + final, + p['pg_autoscale_mode'], + ]) + return 0, table.get_string(), '' + + def serve(self): + self.config_notify() + while not self._shutdown.is_set(): + self._maybe_adjust() + self._shutdown.wait(timeout=int(self.sleep_interval)) + + def shutdown(self): + self.log.info('Stopping pg_autoscaler') + self._shutdown.set() + + def get_subtree_resource_status(self, osdmap, crush): + """ + For each CRUSH subtree of interest (i.e. the roots under which + we have pools), calculate the current resource usages and targets, + such as how many PGs there are, vs. how many PGs we would + like there to be. + """ + result = {} + pool_root = {} + roots = [] + + class CrushSubtreeResourceStatus(object): + def __init__(self): + self.root_ids = [] + self.osds = set() + self.osd_count = None # Number of OSDs + self.pg_target = None # Ideal full-capacity PG count? + self.pg_current = 0 # How many PGs already? + self.capacity = None # Total capacity of OSDs in subtree + self.pool_ids = [] + self.pool_names = [] + self.total_target_ratio = 0.0 + self.total_target_bytes = 0 # including replication / EC overhead + + # identify subtrees (note that they may overlap!) + for pool_id, pool in osdmap.get_pools().items(): + cr_name = crush.get_rule_by_id(pool['crush_rule'])['rule_name'] + root_id = int(crush.get_rule_root(cr_name)) + pool_root[pool_id] = root_id + osds = set(crush.get_osds_under(root_id)) + + # do we intersect an existing root? + s = None + for prev in itervalues(result): + if osds & prev.osds: + s = prev + break + if not s: + s = CrushSubtreeResourceStatus() + roots.append(s) + result[root_id] = s + s.root_ids.append(root_id) + s.osds |= osds + s.pool_ids.append(int(pool_id)) + s.pool_names.append(pool['pool_name']) + s.pg_current += pool['pg_num_target'] * pool['size'] + target_ratio = pool['options'].get('target_size_ratio', 0.0) + if target_ratio: + s.total_target_ratio += target_ratio + else: + target_bytes = pool['options'].get('target_size_bytes', 0) + if target_bytes: + s.total_target_bytes += target_bytes * osdmap.pool_raw_used_rate(pool_id) + + # finish subtrees + all_stats = self.get('osd_stats') + for s in roots: + s.osd_count = len(s.osds) + s.pg_target = s.osd_count * int(self.mon_target_pg_per_osd) + + capacity = 0.0 + for osd_stats in all_stats['osd_stats']: + if osd_stats['osd'] in s.osds: + # Intentionally do not apply the OSD's reweight to + # this, because we want to calculate PG counts based + # on the physical storage available, not how it is + # reweighted right now. + capacity += osd_stats['kb'] * 1024 + + s.capacity = capacity + + self.log.debug('root_ids %s pools %s with %d osds, pg_target %d', + s.root_ids, + s.pool_ids, + s.osd_count, + s.pg_target) + + return result, pool_root + + def _get_pool_status( + self, + osdmap, + pools, + threshold=3.0, + ): + assert threshold >= 2.0 + + crush_map = osdmap.get_crush() + + root_map, pool_root = self.get_subtree_resource_status(osdmap, crush_map) + + df = self.get('df') + pool_stats = dict([(p['id'], p['stats']) for p in df['pools']]) + + ret = [] + + # iterate over all pools to determine how they should be sized + for pool_name, p in iteritems(pools): + pool_id = p['pool'] + if pool_id not in pool_stats: + # race with pool deletion; skip + continue + + # FIXME: we assume there is only one take per pool, but that + # may not be true. + cr_name = crush_map.get_rule_by_id(p['crush_rule'])['rule_name'] + root_id = int(crush_map.get_rule_root(cr_name)) + pool_root[pool_name] = root_id + + capacity = root_map[root_id].capacity + if capacity == 0: + self.log.debug('skipping empty subtree %s', cr_name) + continue + + raw_used_rate = osdmap.pool_raw_used_rate(pool_id) + + pool_logical_used = pool_stats[pool_id]['stored'] + bias = p['options'].get('pg_autoscale_bias', 1.0) + target_bytes = 0 + # ratio takes precedence if both are set + if p['options'].get('target_size_ratio', 0.0) == 0.0: + target_bytes = p['options'].get('target_size_bytes', 0) + + # What proportion of space are we using? + actual_raw_used = pool_logical_used * raw_used_rate + actual_capacity_ratio = float(actual_raw_used) / capacity + + pool_raw_used = max(pool_logical_used, target_bytes) * raw_used_rate + capacity_ratio = float(pool_raw_used) / capacity + + self.log.info("effective_target_ratio {0} {1} {2} {3}".format( + p['options'].get('target_size_ratio', 0.0), + root_map[root_id].total_target_ratio, + root_map[root_id].total_target_bytes, + capacity)) + target_ratio = effective_target_ratio(p['options'].get('target_size_ratio', 0.0), + root_map[root_id].total_target_ratio, + root_map[root_id].total_target_bytes, + capacity) + + final_ratio = max(capacity_ratio, target_ratio) + + # So what proportion of pg allowance should we be using? + pool_pg_target = (final_ratio * root_map[root_id].pg_target) / p['size'] * bias + + final_pg_target = max(p['options'].get('pg_num_min', PG_NUM_MIN), + nearest_power_of_two(pool_pg_target)) + + self.log.info("Pool '{0}' root_id {1} using {2} of space, bias {3}, " + "pg target {4} quantized to {5} (current {6})".format( + p['pool_name'], + root_id, + final_ratio, + bias, + pool_pg_target, + final_pg_target, + p['pg_num_target'] + )) + + adjust = False + if (final_pg_target > p['pg_num_target'] * threshold or \ + final_pg_target <= p['pg_num_target'] / threshold) and \ + final_ratio >= 0.0 and \ + final_ratio <= 1.0: + adjust = True + + ret.append({ + 'pool_id': pool_id, + 'pool_name': p['pool_name'], + 'crush_root_id': root_id, + 'pg_autoscale_mode': p['pg_autoscale_mode'], + 'pg_num_target': p['pg_num_target'], + 'logical_used': pool_logical_used, + 'target_bytes': target_bytes, + 'raw_used_rate': raw_used_rate, + 'subtree_capacity': capacity, + 'actual_raw_used': actual_raw_used, + 'raw_used': pool_raw_used, + 'actual_capacity_ratio': actual_capacity_ratio, + 'capacity_ratio': capacity_ratio, + 'target_ratio': p['options'].get('target_size_ratio', 0.0), + 'effective_target_ratio': target_ratio, + 'pg_num_ideal': int(pool_pg_target), + 'pg_num_final': final_pg_target, + 'would_adjust': adjust, + 'bias': p.get('options', {}).get('pg_autoscale_bias', 1.0), + }); + + return (ret, root_map, pool_root) + + + def _maybe_adjust(self): + self.log.info('_maybe_adjust') + osdmap = self.get_osdmap() + pools = osdmap.get_pools_by_name() + ps, root_map, pool_root = self._get_pool_status(osdmap, pools) + + # Anyone in 'warn', set the health message for them and then + # drop them from consideration. + too_few = [] + too_many = [] + bytes_and_ratio = [] + health_checks = {} + + total_bytes = dict([(r, 0) for r in iter(root_map)]) + total_target_bytes = dict([(r, 0.0) for r in iter(root_map)]) + target_bytes_pools = dict([(r, []) for r in iter(root_map)]) + + for p in ps: + pool_opts = pools[p['pool_name']]['options'] + if pool_opts.get('target_size_ratio', 0) > 0 and pool_opts.get('target_size_bytes', 0) > 0: + bytes_and_ratio.append('Pool %s has target_size_bytes and target_size_ratio set' % p['pool_name']) + total_bytes[p['crush_root_id']] += max( + p['actual_raw_used'], + p['target_bytes'] * p['raw_used_rate']) + if p['target_bytes'] > 0: + total_target_bytes[p['crush_root_id']] += p['target_bytes'] * p['raw_used_rate'] + target_bytes_pools[p['crush_root_id']].append(p['pool_name']) + if not p['would_adjust']: + continue + if p['pg_autoscale_mode'] == 'warn': + msg = 'Pool %s has %d placement groups, should have %d' % ( + p['pool_name'], + p['pg_num_target'], + p['pg_num_final']) + if p['pg_num_final'] > p['pg_num_target']: + too_few.append(msg) + else: + too_many.append(msg) + + if p['pg_autoscale_mode'] == 'on': + # Note that setting pg_num actually sets pg_num_target (see + # OSDMonitor.cc) + r = self.mon_command({ + 'prefix': 'osd pool set', + 'pool': p['pool_name'], + 'var': 'pg_num', + 'val': str(p['pg_num_final']) + }) + + if r[0] != 0: + # FIXME: this is a serious and unexpected thing, + # we should expose it as a cluster log error once + # the hook for doing that from ceph-mgr modules is + # in. + self.log.error("pg_num adjustment on {0} to {1} failed: {2}" + .format(p['pool_name'], + p['pg_num_final'], r)) + + if too_few: + summary = "{0} pools have too few placement groups".format( + len(too_few)) + health_checks['POOL_TOO_FEW_PGS'] = { + 'severity': 'warning', + 'summary': summary, + 'detail': too_few + } + if too_many: + summary = "{0} pools have too many placement groups".format( + len(too_many)) + health_checks['POOL_TOO_MANY_PGS'] = { + 'severity': 'warning', + 'summary': summary, + 'detail': too_many + } + + too_much_target_bytes = [] + for root_id, total in iteritems(total_bytes): + total_target = total_target_bytes[root_id] + if total_target > 0 and total > root_map[root_id].capacity and root_map[root_id].capacity: + too_much_target_bytes.append( + 'Pools %s overcommit available storage by %.03fx due to ' + 'target_size_bytes %s on pools %s' % ( + root_map[root_id].pool_names, + total / root_map[root_id].capacity, + mgr_util.format_bytes(total_target, 5, colored=False), + target_bytes_pools[root_id] + ) + ) + elif total_target > root_map[root_id].capacity and root_map[root_id].capacity: + too_much_target_bytes.append( + 'Pools %s overcommit available storage by %.03fx due to ' + 'collective target_size_bytes of %s' % ( + root_map[root_id].pool_names, + total / root_map[root_id].capacity, + mgr_util.format_bytes(total_target, 5, colored=False), + ) + ) + if too_much_target_bytes: + health_checks['POOL_TARGET_SIZE_BYTES_OVERCOMMITTED'] = { + 'severity': 'warning', + 'summary': "%d subtrees have overcommitted pool target_size_bytes" % len(too_much_target_bytes), + 'detail': too_much_target_bytes, + } + + if bytes_and_ratio: + health_checks['POOL_HAS_TARGET_SIZE_BYTES_AND_RATIO'] = { + 'severity': 'warning', + 'summary': "%d pools have both target_size_bytes and target_size_ratio set" % len(bytes_and_ratio), + 'count': len(bytes_and_ratio), + 'detail': bytes_and_ratio, + } + + self.set_health_checks(health_checks) diff --git a/src/pybind/mgr/progress/__init__.py b/src/pybind/mgr/progress/__init__.py new file mode 100644 index 00000000..0f7dab55 --- /dev/null +++ b/src/pybind/mgr/progress/__init__.py @@ -0,0 +1,2 @@ + +from .module import * diff --git a/src/pybind/mgr/progress/module.py b/src/pybind/mgr/progress/module.py new file mode 100644 index 00000000..f880bb6e --- /dev/null +++ b/src/pybind/mgr/progress/module.py @@ -0,0 +1,693 @@ +from mgr_module import MgrModule +import threading +import datetime +import uuid + +import json + + +ENCODING_VERSION = 1 + +# keep a global reference to the module so we can use it from Event methods +_module = None + + +class Event(object): + """ + A generic "event" that has a start time, completion percentage, + and a list of "refs" that are (type, id) tuples describing which + objects (osds, pools) this relates to. + """ + + def __init__(self, message, refs): + self._message = message + self._refs = refs + + self.started_at = datetime.datetime.utcnow() + + self.id = None + + def _refresh(self): + global _module + _module.log.debug('refreshing mgr for %s (%s) at %f' % (self.id, self._message, + self.progress)) + _module.update_progress_event(self.id, self._message, self.progress) + + @property + def message(self): + return self._message + + @property + def refs(self): + return self._refs + + @property + def progress(self): + raise NotImplementedError() + + @property + def failed(self): + return False + + @property + def failure_message(self): + return None + + def summary(self): + return "{0} {1}".format(self.progress, self.message) + + def _progress_str(self, width): + inner_width = width - 2 + out = "[" + done_chars = int(self.progress * inner_width) + out += done_chars * '=' + out += (inner_width - done_chars) * '.' + out += "]" + + return out + + def twoline_progress(self): + """ + e.g. + + - Eating my delicious strudel + [===============..............] + + """ + return "{0}\n {1}".format( + self._message, self._progress_str(30)) + + def to_json(self): + return { + "id": self.id, + "message": self.message, + "refs": self._refs + } + + +class GhostEvent(Event): + """ + The ghost of a completed event: these are the fields that we persist + after the event is complete. + """ + + def __init__(self, my_id, message, refs, + failed=False, failure_message=None): + super(GhostEvent, self).__init__(message, refs) + self.id = my_id + + if failed: + self._failed = True + self._failure_message = failure_message + else: + self._failed = False + + @property + def progress(self): + return 1.0 + + @property + def failed(self): + return self._failed + + @property + def failure_message(self): + return self._failure_message if self._failed else None + + def to_json(self): + d = { + "id": self.id, + "message": self.message, + "refs": self._refs + } + if self._failed: + d["failed"] = True + d["failure_message"] = self._failure_message + return d + + +class RemoteEvent(Event): + """ + An event that was published by another module: we know nothing about + this, rely on the other module to continuously update us with + progress information as it emerges. + """ + + def __init__(self, my_id, message, refs): + super(RemoteEvent, self).__init__(message, refs) + self.id = my_id + self._progress = 0.0 + self._failed = False + self._refresh() + + def set_progress(self, progress): + self._progress = progress + self._refresh() + + def set_failed(self, message): + self._progress = 1.0 + self._failed = True + self._failure_message = message + self._refresh() + + @property + def progress(self): + return self._progress + + @property + def failed(self): + return self._failed + + @property + def failure_message(self): + return self._failure_message if self._failed else None + + +class PgRecoveryEvent(Event): + """ + An event whose completion is determined by the recovery of a set of + PGs to a healthy state. + + Always call update() immediately after construction. + """ + + def __init__(self, message, refs, which_pgs, evacuate_osds): + super(PgRecoveryEvent, self).__init__(message, refs) + + self._pgs = which_pgs + + self._evacuate_osds = evacuate_osds + + self._original_pg_count = len(self._pgs) + + self._original_bytes_recovered = None + + self._progress = 0.0 + + self._start_epoch = _module.get_osdmap().get_epoch() + + self.id = str(uuid.uuid4()) + self._refresh() + + @property + def evacuating_osds(self): + return self. _evacuate_osds + + def pg_update(self, raw_pg_stats, pg_ready, log): + # FIXME: O(pg_num) in python + # FIXME: far more fields getting pythonized than we really care about + pg_to_state = dict([(p['pgid'], p) for p in raw_pg_stats['pg_stats']]) + if self._original_bytes_recovered is None: + self._original_bytes_recovered = {} + missing_pgs = [] + for pg in self._pgs: + pg_str = str(pg) + if pg_str in pg_to_state: + self._original_bytes_recovered[pg] = \ + pg_to_state[pg_str]['stat_sum']['num_bytes_recovered'] + else: + missing_pgs.append(pg) + if pg_ready: + for pg in missing_pgs: + self._pgs.remove(pg) + + complete_accumulate = 0.0 + + # Calculating progress as the number of PGs recovered divided by the + # original where partially completed PGs count for something + # between 0.0-1.0. This is perhaps less faithful than looking at the + # total number of bytes recovered, but it does a better job of + # representing the work still to do if there are a number of very + # few-bytes PGs that still need the housekeeping of their recovery + # to be done. This is subjective... + + complete = set() + for pg in self._pgs: + pg_str = str(pg) + try: + info = pg_to_state[pg_str] + except KeyError: + # The PG is gone! Probably a pool was deleted. Drop it. + complete.add(pg) + continue + # Only checks the state of each PGs when it's epoch >= the OSDMap's epoch + if int(info['reported_epoch']) < int(self._start_epoch): + continue + + state = info['state'] + + states = state.split("+") + + if "active" in states and "clean" in states: + complete.add(pg) + else: + if info['stat_sum']['num_bytes'] == 0: + # Empty PGs are considered 0% done until they are + # in the correct state. + pass + else: + recovered = info['stat_sum']['num_bytes_recovered'] + total_bytes = info['stat_sum']['num_bytes'] + if total_bytes > 0: + ratio = float(recovered - + self._original_bytes_recovered[pg]) / \ + total_bytes + # Since the recovered bytes (over time) could perhaps + # exceed the contents of the PG (moment in time), we + # must clamp this + ratio = min(ratio, 1.0) + + else: + # Dataless PGs (e.g. containing only OMAPs) count + # as half done. + ratio = 0.5 + complete_accumulate += ratio + + self._pgs = list(set(self._pgs) ^ complete) + completed_pgs = self._original_pg_count - len(self._pgs) + self._progress = (completed_pgs + complete_accumulate)\ + / self._original_pg_count + self._refresh() + + log.info("Updated progress to {0} ({1})".format( + self._progress, self._message + )) + + @property + def progress(self): + return self._progress + + +class PgId(object): + def __init__(self, pool_id, ps): + self.pool_id = pool_id + self.ps = ps + + def __cmp__(self, other): + return (self.pool_id, self.ps) == (other.pool_id, other.ps) + + def __lt__(self, other): + return (self.pool_id, self.ps) < (other.pool_id, other.ps) + + def __str__(self): + return "{0}.{1:x}".format(self.pool_id, self.ps) + + +class Module(MgrModule): + COMMANDS = [ + {"cmd": "progress", + "desc": "Show progress of recovery operations", + "perm": "r"}, + {"cmd": "progress json", + "desc": "Show machine readable progress information", + "perm": "r"}, + {"cmd": "progress clear", + "desc": "Reset progress tracking", + "perm": "rw"}, + {"cmd": "progress on", + "desc": "Enable progress tracking", + "perm": "rw"}, + {"cmd": "progress off", + "desc": "Disable progress tracking", + "perm": "rw"} + + ] + + MODULE_OPTIONS = [ + { + 'name': 'max_completed_events', + 'default': 50, + 'type': 'int', + 'desc': 'number of past completed events to remember', + 'runtime': True, + }, + { + 'name': 'persist_interval', + 'default': 5, + 'type': 'secs', + 'desc': 'how frequently to persist completed events', + 'runtime': True, + }, + { + 'name': 'enabled', + 'default': True, + 'type': 'bool', + } + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + + self._events = {} + self._completed_events = [] + + self._old_osd_map = None + + self._ready = threading.Event() + self._shutdown = threading.Event() + + self._latest_osdmap = None + + self._dirty = False + + global _module + _module = self + + def config_notify(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name'])) + + def _osd_in_out(self, old_map, old_dump, new_map, osd_id, marked): + # A function that will create or complete an event when an + # OSD is marked in or out according to the affected PGs + affected_pgs = [] + unmoved_pgs = [] + for pool in old_dump['pools']: + pool_id = pool['pool'] + for ps in range(0, pool['pg_num']): + + # Was this OSD affected by the OSD coming in/out? + # Compare old and new osds using + # data from the json dump + old_up_acting = old_map.pg_to_up_acting_osds(pool['pool'], ps) + old_osds = set(old_up_acting['acting']) + + new_up_acting = new_map.pg_to_up_acting_osds(pool['pool'], ps) + new_osds = set(new_up_acting['acting']) + + # Check the osd_id being in the acting set for both old + # and new maps to cover both out and in cases + was_on_out_or_in_osd = osd_id in old_osds or osd_id in new_osds + if not was_on_out_or_in_osd: + continue + + self.log.debug("pool_id, ps = {0}, {1}".format( + pool_id, ps + )) + + self.log.debug( + "old_up_acting: {0}".format(json.dumps(old_up_acting, indent=2))) + + # Has this OSD been assigned a new location? + # (it might not be if there is no suitable place to move + # after an OSD is marked in/out) + if marked == "in": + is_relocated = len(old_osds - new_osds) > 0 + else: + is_relocated = len(new_osds - old_osds) > 0 + + self.log.debug( + "new_up_acting: {0}".format(json.dumps(new_up_acting, + indent=2))) + + if was_on_out_or_in_osd and is_relocated: + # This PG is now in motion, track its progress + affected_pgs.append(PgId(pool_id, ps)) + elif not is_relocated: + # This PG didn't get a new location, we'll log it + unmoved_pgs.append(PgId(pool_id, ps)) + + # In the case that we ignored some PGs, log the reason why (we may + # not end up creating a progress event) + if len(unmoved_pgs): + self.log.warn("{0} PGs were on osd.{1}, but didn't get new locations".format( + len(unmoved_pgs), osd_id)) + + self.log.warn("{0} PGs affected by osd.{1} being marked {2}".format( + len(affected_pgs), osd_id, marked)) + + + # In the case of the osd coming back in, we might need to cancel + # previous recovery event for that osd + if marked == "in": + for ev_id in list(self._events): + ev = self._events[ev_id] + if isinstance(ev, PgRecoveryEvent) and osd_id in ev.evacuating_osds: + self.log.info("osd.{0} came back in, cancelling event".format( + osd_id + )) + self._complete(ev) + + if len(affected_pgs) > 0: + ev = PgRecoveryEvent( + "Rebalancing after osd.{0} marked {1}".format(osd_id, marked), + refs=[("osd", osd_id)], + which_pgs=affected_pgs, + evacuate_osds=[osd_id] + ) + ev.pg_update(self.get("pg_dump"), self.get("pg_ready"), self.log) + self._events[ev.id] = ev + + def _osdmap_changed(self, old_osdmap, new_osdmap): + old_dump = old_osdmap.dump() + new_dump = new_osdmap.dump() + + old_osds = dict([(o['osd'], o) for o in old_dump['osds']]) + + for osd in new_dump['osds']: + osd_id = osd['osd'] + new_weight = osd['in'] + if osd_id in old_osds: + old_weight = old_osds[osd_id]['in'] + + if new_weight == 0.0 and old_weight > new_weight: + self.log.warn("osd.{0} marked out".format(osd_id)) + self._osd_in_out(old_osdmap, old_dump, new_osdmap, osd_id, "out") + elif new_weight >= 1.0 and old_weight == 0.0: + # Only consider weight>=1.0 as "in" to avoid spawning + # individual recovery events on every adjustment + # in a gradual weight-in + self.log.warn("osd.{0} marked in".format(osd_id)) + self._osd_in_out(old_osdmap, old_dump, new_osdmap, osd_id, "in") + + def notify(self, notify_type, notify_data): + self._ready.wait() + if not self.enabled: + return + if notify_type == "osd_map": + old_osdmap = self._latest_osdmap + self._latest_osdmap = self.get_osdmap() + + self.log.info("Processing OSDMap change {0}..{1}".format( + old_osdmap.get_epoch(), self._latest_osdmap.get_epoch() + )) + self._osdmap_changed(old_osdmap, self._latest_osdmap) + elif notify_type == "pg_summary": + # if there are no events we will skip this here to avoid + # expensive get calls + if len(self._events) == 0: + return + data = self.get("pg_stats") + ready = self.get("pg_ready") + for ev_id, ev in self._events.items(): + if isinstance(ev, PgRecoveryEvent): + ev.pg_update(data, ready, self.log) + self.maybe_complete(ev) + + def maybe_complete(self, event): + if event.progress >= 1.0: + self._complete(event) + + def _save(self): + self.log.info("Writing back {0} completed events".format( + len(self._completed_events) + )) + # TODO: bound the number we store. + encoded = json.dumps({ + "events": [ev.to_json() for ev in self._completed_events], + "version": ENCODING_VERSION, + "compat_version": ENCODING_VERSION + }) + self.set_store("completed", encoded) + + def _load(self): + stored = self.get_store("completed") + + if stored is None: + self.log.info("No stored events to load") + return + + decoded = json.loads(stored) + if decoded['compat_version'] > ENCODING_VERSION: + raise RuntimeError("Cannot decode version {0}".format( + decoded['compat_version'])) + + for ev in decoded['events']: + self._completed_events.append(GhostEvent(ev['id'], ev['message'], + ev['refs'], + ev.get('failed', False), + ev.get('failure_message'))) + + self._prune_completed_events() + + def _prune_completed_events(self): + length = len(self._completed_events) + if length > self.max_completed_events: + self._completed_events = self._completed_events[length - self.max_completed_events : length] + self._dirty = True + + def serve(self): + self.config_notify() + self.clear_all_progress_events() + self.log.info("Loading...") + + self._load() + self.log.info("Loaded {0} historic events".format(self._completed_events)) + + self._latest_osdmap = self.get_osdmap() + self.log.info("Loaded OSDMap, ready.") + + self._ready.set() + + while not self._shutdown.is_set(): + # Lazy periodic write back of completed events + if self._dirty: + self._save() + self._dirty = False + + self._shutdown.wait(timeout=self.persist_interval) + + self._shutdown.wait() + + def shutdown(self): + self._shutdown.set() + self.clear_all_progress_events() + + def update(self, ev_id, ev_msg, ev_progress, refs=None): + """ + For calling from other mgr modules + """ + if not self.enabled: + return + + if refs is None: + refs = [] + try: + ev = self._events[ev_id] + except KeyError: + ev = RemoteEvent(ev_id, ev_msg, refs) + self._events[ev_id] = ev + self.log.info("update: starting ev {0} ({1})".format( + ev_id, ev_msg)) + else: + self.log.debug("update: {0} on {1}".format( + ev_progress, ev_msg)) + + ev.set_progress(ev_progress) + ev._refresh() + + def _complete(self, ev): + duration = (datetime.datetime.utcnow() - ev.started_at) + self.log.info("Completed event {0} ({1}) in {2} seconds".format( + ev.id, ev.message, duration.seconds + )) + self.complete_progress_event(ev.id) + + self._completed_events.append( + GhostEvent(ev.id, ev.message, ev.refs, + failed=ev.failed, failure_message=ev.failure_message)) + del self._events[ev.id] + self._prune_completed_events() + self._dirty = True + + def complete(self, ev_id): + """ + For calling from other mgr modules + """ + if not self.enabled: + return + try: + ev = self._events[ev_id] + ev.set_progress(1.0) + self.log.info("complete: finished ev {0} ({1})".format(ev_id, + ev.message)) + self._complete(ev) + except KeyError: + self.log.warn("complete: ev {0} does not exist".format(ev_id)) + pass + + def fail(self, ev_id, message): + """ + For calling from other mgr modules to mark an event as failed (and + complete) + """ + try: + ev = self._events[ev_id] + ev.set_failed(message) + self.log.info("fail: finished ev {0} ({1}): {2}".format(ev_id, + ev.message, + message)) + self._complete(ev) + except KeyError: + self.log.warn("fail: ev {0} does not exist".format(ev_id)) + + def on(self): + self.set_module_option('enabled', True) + + def off(self): + self.set_module_option('enabled', False) + + def _handle_ls(self): + if len(self._events) or len(self._completed_events): + out = "" + chrono_order = sorted(self._events.values(), + key=lambda x: x.started_at, reverse=True) + for ev in chrono_order: + out += ev.twoline_progress() + out += "\n" + + if len(self._completed_events): + # TODO: limit number of completed events to show + out += "\n" + for ev in self._completed_events: + out += "[{0}]: {1}\n".format("Complete" if not ev.failed else "Failed", + ev.twoline_progress()) + + return 0, out, "" + else: + return 0, "", "Nothing in progress" + + def _json(self): + return { + 'events': [ev.to_json() for ev in self._events.values()], + 'completed': [ev.to_json() for ev in self._completed_events] + } + + def clear(self): + self._events = {} + self._completed_events = [] + self._dirty = True + self._save() + self.clear_all_progress_events() + + def _handle_clear(self): + self.clear() + return 0, "", "" + + def handle_command(self, _, cmd): + if cmd['prefix'] == "progress": + return self._handle_ls() + elif cmd['prefix'] == "progress clear": + # The clear command isn't usually needed - it's to enable + # the admin to "kick" this module if it seems to have done + # something wrong (e.g. we have a bug causing a progress event + # that never finishes) + return self._handle_clear() + elif cmd['prefix'] == "progress json": + return 0, json.dumps(self._json(), indent=4, sort_keys=True), "" + elif cmd['prefix'] == "progress on": + if self.enabled: + return 0, "", "progress already enabled!" + self.on() + return 0, "", "progress enabled" + elif cmd['prefix'] == "progress off": + if not self.enabled: + return 0, "", "progress already disabled!" + self.off() + self.clear() + return 0, "", "progress disabled" + else: + raise NotImplementedError(cmd['prefix']) diff --git a/src/pybind/mgr/prometheus/__init__.py b/src/pybind/mgr/prometheus/__init__.py new file mode 100644 index 00000000..763a8426 --- /dev/null +++ b/src/pybind/mgr/prometheus/__init__.py @@ -0,0 +1,2 @@ +from .module import Module, StandbyModule + diff --git a/src/pybind/mgr/prometheus/module.py b/src/pybind/mgr/prometheus/module.py new file mode 100644 index 00000000..16fd6f7f --- /dev/null +++ b/src/pybind/mgr/prometheus/module.py @@ -0,0 +1,1324 @@ +import cherrypy +from distutils.version import StrictVersion +import json +import errno +import math +import os +import re +import socket +import threading +import time +from mgr_module import MgrModule, MgrStandbyModule, CommandResult, PG_STATES +from mgr_util import get_default_addr +from rbd import RBD +from collections import namedtuple +try: + from typing import Optional +except: + pass + +# Defaults for the Prometheus HTTP server. Can also set in config-key +# see https://github.com/prometheus/prometheus/wiki/Default-port-allocations +# for Prometheus exporter port registry + +DEFAULT_PORT = 9283 + +# When the CherryPy server in 3.2.2 (and later) starts it attempts to verify +# that the ports its listening on are in fact bound. When using the any address +# "::" it tries both ipv4 and ipv6, and in some environments (e.g. kubernetes) +# ipv6 isn't yet configured / supported and CherryPy throws an uncaught +# exception. +if cherrypy is not None: + v = StrictVersion(cherrypy.__version__) + # the issue was fixed in 3.2.3. it's present in 3.2.2 (current version on + # centos:7) and back to at least 3.0.0. + if StrictVersion("3.1.2") <= v < StrictVersion("3.2.3"): + # https://github.com/cherrypy/cherrypy/issues/1100 + from cherrypy.process import servers + servers.wait_for_occupied_port = lambda host, port: None + +# cherrypy likes to sys.exit on error. don't let it take us down too! +def os_exit_noop(*args, **kwargs): + pass + + +os._exit = os_exit_noop + +# to access things in class Module from subclass Root. Because +# it's a dict, the writer doesn't need to declare 'global' for access + +_global_instance = None # type: Optional[Module] +cherrypy.config.update({ + 'response.headers.server': 'Ceph-Prometheus' +}) + + +def health_status_to_number(status): + if status == 'HEALTH_OK': + return 0 + elif status == 'HEALTH_WARN': + return 1 + elif status == 'HEALTH_ERR': + return 2 + + +DF_CLUSTER = ['total_bytes', 'total_used_bytes', 'total_used_raw_bytes'] + +DF_POOL = ['max_avail', 'stored', 'stored_raw', 'objects', 'dirty', + 'quota_bytes', 'quota_objects', 'rd', 'rd_bytes', 'wr', 'wr_bytes', + 'compress_bytes_used', 'compress_under_bytes'] + +OSD_POOL_STATS = ('recovering_objects_per_sec', 'recovering_bytes_per_sec', + 'recovering_keys_per_sec', 'num_objects_recovered', + 'num_bytes_recovered', 'num_bytes_recovered') + +OSD_FLAGS = ('noup', 'nodown', 'noout', 'noin', 'nobackfill', 'norebalance', + 'norecover', 'noscrub', 'nodeep-scrub') + +FS_METADATA = ('data_pools', 'fs_id', 'metadata_pool', 'name') + +MDS_METADATA = ('ceph_daemon', 'fs_id', 'hostname', 'public_addr', 'rank', + 'ceph_version') + +MON_METADATA = ('ceph_daemon', 'hostname', + 'public_addr', 'rank', 'ceph_version') + +MGR_METADATA = ('ceph_daemon', 'hostname', 'ceph_version') + +MGR_STATUS = ('ceph_daemon',) + +MGR_MODULE_STATUS = ('name',) + +MGR_MODULE_CAN_RUN = ('name',) + +OSD_METADATA = ('back_iface', 'ceph_daemon', 'cluster_addr', 'device_class', + 'front_iface', 'hostname', 'objectstore', 'public_addr', + 'ceph_version') + +OSD_STATUS = ['weight', 'up', 'in'] + +OSD_STATS = ['apply_latency_ms', 'commit_latency_ms'] + +POOL_METADATA = ('pool_id', 'name') + +RGW_METADATA = ('ceph_daemon', 'hostname', 'ceph_version') + +RBD_MIRROR_METADATA = ('ceph_daemon', 'id', 'instance_id', 'hostname', + 'ceph_version') + +DISK_OCCUPATION = ('ceph_daemon', 'device', 'db_device', + 'wal_device', 'instance') + +NUM_OBJECTS = ['degraded', 'misplaced', 'unfound'] + +alert_metric = namedtuple('alert_metric', 'name description') +HEALTH_CHECKS = [ + alert_metric('SLOW_OPS', 'OSD or Monitor requests taking a long time to process' ), +] + + +class Metric(object): + def __init__(self, mtype, name, desc, labels=None): + self.mtype = mtype + self.name = name + self.desc = desc + self.labelnames = labels # tuple if present + self.value = {} # indexed by label values + + def clear(self): + self.value = {} + + def set(self, value, labelvalues=None): + # labelvalues must be a tuple + labelvalues = labelvalues or ('',) + self.value[labelvalues] = value + + def str_expfmt(self): + + def promethize(path): + ''' replace illegal metric name characters ''' + result = re.sub(r'[./\s]|::', '_', path).replace('+', '_plus') + + # Hyphens usually turn into underscores, unless they are + # trailing + if result.endswith("-"): + result = result[0:-1] + "_minus" + else: + result = result.replace("-", "_") + + return "ceph_{0}".format(result) + + def floatstr(value): + ''' represent as Go-compatible float ''' + if value == float('inf'): + return '+Inf' + if value == float('-inf'): + return '-Inf' + if math.isnan(value): + return 'NaN' + return repr(float(value)) + + name = promethize(self.name) + expfmt = ''' +# HELP {name} {desc} +# TYPE {name} {mtype}'''.format( + name=name, + desc=self.desc, + mtype=self.mtype, + ) + + for labelvalues, value in self.value.items(): + if self.labelnames: + labels = zip(self.labelnames, labelvalues) + labels = ','.join('%s="%s"' % (k, v) for k, v in labels) + else: + labels = '' + if labels: + fmtstr = '\n{name}{{{labels}}} {value}' + else: + fmtstr = '\n{name} {value}' + expfmt += fmtstr.format( + name=name, + labels=labels, + value=floatstr(value), + ) + return expfmt + + +class MetricCollectionThread(threading.Thread): + def __init__(self, module): + # type: (Module) -> None + self.mod = module + self.active = True + self.event = threading.Event() + super(MetricCollectionThread, self).__init__(target=self.collect) + + def collect(self): + self.mod.log.info('starting metric collection thread') + while self.active: + self.mod.log.debug('collecting cache in thread') + if self.mod.have_mon_connection(): + start_time = time.time() + + try: + data = self.mod.collect() + except: + # Log any issues encountered during the data collection and continue + self.mod.log.exception("failed to collect metrics:") + self.event.wait(self.mod.scrape_interval) + continue + + duration = time.time() - start_time + + sleep_time = self.mod.scrape_interval - duration + if sleep_time < 0: + self.mod.log.warning( + 'Collecting data took more time than configured scrape interval. ' + 'This possibly results in stale data. Please check the ' + '`stale_cache_strategy` configuration option. ' + 'Collecting data took {:.2f} seconds but scrape interval is configured ' + 'to be {:.0f} seconds.'.format( + duration, + self.mod.scrape_interval, + ) + ) + sleep_time = 0 + + with self.mod.collect_lock: + self.mod.collect_cache = data + self.mod.collect_time = duration + + self.event.wait(sleep_time) + else: + self.mod.log.error('No MON connection') + self.event.wait(self.mod.scrape_interval) + + def stop(self): + self.active = False + self.event.set() + +class Module(MgrModule): + COMMANDS = [ + { + "cmd": "prometheus file_sd_config", + "desc": "Return file_sd compatible prometheus config for mgr cluster", + "perm": "r" + }, + ] + + MODULE_OPTIONS = [ + {'name': 'server_addr'}, + {'name': 'server_port'}, + {'name': 'scrape_interval'}, + {'name': 'stale_cache_strategy'}, + {'name': 'rbd_stats_pools'}, + {'name': 'rbd_stats_pools_refresh_interval', 'type': 'int', 'default': 300}, + ] + + STALE_CACHE_FAIL = 'fail' + STALE_CACHE_RETURN = 'return' + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.metrics = self._setup_static_metrics() + self.shutdown_event = threading.Event() + self.collect_lock = threading.Lock() + self.collect_time = 0 + self.scrape_interval = 15.0 + self.stale_cache_strategy = self.STALE_CACHE_FAIL + self.collect_cache = None + self.rbd_stats = { + 'pools': {}, + 'pools_refresh_time': 0, + 'counters_info': { + 'write_ops': {'type': self.PERFCOUNTER_COUNTER, + 'desc': 'RBD image writes count'}, + 'read_ops': {'type': self.PERFCOUNTER_COUNTER, + 'desc': 'RBD image reads count'}, + 'write_bytes': {'type': self.PERFCOUNTER_COUNTER, + 'desc': 'RBD image bytes written'}, + 'read_bytes': {'type': self.PERFCOUNTER_COUNTER, + 'desc': 'RBD image bytes read'}, + 'write_latency': {'type': self.PERFCOUNTER_LONGRUNAVG, + 'desc': 'RBD image writes latency (msec)'}, + 'read_latency': {'type': self.PERFCOUNTER_LONGRUNAVG, + 'desc': 'RBD image reads latency (msec)'}, + }, + } + global _global_instance + _global_instance = self + self.metrics_thread = MetricCollectionThread(_global_instance) + + def _setup_static_metrics(self): + metrics = {} + metrics['health_status'] = Metric( + 'untyped', + 'health_status', + 'Cluster health status' + ) + metrics['mon_quorum_status'] = Metric( + 'gauge', + 'mon_quorum_status', + 'Monitors in quorum', + ('ceph_daemon',) + ) + metrics['fs_metadata'] = Metric( + 'untyped', + 'fs_metadata', + 'FS Metadata', + FS_METADATA + ) + metrics['mds_metadata'] = Metric( + 'untyped', + 'mds_metadata', + 'MDS Metadata', + MDS_METADATA + ) + metrics['mon_metadata'] = Metric( + 'untyped', + 'mon_metadata', + 'MON Metadata', + MON_METADATA + ) + metrics['mgr_metadata'] = Metric( + 'gauge', + 'mgr_metadata', + 'MGR metadata', + MGR_METADATA + ) + metrics['mgr_status'] = Metric( + 'gauge', + 'mgr_status', + 'MGR status (0=standby, 1=active)', + MGR_STATUS + ) + metrics['mgr_module_status'] = Metric( + 'gauge', + 'mgr_module_status', + 'MGR module status (0=disabled, 1=enabled, 2=auto-enabled)', + MGR_MODULE_STATUS + ) + metrics['mgr_module_can_run'] = Metric( + 'gauge', + 'mgr_module_can_run', + 'MGR module runnable state i.e. can it run (0=no, 1=yes)', + MGR_MODULE_CAN_RUN + ) + metrics['osd_metadata'] = Metric( + 'untyped', + 'osd_metadata', + 'OSD Metadata', + OSD_METADATA + ) + + # The reason for having this separate to OSD_METADATA is + # so that we can stably use the same tag names that + # the Prometheus node_exporter does + metrics['disk_occupation'] = Metric( + 'untyped', + 'disk_occupation', + 'Associate Ceph daemon with disk used', + DISK_OCCUPATION + ) + + metrics['pool_metadata'] = Metric( + 'untyped', + 'pool_metadata', + 'POOL Metadata', + POOL_METADATA + ) + + metrics['rgw_metadata'] = Metric( + 'untyped', + 'rgw_metadata', + 'RGW Metadata', + RGW_METADATA + ) + + metrics['rbd_mirror_metadata'] = Metric( + 'untyped', + 'rbd_mirror_metadata', + 'RBD Mirror Metadata', + RBD_MIRROR_METADATA + ) + + metrics['pg_total'] = Metric( + 'gauge', + 'pg_total', + 'PG Total Count per Pool', + ('pool_id',) + ) + + metrics['scrape_duration_seconds'] = Metric( + 'gauge', + 'scrape_duration_secs', + 'Time taken to gather metrics from Ceph (secs)' + ) + + for flag in OSD_FLAGS: + path = 'osd_flag_{}'.format(flag) + metrics[path] = Metric( + 'untyped', + path, + 'OSD Flag {}'.format(flag) + ) + for state in OSD_STATUS: + path = 'osd_{}'.format(state) + metrics[path] = Metric( + 'untyped', + path, + 'OSD status {}'.format(state), + ('ceph_daemon',) + ) + for stat in OSD_STATS: + path = 'osd_{}'.format(stat) + metrics[path] = Metric( + 'gauge', + path, + 'OSD stat {}'.format(stat), + ('ceph_daemon',) + ) + for stat in OSD_POOL_STATS: + path = 'pool_{}'.format(stat) + metrics[path] = Metric( + 'gauge', + path, + "OSD POOL STATS: {}".format(stat), + ('pool_id',) + ) + for state in PG_STATES: + path = 'pg_{}'.format(state) + metrics[path] = Metric( + 'gauge', + path, + 'PG {} per pool'.format(state), + ('pool_id',) + ) + for state in DF_CLUSTER: + path = 'cluster_{}'.format(state) + metrics[path] = Metric( + 'gauge', + path, + 'DF {}'.format(state), + ) + for state in DF_POOL: + path = 'pool_{}'.format(state) + metrics[path] = Metric( + 'gauge', + path, + 'DF pool {}'.format(state), + ('pool_id',) + ) + for state in NUM_OBJECTS: + path = 'num_objects_{}'.format(state) + metrics[path] = Metric( + 'gauge', + path, + 'Number of {} objects'.format(state), + ) + + for check in HEALTH_CHECKS: + path = 'healthcheck_{}'.format(check.name.lower()) + metrics[path] = Metric( + 'gauge', + path, + check.description, + ) + + return metrics + + def get_health(self): + + def _get_value(message, delim=' ', word_pos=0): + """Extract value from message (default is 1st field)""" + v_str = message.split(delim)[word_pos] + if v_str.isdigit(): + return int(v_str), 0 + return 0, 1 + + health = json.loads(self.get('health')['json']) + # set overall health + self.metrics['health_status'].set( + health_status_to_number(health['status']) + ) + + # Examine the health to see if any health checks triggered need to + # become a metric. + active_healthchecks = health.get('checks', {}) + active_names = active_healthchecks.keys() + + for check in HEALTH_CHECKS: + path = 'healthcheck_{}'.format(check.name.lower()) + + if path in self.metrics: + + if check.name in active_names: + check_data = active_healthchecks[check.name] + message = check_data['summary'].get('message', '') + v, err = 0, 0 + + if check.name == "SLOW_OPS": + # 42 slow ops, oldest one blocked for 12 sec, daemons [osd.0, osd.3] have slow ops. + v, err = _get_value(message) + + if err: + self.log.error("healthcheck {} message format is incompatible and has been dropped".format(check.name)) + # drop the metric, so it's no longer emitted + del self.metrics[path] + continue + else: + self.metrics[path].set(v) + else: + # health check is not active, so give it a default of 0 + self.metrics[path].set(0) + + def get_pool_stats(self): + # retrieve pool stats to provide per pool recovery metrics + # (osd_pool_stats moved to mgr in Mimic) + pstats = self.get('osd_pool_stats') + for pool in pstats['pool_stats']: + for stat in OSD_POOL_STATS: + self.metrics['pool_{}'.format(stat)].set( + pool['recovery_rate'].get(stat, 0), + (pool['pool_id'],) + ) + + def get_df(self): + # maybe get the to-be-exported metrics from a config? + df = self.get('df') + for stat in DF_CLUSTER: + self.metrics['cluster_{}'.format(stat)].set(df['stats'][stat]) + + for pool in df['pools']: + for stat in DF_POOL: + self.metrics['pool_{}'.format(stat)].set( + pool['stats'][stat], + (pool['id'],) + ) + + def get_fs(self): + fs_map = self.get('fs_map') + servers = self.get_service_list() + active_daemons = [] + for fs in fs_map['filesystems']: + # collect fs metadata + data_pools = ",".join([str(pool) + for pool in fs['mdsmap']['data_pools']]) + self.metrics['fs_metadata'].set(1, ( + data_pools, + fs['id'], + fs['mdsmap']['metadata_pool'], + fs['mdsmap']['fs_name'] + )) + self.log.debug('mdsmap: {}'.format(fs['mdsmap'])) + for gid, daemon in fs['mdsmap']['info'].items(): + id_ = daemon['name'] + host_version = servers.get((id_, 'mds'), ('', '')) + self.metrics['mds_metadata'].set(1, ( + 'mds.{}'.format(id_), fs['id'], + host_version[0], daemon['addr'], + daemon['rank'], host_version[1] + )) + + def get_quorum_status(self): + mon_status = json.loads(self.get('mon_status')['json']) + servers = self.get_service_list() + for mon in mon_status['monmap']['mons']: + rank = mon['rank'] + id_ = mon['name'] + host_version = servers.get((id_, 'mon'), ('', '')) + self.metrics['mon_metadata'].set(1, ( + 'mon.{}'.format(id_), host_version[0], + mon['public_addr'].rsplit(':', 1)[0], rank, + host_version[1] + )) + in_quorum = int(rank in mon_status['quorum']) + self.metrics['mon_quorum_status'].set(in_quorum, ( + 'mon.{}'.format(id_), + )) + + def get_mgr_status(self): + mgr_map = self.get('mgr_map') + servers = self.get_service_list() + + active = mgr_map['active_name'] + standbys = [s.get('name') for s in mgr_map['standbys']] + + all_mgrs = list(standbys) + all_mgrs.append(active) + + all_modules = {module.get('name'):module.get('can_run') for module in mgr_map['available_modules']} + + for mgr in all_mgrs: + host_version = servers.get((mgr, 'mgr'), ('', '')) + if mgr == active: + _state = 1 + else: + _state = 0 + + self.metrics['mgr_metadata'].set(1, ( + 'mgr.{}'.format(mgr), host_version[0], + host_version[1] + )) + self.metrics['mgr_status'].set(_state, ( + 'mgr.{}'.format(mgr), + )) + always_on_modules = mgr_map['always_on_modules'].get(self.release_name, []) + active_modules = list(always_on_modules) + active_modules.extend(mgr_map['modules']) + + for mod_name in all_modules.keys(): + + if mod_name in always_on_modules: + _state = 2 + elif mod_name in active_modules: + _state = 1 + else: + _state = 0 + + _can_run = 1 if all_modules[mod_name] else 0 + self.metrics['mgr_module_status'].set(_state, (mod_name,)) + self.metrics['mgr_module_can_run'].set(_can_run, (mod_name,)) + + def get_pg_status(self): + + pg_summary = self.get('pg_summary') + + for pool in pg_summary['by_pool']: + num_by_state = dict((state, 0) for state in PG_STATES) + num_by_state['total'] = 0 + + for state_name, count in pg_summary['by_pool'][pool].items(): + for state in state_name.split('+'): + num_by_state[state] += count + num_by_state['total'] += count + + for state, num in num_by_state.items(): + try: + self.metrics["pg_{}".format(state)].set(num, (pool,)) + except KeyError: + self.log.warn("skipping pg in unknown state {}".format(state)) + + def get_osd_stats(self): + osd_stats = self.get('osd_stats') + for osd in osd_stats['osd_stats']: + id_ = osd['osd'] + for stat in OSD_STATS: + val = osd['perf_stat'][stat] + self.metrics['osd_{}'.format(stat)].set(val, ( + 'osd.{}'.format(id_), + )) + + def get_service_list(self): + ret = {} + for server in self.list_servers(): + version = server.get('ceph_version', '') + host = server.get('hostname', '') + for service in server.get('services', []): + ret.update({(service['id'], service['type']): (host, version)}) + return ret + + def get_metadata_and_osd_status(self): + osd_map = self.get('osd_map') + osd_flags = osd_map['flags'].split(',') + for flag in OSD_FLAGS: + self.metrics['osd_flag_{}'.format(flag)].set( + int(flag in osd_flags) + ) + + osd_devices = self.get('osd_map_crush')['devices'] + servers = self.get_service_list() + for osd in osd_map['osds']: + # id can be used to link osd metrics and metadata + id_ = osd['osd'] + # collect osd metadata + p_addr = osd['public_addr'].rsplit(':', 1)[0] + c_addr = osd['cluster_addr'].rsplit(':', 1)[0] + if p_addr == "-" or c_addr == "-": + self.log.info( + "Missing address metadata for osd {0}, skipping occupation" + " and metadata records for this osd".format(id_) + ) + continue + + dev_class = None + for osd_device in osd_devices: + if osd_device['id'] == id_: + dev_class = osd_device.get('class', '') + break + + if dev_class is None: + self.log.info( + "OSD {0} is missing from CRUSH map, skipping output".format( + id_)) + continue + + host_version = servers.get((str(id_), 'osd'), ('', '')) + + # collect disk occupation metadata + osd_metadata = self.get_metadata("osd", str(id_)) + if osd_metadata is None: + continue + + obj_store = osd_metadata.get('osd_objectstore', '') + f_iface = osd_metadata.get('front_iface', '') + b_iface = osd_metadata.get('back_iface', '') + + self.metrics['osd_metadata'].set(1, ( + b_iface, + 'osd.{}'.format(id_), + c_addr, + dev_class, + f_iface, + host_version[0], + obj_store, + p_addr, + host_version[1] + )) + + # collect osd status + for state in OSD_STATUS: + status = osd[state] + self.metrics['osd_{}'.format(state)].set(status, ( + 'osd.{}'.format(id_), + )) + + osd_dev_node = None + if obj_store == "filestore": + # collect filestore backend device + osd_dev_node = osd_metadata.get( + 'backend_filestore_dev_node', None) + # collect filestore journal device + osd_wal_dev_node = osd_metadata.get('osd_journal', '') + osd_db_dev_node = '' + elif obj_store == "bluestore": + # collect bluestore backend device + osd_dev_node = osd_metadata.get( + 'bluestore_bdev_dev_node', None) + # collect bluestore wal backend + osd_wal_dev_node = osd_metadata.get('bluefs_wal_dev_node', '') + # collect bluestore db backend + osd_db_dev_node = osd_metadata.get('bluefs_db_dev_node', '') + if osd_dev_node and osd_dev_node == "unknown": + osd_dev_node = None + + osd_hostname = osd_metadata.get('hostname', None) + if osd_dev_node and osd_hostname: + self.log.debug("Got dev for osd {0}: {1}/{2}".format( + id_, osd_hostname, osd_dev_node)) + self.metrics['disk_occupation'].set(1, ( + "osd.{0}".format(id_), + osd_dev_node, + osd_db_dev_node, + osd_wal_dev_node, + osd_hostname + )) + else: + self.log.info("Missing dev node metadata for osd {0}, skipping " + "occupation record for this osd".format(id_)) + + pool_meta = [] + for pool in osd_map['pools']: + self.metrics['pool_metadata'].set( + 1, (pool['pool'], pool['pool_name'])) + + # Populate other servers metadata + for key, value in servers.items(): + service_id, service_type = key + if service_type == 'rgw': + hostname, version = value + self.metrics['rgw_metadata'].set( + 1, + ('{}.{}'.format(service_type, service_id), hostname, version) + ) + elif service_type == 'rbd-mirror': + mirror_metadata = self.get_metadata('rbd-mirror', service_id) + if mirror_metadata is None: + continue + mirror_metadata['ceph_daemon'] = '{}.{}'.format(service_type, + service_id) + self.metrics['rbd_mirror_metadata'].set( + 1, (mirror_metadata.get(k, '') + for k in RBD_MIRROR_METADATA) + ) + + def get_num_objects(self): + pg_sum = self.get('pg_summary')['pg_stats_sum']['stat_sum'] + for obj in NUM_OBJECTS: + stat = 'num_objects_{}'.format(obj) + self.metrics[stat].set(pg_sum[stat]) + + def get_rbd_stats(self): + # Per RBD image stats is collected by registering a dynamic osd perf + # stats query that tells OSDs to group stats for requests associated + # with RBD objects by pool, namespace, and image id, which are + # extracted from the request object names or other attributes. + # The RBD object names have the following prefixes: + # - rbd_data.{image_id}. (data stored in the same pool as metadata) + # - rbd_data.{pool_id}.{image_id}. (data stored in a dedicated data pool) + # - journal_data.{pool_id}.{image_id}. (journal if journaling is enabled) + # The pool_id in the object name is the id of the pool with the image + # metdata, and should be used in the image spec. If there is no pool_id + # in the object name, the image pool is the pool where the object is + # located. + + # Parse rbd_stats_pools option, which is a comma or space separated + # list of pool[/namespace] entries. If no namespace is specifed the + # stats are collected for every namespace in the pool. The wildcard + # '*' can be used to indicate all pools or namespaces + pools_string = self.get_localized_module_option('rbd_stats_pools', '') + pool_keys = [] + for x in re.split('[\s,]+', pools_string): + if not x: + continue + + s = x.split('/', 2) + pool_name = s[0] + namespace_name = None + if len(s) == 2: + namespace_name = s[1] + + if pool_name == "*": + # collect for all pools + osd_map = self.get('osd_map') + for pool in osd_map['pools']: + if 'rbd' not in pool.get('application_metadata', {}): + continue + pool_keys.append((pool['pool_name'], namespace_name)) + else: + pool_keys.append((pool_name, namespace_name)) + + pools = {} + for pool_key in pool_keys: + pool_name = pool_key[0] + namespace_name = pool_key[1] + if not namespace_name or namespace_name == "*": + # empty set means collect for all namespaces + pools[pool_name] = set() + continue + + if pool_name not in pools: + pools[pool_name] = set() + elif not pools[pool_name]: + continue + pools[pool_name].add(namespace_name) + + rbd_stats_pools = {} + for pool_id in list(self.rbd_stats['pools']): + name = self.rbd_stats['pools'][pool_id]['name'] + if name not in pools: + del self.rbd_stats['pools'][pool_id] + else: + rbd_stats_pools[name] = \ + self.rbd_stats['pools'][pool_id]['ns_names'] + + pools_refreshed = False + if pools: + next_refresh = self.rbd_stats['pools_refresh_time'] + \ + self.get_localized_module_option( + 'rbd_stats_pools_refresh_interval', 300) + if rbd_stats_pools != pools or time.time() >= next_refresh: + self.refresh_rbd_stats_pools(pools) + pools_refreshed = True + + pool_ids = list(self.rbd_stats['pools']) + pool_ids.sort() + pool_id_regex = '^(' + '|'.join([str(x) for x in pool_ids]) + ')$' + + nspace_names = [] + for pool_id, pool in self.rbd_stats['pools'].items(): + if pool['ns_names']: + nspace_names.extend(pool['ns_names']) + else: + nspace_names = [] + break + if nspace_names: + namespace_regex = '^(' + \ + "|".join([re.escape(x) + for x in set(nspace_names)]) + ')$' + else: + namespace_regex = '^(.*)$' + + if 'query' in self.rbd_stats and \ + (pool_id_regex != self.rbd_stats['query']['key_descriptor'][0]['regex'] or + namespace_regex != self.rbd_stats['query']['key_descriptor'][1]['regex']): + self.remove_osd_perf_query(self.rbd_stats['query_id']) + del self.rbd_stats['query_id'] + del self.rbd_stats['query'] + + if not self.rbd_stats['pools']: + return + + counters_info = self.rbd_stats['counters_info'] + + if 'query_id' not in self.rbd_stats: + query = { + 'key_descriptor': [ + {'type': 'pool_id', 'regex': pool_id_regex}, + {'type': 'namespace', 'regex': namespace_regex}, + {'type': 'object_name', + 'regex': '^(?:rbd|journal)_data\.(?:([0-9]+)\.)?([^.]+)\.'}, + ], + 'performance_counter_descriptors': list(counters_info), + } + query_id = self.add_osd_perf_query(query) + if query_id is None: + self.log.error('failed to add query %s' % query) + return + self.rbd_stats['query'] = query + self.rbd_stats['query_id'] = query_id + + res = self.get_osd_perf_counters(self.rbd_stats['query_id']) + for c in res['counters']: + # if the pool id is not found in the object name use id of the + # pool where the object is located + if c['k'][2][0]: + pool_id = int(c['k'][2][0]) + else: + pool_id = int(c['k'][0][0]) + if pool_id not in self.rbd_stats['pools'] and not pools_refreshed: + self.refresh_rbd_stats_pools(pools) + pools_refreshed = True + if pool_id not in self.rbd_stats['pools']: + continue + pool = self.rbd_stats['pools'][pool_id] + nspace_name = c['k'][1][0] + if nspace_name not in pool['images']: + continue + image_id = c['k'][2][1] + if image_id not in pool['images'][nspace_name] and \ + not pools_refreshed: + self.refresh_rbd_stats_pools(pools) + pool = self.rbd_stats['pools'][pool_id] + pools_refreshed = True + if image_id not in pool['images'][nspace_name]: + continue + counters = pool['images'][nspace_name][image_id]['c'] + for i in range(len(c['c'])): + counters[i][0] += c['c'][i][0] + counters[i][1] += c['c'][i][1] + + label_names = ("pool", "namespace", "image") + for pool_id, pool in self.rbd_stats['pools'].items(): + pool_name = pool['name'] + for nspace_name, images in pool['images'].items(): + for image_id in images: + image_name = images[image_id]['n'] + counters = images[image_id]['c'] + i = 0 + for key in counters_info: + counter_info = counters_info[key] + stattype = self._stattype_to_str(counter_info['type']) + labels = (pool_name, nspace_name, image_name) + if counter_info['type'] == self.PERFCOUNTER_COUNTER: + path = 'rbd_' + key + if path not in self.metrics: + self.metrics[path] = Metric( + stattype, + path, + counter_info['desc'], + label_names, + ) + self.metrics[path].set(counters[i][0], labels) + elif counter_info['type'] == self.PERFCOUNTER_LONGRUNAVG: + path = 'rbd_' + key + '_sum' + if path not in self.metrics: + self.metrics[path] = Metric( + stattype, + path, + counter_info['desc'] + ' Total', + label_names, + ) + self.metrics[path].set(counters[i][0], labels) + path = 'rbd_' + key + '_count' + if path not in self.metrics: + self.metrics[path] = Metric( + 'counter', + path, + counter_info['desc'] + ' Count', + label_names, + ) + self.metrics[path].set(counters[i][1], labels) + i += 1 + + def refresh_rbd_stats_pools(self, pools): + self.log.debug('refreshing rbd pools %s' % (pools)) + + rbd = RBD() + counters_info = self.rbd_stats['counters_info'] + for pool_name, cfg_ns_names in pools.items(): + try: + pool_id = self.rados.pool_lookup(pool_name) + with self.rados.open_ioctx(pool_name) as ioctx: + if pool_id not in self.rbd_stats['pools']: + self.rbd_stats['pools'][pool_id] = {'images': {}} + pool = self.rbd_stats['pools'][pool_id] + pool['name'] = pool_name + pool['ns_names'] = cfg_ns_names + if cfg_ns_names: + nspace_names = list(cfg_ns_names) + else: + nspace_names = [''] + rbd.namespace_list(ioctx) + for nspace_name in pool['images']: + if nspace_name not in nspace_names: + del pool['images'][nspace_name] + for nspace_name in nspace_names: + if (nspace_name and + not rbd.namespace_exists(ioctx, nspace_name)): + self.log.debug('unknown namespace %s for pool %s' % + (nspace_name, pool_name)) + continue + ioctx.set_namespace(nspace_name) + if nspace_name not in pool['images']: + pool['images'][nspace_name] = {} + namespace = pool['images'][nspace_name] + images = {} + for image_meta in RBD().list2(ioctx): + image = {'n': image_meta['name']} + image_id = image_meta['id'] + if image_id in namespace: + image['c'] = namespace[image_id]['c'] + else: + image['c'] = [[0, 0] for x in counters_info] + images[image_id] = image + pool['images'][nspace_name] = images + except Exception as e: + self.log.error('failed listing pool %s: %s' % (pool_name, e)) + self.rbd_stats['pools_refresh_time'] = time.time() + + def shutdown_rbd_stats(self): + if 'query_id' in self.rbd_stats: + self.remove_osd_perf_query(self.rbd_stats['query_id']) + del self.rbd_stats['query_id'] + del self.rbd_stats['query'] + self.rbd_stats['pools'].clear() + + def collect(self): + # Clear the metrics before scraping + for k in self.metrics.keys(): + self.metrics[k].clear() + + _start_time = time.time() + + self.get_health() + self.get_df() + self.get_pool_stats() + self.get_fs() + self.get_osd_stats() + self.get_quorum_status() + self.get_mgr_status() + self.get_metadata_and_osd_status() + self.get_pg_status() + self.get_num_objects() + + for daemon, counters in self.get_all_perf_counters().items(): + for path, counter_info in counters.items(): + # Skip histograms, they are represented by long running avgs + stattype = self._stattype_to_str(counter_info['type']) + if not stattype or stattype == 'histogram': + self.log.debug('ignoring %s, type %s' % (path, stattype)) + continue + + path, label_names, labels = self._perfpath_to_path_labels( + daemon, path) + + # Get the value of the counter + value = self._perfvalue_to_value( + counter_info['type'], counter_info['value']) + + # Represent the long running avgs as sum/count pairs + if counter_info['type'] & self.PERFCOUNTER_LONGRUNAVG: + _path = path + '_sum' + if _path not in self.metrics: + self.metrics[_path] = Metric( + stattype, + _path, + counter_info['description'] + ' Total', + label_names, + ) + self.metrics[_path].set(value, labels) + + _path = path + '_count' + if _path not in self.metrics: + self.metrics[_path] = Metric( + 'counter', + _path, + counter_info['description'] + ' Count', + label_names, + ) + self.metrics[_path].set(counter_info['count'], labels,) + else: + if path not in self.metrics: + self.metrics[path] = Metric( + stattype, + path, + counter_info['description'], + label_names, + ) + self.metrics[path].set(value, labels) + + self.get_rbd_stats() + + _end_time = time.time() + self.metrics['scrape_duration_seconds'].set(_end_time - _start_time) + + # Return formatted metrics and clear no longer used data + _metrics = [m.str_expfmt() for m in self.metrics.values()] + for k in self.metrics.keys(): + self.metrics[k].clear() + + return ''.join(_metrics) + '\n' + + def get_file_sd_config(self): + servers = self.list_servers() + targets = [] + for server in servers: + hostname = server.get('hostname', '') + for service in server.get('services', []): + if service['type'] != 'mgr': + continue + id_ = service['id'] + # get port for prometheus module at mgr with id_ + # TODO use get_config_prefix or get_config here once + # https://github.com/ceph/ceph/pull/20458 is merged + result = CommandResult("") + _global_instance.send_command( + result, "mon", '', + json.dumps({ + "prefix": "config-key get", + 'key': "config/mgr/mgr/prometheus/{}/server_port".format(id_), + }), + "") + r, outb, outs = result.wait() + if r != 0: + _global_instance.log.error("Failed to retrieve port for mgr {}: {}".format(id_, outs)) + targets.append('{}:{}'.format(hostname, DEFAULT_PORT)) + else: + port = json.loads(outb) + targets.append('{}:{}'.format(hostname, port)) + + ret = [ + { + "targets": targets, + "labels": {} + } + ] + return 0, json.dumps(ret), "" + + def self_test(self): + self.collect() + self.get_file_sd_config() + + def handle_command(self, inbuf, cmd): + if cmd['prefix'] == 'prometheus file_sd_config': + return self.get_file_sd_config() + else: + return (-errno.EINVAL, '', + "Command not found '{0}'".format(cmd['prefix'])) + + def serve(self): + + class Root(object): + + # collapse everything to '/' + def _cp_dispatch(self, vpath): + cherrypy.request.path = '' + return self + + @cherrypy.expose + def index(self): + return ''' + + Ceph Exporter + +

Ceph Exporter

+

Metrics

+ +''' + + @cherrypy.expose + def metrics(self): + # Lock the function execution + with _global_instance.collect_lock: + return self._metrics(_global_instance) + + @staticmethod + def _metrics(instance): + # Return cached data if available + if not instance.collect_cache: + raise cherrypy.HTTPError(503, 'No cached data available yet') + + def respond(): + cherrypy.response.headers['Content-Type'] = 'text/plain' + return instance.collect_cache + + if instance.collect_time < instance.scrape_interval: + # Respond if cache isn't stale + return respond() + + if instance.stale_cache_strategy == instance.STALE_CACHE_RETURN: + # Respond even if cache is stale + instance.log.info( + 'Gathering data took {:.2f} seconds, metrics are stale for {:.2f} seconds, ' + 'returning metrics from stale cache.'.format( + instance.collect_time, + instance.collect_time - instance.scrape_interval + ) + ) + return respond() + + if instance.stale_cache_strategy == instance.STALE_CACHE_FAIL: + # Fail if cache is stale + msg = ( + 'Gathering data took {:.2f} seconds, metrics are stale for {:.2f} seconds, ' + 'returning "service unavailable".'.format( + instance.collect_time, + instance.collect_time - instance.scrape_interval, + ) + ) + instance.log.error(msg) + raise cherrypy.HTTPError(503, msg) + + # Make the cache timeout for collecting configurable + self.scrape_interval = float(self.get_localized_module_option('scrape_interval', 15.0)) + + self.stale_cache_strategy = self.get_localized_module_option('stale_cache_strategy', 'log') + if self.stale_cache_strategy not in [self.STALE_CACHE_FAIL, + self.STALE_CACHE_RETURN]: + self.stale_cache_strategy = self.STALE_CACHE_FAIL + + server_addr = self.get_localized_module_option( + 'server_addr', get_default_addr()) + server_port = self.get_localized_module_option( + 'server_port', DEFAULT_PORT) + self.log.info( + "server_addr: %s server_port: %s" % + (server_addr, server_port) + ) + + self.metrics_thread.start() + + # Publish the URI that others may use to access the service we're + # about to start serving + self.set_uri('http://{0}:{1}/'.format( + socket.getfqdn() if server_addr in ['::', '0.0.0.0'] else server_addr, + server_port + )) + + cherrypy.config.update({ + 'server.socket_host': server_addr, + 'server.socket_port': int(server_port), + 'engine.autoreload.on': False + }) + cherrypy.tree.mount(Root(), "/") + self.log.info('Starting engine...') + cherrypy.engine.start() + self.log.info('Engine started.') + # wait for the shutdown event + self.shutdown_event.wait() + self.shutdown_event.clear() + # tell metrics collection thread to stop collecting new metrics + self.metrics_thread.stop() + cherrypy.engine.stop() + self.log.info('Engine stopped.') + self.shutdown_rbd_stats() + # wait for the metrics collection thread to stop + self.metrics_thread.join() + + def shutdown(self): + self.log.info('Stopping engine...') + self.shutdown_event.set() + + +class StandbyModule(MgrStandbyModule): + def __init__(self, *args, **kwargs): + super(StandbyModule, self).__init__(*args, **kwargs) + self.shutdown_event = threading.Event() + + def serve(self): + server_addr = self.get_localized_module_option( + 'server_addr', get_default_addr()) + server_port = self.get_localized_module_option( + 'server_port', DEFAULT_PORT) + self.log.info("server_addr: %s server_port: %s" % + (server_addr, server_port)) + cherrypy.config.update({ + 'server.socket_host': server_addr, + 'server.socket_port': int(server_port), + 'engine.autoreload.on': False + }) + + module = self + + class Root(object): + @cherrypy.expose + def index(self): + active_uri = module.get_active_uri() + return ''' + + Ceph Exporter + +

Ceph Exporter

+

Metrics

+ +'''.format(active_uri) + + @cherrypy.expose + def metrics(self): + cherrypy.response.headers['Content-Type'] = 'text/plain' + return '' + + cherrypy.tree.mount(Root(), '/', {}) + self.log.info('Starting engine...') + cherrypy.engine.start() + self.log.info('Engine started.') + # Wait for shutdown event + self.shutdown_event.wait() + self.shutdown_event.clear() + cherrypy.engine.stop() + self.log.info('Engine stopped.') + + def shutdown(self): + self.log.info("Stopping engine...") + self.shutdown_event.set() + self.log.info("Stopped engine") diff --git a/src/pybind/mgr/rbd_support/__init__.py b/src/pybind/mgr/rbd_support/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/rbd_support/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/rbd_support/module.py b/src/pybind/mgr/rbd_support/module.py new file mode 100644 index 00000000..f8789339 --- /dev/null +++ b/src/pybind/mgr/rbd_support/module.py @@ -0,0 +1,1427 @@ +""" +RBD support module +""" + +import errno +import json +import rados +import rbd +import re +import time +import traceback +import uuid + +from mgr_module import MgrModule + +from contextlib import contextmanager +from datetime import datetime, timedelta +from functools import partial, wraps +from threading import Condition, Lock, Thread + + +GLOBAL_POOL_KEY = (None, None) + +QUERY_POOL_ID = "pool_id" +QUERY_POOL_ID_MAP = "pool_id_map" +QUERY_IDS = "query_ids" +QUERY_SUM_POOL_COUNTERS = "pool_counters" +QUERY_RAW_POOL_COUNTERS = "raw_pool_counters" +QUERY_LAST_REQUEST = "last_request" + +OSD_PERF_QUERY_REGEX_MATCH_ALL = '^(.*)$' +OSD_PERF_QUERY_COUNTERS = ['write_ops', + 'read_ops', + 'write_bytes', + 'read_bytes', + 'write_latency', + 'read_latency'] +OSD_PERF_QUERY_COUNTERS_INDICES = { + OSD_PERF_QUERY_COUNTERS[i]: i for i in range(len(OSD_PERF_QUERY_COUNTERS))} + +OSD_PERF_QUERY_LATENCY_COUNTER_INDICES = [4, 5] +OSD_PERF_QUERY_MAX_RESULTS = 256 + +POOL_REFRESH_INTERVAL = timedelta(minutes=5) +QUERY_EXPIRE_INTERVAL = timedelta(minutes=1) +STATS_RATE_INTERVAL = timedelta(minutes=1) + +REPORT_MAX_RESULTS = 64 + +RBD_TASK_OID = "rbd_task" + +TASK_SEQUENCE = "sequence" +TASK_ID = "id" +TASK_REFS = "refs" +TASK_MESSAGE = "message" +TASK_RETRY_ATTEMPTS = "retry_attempts" +TASK_RETRY_TIME = "retry_time" +TASK_RETRY_MESSAGE = "retry_message" +TASK_IN_PROGRESS = "in_progress" +TASK_PROGRESS = "progress" +TASK_CANCELED = "canceled" + +TASK_REF_POOL_NAME = "pool_name" +TASK_REF_POOL_NAMESPACE = "pool_namespace" +TASK_REF_IMAGE_NAME = "image_name" +TASK_REF_IMAGE_ID = "image_id" +TASK_REF_ACTION = "action" + +TASK_REF_ACTION_FLATTEN = "flatten" +TASK_REF_ACTION_REMOVE = "remove" +TASK_REF_ACTION_TRASH_REMOVE = "trash remove" +TASK_REF_ACTION_MIGRATION_EXECUTE = "migrate execute" +TASK_REF_ACTION_MIGRATION_COMMIT = "migrate commit" +TASK_REF_ACTION_MIGRATION_ABORT = "migrate abort" + +VALID_TASK_ACTIONS = [TASK_REF_ACTION_FLATTEN, + TASK_REF_ACTION_REMOVE, + TASK_REF_ACTION_TRASH_REMOVE, + TASK_REF_ACTION_MIGRATION_EXECUTE, + TASK_REF_ACTION_MIGRATION_COMMIT, + TASK_REF_ACTION_MIGRATION_ABORT] + +TASK_RETRY_INTERVAL = timedelta(seconds=30) +TASK_MAX_RETRY_INTERVAL = timedelta(seconds=300) +MAX_COMPLETED_TASKS = 50 + + +class NotAuthorizedError(Exception): + pass + + +def is_authorized(module, pool, namespace): + return module.is_authorized({"pool": pool or '', + "namespace": namespace or ''}) + + +def authorize_request(module, pool, namespace): + if not is_authorized(module, pool, namespace): + raise NotAuthorizedError("not authorized on pool={}, namespace={}".format( + pool, namespace)) + + +def extract_pool_key(pool_spec): + if not pool_spec: + return GLOBAL_POOL_KEY + + match = re.match(r'^([^/]+)(?:/([^/]+))?$', pool_spec) + if not match: + raise ValueError("Invalid pool spec: {}".format(pool_spec)) + return (match.group(1), match.group(2) or '') + + +def get_rbd_pools(module): + osd_map = module.get('osd_map') + return {pool['pool']: pool['pool_name'] for pool in osd_map['pools'] + if 'rbd' in pool.get('application_metadata', {})} + + +class PerfHandler: + user_queries = {} + image_cache = {} + + lock = Lock() + query_condition = Condition(lock) + refresh_condition = Condition(lock) + thread = None + + image_name_cache = {} + image_name_refresh_time = datetime.fromtimestamp(0) + + @classmethod + def prepare_regex(cls, value): + return '^({})$'.format(value) + + @classmethod + def prepare_osd_perf_query(cls, pool_id, namespace, counter_type): + pool_id_regex = OSD_PERF_QUERY_REGEX_MATCH_ALL + namespace_regex = OSD_PERF_QUERY_REGEX_MATCH_ALL + if pool_id: + pool_id_regex = cls.prepare_regex(pool_id) + if namespace: + namespace_regex = cls.prepare_regex(namespace) + + return { + 'key_descriptor': [ + {'type': 'pool_id', 'regex': pool_id_regex}, + {'type': 'namespace', 'regex': namespace_regex}, + {'type': 'object_name', + 'regex': '^(?:rbd|journal)_data\\.(?:([0-9]+)\\.)?([^.]+)\\.'}, + ], + 'performance_counter_descriptors': OSD_PERF_QUERY_COUNTERS, + 'limit': {'order_by': counter_type, + 'max_count': OSD_PERF_QUERY_MAX_RESULTS}, + } + + @classmethod + def pool_spec_search_keys(cls, pool_key): + return [pool_key[0:len(pool_key) - x] + for x in range(0, len(pool_key) + 1)] + + @classmethod + def submatch_pool_key(cls, pool_key, search_key): + return ((pool_key[1] == search_key[1] or not search_key[1]) + and (pool_key[0] == search_key[0] or not search_key[0])) + + def __init__(self, module): + self.module = module + self.log = module.log + + self.thread = Thread(target=self.run) + self.thread.start() + + def run(self): + try: + self.log.info("PerfHandler: starting") + while True: + with self.lock: + self.scrub_expired_queries() + self.process_raw_osd_perf_counters() + self.refresh_condition.notify() + + stats_period = int(self.module.get_ceph_option("mgr_stats_period")) + self.query_condition.wait(stats_period) + + self.log.debug("PerfHandler: tick") + + except Exception as ex: + self.log.fatal("Fatal runtime error: {}\n{}".format( + ex, traceback.format_exc())) + + def merge_raw_osd_perf_counters(self, pool_key, query, now_ts, + resolve_image_names): + pool_id_map = query[QUERY_POOL_ID_MAP] + + # collect and combine the raw counters from all sort orders + raw_pool_counters = query.setdefault(QUERY_RAW_POOL_COUNTERS, {}) + for query_id in query[QUERY_IDS]: + res = self.module.get_osd_perf_counters(query_id) + for counter in res['counters']: + # replace pool id from object name if it exists + k = counter['k'] + pool_id = int(k[2][0]) if k[2][0] else int(k[0][0]) + namespace = k[1][0] + image_id = k[2][1] + + # ignore metrics from non-matching pools/namespaces + if pool_id not in pool_id_map: + continue + if pool_key[1] is not None and pool_key[1] != namespace: + continue + + # flag the pool (and namespace) for refresh if we cannot find + # image name in the cache + resolve_image_key = (pool_id, namespace) + if image_id not in self.image_name_cache.get(resolve_image_key, {}): + resolve_image_names.add(resolve_image_key) + + # copy the 'sum' counter values for each image (ignore count) + # if we haven't already processed it for this round + raw_namespaces = raw_pool_counters.setdefault(pool_id, {}) + raw_images = raw_namespaces.setdefault(namespace, {}) + raw_image = raw_images.setdefault(image_id, [None, None]) + + # save the last two perf counters for each image + if raw_image[0] and raw_image[0][0] < now_ts: + raw_image[1] = raw_image[0] + raw_image[0] = None + if not raw_image[0]: + raw_image[0] = [now_ts, [int(x[0]) for x in counter['c']]] + + self.log.debug("merge_raw_osd_perf_counters: {}".format(raw_pool_counters)) + return raw_pool_counters + + def sum_osd_perf_counters(self, query, raw_pool_counters, now_ts): + # update the cumulative counters for each image + sum_pool_counters = query.setdefault(QUERY_SUM_POOL_COUNTERS, {}) + for pool_id, raw_namespaces in raw_pool_counters.items(): + sum_namespaces = sum_pool_counters.setdefault(pool_id, {}) + for namespace, raw_images in raw_namespaces.items(): + sum_namespace = sum_namespaces.setdefault(namespace, {}) + for image_id, raw_image in raw_images.items(): + # zero-out non-updated raw counters + if not raw_image[0]: + continue + elif raw_image[0][0] < now_ts: + raw_image[1] = raw_image[0] + raw_image[0] = [now_ts, [0 for x in raw_image[1][1]]] + continue + + counters = raw_image[0][1] + + # copy raw counters if this is a newly discovered image or + # increment existing counters + sum_image = sum_namespace.setdefault(image_id, None) + if sum_image: + for i in range(len(counters)): + sum_image[i] += counters[i] + else: + sum_namespace[image_id] = [x for x in counters] + + self.log.debug("sum_osd_perf_counters: {}".format(sum_pool_counters)) + return sum_pool_counters + + def refresh_image_names(self, resolve_image_names): + for pool_id, namespace in resolve_image_names: + image_key = (pool_id, namespace) + images = self.image_name_cache.setdefault(image_key, {}) + with self.module.rados.open_ioctx2(int(pool_id)) as ioctx: + ioctx.set_namespace(namespace) + for image_meta in rbd.RBD().list2(ioctx): + images[image_meta['id']] = image_meta['name'] + self.log.debug("resolve_image_names: {}={}".format(image_key, images)) + + def scrub_missing_images(self): + for pool_key, query in self.user_queries.items(): + raw_pool_counters = query.get(QUERY_RAW_POOL_COUNTERS, {}) + sum_pool_counters = query.get(QUERY_SUM_POOL_COUNTERS, {}) + for pool_id, sum_namespaces in sum_pool_counters.items(): + raw_namespaces = raw_pool_counters.get(pool_id, {}) + for namespace, sum_images in sum_namespaces.items(): + raw_images = raw_namespaces.get(namespace, {}) + + image_key = (pool_id, namespace) + image_names = self.image_name_cache.get(image_key, {}) + for image_id in list(sum_images.keys()): + # scrub image counters if we failed to resolve image name + if image_id not in image_names: + self.log.debug("scrub_missing_images: dropping {}/{}".format( + image_key, image_id)) + del sum_images[image_id] + if image_id in raw_images: + del raw_images[image_id] + + def process_raw_osd_perf_counters(self): + now = datetime.now() + now_ts = int(now.strftime("%s")) + + # clear the image name cache if we need to refresh all active pools + if self.image_name_cache and \ + self.image_name_refresh_time + POOL_REFRESH_INTERVAL < now: + self.log.debug("process_raw_osd_perf_counters: expiring image name cache") + self.image_name_cache = {} + + resolve_image_names = set() + for pool_key, query in self.user_queries.items(): + if not query[QUERY_IDS]: + continue + + raw_pool_counters = self.merge_raw_osd_perf_counters( + pool_key, query, now_ts, resolve_image_names) + self.sum_osd_perf_counters(query, raw_pool_counters, now_ts) + + if resolve_image_names: + self.image_name_refresh_time = now + self.refresh_image_names(resolve_image_names) + self.scrub_missing_images() + elif not self.image_name_cache: + self.scrub_missing_images() + + def resolve_pool_id(self, pool_name): + pool_id = self.module.rados.pool_lookup(pool_name) + if not pool_id: + raise rados.ObjectNotFound("Pool '{}' not found".format(pool_name), + errno.ENOENT) + return pool_id + + def scrub_expired_queries(self): + # perf counters need to be periodically refreshed to continue + # to be registered + expire_time = datetime.now() - QUERY_EXPIRE_INTERVAL + for pool_key in list(self.user_queries.keys()): + user_query = self.user_queries[pool_key] + if user_query[QUERY_LAST_REQUEST] < expire_time: + self.unregister_osd_perf_queries(pool_key, user_query[QUERY_IDS]) + del self.user_queries[pool_key] + + def register_osd_perf_queries(self, pool_id, namespace): + query_ids = [] + try: + for counter in OSD_PERF_QUERY_COUNTERS: + query = self.prepare_osd_perf_query(pool_id, namespace, counter) + self.log.debug("register_osd_perf_queries: {}".format(query)) + + query_id = self.module.add_osd_perf_query(query) + if query_id is None: + raise RuntimeError('Failed to add OSD perf query: {}'.format(query)) + query_ids.append(query_id) + + except Exception: + for query_id in query_ids: + self.module.remove_osd_perf_query(query_id) + raise + + return query_ids + + def unregister_osd_perf_queries(self, pool_key, query_ids): + self.log.info("unregister_osd_perf_queries: pool_key={}, query_ids={}".format( + pool_key, query_ids)) + for query_id in query_ids: + self.module.remove_osd_perf_query(query_id) + query_ids[:] = [] + + def register_query(self, pool_key): + if pool_key not in self.user_queries: + pool_id = None + if pool_key[0]: + pool_id = self.resolve_pool_id(pool_key[0]) + + user_query = { + QUERY_POOL_ID: pool_id, + QUERY_POOL_ID_MAP: {pool_id: pool_key[0]}, + QUERY_IDS: self.register_osd_perf_queries(pool_id, pool_key[1]), + QUERY_LAST_REQUEST: datetime.now() + } + + self.user_queries[pool_key] = user_query + + # force an immediate stat pull if this is a new query + self.query_condition.notify() + self.refresh_condition.wait(5) + + else: + user_query = self.user_queries[pool_key] + + # ensure query doesn't expire + user_query[QUERY_LAST_REQUEST] = datetime.now() + + if pool_key == GLOBAL_POOL_KEY: + # refresh the global pool id -> name map upon each + # processing period + user_query[QUERY_POOL_ID_MAP] = { + pool_id: pool_name for pool_id, pool_name + in get_rbd_pools(self.module).items()} + + self.log.debug("register_query: pool_key={}, query_ids={}".format( + pool_key, user_query[QUERY_IDS])) + + return user_query + + def extract_stat(self, index, raw_image, sum_image): + # require two raw counters between a fixed time window + if not raw_image or not raw_image[0] or not raw_image[1]: + return 0 + + current_time = raw_image[0][0] + previous_time = raw_image[1][0] + if current_time <= previous_time or \ + current_time - previous_time > STATS_RATE_INTERVAL.total_seconds(): + return 0 + + current_value = raw_image[0][1][index] + instant_rate = float(current_value) / (current_time - previous_time) + + # convert latencies from sum to average per op + ops_index = None + if OSD_PERF_QUERY_COUNTERS[index] == 'write_latency': + ops_index = OSD_PERF_QUERY_COUNTERS_INDICES['write_ops'] + elif OSD_PERF_QUERY_COUNTERS[index] == 'read_latency': + ops_index = OSD_PERF_QUERY_COUNTERS_INDICES['read_ops'] + + if ops_index is not None: + ops = max(1, self.extract_stat(ops_index, raw_image, sum_image)) + instant_rate /= ops + + return instant_rate + + def extract_counter(self, index, raw_image, sum_image): + if sum_image: + return sum_image[index] + return 0 + + def generate_report(self, query, sort_by, extract_data): + pool_id_map = query[QUERY_POOL_ID_MAP] + sum_pool_counters = query.setdefault(QUERY_SUM_POOL_COUNTERS, {}) + raw_pool_counters = query.setdefault(QUERY_RAW_POOL_COUNTERS, {}) + + sort_by_index = OSD_PERF_QUERY_COUNTERS.index(sort_by) + + # pre-sort and limit the response + results = [] + for pool_id, sum_namespaces in sum_pool_counters.items(): + if pool_id not in pool_id_map: + continue + raw_namespaces = raw_pool_counters.get(pool_id, {}) + for namespace, sum_images in sum_namespaces.items(): + raw_images = raw_namespaces.get(namespace, {}) + for image_id, sum_image in sum_images.items(): + raw_image = raw_images.get(image_id, []) + + # always sort by recent IO activity + results.append([(pool_id, namespace, image_id), + self.extract_stat(sort_by_index, raw_image, + sum_image)]) + results = sorted(results, key=lambda x: x[1], reverse=True)[:REPORT_MAX_RESULTS] + + # build the report in sorted order + pool_descriptors = {} + counters = [] + for key, _ in results: + pool_id = key[0] + pool_name = pool_id_map[pool_id] + + namespace = key[1] + image_id = key[2] + image_names = self.image_name_cache.get((pool_id, namespace), {}) + image_name = image_names[image_id] + + raw_namespaces = raw_pool_counters.get(pool_id, {}) + raw_images = raw_namespaces.get(namespace, {}) + raw_image = raw_images.get(image_id, []) + + sum_namespaces = sum_pool_counters[pool_id] + sum_images = sum_namespaces[namespace] + sum_image = sum_images.get(image_id, []) + + pool_descriptor = pool_name + if namespace: + pool_descriptor += "/{}".format(namespace) + pool_index = pool_descriptors.setdefault(pool_descriptor, + len(pool_descriptors)) + image_descriptor = "{}/{}".format(pool_index, image_name) + data = [extract_data(i, raw_image, sum_image) + for i in range(len(OSD_PERF_QUERY_COUNTERS))] + + # skip if no data to report + if data == [0 for i in range(len(OSD_PERF_QUERY_COUNTERS))]: + continue + + counters.append({image_descriptor: data}) + + return {idx: descriptor for descriptor, idx + in pool_descriptors.items()}, \ + counters + + def get_perf_data(self, report, pool_spec, sort_by, extract_data): + self.log.debug("get_perf_{}s: pool_spec={}, sort_by={}".format( + report, pool_spec, sort_by)) + self.scrub_expired_queries() + + pool_key = extract_pool_key(pool_spec) + authorize_request(self.module, pool_key[0], pool_key[1]) + + user_query = self.register_query(pool_key) + + now = datetime.now() + pool_descriptors, counters = self.generate_report( + user_query, sort_by, extract_data) + + report = { + 'timestamp': time.mktime(now.timetuple()), + '{}_descriptors'.format(report): OSD_PERF_QUERY_COUNTERS, + 'pool_descriptors': pool_descriptors, + '{}s'.format(report): counters + } + + return 0, json.dumps(report), "" + + def get_perf_stats(self, pool_spec, sort_by): + return self.get_perf_data( + "stat", pool_spec, sort_by, self.extract_stat) + + def get_perf_counters(self, pool_spec, sort_by): + return self.get_perf_data( + "counter", pool_spec, sort_by, self.extract_counter) + + def handle_command(self, inbuf, prefix, cmd): + with self.lock: + if prefix == 'image stats': + return self.get_perf_stats(cmd.get('pool_spec', None), + cmd.get('sort_by', OSD_PERF_QUERY_COUNTERS[0])) + elif prefix == 'image counters': + return self.get_perf_counters(cmd.get('pool_spec', None), + cmd.get('sort_by', OSD_PERF_QUERY_COUNTERS[0])) + + raise NotImplementedError(cmd['prefix']) + + +class Throttle: + def __init__(self, throttle_period): + self.throttle_period = throttle_period + self.time_of_last_call = datetime.min + + def __call__(self, fn): + @wraps(fn) + def wrapper(*args, **kwargs): + now = datetime.now() + if self.time_of_last_call + self.throttle_period <= now: + self.time_of_last_call = now + return fn(*args, **kwargs) + return wrapper + + +class Task: + def __init__(self, sequence, task_id, message, refs): + self.sequence = sequence + self.task_id = task_id + self.message = message + self.refs = refs + self.retry_message = None + self.retry_attempts = 0 + self.retry_time = None + self.in_progress = False + self.progress = 0.0 + self.canceled = False + self.failed = False + self.progress_posted = False + + def __str__(self): + return self.to_json() + + @property + def sequence_key(self): + return "{0:016X}".format(self.sequence) + + def cancel(self): + self.canceled = True + self.fail("Operation canceled") + + def fail(self, message): + self.failed = True + self.failure_message = message + + def to_dict(self): + d = {TASK_SEQUENCE: self.sequence, + TASK_ID: self.task_id, + TASK_MESSAGE: self.message, + TASK_REFS: self.refs + } + if self.retry_message: + d[TASK_RETRY_MESSAGE] = self.retry_message + if self.retry_attempts: + d[TASK_RETRY_ATTEMPTS] = self.retry_attempts + if self.retry_time: + d[TASK_RETRY_TIME] = self.retry_time.isoformat() + if self.in_progress: + d[TASK_IN_PROGRESS] = True + d[TASK_PROGRESS] = self.progress + if self.canceled: + d[TASK_CANCELED] = True + return d + + def to_json(self): + return str(json.dumps(self.to_dict())) + + @classmethod + def from_json(cls, val): + try: + d = json.loads(val) + action = d.get(TASK_REFS, {}).get(TASK_REF_ACTION) + if action not in VALID_TASK_ACTIONS: + raise ValueError("Invalid task action: {}".format(action)) + + return Task(d[TASK_SEQUENCE], d[TASK_ID], d[TASK_MESSAGE], d[TASK_REFS]) + except json.JSONDecodeError as e: + raise ValueError("Invalid JSON ({})".format(str(e))) + except KeyError as e: + raise ValueError("Invalid task format (missing key {})".format(str(e))) + + +class TaskHandler: + lock = Lock() + condition = Condition(lock) + thread = None + + in_progress_task = None + tasks_by_sequence = dict() + tasks_by_id = dict() + + completed_tasks = [] + + sequence = 0 + + def __init__(self, module): + self.module = module + self.log = module.log + + with self.lock: + self.init_task_queue() + + self.thread = Thread(target=self.run) + self.thread.start() + + @property + def default_pool_name(self): + return self.module.get_ceph_option("rbd_default_pool") + + def extract_pool_spec(self, pool_spec): + pool_spec = extract_pool_key(pool_spec) + if pool_spec == GLOBAL_POOL_KEY: + pool_spec = (self.default_pool_name, '') + return pool_spec + + def extract_image_spec(self, image_spec): + match = re.match(r'^(?:([^/]+)/(?:([^/]+)/)?)?([^/@]+)$', + image_spec or '') + if not match: + raise ValueError("Invalid image spec: {}".format(image_spec)) + return (match.group(1) or self.default_pool_name, match.group(2) or '', + match.group(3)) + + def run(self): + try: + self.log.info("TaskHandler: starting") + while True: + with self.lock: + now = datetime.now() + for sequence in sorted([sequence for sequence, task + in self.tasks_by_sequence.items() + if not task.retry_time or task.retry_time <= now]): + self.execute_task(sequence) + + self.condition.wait(5) + self.log.debug("TaskHandler: tick") + + except Exception as ex: + self.log.fatal("Fatal runtime error: {}\n{}".format( + ex, traceback.format_exc())) + + @contextmanager + def open_ioctx(self, spec): + try: + with self.module.rados.open_ioctx(spec[0]) as ioctx: + ioctx.set_namespace(spec[1]) + yield ioctx + except rados.ObjectNotFound: + self.log.error("Failed to locate pool {}".format(spec[0])) + raise + + @classmethod + def format_image_spec(cls, image_spec): + image = image_spec[2] + if image_spec[1]: + image = "{}/{}".format(image_spec[1], image) + if image_spec[0]: + image = "{}/{}".format(image_spec[0], image) + return image + + def init_task_queue(self): + for pool_id, pool_name in get_rbd_pools(self.module).items(): + try: + with self.module.rados.open_ioctx2(int(pool_id)) as ioctx: + self.load_task_queue(ioctx, pool_name) + + try: + namespaces = rbd.RBD().namespace_list(ioctx) + except rbd.OperationNotSupported: + self.log.debug("Namespaces not supported") + continue + + for namespace in namespaces: + ioctx.set_namespace(namespace) + self.load_task_queue(ioctx, pool_name) + + except rados.ObjectNotFound: + # pool DNE + pass + + if self.tasks_by_sequence: + self.sequence = list(sorted(self.tasks_by_sequence.keys()))[-1] + + self.log.debug("sequence={}, tasks_by_sequence={}, tasks_by_id={}".format( + self.sequence, str(self.tasks_by_sequence), str(self.tasks_by_id))) + + def load_task_queue(self, ioctx, pool_name): + pool_spec = pool_name + if ioctx.nspace: + pool_spec += "/{}".format(ioctx.nspace) + + start_after = '' + try: + while True: + with rados.ReadOpCtx() as read_op: + self.log.info("load_task_task: {}, start_after={}".format( + pool_spec, start_after)) + it, ret = ioctx.get_omap_vals(read_op, start_after, "", 128) + ioctx.operate_read_op(read_op, RBD_TASK_OID) + + it = list(it) + for k, v in it: + start_after = k + v = v.decode() + self.log.info("load_task_task: task={}".format(v)) + + try: + task = Task.from_json(v) + self.append_task(task) + except ValueError: + self.log.error("Failed to decode task: pool_spec={}, task={}".format(pool_spec, v)) + + if not it: + break + + except StopIteration: + pass + except rados.ObjectNotFound: + # rbd_task DNE + pass + + def append_task(self, task): + self.tasks_by_sequence[task.sequence] = task + self.tasks_by_id[task.task_id] = task + + def task_refs_match(self, task_refs, refs): + if TASK_REF_IMAGE_ID not in refs and TASK_REF_IMAGE_ID in task_refs: + task_refs = task_refs.copy() + del task_refs[TASK_REF_IMAGE_ID] + + self.log.debug("task_refs_match: ref1={}, ref2={}".format(task_refs, refs)) + return task_refs == refs + + def find_task(self, refs): + self.log.debug("find_task: refs={}".format(refs)) + + # search for dups and return the original + for task_id in reversed(sorted(self.tasks_by_id.keys())): + task = self.tasks_by_id[task_id] + if self.task_refs_match(task.refs, refs): + return task + + # search for a completed task (message replay) + for task in reversed(self.completed_tasks): + if self.task_refs_match(task.refs, refs): + return task + + def add_task(self, ioctx, message, refs): + self.log.debug("add_task: message={}, refs={}".format(message, refs)) + + # ensure unique uuid across all pools + while True: + task_id = str(uuid.uuid4()) + if task_id not in self.tasks_by_id: + break + + self.sequence += 1 + task = Task(self.sequence, task_id, message, refs) + + # add the task to the rbd_task omap + task_json = task.to_json() + omap_keys = (task.sequence_key, ) + omap_vals = (str.encode(task_json), ) + self.log.info("adding task: {} {}".format(omap_keys[0], omap_vals[0])) + + with rados.WriteOpCtx() as write_op: + ioctx.set_omap(write_op, omap_keys, omap_vals) + ioctx.operate_write_op(write_op, RBD_TASK_OID) + self.append_task(task) + + self.condition.notify() + return task_json + + def remove_task(self, ioctx, task, remove_in_memory=True): + self.log.info("remove_task: task={}".format(str(task))) + omap_keys = (task.sequence_key, ) + try: + with rados.WriteOpCtx() as write_op: + ioctx.remove_omap_keys(write_op, omap_keys) + ioctx.operate_write_op(write_op, RBD_TASK_OID) + except rados.ObjectNotFound: + pass + + if remove_in_memory: + try: + del self.tasks_by_id[task.task_id] + del self.tasks_by_sequence[task.sequence] + + # keep a record of the last N tasks to help avoid command replay + # races + if not task.failed and not task.canceled: + self.log.debug("remove_task: moving to completed tasks") + self.completed_tasks.append(task) + self.completed_tasks = self.completed_tasks[-MAX_COMPLETED_TASKS:] + + except KeyError: + pass + + def execute_task(self, sequence): + task = self.tasks_by_sequence[sequence] + self.log.info("execute_task: task={}".format(str(task))) + + pool_valid = False + try: + with self.open_ioctx((task.refs[TASK_REF_POOL_NAME], + task.refs[TASK_REF_POOL_NAMESPACE])) as ioctx: + pool_valid = True + + action = task.refs[TASK_REF_ACTION] + execute_fn = {TASK_REF_ACTION_FLATTEN: self.execute_flatten, + TASK_REF_ACTION_REMOVE: self.execute_remove, + TASK_REF_ACTION_TRASH_REMOVE: self.execute_trash_remove, + TASK_REF_ACTION_MIGRATION_EXECUTE: self.execute_migration_execute, + TASK_REF_ACTION_MIGRATION_COMMIT: self.execute_migration_commit, + TASK_REF_ACTION_MIGRATION_ABORT: self.execute_migration_abort + }.get(action) + if not execute_fn: + self.log.error("Invalid task action: {}".format(action)) + else: + task.in_progress = True + self.in_progress_task = task + + self.lock.release() + try: + execute_fn(ioctx, task) + + except rbd.OperationCanceled: + self.log.info("Operation canceled: task={}".format( + str(task))) + + finally: + self.lock.acquire() + + task.in_progress = False + self.in_progress_task = None + + self.complete_progress(task) + self.remove_task(ioctx, task) + + except rados.ObjectNotFound as e: + self.log.error("execute_task: {}".format(e)) + if pool_valid: + task.retry_message = "{}".format(e) + self.update_progress(task, 0) + else: + # pool DNE -- remove the task + self.complete_progress(task) + self.remove_task(ioctx, task) + + except (rados.Error, rbd.Error) as e: + self.log.error("execute_task: {}".format(e)) + task.retry_message = "{}".format(e) + self.update_progress(task, 0) + + finally: + task.in_progress = False + task.retry_attempts += 1 + task.retry_time = datetime.now() + min( + TASK_RETRY_INTERVAL * task.retry_attempts, + TASK_MAX_RETRY_INTERVAL) + + def progress_callback(self, task, current, total): + progress = float(current) / float(total) + self.log.debug("progress_callback: task={}, progress={}".format( + str(task), progress)) + + # avoid deadlocking when a new command comes in during a progress callback + if not self.lock.acquire(False): + return 0 + + try: + if not self.in_progress_task or self.in_progress_task.canceled: + return -rbd.ECANCELED + self.in_progress_task.progress = progress + finally: + self.lock.release() + + if not task.progress_posted: + # delayed creation of progress event until first callback + self.post_progress(task, progress) + else: + self.throttled_update_progress(task, progress) + + return 0 + + def execute_flatten(self, ioctx, task): + self.log.info("execute_flatten: task={}".format(str(task))) + + try: + with rbd.Image(ioctx, task.refs[TASK_REF_IMAGE_NAME]) as image: + image.flatten(on_progress=partial(self.progress_callback, task)) + except rbd.InvalidArgument: + task.fail("Image does not have parent") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + except rbd.ImageNotFound: + task.fail("Image does not exist") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + + def execute_remove(self, ioctx, task): + self.log.info("execute_remove: task={}".format(str(task))) + + try: + rbd.RBD().remove(ioctx, task.refs[TASK_REF_IMAGE_NAME], + on_progress=partial(self.progress_callback, task)) + except rbd.ImageNotFound: + task.fail("Image does not exist") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + + def execute_trash_remove(self, ioctx, task): + self.log.info("execute_trash_remove: task={}".format(str(task))) + + try: + rbd.RBD().trash_remove(ioctx, task.refs[TASK_REF_IMAGE_ID], + on_progress=partial(self.progress_callback, task)) + except rbd.ImageNotFound: + task.fail("Image does not exist") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + + def execute_migration_execute(self, ioctx, task): + self.log.info("execute_migration_execute: task={}".format(str(task))) + + try: + rbd.RBD().migration_execute(ioctx, task.refs[TASK_REF_IMAGE_NAME], + on_progress=partial(self.progress_callback, task)) + except rbd.ImageNotFound: + task.fail("Image does not exist") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + except rbd.InvalidArgument: + task.fail("Image is not migrating") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + + def execute_migration_commit(self, ioctx, task): + self.log.info("execute_migration_commit: task={}".format(str(task))) + + try: + rbd.RBD().migration_commit(ioctx, task.refs[TASK_REF_IMAGE_NAME], + on_progress=partial(self.progress_callback, task)) + except rbd.ImageNotFound: + task.fail("Image does not exist") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + except rbd.InvalidArgument: + task.fail("Image is not migrating or migration not executed") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + + def execute_migration_abort(self, ioctx, task): + self.log.info("execute_migration_abort: task={}".format(str(task))) + + try: + rbd.RBD().migration_abort(ioctx, task.refs[TASK_REF_IMAGE_NAME], + on_progress=partial(self.progress_callback, task)) + except rbd.ImageNotFound: + task.fail("Image does not exist") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + except rbd.InvalidArgument: + task.fail("Image is not migrating") + self.log.info("{}: task={}".format(task.failure_message, str(task))) + + def complete_progress(self, task): + if not task.progress_posted: + # ensure progress event exists before we complete/fail it + self.post_progress(task, 0) + + self.log.debug("complete_progress: task={}".format(str(task))) + try: + if task.failed: + self.module.remote("progress", "fail", task.task_id, + task.failure_message) + else: + self.module.remote("progress", "complete", task.task_id) + except ImportError: + # progress module is disabled + pass + + def _update_progress(self, task, progress): + self.log.debug("update_progress: task={}, progress={}".format(str(task), progress)) + try: + refs = {"origin": "rbd_support"} + refs.update(task.refs) + + self.module.remote("progress", "update", task.task_id, + task.message, progress, refs) + except ImportError: + # progress module is disabled + pass + + def post_progress(self, task, progress): + self._update_progress(task, progress) + task.progress_posted = True + + def update_progress(self, task, progress): + if task.progress_posted: + self._update_progress(task, progress) + + @Throttle(timedelta(seconds=1)) + def throttled_update_progress(self, task, progress): + self.update_progress(task, progress) + + def queue_flatten(self, image_spec): + image_spec = self.extract_image_spec(image_spec) + + authorize_request(self.module, image_spec[0], image_spec[1]) + self.log.info("queue_flatten: {}".format(image_spec)) + + refs = {TASK_REF_ACTION: TASK_REF_ACTION_FLATTEN, + TASK_REF_POOL_NAME: image_spec[0], + TASK_REF_POOL_NAMESPACE: image_spec[1], + TASK_REF_IMAGE_NAME: image_spec[2]} + + with self.open_ioctx(image_spec) as ioctx: + try: + with rbd.Image(ioctx, image_spec[2]) as image: + refs[TASK_REF_IMAGE_ID] = image.id() + + try: + parent_image_id = image.parent_id() + except rbd.ImageNotFound: + parent_image_id = None + + except rbd.ImageNotFound: + pass + + task = self.find_task(refs) + if task: + return 0, task.to_json(), '' + + if TASK_REF_IMAGE_ID not in refs: + raise rbd.ImageNotFound("Image {} does not exist".format( + self.format_image_spec(image_spec)), errno=errno.ENOENT) + if not parent_image_id: + raise rbd.ImageNotFound("Image {} does not have a parent".format( + self.format_image_spec(image_spec)), errno=errno.ENOENT) + + return 0, self.add_task(ioctx, + "Flattening image {}".format( + self.format_image_spec(image_spec)), + refs), "" + + def queue_remove(self, image_spec): + image_spec = self.extract_image_spec(image_spec) + + authorize_request(self.module, image_spec[0], image_spec[1]) + self.log.info("queue_remove: {}".format(image_spec)) + + refs = {TASK_REF_ACTION: TASK_REF_ACTION_REMOVE, + TASK_REF_POOL_NAME: image_spec[0], + TASK_REF_POOL_NAMESPACE: image_spec[1], + TASK_REF_IMAGE_NAME: image_spec[2]} + + with self.open_ioctx(image_spec) as ioctx: + try: + with rbd.Image(ioctx, image_spec[2]) as image: + refs[TASK_REF_IMAGE_ID] = image.id() + snaps = list(image.list_snaps()) + + except rbd.ImageNotFound: + pass + + task = self.find_task(refs) + if task: + return 0, task.to_json(), '' + + if TASK_REF_IMAGE_ID not in refs: + raise rbd.ImageNotFound("Image {} does not exist".format( + self.format_image_spec(image_spec)), errno=errno.ENOENT) + if snaps: + raise rbd.ImageBusy("Image {} has snapshots".format( + self.format_image_spec(image_spec)), errno=errno.EBUSY) + + return 0, self.add_task(ioctx, + "Removing image {}".format( + self.format_image_spec(image_spec)), + refs), '' + + def queue_trash_remove(self, image_id_spec): + image_id_spec = self.extract_image_spec(image_id_spec) + + authorize_request(self.module, image_id_spec[0], image_id_spec[1]) + self.log.info("queue_trash_remove: {}".format(image_id_spec)) + + refs = {TASK_REF_ACTION: TASK_REF_ACTION_TRASH_REMOVE, + TASK_REF_POOL_NAME: image_id_spec[0], + TASK_REF_POOL_NAMESPACE: image_id_spec[1], + TASK_REF_IMAGE_ID: image_id_spec[2]} + task = self.find_task(refs) + if task: + return 0, task.to_json(), '' + + # verify that image exists in trash + with self.open_ioctx(image_id_spec) as ioctx: + rbd.RBD().trash_get(ioctx, image_id_spec[2]) + + return 0, self.add_task(ioctx, + "Removing image {} from trash".format( + self.format_image_spec(image_id_spec)), + refs), '' + + def get_migration_status(self, ioctx, image_spec): + try: + return rbd.RBD().migration_status(ioctx, image_spec[2]) + except (rbd.InvalidArgument, rbd.ImageNotFound): + return None + + def validate_image_migrating(self, image_spec, migration_status): + if not migration_status: + raise rbd.InvalidArgument("Image {} is not migrating".format( + self.format_image_spec(image_spec)), errno=errno.EINVAL) + + def resolve_pool_name(self, pool_id): + osd_map = self.module.get('osd_map') + for pool in osd_map['pools']: + if pool['pool'] == pool_id: + return pool['pool_name'] + return '' + + def queue_migration_execute(self, image_spec): + image_spec = self.extract_image_spec(image_spec) + + authorize_request(self.module, image_spec[0], image_spec[1]) + self.log.info("queue_migration_execute: {}".format(image_spec)) + + refs = {TASK_REF_ACTION: TASK_REF_ACTION_MIGRATION_EXECUTE, + TASK_REF_POOL_NAME: image_spec[0], + TASK_REF_POOL_NAMESPACE: image_spec[1], + TASK_REF_IMAGE_NAME: image_spec[2]} + + with self.open_ioctx(image_spec) as ioctx: + status = self.get_migration_status(ioctx, image_spec) + if status: + refs[TASK_REF_IMAGE_ID] = status['dest_image_id'] + + task = self.find_task(refs) + if task: + return 0, task.to_json(), '' + + self.validate_image_migrating(image_spec, status) + if status['state'] not in [rbd.RBD_IMAGE_MIGRATION_STATE_PREPARED, + rbd.RBD_IMAGE_MIGRATION_STATE_EXECUTING]: + raise rbd.InvalidArgument("Image {} is not in ready state".format( + self.format_image_spec(image_spec)), errno=errno.EINVAL) + + source_pool = self.resolve_pool_name(status['source_pool_id']) + dest_pool = self.resolve_pool_name(status['dest_pool_id']) + return 0, self.add_task(ioctx, + "Migrating image {} to {}".format( + self.format_image_spec((source_pool, + status['source_pool_namespace'], + status['source_image_name'])), + self.format_image_spec((dest_pool, + status['dest_pool_namespace'], + status['dest_image_name']))), + refs), '' + + def queue_migration_commit(self, image_spec): + image_spec = self.extract_image_spec(image_spec) + + authorize_request(self.module, image_spec[0], image_spec[1]) + self.log.info("queue_migration_commit: {}".format(image_spec)) + + refs = {TASK_REF_ACTION: TASK_REF_ACTION_MIGRATION_COMMIT, + TASK_REF_POOL_NAME: image_spec[0], + TASK_REF_POOL_NAMESPACE: image_spec[1], + TASK_REF_IMAGE_NAME: image_spec[2]} + + with self.open_ioctx(image_spec) as ioctx: + status = self.get_migration_status(ioctx, image_spec) + if status: + refs[TASK_REF_IMAGE_ID] = status['dest_image_id'] + + task = self.find_task(refs) + if task: + return 0, task.to_json(), '' + + self.validate_image_migrating(image_spec, status) + if status['state'] != rbd.RBD_IMAGE_MIGRATION_STATE_EXECUTED: + raise rbd.InvalidArgument("Image {} has not completed migration".format( + self.format_image_spec(image_spec)), errno=errno.EINVAL) + + return 0, self.add_task(ioctx, + "Committing image migration for {}".format( + self.format_image_spec(image_spec)), + refs), '' + + def queue_migration_abort(self, image_spec): + image_spec = self.extract_image_spec(image_spec) + + authorize_request(self.module, image_spec[0], image_spec[1]) + self.log.info("queue_migration_abort: {}".format(image_spec)) + + refs = {TASK_REF_ACTION: TASK_REF_ACTION_MIGRATION_ABORT, + TASK_REF_POOL_NAME: image_spec[0], + TASK_REF_POOL_NAMESPACE: image_spec[1], + TASK_REF_IMAGE_NAME: image_spec[2]} + + with self.open_ioctx(image_spec) as ioctx: + status = self.get_migration_status(ioctx, image_spec) + if status: + refs[TASK_REF_IMAGE_ID] = status['dest_image_id'] + + task = self.find_task(refs) + if task: + return 0, task.to_json(), '' + + self.validate_image_migrating(image_spec, status) + return 0, self.add_task(ioctx, + "Aborting image migration for {}".format( + self.format_image_spec(image_spec)), + refs), '' + + def task_cancel(self, task_id): + self.log.info("task_cancel: {}".format(task_id)) + + task = self.tasks_by_id.get(task_id) + if not task or not is_authorized(self.module, + task.refs[TASK_REF_POOL_NAME], + task.refs[TASK_REF_POOL_NAMESPACE]): + return -errno.ENOENT, '', "No such task {}".format(task_id) + + task.cancel() + + remove_in_memory = True + if self.in_progress_task and self.in_progress_task.task_id == task_id: + self.log.info("Attempting to cancel in-progress task: {}".format(str(self.in_progress_task))) + remove_in_memory = False + + # complete any associated event in the progress module + self.complete_progress(task) + + # remove from rbd_task omap + with self.open_ioctx((task.refs[TASK_REF_POOL_NAME], + task.refs[TASK_REF_POOL_NAMESPACE])) as ioctx: + self.remove_task(ioctx, task, remove_in_memory) + + return 0, "", "" + + def task_list(self, task_id): + self.log.info("task_list: {}".format(task_id)) + + if task_id: + task = self.tasks_by_id.get(task_id) + if not task or not is_authorized(self.module, + task.refs[TASK_REF_POOL_NAME], + task.refs[TASK_REF_POOL_NAMESPACE]): + return -errno.ENOENT, '', "No such task {}".format(task_id) + + result = task.to_dict() + else: + result = [] + for sequence in sorted(self.tasks_by_sequence.keys()): + task = self.tasks_by_sequence[sequence] + if is_authorized(self.module, + task.refs[TASK_REF_POOL_NAME], + task.refs[TASK_REF_POOL_NAMESPACE]): + result.append(task.to_dict()) + + return 0, json.dumps(result), "" + + def handle_command(self, inbuf, prefix, cmd): + with self.lock: + if prefix == 'add flatten': + return self.queue_flatten(cmd['image_spec']) + elif prefix == 'add remove': + return self.queue_remove(cmd['image_spec']) + elif prefix == 'add trash remove': + return self.queue_trash_remove(cmd['image_id_spec']) + elif prefix == 'add migration execute': + return self.queue_migration_execute(cmd['image_spec']) + elif prefix == 'add migration commit': + return self.queue_migration_commit(cmd['image_spec']) + elif prefix == 'add migration abort': + return self.queue_migration_abort(cmd['image_spec']) + elif prefix == 'cancel': + return self.task_cancel(cmd['task_id']) + elif prefix == 'list': + return self.task_list(cmd.get('task_id')) + + raise NotImplementedError(cmd['prefix']) + + +class Module(MgrModule): + COMMANDS = [ + { + "cmd": "rbd perf image stats " + "name=pool_spec,type=CephString,req=false " + "name=sort_by,type=CephChoices,strings=" + "write_ops|write_bytes|write_latency|" + "read_ops|read_bytes|read_latency," + "req=false ", + "desc": "Retrieve current RBD IO performance stats", + "perm": "r" + }, + { + "cmd": "rbd perf image counters " + "name=pool_spec,type=CephString,req=false " + "name=sort_by,type=CephChoices,strings=" + "write_ops|write_bytes|write_latency|" + "read_ops|read_bytes|read_latency," + "req=false ", + "desc": "Retrieve current RBD IO performance counters", + "perm": "r" + }, + { + "cmd": "rbd task add flatten " + "name=image_spec,type=CephString", + "desc": "Flatten a cloned image asynchronously in the background", + "perm": "w" + }, + { + "cmd": "rbd task add remove " + "name=image_spec,type=CephString", + "desc": "Remove an image asynchronously in the background", + "perm": "w" + }, + { + "cmd": "rbd task add trash remove " + "name=image_id_spec,type=CephString", + "desc": "Remove an image from the trash asynchronously in the background", + "perm": "w" + }, + { + "cmd": "rbd task add migration execute " + "name=image_spec,type=CephString", + "desc": "Execute an image migration asynchronously in the background", + "perm": "w" + }, + { + "cmd": "rbd task add migration commit " + "name=image_spec,type=CephString", + "desc": "Commit an executed migration asynchronously in the background", + "perm": "w" + }, + { + "cmd": "rbd task add migration abort " + "name=image_spec,type=CephString", + "desc": "Abort a prepared migration asynchronously in the background", + "perm": "w" + }, + { + "cmd": "rbd task cancel " + "name=task_id,type=CephString ", + "desc": "Cancel a pending or running asynchronous task", + "perm": "r" + }, + { + "cmd": "rbd task list " + "name=task_id,type=CephString,req=false ", + "desc": "List pending or running asynchronous tasks", + "perm": "r" + } + ] + MODULE_OPTIONS = [] + + perf = None + task = None + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.perf = PerfHandler(self) + self.task = TaskHandler(self) + + def handle_command(self, inbuf, cmd): + prefix = cmd['prefix'] + try: + try: + if prefix.startswith('rbd perf '): + return self.perf.handle_command(inbuf, prefix[9:], cmd) + elif prefix.startswith('rbd task '): + return self.task.handle_command(inbuf, prefix[9:], cmd) + + except NotAuthorizedError: + raise + except Exception as ex: + # log the full traceback but don't send it to the CLI user + self.log.fatal("Fatal runtime error: {}\n{}".format( + ex, traceback.format_exc())) + raise + + except rados.Error as ex: + return -ex.errno, "", str(ex) + except rbd.OSError as ex: + return -ex.errno, "", str(ex) + except rbd.Error as ex: + return -errno.EINVAL, "", str(ex) + except KeyError as ex: + return -errno.ENOENT, "", str(ex) + except ValueError as ex: + return -errno.EINVAL, "", str(ex) + except NotAuthorizedError as ex: + return -errno.EACCES, "", str(ex) + + raise NotImplementedError(cmd['prefix']) diff --git a/src/pybind/mgr/restful/__init__.py b/src/pybind/mgr/restful/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/restful/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/restful/api/__init__.py b/src/pybind/mgr/restful/api/__init__.py new file mode 100644 index 00000000..a105dfe8 --- /dev/null +++ b/src/pybind/mgr/restful/api/__init__.py @@ -0,0 +1,39 @@ +from pecan import expose +from pecan.rest import RestController + +from .config import Config +from .crush import Crush +from .doc import Doc +from .mon import Mon +from .osd import Osd +from .pool import Pool +from .perf import Perf +from .request import Request +from .server import Server + + +class Root(RestController): + config = Config() + crush = Crush() + doc = Doc() + mon = Mon() + osd = Osd() + perf = Perf() + pool = Pool() + request = Request() + server = Server() + + @expose(template='json') + def get(self, **kwargs): + """ + Show the basic information for the REST API + This includes values like api version or auth method + """ + return { + 'api_version': 1, + 'auth': + 'Use "ceph restful create-key " to create a key pair, ' + 'pass it as HTTP Basic auth to authenticate', + 'doc': 'See /doc endpoint', + 'info': "Ceph Manager RESTful API server", + } diff --git a/src/pybind/mgr/restful/api/config.py b/src/pybind/mgr/restful/api/config.py new file mode 100644 index 00000000..565896c8 --- /dev/null +++ b/src/pybind/mgr/restful/api/config.py @@ -0,0 +1,86 @@ +from pecan import expose, request +from pecan.rest import RestController + +from restful import common, context +from restful.decorators import auth + + +class ConfigOsd(RestController): + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show OSD configuration options + """ + flags = context.instance.get("osd_map")['flags'] + + # pause is a valid osd config command that sets pauserd,pausewr + flags = flags.replace('pauserd,pausewr', 'pause') + + return flags.split(',') + + + @expose(template='json') + @auth + def patch(self, **kwargs): + """ + Modify OSD configuration options + """ + args = request.json + + commands = [] + + valid_flags = set(args.keys()) & set(common.OSD_FLAGS) + invalid_flags = list(set(args.keys()) - valid_flags) + if invalid_flags: + context.instance.log.warn("%s not valid to set/unset", invalid_flags) + + for flag in list(valid_flags): + if args[flag]: + mode = 'set' + else: + mode = 'unset' + + commands.append({ + 'prefix': 'osd ' + mode, + 'key': flag, + }) + + return context.instance.submit_request([commands], **kwargs) + + + +class ConfigClusterKey(RestController): + def __init__(self, key): + self.key = key + + + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show specific configuration option + """ + return context.instance.get("config").get(self.key, None) + + + +class ConfigCluster(RestController): + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show all cluster configuration options + """ + return context.instance.get("config") + + + @expose() + def _lookup(self, key, *remainder): + return ConfigClusterKey(key), remainder + + + +class Config(RestController): + cluster = ConfigCluster() + osd = ConfigOsd() diff --git a/src/pybind/mgr/restful/api/crush.py b/src/pybind/mgr/restful/api/crush.py new file mode 100644 index 00000000..015c4949 --- /dev/null +++ b/src/pybind/mgr/restful/api/crush.py @@ -0,0 +1,26 @@ +from pecan import expose +from pecan.rest import RestController + +from restful import common, context +from collections import defaultdict + +from restful.decorators import auth + + +class CrushRule(RestController): + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show crush rules + """ + crush = context.instance.get('osd_map_crush') + rules = crush['rules'] + + for rule in rules: + rule['osd_count'] = len(common.crush_rule_osds(crush['buckets'], rule)) + + return rules + +class Crush(RestController): + rule = CrushRule() diff --git a/src/pybind/mgr/restful/api/doc.py b/src/pybind/mgr/restful/api/doc.py new file mode 100644 index 00000000..f1038c21 --- /dev/null +++ b/src/pybind/mgr/restful/api/doc.py @@ -0,0 +1,15 @@ +from pecan import expose +from pecan.rest import RestController + +from restful import context + +import restful + + +class Doc(RestController): + @expose(template='json') + def get(self, **kwargs): + """ + Show documentation information + """ + return context.instance.get_doc_api(restful.api.Root) diff --git a/src/pybind/mgr/restful/api/mon.py b/src/pybind/mgr/restful/api/mon.py new file mode 100644 index 00000000..20d03360 --- /dev/null +++ b/src/pybind/mgr/restful/api/mon.py @@ -0,0 +1,40 @@ +from pecan import expose, response +from pecan.rest import RestController + +from restful import context +from restful.decorators import auth + + +class MonName(RestController): + def __init__(self, name): + self.name = name + + + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for the monitor name + """ + mon = [x for x in context.instance.get_mons() + if x['name'] == self.name] + if len(mon) != 1: + response.status = 500 + return {'message': 'Failed to identify the monitor node "{}"'.format(self.name)} + return mon[0] + + + +class Mon(RestController): + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for all the monitors + """ + return context.instance.get_mons() + + + @expose() + def _lookup(self, name, *remainder): + return MonName(name), remainder diff --git a/src/pybind/mgr/restful/api/osd.py b/src/pybind/mgr/restful/api/osd.py new file mode 100644 index 00000000..8577fae9 --- /dev/null +++ b/src/pybind/mgr/restful/api/osd.py @@ -0,0 +1,135 @@ +from pecan import expose, request, response +from pecan.rest import RestController + +from restful import common, context +from restful.decorators import auth + + +class OsdIdCommand(RestController): + def __init__(self, osd_id): + self.osd_id = osd_id + + + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show implemented commands for the OSD id + """ + osd = context.instance.get_osd_by_id(self.osd_id) + + if not osd: + response.status = 500 + return {'message': 'Failed to identify the OSD id "{}"'.format(self.osd_id)} + + if osd['up']: + return common.OSD_IMPLEMENTED_COMMANDS + else: + return [] + + + @expose(template='json') + @auth + def post(self, **kwargs): + """ + Run the implemented command for the OSD id + """ + command = request.json.get('command', None) + + osd = context.instance.get_osd_by_id(self.osd_id) + + if not osd: + response.status = 500 + return {'message': 'Failed to identify the OSD id "{}"'.format(self.osd_id)} + + if not osd['up'] or command not in common.OSD_IMPLEMENTED_COMMANDS: + response.status = 500 + return {'message': 'Command "{}" not available'.format(command)} + + return context.instance.submit_request([[{ + 'prefix': 'osd ' + command, + 'who': str(self.osd_id) + }]], **kwargs) + + + +class OsdId(RestController): + def __init__(self, osd_id): + self.osd_id = osd_id + self.command = OsdIdCommand(osd_id) + + + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for the OSD id + """ + osd = context.instance.get_osds(ids=[str(self.osd_id)]) + if len(osd) != 1: + response.status = 500 + return {'message': 'Failed to identify the OSD id "{}"'.format(self.osd_id)} + + return osd[0] + + + @expose(template='json') + @auth + def patch(self, **kwargs): + """ + Modify the state (up, in) of the OSD id or reweight it + """ + args = request.json + + commands = [] + + if 'in' in args: + if args['in']: + commands.append({ + 'prefix': 'osd in', + 'ids': [str(self.osd_id)] + }) + else: + commands.append({ + 'prefix': 'osd out', + 'ids': [str(self.osd_id)] + }) + + if 'up' in args: + if args['up']: + response.status = 500 + return {'message': "It is not valid to set a down OSD to be up"} + else: + commands.append({ + 'prefix': 'osd down', + 'ids': [str(self.osd_id)] + }) + + if 'reweight' in args: + commands.append({ + 'prefix': 'osd reweight', + 'id': self.osd_id, + 'weight': args['reweight'] + }) + + return context.instance.submit_request([commands], **kwargs) + + + +class Osd(RestController): + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for all the OSDs + """ + # Parse request args + # TODO Filter by ids + pool_id = kwargs.get('pool', None) + + return context.instance.get_osds(pool_id) + + + @expose() + def _lookup(self, osd_id, *remainder): + return OsdId(int(osd_id)), remainder diff --git a/src/pybind/mgr/restful/api/perf.py b/src/pybind/mgr/restful/api/perf.py new file mode 100644 index 00000000..4224599f --- /dev/null +++ b/src/pybind/mgr/restful/api/perf.py @@ -0,0 +1,27 @@ +from pecan import expose, request, response +from pecan.rest import RestController + +from restful import context +from restful.decorators import auth, lock, paginate + +import re + +class Perf(RestController): + @expose(template='json') + @paginate + @auth + def get(self, **kwargs): + """ + List all the available performance counters + + Options: + - 'daemon' -- filter by daemon, accepts Python regexp + """ + + counters = context.instance.get_all_perf_counters() + + if 'daemon' in kwargs: + _re = re.compile(kwargs['daemon']) + counters = {k: v for k, v in counters.items() if _re.match(k)} + + return counters diff --git a/src/pybind/mgr/restful/api/pool.py b/src/pybind/mgr/restful/api/pool.py new file mode 100644 index 00000000..40de54eb --- /dev/null +++ b/src/pybind/mgr/restful/api/pool.py @@ -0,0 +1,140 @@ +from pecan import expose, request, response +from pecan.rest import RestController + +from restful import common, context +from restful.decorators import auth + + +class PoolId(RestController): + def __init__(self, pool_id): + self.pool_id = pool_id + + + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for the pool id + """ + pool = context.instance.get_pool_by_id(self.pool_id) + + if not pool: + response.status = 500 + return {'message': 'Failed to identify the pool id "{}"'.format(self.pool_id)} + + # pgp_num is called pg_placement_num, deal with that + if 'pg_placement_num' in pool: + pool['pgp_num'] = pool.pop('pg_placement_num') + return pool + + + @expose(template='json') + @auth + def patch(self, **kwargs): + """ + Modify the information for the pool id + """ + try: + args = request.json + except ValueError: + response.status = 400 + return {'message': 'Bad request: malformed JSON or wrong Content-Type'} + + # Get the pool info for its name + pool = context.instance.get_pool_by_id(self.pool_id) + if not pool: + response.status = 500 + return {'message': 'Failed to identify the pool id "{}"'.format(self.pool_id)} + + # Check for invalid pool args + invalid = common.invalid_pool_args(args) + if invalid: + response.status = 500 + return {'message': 'Invalid arguments found: "{}"'.format(invalid)} + + # Schedule the update request + return context.instance.submit_request(common.pool_update_commands(pool['pool_name'], args), **kwargs) + + + @expose(template='json') + @auth + def delete(self, **kwargs): + """ + Remove the pool data for the pool id + """ + pool = context.instance.get_pool_by_id(self.pool_id) + + if not pool: + response.status = 500 + return {'message': 'Failed to identify the pool id "{}"'.format(self.pool_id)} + + return context.instance.submit_request([[{ + 'prefix': 'osd pool delete', + 'pool': pool['pool_name'], + 'pool2': pool['pool_name'], + 'yes_i_really_really_mean_it': True + }]], **kwargs) + + + +class Pool(RestController): + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for all the pools + """ + pools = context.instance.get('osd_map')['pools'] + + # pgp_num is called pg_placement_num, deal with that + for pool in pools: + if 'pg_placement_num' in pool: + pool['pgp_num'] = pool.pop('pg_placement_num') + + return pools + + + @expose(template='json') + @auth + def post(self, **kwargs): + """ + Create a new pool + Requires name and pg_num dict arguments + """ + args = request.json + + # Check for the required arguments + pool_name = args.pop('name', None) + if pool_name is None: + response.status = 500 + return {'message': 'You need to specify the pool "name" argument'} + + pg_num = args.pop('pg_num', None) + if pg_num is None: + response.status = 500 + return {'message': 'You need to specify the "pg_num" argument'} + + # Run the pool create command first + create_command = { + 'prefix': 'osd pool create', + 'pool': pool_name, + 'pg_num': pg_num + } + + # Check for invalid pool args + invalid = common.invalid_pool_args(args) + if invalid: + response.status = 500 + return {'message': 'Invalid arguments found: "{}"'.format(invalid)} + + # Schedule the creation and update requests + return context.instance.submit_request( + [[create_command]] + + common.pool_update_commands(pool_name, args), + **kwargs + ) + + + @expose() + def _lookup(self, pool_id, *remainder): + return PoolId(int(pool_id)), remainder diff --git a/src/pybind/mgr/restful/api/request.py b/src/pybind/mgr/restful/api/request.py new file mode 100644 index 00000000..67143ef5 --- /dev/null +++ b/src/pybind/mgr/restful/api/request.py @@ -0,0 +1,93 @@ +from pecan import expose, request, response +from pecan.rest import RestController + +from restful import context +from restful.decorators import auth, lock, paginate + + +class RequestId(RestController): + def __init__(self, request_id): + self.request_id = request_id + + + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for the request id + """ + request = [x for x in context.instance.requests + if x.id == self.request_id] + if len(request) != 1: + response.status = 500 + return {'message': 'Unknown request id "{}"'.format(self.request_id)} + return request[0] + + + @expose(template='json') + @auth + @lock + def delete(self, **kwargs): + """ + Remove the request id from the database + """ + for index in range(len(context.instance.requests)): + if context.instance.requests[index].id == self.request_id: + return context.instance.requests.pop(index) + + # Failed to find the job to cancel + response.status = 500 + return {'message': 'No such request id'} + + + +class Request(RestController): + @expose(template='json') + @paginate + @auth + def get(self, **kwargs): + """ + List all the available requests + """ + return context.instance.requests + + + @expose(template='json') + @auth + @lock + def delete(self, **kwargs): + """ + Remove all the finished requests + """ + num_requests = len(context.instance.requests) + + context.instance.requests = [x for x in context.instance.requests + if not x.is_finished()] + remaining = len(context.instance.requests) + # Return the job statistics + return { + 'cleaned': num_requests - remaining, + 'remaining': remaining, + } + + + @expose(template='json') + @auth + def post(self, **kwargs): + """ + Pass through method to create any request + """ + if isinstance(request.json, list): + if all(isinstance(element, list) for element in request.json): + return context.instance.submit_request(request.json, **kwargs) + + # The request.json has wrong format + response.status = 500 + return {'message': 'The request format should be [[{c1},{c2}]]'} + + return context.instance.submit_request([[request.json]], **kwargs) + + + @expose() + def _lookup(self, request_id, *remainder): + return RequestId(request_id), remainder diff --git a/src/pybind/mgr/restful/api/server.py b/src/pybind/mgr/restful/api/server.py new file mode 100644 index 00000000..8ce63493 --- /dev/null +++ b/src/pybind/mgr/restful/api/server.py @@ -0,0 +1,35 @@ +from pecan import expose +from pecan.rest import RestController + +from restful import context +from restful.decorators import auth + + +class ServerFqdn(RestController): + def __init__(self, fqdn): + self.fqdn = fqdn + + + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for the server fqdn + """ + return context.instance.get_server(self.fqdn) + + + +class Server(RestController): + @expose(template='json') + @auth + def get(self, **kwargs): + """ + Show the information for all the servers + """ + return context.instance.list_servers() + + + @expose() + def _lookup(self, fqdn, *remainder): + return ServerFqdn(fqdn), remainder diff --git a/src/pybind/mgr/restful/common.py b/src/pybind/mgr/restful/common.py new file mode 100644 index 00000000..1b957d6b --- /dev/null +++ b/src/pybind/mgr/restful/common.py @@ -0,0 +1,156 @@ +# List of valid osd flags +OSD_FLAGS = [ + 'pause', 'noup', 'nodown', 'noout', 'noin', 'nobackfill', + 'norecover', 'noscrub', 'nodeep-scrub', +] + +# Implemented osd commands +OSD_IMPLEMENTED_COMMANDS = [ + 'scrub', 'deep-scrub', 'repair' +] + +# Valid values for the 'var' argument to 'ceph osd pool set' +POOL_PROPERTIES_1 = [ + 'size', 'min_size', 'pg_num', + 'crush_rule', 'hashpspool', +] + +POOL_PROPERTIES_2 = [ + 'pgp_num' +] + +POOL_PROPERTIES = POOL_PROPERTIES_1 + POOL_PROPERTIES_2 + +# Valid values for the 'ceph osd pool set-quota' command +POOL_QUOTA_PROPERTIES = [ + ('quota_max_bytes', 'max_bytes'), + ('quota_max_objects', 'max_objects'), +] + +POOL_ARGS = POOL_PROPERTIES + [x for x,_ in POOL_QUOTA_PROPERTIES] + + +# Transform command to a human readable form +def humanify_command(command): + out = [command['prefix']] + + for arg, val in command.items(): + if arg != 'prefix': + out.append("%s=%s" % (str(arg), str(val))) + + return " ".join(out) + + +def invalid_pool_args(args): + invalid = [] + for arg in args: + if arg not in POOL_ARGS: + invalid.append(arg) + + return invalid + + +def pool_update_commands(pool_name, args): + commands = [[], []] + + # We should increase pgp_num when we are re-setting pg_num + if 'pg_num' in args and 'pgp_num' not in args: + args['pgp_num'] = args['pg_num'] + + # Run the first pool set and quota properties in parallel + for var in POOL_PROPERTIES_1: + if var in args: + commands[0].append({ + 'prefix': 'osd pool set', + 'pool': pool_name, + 'var': var, + 'val': args[var], + }) + + for (var, field) in POOL_QUOTA_PROPERTIES: + if var in args: + commands[0].append({ + 'prefix': 'osd pool set-quota', + 'pool': pool_name, + 'field': field, + 'val': str(args[var]), + }) + + # The second pool set properties need to be run after the first wave + for var in POOL_PROPERTIES_2: + if var in args: + commands[1].append({ + 'prefix': 'osd pool set', + 'pool': pool_name, + 'var': var, + 'val': args[var], + }) + + return commands + +def crush_rule_osds(node_buckets, rule): + nodes_by_id = dict((b['id'], b) for b in node_buckets) + + def _gather_leaf_ids(node_id): + if node_id >= 0: + return set([node_id]) + + result = set() + for item in nodes_by_id[node_id]['items']: + result |= _gather_leaf_ids(item['id']) + + return result + + def _gather_descendent_ids(node, typ): + result = set() + for item in node['items']: + if item['id'] >= 0: + if typ == "osd": + result.add(item['id']) + else: + child_node = nodes_by_id[item['id']] + if child_node['type_name'] == typ: + result.add(child_node['id']) + elif 'items' in child_node: + result |= _gather_descendent_ids(child_node, typ) + + return result + + def _gather_osds(root, steps): + if root['id'] >= 0: + return set([root['id']]) + + osds = set() + step = steps[0] + if step['op'] == 'choose_firstn': + # Choose all descendents of the current node of type 'type' + descendent_ids = _gather_descendent_ids(root, step['type']) + for node_id in descendent_ids: + if node_id >= 0: + osds.add(node_id) + else: + osds |= _gather_osds(nodes_by_id[node_id], steps[1:]) + elif step['op'] == 'chooseleaf_firstn': + # Choose all descendents of the current node of type 'type', + # and select all leaves beneath those + descendent_ids = _gather_descendent_ids(root, step['type']) + for node_id in descendent_ids: + if node_id >= 0: + osds.add(node_id) + else: + for desc_node in nodes_by_id[node_id]['items']: + # Short circuit another iteration to find the emit + # and assume anything we've done a chooseleaf on + # is going to be part of the selected set of osds + osds |= _gather_leaf_ids(desc_node['id']) + elif step['op'] == 'emit': + if root['id'] >= 0: + osds |= root['id'] + + return osds + + osds = set() + for i, step in enumerate(rule['steps']): + if step['op'] == 'take': + osds |= _gather_osds(nodes_by_id[step['item']], rule['steps'][i + 1:]) + return osds diff --git a/src/pybind/mgr/restful/context.py b/src/pybind/mgr/restful/context.py new file mode 100644 index 00000000..a05ea854 --- /dev/null +++ b/src/pybind/mgr/restful/context.py @@ -0,0 +1,2 @@ +# Global instance to share +instance = None diff --git a/src/pybind/mgr/restful/decorators.py b/src/pybind/mgr/restful/decorators.py new file mode 100644 index 00000000..abf36e33 --- /dev/null +++ b/src/pybind/mgr/restful/decorators.py @@ -0,0 +1,79 @@ +from __future__ import absolute_import + +from pecan import request, response +from base64 import b64decode +from functools import wraps + +import traceback + +from . import context + + +# Handle authorization +def auth(f): + @wraps(f) + def decorated(*args, **kwargs): + if not request.authorization: + response.status = 401 + response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"' + return {'message': 'auth: No HTTP username/password'} + + username, password = b64decode(request.authorization[1]).decode('utf-8').split(':') + + # Check that the username exists + if username not in context.instance.keys: + response.status = 401 + response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"' + return {'message': 'auth: No such user'} + + # Check the password + if context.instance.keys[username] != password: + response.status = 401 + response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"' + return {'message': 'auth: Incorrect password'} + + return f(*args, **kwargs) + return decorated + + +# Helper function to lock the function +def lock(f): + @wraps(f) + def decorated(*args, **kwargs): + with context.instance.requests_lock: + return f(*args, **kwargs) + return decorated + + +# Support ?page=N argument +def paginate(f): + @wraps(f) + def decorated(*args, **kwargs): + _out = f(*args, **kwargs) + + # Do not modify anything without a specific request + if not 'page' in kwargs: + return _out + + # A pass-through for errors, etc + if not isinstance(_out, list): + return _out + + # Parse the page argument + _page = kwargs['page'] + try: + _page = int(_page) + except ValueError: + response.status = 500 + return {'message': 'The requested page is not an integer'} + + # Raise _page so that 0 is the first page and -1 is the last + _page += 1 + + if _page > 0: + _page *= 100 + else: + _page = len(_out) - (_page*100) + + return _out[_page - 100: _page] + return decorated diff --git a/src/pybind/mgr/restful/hooks.py b/src/pybind/mgr/restful/hooks.py new file mode 100644 index 00000000..d677dcc2 --- /dev/null +++ b/src/pybind/mgr/restful/hooks.py @@ -0,0 +1,11 @@ +from __future__ import absolute_import + +from pecan.hooks import PecanHook + +import traceback + +from . import context + +class ErrorHook(PecanHook): + def on_error(self, stat, exc): + context.instance.log.error(str(traceback.format_exc())) diff --git a/src/pybind/mgr/restful/module.py b/src/pybind/mgr/restful/module.py new file mode 100644 index 00000000..bb113312 --- /dev/null +++ b/src/pybind/mgr/restful/module.py @@ -0,0 +1,610 @@ +""" +A RESTful API for Ceph +""" +from __future__ import absolute_import + +import os +import json +import time +import errno +import inspect +import tempfile +import threading +import traceback +import six +import socket +import fcntl + +from . import common +from . import context + +from uuid import uuid4 +from pecan import jsonify, make_app +from OpenSSL import crypto +from pecan.rest import RestController +from six import iteritems +from werkzeug.serving import make_server, make_ssl_devcert + +from .hooks import ErrorHook +from mgr_module import MgrModule, CommandResult + + +class CannotServe(Exception): + pass + + +class CommandsRequest(object): + """ + This class handles parallel as well as sequential execution of + commands. The class accept a list of iterables that should be + executed sequentially. Each iterable can contain several commands + that can be executed in parallel. + + Example: + [[c1,c2],[c3,c4]] + - run c1 and c2 in parallel + - wait for them to finish + - run c3 and c4 in parallel + - wait for them to finish + """ + + + def __init__(self, commands_arrays): + self.id = str(id(self)) + + # Filter out empty sub-requests + commands_arrays = [x for x in commands_arrays + if len(x) != 0] + + self.running = [] + self.waiting = commands_arrays[1:] + self.finished = [] + self.failed = [] + + self.lock = threading.RLock() + if not len(commands_arrays): + # Nothing to run + return + + # Process first iteration of commands_arrays in parallel + results = self.run(commands_arrays[0]) + + self.running.extend(results) + + + def run(self, commands): + """ + A static method that will execute the given list of commands in + parallel and will return the list of command results. + """ + + # Gather the results (in parallel) + results = [] + for index, command in enumerate(commands): + tag = '%s:%s:%d' % (__name__, self.id, index) + + # Store the result + result = CommandResult(tag) + result.command = common.humanify_command(command) + results.append(result) + + # Run the command + context.instance.send_command(result, 'mon', '', json.dumps(command), tag) + + return results + + + def next(self): + with self.lock: + if not self.waiting: + # Nothing to run + return + + # Run a next iteration of commands + commands = self.waiting[0] + self.waiting = self.waiting[1:] + + self.running.extend(self.run(commands)) + + + def finish(self, tag): + with self.lock: + for index in range(len(self.running)): + if self.running[index].tag == tag: + if self.running[index].r == 0: + self.finished.append(self.running.pop(index)) + else: + self.failed.append(self.running.pop(index)) + return True + + # No such tag found + return False + + + def is_running(self, tag): + for result in self.running: + if result.tag == tag: + return True + return False + + + def is_ready(self): + with self.lock: + return not self.running and self.waiting + + + def is_waiting(self): + return bool(self.waiting) + + + def is_finished(self): + with self.lock: + return not self.running and not self.waiting + + + def has_failed(self): + return bool(self.failed) + + + def get_state(self): + with self.lock: + if not self.is_finished(): + return "pending" + + if self.has_failed(): + return "failed" + + return "success" + + + def __json__(self): + return { + 'id': self.id, + 'running': map( + lambda x: { + 'command': x.command, + 'outs': x.outs, + 'outb': x.outb, + }, + self.running + ), + 'finished': map( + lambda x: { + 'command': x.command, + 'outs': x.outs, + 'outb': x.outb, + }, + self.finished + ), + 'waiting': map( + lambda x: map( + lambda y: common.humanify_command(y), + x + ), + self.waiting + ), + 'failed': map( + lambda x: { + 'command': x.command, + 'outs': x.outs, + 'outb': x.outb, + }, + self.failed + ), + 'is_waiting': self.is_waiting(), + 'is_finished': self.is_finished(), + 'has_failed': self.has_failed(), + 'state': self.get_state(), + } + + + +class Module(MgrModule): + MODULE_OPTIONS = [ + {'name': 'server_addr'}, + {'name': 'server_port'}, + {'name': 'key_file'}, + ] + + COMMANDS = [ + { + "cmd": "restful create-key name=key_name,type=CephString", + "desc": "Create an API key with this name", + "perm": "rw" + }, + { + "cmd": "restful delete-key name=key_name,type=CephString", + "desc": "Delete an API key with this name", + "perm": "rw" + }, + { + "cmd": "restful list-keys", + "desc": "List all API keys", + "perm": "r" + }, + { + "cmd": "restful create-self-signed-cert", + "desc": "Create localized self signed certificate", + "perm": "rw" + }, + { + "cmd": "restful restart", + "desc": "Restart API server", + "perm": "rw" + }, + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + context.instance = self + + self.requests = [] + self.requests_lock = threading.RLock() + + self.keys = {} + self.disable_auth = False + + self.server = None + + self.stop_server = False + self.serve_event = threading.Event() + + + def serve(self): + while not self.stop_server: + try: + self._serve() + self.server.socket.close() + except CannotServe as cs: + self.log.warn("server not running: %s", cs) + except: + self.log.error(str(traceback.format_exc())) + + # Wait and clear the threading event + self.serve_event.wait() + self.serve_event.clear() + + def refresh_keys(self): + self.keys = {} + rawkeys = self.get_store_prefix('keys/') or {} + for k, v in six.iteritems(rawkeys): + self.keys[k[5:]] = v # strip of keys/ prefix + + def _serve(self): + # Load stored authentication keys + self.refresh_keys() + + jsonify._instance = jsonify.GenericJSON( + sort_keys=True, + indent=4, + separators=(',', ': '), + ) + + server_addr = self.get_localized_module_option('server_addr', '::') + if server_addr is None: + raise CannotServe('no server_addr configured; try "ceph config-key set mgr/restful/server_addr "') + + server_port = int(self.get_localized_module_option('server_port', '8003')) + self.log.info('server_addr: %s server_port: %d', + server_addr, server_port) + + cert = self.get_localized_store("crt") + if cert is not None: + cert_tmp = tempfile.NamedTemporaryFile() + cert_tmp.write(cert.encode('utf-8')) + cert_tmp.flush() + cert_fname = cert_tmp.name + else: + cert_fname = self.get_localized_store('crt_file') + + pkey = self.get_localized_store("key") + if pkey is not None: + pkey_tmp = tempfile.NamedTemporaryFile() + pkey_tmp.write(pkey.encode('utf-8')) + pkey_tmp.flush() + pkey_fname = pkey_tmp.name + else: + pkey_fname = self.get_localized_module_option('key_file') + + if not cert_fname or not pkey_fname: + raise CannotServe('no certificate configured') + if not os.path.isfile(cert_fname): + raise CannotServe('certificate %s does not exist' % cert_fname) + if not os.path.isfile(pkey_fname): + raise CannotServe('private key %s does not exist' % pkey_fname) + + # Publish the URI that others may use to access the service we're + # about to start serving + self.set_uri("https://{0}:{1}/".format( + socket.gethostname() if server_addr == "::" else server_addr, + server_port + )) + + # Create the HTTPS werkzeug server serving pecan app + self.server = make_server( + host=server_addr, + port=server_port, + app=make_app( + root='restful.api.Root', + hooks = [ErrorHook()], # use a callable if pecan >= 0.3.2 + ), + ssl_context=(cert_fname, pkey_fname), + ) + sock_fd_flag = fcntl.fcntl(self.server.socket.fileno(), fcntl.F_GETFD) + if not (sock_fd_flag & fcntl.FD_CLOEXEC): + self.log.debug("set server socket close-on-exec") + fcntl.fcntl(self.server.socket.fileno(), fcntl.F_SETFD, sock_fd_flag | fcntl.FD_CLOEXEC) + if self.stop_server: + self.log.debug('made server, but stop flag set') + else: + self.log.debug('made server, serving forever') + self.server.serve_forever() + + + def shutdown(self): + try: + self.stop_server = True + if self.server: + self.server.shutdown() + self.serve_event.set() + except: + self.log.error(str(traceback.format_exc())) + raise + + + def restart(self): + try: + if self.server: + self.server.shutdown() + self.serve_event.set() + except: + self.log.error(str(traceback.format_exc())) + + + def notify(self, notify_type, tag): + try: + self._notify(notify_type, tag) + except: + self.log.error(str(traceback.format_exc())) + + + def _notify(self, notify_type, tag): + if notify_type != "command": + self.log.debug("Unhandled notification type '%s'", notify_type) + return + # we can safely skip all the sequential commands + if tag == 'seq': + return + try: + with self.requests_lock: + request = next(x for x in self.requests if x.is_running(tag)) + request.finish(tag) + if request.is_ready(): + request.next() + except StopIteration: + # the command was not issued by me + pass + + + def create_self_signed_cert(self): + # create a key pair + pkey = crypto.PKey() + pkey.generate_key(crypto.TYPE_RSA, 2048) + + # create a self-signed cert + cert = crypto.X509() + cert.get_subject().O = "IT" + cert.get_subject().CN = "ceph-restful" + cert.set_serial_number(int(uuid4())) + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(10*365*24*60*60) + cert.set_issuer(cert.get_subject()) + cert.set_pubkey(pkey) + cert.sign(pkey, 'sha512') + + return ( + crypto.dump_certificate(crypto.FILETYPE_PEM, cert), + crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey) + ) + + + def handle_command(self, inbuf, command): + self.log.warn("Handling command: '%s'" % str(command)) + if command['prefix'] == "restful create-key": + if command['key_name'] in self.keys: + return 0, self.keys[command['key_name']], "" + + else: + key = str(uuid4()) + self.keys[command['key_name']] = key + self.set_store('keys/' + command['key_name'], key) + + return ( + 0, + self.keys[command['key_name']], + "", + ) + + elif command['prefix'] == "restful delete-key": + if command['key_name'] in self.keys: + del self.keys[command['key_name']] + self.set_store('keys/' + command['key_name'], None) + + return ( + 0, + "", + "", + ) + + elif command['prefix'] == "restful list-keys": + self.refresh_keys() + return ( + 0, + json.dumps(self.keys, indent=2), + "", + ) + + elif command['prefix'] == "restful create-self-signed-cert": + cert, pkey = self.create_self_signed_cert() + self.set_store(self.get_mgr_id() + '/crt', cert.decode('utf-8')) + self.set_store(self.get_mgr_id() + '/key', pkey.decode('utf-8')) + + self.restart() + return ( + 0, + "Restarting RESTful API server...", + "" + ) + + elif command['prefix'] == 'restful restart': + self.restart(); + return ( + 0, + "Restarting RESTful API server...", + "" + ) + + else: + return ( + -errno.EINVAL, + "", + "Command not found '{0}'".format(command['prefix']) + ) + + + def get_doc_api(self, root, prefix=''): + doc = {} + for _obj in dir(root): + obj = getattr(root, _obj) + + if isinstance(obj, RestController): + doc.update(self.get_doc_api(obj, prefix + '/' + _obj)) + + if getattr(root, '_lookup', None) and isinstance(root._lookup('0')[0], RestController): + doc.update(self.get_doc_api(root._lookup('0')[0], prefix + '/')) + + prefix = prefix or '/' + + doc[prefix] = {} + for method in 'get', 'post', 'patch', 'delete': + if getattr(root, method, None): + doc[prefix][method.upper()] = inspect.getdoc(getattr(root, method)).split('\n') + + if len(doc[prefix]) == 0: + del doc[prefix] + + return doc + + + def get_mons(self): + mon_map_mons = self.get('mon_map')['mons'] + mon_status = json.loads(self.get('mon_status')['json']) + + # Add more information + for mon in mon_map_mons: + mon['in_quorum'] = mon['rank'] in mon_status['quorum'] + mon['server'] = self.get_metadata("mon", mon['name'])['hostname'] + mon['leader'] = mon['rank'] == mon_status['quorum'][0] + + return mon_map_mons + + + def get_osd_pools(self): + osds = dict(map(lambda x: (x['osd'], []), self.get('osd_map')['osds'])) + pools = dict(map(lambda x: (x['pool'], x), self.get('osd_map')['pools'])) + crush = self.get('osd_map_crush') + crush_rules = crush['rules'] + + osds_by_pool = {} + for pool_id, pool in pools.items(): + pool_osds = None + for rule in [r for r in crush_rules if r['rule_id'] == pool['crush_rule']]: + if rule['min_size'] <= pool['size'] <= rule['max_size']: + pool_osds = common.crush_rule_osds(crush['buckets'], rule) + + osds_by_pool[pool_id] = pool_osds + + for pool_id in pools.keys(): + for in_pool_id in osds_by_pool[pool_id]: + osds[in_pool_id].append(pool_id) + + return osds + + + def get_osds(self, pool_id=None, ids=None): + # Get data + osd_map = self.get('osd_map') + osd_metadata = self.get('osd_metadata') + + # Update the data with the additional info from the osd map + osds = osd_map['osds'] + + # Filter by osd ids + if ids is not None: + osds = [x for x in osds if str(x['osd']) in ids] + + # Get list of pools per osd node + pools_map = self.get_osd_pools() + + # map osd IDs to reweight + reweight_map = dict([ + (x.get('id'), x.get('reweight', None)) + for x in self.get('osd_map_tree')['nodes'] + ]) + + # Build OSD data objects + for osd in osds: + osd['pools'] = pools_map[osd['osd']] + osd['server'] = osd_metadata.get(str(osd['osd']), {}).get('hostname', None) + + osd['reweight'] = reweight_map.get(osd['osd'], 0.0) + + if osd['up']: + osd['valid_commands'] = common.OSD_IMPLEMENTED_COMMANDS + else: + osd['valid_commands'] = [] + + # Filter by pool + if pool_id: + pool_id = int(pool_id) + osds = [x for x in osds if pool_id in x['pools']] + + return osds + + + def get_osd_by_id(self, osd_id): + osd = [x for x in self.get('osd_map')['osds'] + if x['osd'] == osd_id] + + if len(osd) != 1: + return None + + return osd[0] + + + def get_pool_by_id(self, pool_id): + pool = [x for x in self.get('osd_map')['pools'] + if x['pool'] == pool_id] + + if len(pool) != 1: + return None + + return pool[0] + + + def submit_request(self, _request, **kwargs): + with self.requests_lock: + request = CommandsRequest(_request) + self.requests.append(request) + if kwargs.get('wait', 0): + while not request.is_finished(): + time.sleep(0.001) + return request + + + def run_command(self, command): + # tag with 'seq' so that we can ignore these in notify function + result = CommandResult('seq') + + self.send_command(result, 'mon', '', json.dumps(command), 'seq') + return result.wait() diff --git a/src/pybind/mgr/rook/__init__.py b/src/pybind/mgr/rook/__init__.py new file mode 100644 index 00000000..b9f08fc8 --- /dev/null +++ b/src/pybind/mgr/rook/__init__.py @@ -0,0 +1,2 @@ + +from .module import RookOrchestrator diff --git a/src/pybind/mgr/rook/module.py b/src/pybind/mgr/rook/module.py new file mode 100644 index 00000000..4b49d681 --- /dev/null +++ b/src/pybind/mgr/rook/module.py @@ -0,0 +1,469 @@ +import threading +import functools +import os +import uuid +try: + from typing import List +except ImportError: + pass # just for type checking + +try: + from kubernetes import client, config + from kubernetes.client.rest import ApiException + + kubernetes_imported = True +except ImportError: + kubernetes_imported = False + client = None + config = None + +from mgr_module import MgrModule +import orchestrator + +from .rook_cluster import RookCluster + + +all_completions = [] + + +class RookReadCompletion(orchestrator.ReadCompletion): + """ + All reads are simply API calls: avoid spawning + huge numbers of threads by just running them + inline when someone calls wait() + """ + + def __init__(self, cb): + super(RookReadCompletion, self).__init__() + self.cb = cb + self._result = None + self._complete = False + + self.message = "" + + # XXX hacky global + global all_completions + all_completions.append(self) + + @property + def result(self): + return self._result + + @property + def is_complete(self): + return self._complete + + def execute(self): + self._result = self.cb() + self._complete = True + + +class RookWriteCompletion(orchestrator.WriteCompletion): + """ + Writes are a two-phase thing, firstly sending + the write to the k8s API (fast) and then waiting + for the corresponding change to appear in the + Ceph cluster (slow) + """ + # XXX kubernetes bindings call_api already usefully has + # a completion= param that uses threads. Maybe just + # use that? + def __init__(self, execute_cb, complete_cb, message): + super(RookWriteCompletion, self).__init__() + self.execute_cb = execute_cb + self.complete_cb = complete_cb + + # Executed means I executed my k8s API call, it may or may + # not have succeeded + self.executed = False + + # Result of k8s API call, this is set if executed==True + self._result = None + + self.effective = False + + self.id = str(uuid.uuid4()) + + self.message = message + + self.error = None + + # XXX hacky global + global all_completions + all_completions.append(self) + + def __str__(self): + return self.message + + @property + def result(self): + return self._result + + @property + def is_persistent(self): + return (not self.is_errored) and self.executed + + @property + def is_effective(self): + return self.effective + + @property + def is_errored(self): + return self.error is not None + + def execute(self): + if not self.executed: + self._result = self.execute_cb() + self.executed = True + + if not self.effective: + # TODO: check self.result for API errors + if self.complete_cb is None: + self.effective = True + else: + self.effective = self.complete_cb() + + +def deferred_read(f): + """ + Decorator to make RookOrchestrator methods return + a completion object that executes themselves. + """ + + @functools.wraps(f) + def wrapper(*args, **kwargs): + return RookReadCompletion(lambda: f(*args, **kwargs)) + + return wrapper + + +class RookEnv(object): + def __init__(self): + # POD_NAMESPACE already exist for Rook 0.9 + self.namespace = os.environ.get('POD_NAMESPACE', 'rook-ceph') + + # ROOK_CEPH_CLUSTER_CRD_NAME is new is Rook 1.0 + self.cluster_name = os.environ.get('ROOK_CEPH_CLUSTER_CRD_NAME', self.namespace) + + self.operator_namespace = os.environ.get('ROOK_OPERATOR_NAMESPACE', "rook-ceph-system") + self.crd_version = os.environ.get('ROOK_CEPH_CLUSTER_CRD_VERSION', 'v1') + self.api_name = "ceph.rook.io/" + self.crd_version + + def api_version_match(self): + return self.crd_version == 'v1' + + def has_namespace(self): + return 'POD_NAMESPACE' in os.environ + + +class RookOrchestrator(MgrModule, orchestrator.Orchestrator): + MODULE_OPTIONS = [ + # TODO: configure k8s API addr instead of assuming local + ] + + def wait(self, completions): + self.log.info("wait: completions={0}".format(completions)) + + incomplete = False + + # Our `wait` implementation is very simple because everything's + # just an API call. + for c in completions: + if not isinstance(c, RookReadCompletion) and \ + not isinstance(c, RookWriteCompletion): + raise TypeError( + "wait() requires list of completions, not {0}".format( + c.__class__ + )) + + if c.is_complete: + continue + + try: + c.execute() + except Exception as e: + if not isinstance(e, orchestrator.OrchestratorError): + self.log.exception("Completion {0} threw an exception:".format( + c.message + )) + c.exception = e + c._complete = True + + if not c.is_complete: + incomplete = True + + return not incomplete + + @staticmethod + def can_run(): + if not kubernetes_imported: + return False, "`kubernetes` python module not found" + if not RookEnv().api_version_match(): + return False, "Rook version unsupported." + return True, '' + + def available(self): + if not kubernetes_imported: + return False, "`kubernetes` python module not found" + elif not self._rook_env.has_namespace(): + return False, "ceph-mgr not running in Rook cluster" + + try: + self.k8s.list_namespaced_pod(self._rook_env.cluster_name) + except ApiException as e: + return False, "Cannot reach Kubernetes API: {}".format(e) + else: + return True, "" + + def __init__(self, *args, **kwargs): + super(RookOrchestrator, self).__init__(*args, **kwargs) + + self._initialized = threading.Event() + self._k8s = None + self._rook_cluster = None + self._rook_env = RookEnv() + + self._shutdown = threading.Event() + + def shutdown(self): + self._shutdown.set() + + @property + def k8s(self): + self._initialized.wait() + return self._k8s + + @property + def rook_cluster(self): + # type: () -> RookCluster + self._initialized.wait() + return self._rook_cluster + + def serve(self): + # For deployed clusters, we should always be running inside + # a Rook cluster. For development convenience, also support + # running outside (reading ~/.kube config) + + if self._rook_env.cluster_name: + config.load_incluster_config() + cluster_name = self._rook_env.cluster_name + else: + self.log.warning("DEVELOPMENT ONLY: Reading kube config from ~") + config.load_kube_config() + + cluster_name = "rook-ceph" + + # So that I can do port forwarding from my workstation - jcsp + from kubernetes.client import configuration + configuration.verify_ssl = False + + self._k8s = client.CoreV1Api() + + try: + # XXX mystery hack -- I need to do an API call from + # this context, or subsequent API usage from handle_command + # fails with SSLError('bad handshake'). Suspect some kind of + # thread context setup in SSL lib? + self._k8s.list_namespaced_pod(cluster_name) + except ApiException: + # Ignore here to make self.available() fail with a proper error message + pass + + self._rook_cluster = RookCluster( + self._k8s, + self._rook_env) + + self._initialized.set() + + while not self._shutdown.is_set(): + # XXX hack (or is it?) to kick all completions periodically, + # in case we had a caller that wait()'ed on them long enough + # to get persistence but not long enough to get completion + + global all_completions + self.wait(all_completions) + all_completions = [c for c in all_completions if not c.is_complete] + + self._shutdown.wait(5) + + # TODO: watch Rook for config changes to complain/update if + # things look a bit out of sync? + + @deferred_read + def get_inventory(self, node_filter=None, refresh=False): + node_list = None + if node_filter and node_filter.nodes: + # Explicit node list + node_list = node_filter.nodes + elif node_filter and node_filter.labels: + # TODO: query k8s API to resolve to node list, and pass + # it into RookCluster.get_discovered_devices + raise NotImplementedError() + + devs = self.rook_cluster.get_discovered_devices(node_list) + + result = [] + for node_name, node_devs in devs.items(): + devs = [] + for d in node_devs: + dev = orchestrator.InventoryDevice() + + # XXX CAUTION! https://github.com/rook/rook/issues/1716 + # Passing this through for the sake of completeness but it + # is not trustworthy! + dev.blank = d['empty'] + dev.type = 'hdd' if d['rotational'] else 'ssd' + dev.id = d['name'] + dev.size = d['size'] + + if d['filesystem'] == "" and not d['rotational']: + # Empty or partitioned SSD + partitioned_space = sum( + [p['size'] for p in d['Partitions']]) + dev.metadata_space_free = max(0, d[ + 'size'] - partitioned_space) + + devs.append(dev) + + result.append(orchestrator.InventoryNode(node_name, devs)) + + return result + + @deferred_read + def describe_service(self, service_type=None, service_id=None, node_name=None, refresh=False): + + if service_type not in ("mds", "osd", "mgr", "mon", "nfs", None): + raise orchestrator.OrchestratorValidationError(service_type + " unsupported") + + pods = self.rook_cluster.describe_pods(service_type, service_id, node_name) + + result = [] + for p in pods: + sd = orchestrator.ServiceDescription() + sd.nodename = p['nodename'] + sd.container_id = p['name'] + sd.service_type = p['labels']['app'].replace('rook-ceph-', '') + + if sd.service_type == "osd": + sd.service_instance = "%s" % p['labels']["ceph-osd-id"] + elif sd.service_type == "mds": + sd.service = p['labels']['rook_file_system'] + pfx = "{0}-".format(sd.service) + sd.service_instance = p['labels']['ceph_daemon_id'].replace(pfx, '', 1) + elif sd.service_type == "mon": + sd.service_instance = p['labels']["mon"] + elif sd.service_type == "mgr": + sd.service_instance = p['labels']["mgr"] + elif sd.service_type == "nfs": + sd.service = p['labels']['ceph_nfs'] + sd.service_instance = p['labels']['instance'] + sd.rados_config_location = self.rook_cluster.get_nfs_conf_url(sd.service, sd.service_instance) + elif sd.service_type == "rgw": + sd.service = p['labels']['rgw'] + sd.service_instance = p['labels']['ceph_daemon_id'] + else: + # Unknown type -- skip it + continue + + result.append(sd) + + return result + + def _service_add_decorate(self, typename, spec, func): + return RookWriteCompletion(lambda: func(spec), None, + "Creating {0} services for {1}".format(typename, spec.name)) + + def add_stateless_service(self, service_type, spec): + # assert isinstance(spec, orchestrator.StatelessServiceSpec) + if service_type == "mds": + return self._service_add_decorate("Filesystem", spec, + self.rook_cluster.add_filesystem) + elif service_type == "rgw" : + return self._service_add_decorate("RGW", spec, + self.rook_cluster.add_objectstore) + elif service_type == "nfs" : + return self._service_add_decorate("NFS", spec, + self.rook_cluster.add_nfsgw) + else: + raise NotImplementedError(service_type) + + def remove_stateless_service(self, service_type, service_id): + return RookWriteCompletion( + lambda: self.rook_cluster.rm_service(service_type, service_id), None, + "Removing {0} services for {1}".format(service_type, service_id)) + + def update_mons(self, num, hosts): + if hosts: + raise RuntimeError("Host list is not supported by rook.") + + return RookWriteCompletion( + lambda: self.rook_cluster.update_mon_count(num), None, + "Updating mon count to {0}".format(num)) + + def update_stateless_service(self, svc_type, spec): + # only nfs is currently supported + if svc_type != "nfs": + raise NotImplementedError(svc_type) + + num = spec.count + return RookWriteCompletion( + lambda: self.rook_cluster.update_nfs_count(spec.name, num), None, + "Updating NFS server count in {0} to {1}".format(spec.name, num)) + + def create_osds(self, drive_group, all_hosts): + # type: (orchestrator.DriveGroupSpec, List[str]) -> RookWriteCompletion + + assert len(drive_group.hosts(all_hosts)) == 1 + targets = [] + if drive_group.data_devices: + targets += drive_group.data_devices.paths + if drive_group.data_directories: + targets += drive_group.data_directories + + if not self.rook_cluster.node_exists(drive_group.hosts(all_hosts)[0]): + raise RuntimeError("Node '{0}' is not in the Kubernetes " + "cluster".format(drive_group.hosts(all_hosts))) + + # Validate whether cluster CRD can accept individual OSD + # creations (i.e. not useAllDevices) + if not self.rook_cluster.can_create_osd(): + raise RuntimeError("Rook cluster configuration does not " + "support OSD creation.") + + def execute(): + return self.rook_cluster.add_osds(drive_group, all_hosts) + + def is_complete(): + # Find OSD pods on this host + pod_osd_ids = set() + pods = self._k8s.list_namespaced_pod(self._rook_env.namespace, + label_selector="rook_cluster={},app=rook-ceph-osd".format(self._rook_env.cluster_name), + field_selector="spec.nodeName={0}".format( + drive_group.hosts(all_hosts)[0] + )).items + for p in pods: + pod_osd_ids.add(int(p.metadata.labels['ceph-osd-id'])) + + self.log.debug('pod_osd_ids={0}'.format(pod_osd_ids)) + + found = [] + osdmap = self.get("osd_map") + for osd in osdmap['osds']: + osd_id = osd['osd'] + if osd_id not in pod_osd_ids: + continue + + metadata = self.get_metadata('osd', "%s" % osd_id) + if metadata and metadata['devices'] in targets: + found.append(osd_id) + else: + self.log.info("ignoring osd {0} {1}".format( + osd_id, metadata['devices'] + )) + + return found is not None + + return RookWriteCompletion(execute, is_complete, + "Creating OSD on {0}:{1}".format( + drive_group.hosts(all_hosts)[0], targets + )) diff --git a/src/pybind/mgr/rook/rook_cluster.py b/src/pybind/mgr/rook/rook_cluster.py new file mode 100644 index 00000000..ef404075 --- /dev/null +++ b/src/pybind/mgr/rook/rook_cluster.py @@ -0,0 +1,442 @@ +""" +This module wrap's Rook + Kubernetes APIs to expose the calls +needed to implement an orchestrator module. While the orchestrator +module exposes an async API, this module simply exposes blocking API +call methods. + +This module is runnable outside of ceph-mgr, useful for testing. +""" +import logging +import json +from contextlib import contextmanager + +from six.moves.urllib.parse import urljoin # pylint: disable=import-error + +# Optional kubernetes imports to enable MgrModule.can_run +# to behave cleanly. +try: + from kubernetes.client.rest import ApiException +except ImportError: + ApiException = None + +try: + import orchestrator + from rook.module import RookEnv + from typing import List +except ImportError: + pass # just used for type checking. + + +log = logging.getLogger(__name__) + + +class ApplyException(Exception): + """ + For failures to update the Rook CRDs, usually indicating + some kind of interference between our attempted update + and other conflicting activity. + """ + + +class RookCluster(object): + def __init__(self, k8s, rook_env): + self.rook_env = rook_env # type: RookEnv + self.k8s = k8s + + def rook_url(self, path): + prefix = "/apis/ceph.rook.io/%s/namespaces/%s/" % ( + self.rook_env.crd_version, self.rook_env.namespace) + return urljoin(prefix, path) + + def rook_api_call(self, verb, path, **kwargs): + full_path = self.rook_url(path) + log.debug("[%s] %s" % (verb, full_path)) + + return self.k8s.api_client.call_api( + full_path, + verb, + auth_settings=['BearerToken'], + response_type="object", + _return_http_data_only=True, + _preload_content=True, + **kwargs) + + def rook_api_get(self, path, **kwargs): + return self.rook_api_call("GET", path, **kwargs) + + def rook_api_delete(self, path): + return self.rook_api_call("DELETE", path) + + def rook_api_patch(self, path, **kwargs): + return self.rook_api_call("PATCH", path, + header_params={"Content-Type": "application/json-patch+json"}, + **kwargs) + + def rook_api_post(self, path, **kwargs): + return self.rook_api_call("POST", path, **kwargs) + + def get_discovered_devices(self, nodenames=None): + # TODO: replace direct k8s calls with Rook API calls + # when they're implemented + label_selector = "app=rook-discover" + if nodenames is not None: + # FIXME: is there a practical or official limit on the + # number of entries in a label selector + label_selector += ", rook.io/node in ({0})".format( + ", ".join(nodenames)) + + try: + result = self.k8s.list_namespaced_config_map( + self.rook_env.operator_namespace, + label_selector=label_selector) + except ApiException as e: + log.exception("Failed to fetch device metadata: {0}".format(e)) + raise + + nodename_to_devices = {} + for i in result.items: + drives = json.loads(i.data['devices']) + nodename_to_devices[i.metadata.labels['rook.io/node']] = drives + + return nodename_to_devices + + def get_nfs_conf_url(self, nfs_cluster, instance): + # + # Fetch cephnfs object for "nfs_cluster" and then return a rados:// + # URL for the instance within that cluster. If the fetch fails, just + # return None. + # + try: + ceph_nfs = self.rook_api_get("cephnfses/{0}".format(nfs_cluster)) + except ApiException as e: + log.info("Unable to fetch cephnfs object: {}".format(e.status)) + return None + + pool = ceph_nfs['spec']['rados']['pool'] + namespace = ceph_nfs['spec']['rados'].get('namespace', None) + + if namespace == None: + url = "rados://{0}/conf-{1}.{2}".format(pool, nfs_cluster, instance) + else: + url = "rados://{0}/{1}/conf-{2}.{3}".format(pool, namespace, nfs_cluster, instance) + return url + + + def describe_pods(self, service_type, service_id, nodename): + # Go query the k8s API about deployment, containers related to this + # filesystem + + # Inspect the Rook YAML, to decide whether this filesystem + # is Ceph-managed or Rook-managed + # TODO: extend Orchestrator interface to describe whether FS + # is manageable by us or not + + # Example Rook Pod labels for a mgr daemon: + # Labels: app=rook-ceph-mgr + # pod-template-hash=2171958073 + # rook_cluster=rook + # And MDS containers additionally have `rook_filesystem` label + + # Label filter is rook_cluster= + # rook_file_system= + + label_filter = "rook_cluster={0}".format(self.rook_env.cluster_name) + if service_type != None: + label_filter += ",app=rook-ceph-{0}".format(service_type) + if service_id != None: + if service_type == "mds": + label_filter += ",rook_file_system={0}".format(service_id) + elif service_type == "osd": + # Label added in https://github.com/rook/rook/pull/1698 + label_filter += ",ceph-osd-id={0}".format(service_id) + elif service_type == "mon": + # label like mon=rook-ceph-mon0 + label_filter += ",mon={0}".format(service_id) + elif service_type == "mgr": + label_filter += ",mgr={0}".format(service_id) + elif service_type == "nfs": + label_filter += ",ceph_nfs={0}".format(service_id) + elif service_type == "rgw": + # TODO: rgw + pass + + field_filter = "" + if nodename != None: + field_filter = "spec.nodeName={0}".format(nodename) + + pods = self.k8s.list_namespaced_pod( + self.rook_env.namespace, + label_selector=label_filter, + field_selector=field_filter) + + # import json + # print json.dumps(pods.items[0]) + + pods_summary = [] + + for p in pods.items: + d = p.to_dict() + # p['metadata']['creationTimestamp'] + # p['metadata']['nodeName'] + pods_summary.append({ + "name": d['metadata']['name'], + "nodename": d['spec']['node_name'], + "labels": d['metadata']['labels'] + }) + pass + + return pods_summary + + @contextmanager + def ignore_409(self, what): + try: + yield + except ApiException as e: + if e.status == 409: + # Idempotent, succeed. + log.info("{} already exists".format(what)) + else: + raise + + def add_filesystem(self, spec): + # TODO use spec.placement + # TODO warn if spec.extended has entries we don't kow how + # to action. + + rook_fs = { + "apiVersion": self.rook_env.api_name, + "kind": "CephFilesystem", + "metadata": { + "name": spec.name, + "namespace": self.rook_env.namespace + }, + "spec": { + "onlyManageDaemons": True, + "metadataServer": { + "activeCount": spec.count, + "activeStandby": True + + } + } + } + + with self.ignore_409("CephFilesystem '{0}' already exists".format(spec.name)): + self.rook_api_post("cephfilesystems/", body=rook_fs) + + def add_nfsgw(self, spec): + # TODO use spec.placement + # TODO warn if spec.extended has entries we don't kow how + # to action. + + rook_nfsgw = { + "apiVersion": self.rook_env.api_name, + "kind": "CephNFS", + "metadata": { + "name": spec.name, + "namespace": self.rook_env.namespace + }, + "spec": { + "rados": { + "pool": spec.extended["pool"] + }, + "server": { + "active": spec.count, + } + } + } + + if "namespace" in spec.extended: + rook_nfsgw["spec"]["rados"]["namespace"] = spec.extended["namespace"] + + with self.ignore_409("NFS cluster '{0}' already exists".format(spec.name)): + self.rook_api_post("cephnfses/", body=rook_nfsgw) + + def add_objectstore(self, spec): + rook_os = { + "apiVersion": self.rook_env.api_name, + "kind": "CephObjectStore", + "metadata": { + "name": spec.name, + "namespace": self.rook_env.namespace + }, + "spec": { + "metadataPool": { + "failureDomain": "host", + "replicated": { + "size": 1 + } + }, + "dataPool": { + "failureDomain": "osd", + "replicated": { + "size": 1 + } + }, + "gateway": { + "type": "s3", + "port": 80, + "instances": 1, + "allNodes": False + } + } + } + + with self.ignore_409("CephObjectStore '{0}' already exists".format(spec.name)): + self.rook_api_post("cephobjectstores/", body=rook_os) + + def rm_service(self, service_type, service_id): + assert service_type in ("mds", "rgw", "nfs") + + if service_type == "mds": + rooktype = "cephfilesystems" + elif service_type == "rgw": + rooktype = "cephobjectstores" + elif service_type == "nfs": + rooktype = "cephnfses" + + objpath = "{0}/{1}".format(rooktype, service_id) + + try: + self.rook_api_delete(objpath) + except ApiException as e: + if e.status == 404: + log.info("{0} service '{1}' does not exist".format(service_type, service_id)) + # Idempotent, succeed. + else: + raise + + def can_create_osd(self): + current_cluster = self.rook_api_get( + "cephclusters/{0}".format(self.rook_env.cluster_name)) + use_all_nodes = current_cluster['spec'].get('useAllNodes', False) + + # If useAllNodes is set, then Rook will not be paying attention + # to anything we put in 'nodes', so can't do OSD creation. + return not use_all_nodes + + def node_exists(self, node_name): + try: + self.k8s.read_node(node_name, exact=False, export=True) + except ApiException as e: + if e.status == 404: + return False + else: + raise + else: + return True + + def update_mon_count(self, newcount): + patch = [{"op": "replace", "path": "/spec/mon/count", "value": newcount}] + + try: + self.rook_api_patch( + "cephclusters/{0}".format(self.rook_env.cluster_name), + body=patch) + except ApiException as e: + log.exception("API exception: {0}".format(e)) + raise ApplyException( + "Failed to update mon count in Cluster CRD: {0}".format(e)) + + return "Updated mon count to {0}".format(newcount) + + def update_nfs_count(self, svc_id, newcount): + patch = [{"op": "replace", "path": "/spec/server/active", "value": newcount}] + + try: + self.rook_api_patch( + "cephnfses/{0}".format(svc_id), + body=patch) + except ApiException as e: + log.exception("API exception: {0}".format(e)) + raise ApplyException( + "Failed to update NFS server count for {0}: {1}".format(svc_id, e)) + return "Updated NFS server count for {0} to {1}".format(svc_id, newcount) + + def add_osds(self, drive_group, all_hosts): + # type: (orchestrator.DriveGroupSpec, List[str]) -> str + """ + Rook currently (0.8) can only do single-drive OSDs, so we + treat all drive groups as just a list of individual OSDs. + """ + block_devices = drive_group.data_devices.paths if drive_group.data_devices else None + directories = drive_group.data_directories + + assert drive_group.objectstore in ("bluestore", "filestore") + + # The CRD looks something like this: + # nodes: + # - name: "gravel1.rockery" + # devices: + # - name: "sdb" + # config: + # storeType: bluestore + + current_cluster = self.rook_api_get( + "cephclusters/{0}".format(self.rook_env.cluster_name)) + + patch = [] + + # FIXME: this is all not really atomic, because jsonpatch doesn't + # let us do "test" operations that would check if items with + # matching names were in existing lists. + + if 'nodes' not in current_cluster['spec']['storage']: + patch.append({ + 'op': 'add', 'path': '/spec/storage/nodes', 'value': [] + }) + + current_nodes = current_cluster['spec']['storage'].get('nodes', []) + + if drive_group.hosts(all_hosts)[0] not in [n['name'] for n in current_nodes]: + pd = { "name": drive_group.hosts(all_hosts)[0], + "config": { "storeType": drive_group.objectstore }} + + if block_devices: + pd["devices"] = [{'name': d} for d in block_devices] + if directories: + pd["directories"] = [{'path': p} for p in directories] + + patch.append({ "op": "add", "path": "/spec/storage/nodes/-", "value": pd }) + else: + # Extend existing node + node_idx = None + current_node = None + for i, c in enumerate(current_nodes): + if c['name'] == drive_group.hosts(all_hosts)[0]: + current_node = c + node_idx = i + break + + assert node_idx is not None + assert current_node is not None + + new_devices = list(set(block_devices) - set([d['name'] for d in current_node['devices']])) + for n in new_devices: + patch.append({ + "op": "add", + "path": "/spec/storage/nodes/{0}/devices/-".format(node_idx), + "value": {'name': n} + }) + + new_dirs = list(set(directories) - set(current_node['directories'])) + for p in new_dirs: + patch.append({ + "op": "add", + "path": "/spec/storage/nodes/{0}/directories/-".format(node_idx), + "value": {'path': p} + }) + + if len(patch) == 0: + return "No change" + + try: + self.rook_api_patch( + "cephclusters/{0}".format(self.rook_env.cluster_name), + body=patch) + except ApiException as e: + log.exception("API exception: {0}".format(e)) + raise ApplyException( + "Failed to create OSD entries in Cluster CRD: {0}".format( + e)) + + return "Success" diff --git a/src/pybind/mgr/selftest/__init__.py b/src/pybind/mgr/selftest/__init__.py new file mode 100644 index 00000000..554aacbf --- /dev/null +++ b/src/pybind/mgr/selftest/__init__.py @@ -0,0 +1,3 @@ + +from .module import Module + diff --git a/src/pybind/mgr/selftest/module.py b/src/pybind/mgr/selftest/module.py new file mode 100644 index 00000000..6aff2aa5 --- /dev/null +++ b/src/pybind/mgr/selftest/module.py @@ -0,0 +1,489 @@ + +from mgr_module import MgrModule, CommandResult, PersistentStoreDict +import threading +import random +import json +import errno +import six + + +class Module(MgrModule): + """ + This module is for testing the ceph-mgr python interface from within + a running ceph-mgr daemon. + + It implements a sychronous self-test command for calling the functions + in the MgrModule interface one by one, and a background "workload" + command for causing the module to perform some thrashing-type + activities in its serve() thread. + """ + + # These workloads are things that can be requested to run inside the + # serve() function + WORKLOAD_COMMAND_SPAM = "command_spam" + WORKLOAD_THROW_EXCEPTION = "throw_exception" + SHUTDOWN = "shutdown" + + WORKLOADS = (WORKLOAD_COMMAND_SPAM, WORKLOAD_THROW_EXCEPTION) + + # The test code in qa/ relies on these options existing -- they + # are of course not really used for anything in the module + MODULE_OPTIONS = [ + {'name': 'testkey'}, + {'name': 'testlkey'}, + {'name': 'testnewline'}, + {'name': 'roption1'}, + {'name': 'roption2', 'type': 'str', 'default': 'xyz'}, + {'name': 'rwoption1'}, + {'name': 'rwoption2', 'type': 'int'}, + {'name': 'rwoption3', 'type': 'float'}, + {'name': 'rwoption4', 'type': 'str'}, + {'name': 'rwoption5', 'type': 'bool'}, + {'name': 'rwoption6', 'type': 'bool', 'default': True} + ] + + COMMANDS = [ + { + "cmd": "mgr self-test run", + "desc": "Run mgr python interface tests", + "perm": "rw" + }, + { + "cmd": "mgr self-test background start name=workload,type=CephString", + "desc": "Activate a background workload (one of {0})".format( + ", ".join(WORKLOADS)), + "perm": "rw" + }, + { + "cmd": "mgr self-test background stop", + "desc": "Stop background workload if any is running", + "perm": "rw" + }, + { + "cmd": "mgr self-test config get name=key,type=CephString", + "desc": "Peek at a configuration value", + "perm": "rw" + }, + { + "cmd": "mgr self-test config get_localized name=key,type=CephString", + "desc": "Peek at a configuration value (localized variant)", + "perm": "rw" + }, + { + "cmd": "mgr self-test remote", + "desc": "Test inter-module calls", + "perm": "rw" + }, + { + "cmd": "mgr self-test module name=module,type=CephString", + "desc": "Run another module's self_test() method", + "perm": "rw" + }, + { + "cmd": "mgr self-test health set name=checks,type=CephString", + "desc": "Set a health check from a JSON-formatted description.", + "perm": "rw" + }, + { + "cmd": "mgr self-test health clear name=checks,type=CephString,n=N,req=False", + "desc": "Clear health checks by name. If no names provided, clear all.", + "perm": "rw" + }, + { + "cmd": "mgr self-test insights_set_now_offset name=hours,type=CephString", + "desc": "Set the now time for the insights module.", + "perm": "rw" + }, + { + "cmd": "mgr self-test cluster-log name=channel,type=CephString " + "name=priority,type=CephString " + "name=message,type=CephString", + "desc": "Create an audit log record.", + "perm": "rw" + }, + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self._event = threading.Event() + self._workload = None + self._health = {} + + def handle_command(self, inbuf, command): + if command['prefix'] == 'mgr self-test run': + self._self_test() + return 0, '', 'Self-test succeeded' + + elif command['prefix'] == 'mgr self-test background start': + if command['workload'] not in self.WORKLOADS: + return (-errno.EINVAL, '', + "Workload not found '{0}'".format(command['workload'])) + self._workload = command['workload'] + self._event.set() + return 0, '', 'Running `{0}` in background'.format(self._workload) + + elif command['prefix'] == 'mgr self-test background stop': + if self._workload: + was_running = self._workload + self._workload = None + self._event.set() + return 0, '', 'Stopping background workload `{0}`'.format( + was_running) + else: + return 0, '', 'No background workload was running' + elif command['prefix'] == 'mgr self-test config get': + return 0, str(self.get_module_option(command['key'])), '' + elif command['prefix'] == 'mgr self-test config get_localized': + return 0, str(self.get_localized_module_option(command['key'])), '' + elif command['prefix'] == 'mgr self-test remote': + self._test_remote_calls() + return 0, '', 'Successfully called' + elif command['prefix'] == 'mgr self-test module': + try: + r = self.remote(command['module'], "self_test") + except RuntimeError as e: + return -1, '', "Test failed: {0}".format(e) + else: + return 0, str(r), "Self-test OK" + elif command['prefix'] == 'mgr self-test health set': + return self._health_set(inbuf, command) + elif command['prefix'] == 'mgr self-test health clear': + return self._health_clear(inbuf, command) + elif command['prefix'] == 'mgr self-test insights_set_now_offset': + return self._insights_set_now_offset(inbuf, command) + elif command['prefix'] == 'mgr self-test cluster-log': + priority_map = { + 'info': self.CLUSTER_LOG_PRIO_INFO, + 'security': self.CLUSTER_LOG_PRIO_SEC, + 'warning': self.CLUSTER_LOG_PRIO_WARN, + 'error': self.CLUSTER_LOG_PRIO_ERROR + } + self.cluster_log(command['channel'], + priority_map[command['priority']], + command['message']) + return 0, '', 'Successfully called' + else: + return (-errno.EINVAL, '', + "Command not found '{0}'".format(command['prefix'])) + + def _health_set(self, inbuf, command): + try: + checks = json.loads(command["checks"]) + except Exception as e: + return -1, "", "Failed to decode JSON input: {}".format(e) + + try: + for check, info in six.iteritems(checks): + self._health[check] = { + "severity": str(info["severity"]), + "summary": str(info["summary"]), + "detail": [str(m) for m in info["detail"]] + } + except Exception as e: + return -1, "", "Invalid health check format: {}".format(e) + + self.set_health_checks(self._health) + return 0, "", "" + + def _health_clear(self, inbuf, command): + if "checks" in command: + for check in command["checks"]: + if check in self._health: + del self._health[check] + else: + self._health = dict() + + self.set_health_checks(self._health) + return 0, "", "" + + def _insights_set_now_offset(self, inbuf, command): + try: + hours = int(command["hours"]) + except Exception as e: + return -1, "", "Timestamp must be numeric: {}".format(e) + + self.remote("insights", "testing_set_now_time_offset", hours) + return 0, "", "" + + def _self_test(self): + self.log.info("Running self-test procedure...") + + self._self_test_osdmap() + self._self_test_getters() + self._self_test_config() + self._self_test_store() + self._self_test_misc() + self._self_test_perf_counters() + self._self_persistent_store_dict() + + def _self_test_getters(self): + self.version + self.get_context() + self.get_mgr_id() + + # In this function, we will assume that the system is in a steady + # state, i.e. if a server/service appears in one call, it will + # not have gone by the time we call another function referring to it + + objects = [ + "fs_map", + "osdmap_crush_map_text", + "osd_map", + "config", + "mon_map", + "service_map", + "osd_metadata", + "pg_summary", + "pg_status", + "pg_dump", + "pg_ready", + "df", + "pg_stats", + "pool_stats", + "osd_stats", + "osd_ping_times", + "health", + "mon_status", + "mgr_map" + ] + for obj in objects: + assert self.get(obj) is not None + + assert self.get("__OBJ_DNE__") is None + + servers = self.list_servers() + for server in servers: + self.get_server(server['hostname']) + + osdmap = self.get('osd_map') + for o in osdmap['osds']: + osd_id = o['osd'] + self.get_metadata("osd", str(osd_id)) + + self.get_daemon_status("osd", "0") + #send_command + + def _self_test_config(self): + # This is not a strong test (can't tell if values really + # persisted), it's just for the python interface bit. + + self.set_module_option("testkey", "testvalue") + assert self.get_module_option("testkey") == "testvalue" + + self.set_localized_module_option("testkey", "foo") + assert self.get_localized_module_option("testkey") == "foo" + + # Must return the default value defined in MODULE_OPTIONS. + value = self.get_localized_module_option("rwoption6") + assert isinstance(value, bool) + assert value is True + + # Use default value. + assert self.get_module_option("roption1") is None + assert self.get_module_option("roption1", "foobar") == "foobar" + assert self.get_module_option("roption2") == "xyz" + assert self.get_module_option("roption2", "foobar") == "xyz" + + # Option type is not defined => return as string. + self.set_module_option("rwoption1", 8080) + value = self.get_module_option("rwoption1") + assert isinstance(value, str) + assert value == "8080" + + # Option type is defined => return as integer. + self.set_module_option("rwoption2", 10) + value = self.get_module_option("rwoption2") + assert isinstance(value, int) + assert value == 10 + + # Option type is defined => return as float. + self.set_module_option("rwoption3", 1.5) + value = self.get_module_option("rwoption3") + assert isinstance(value, float) + assert value == 1.5 + + # Option type is defined => return as string. + self.set_module_option("rwoption4", "foo") + value = self.get_module_option("rwoption4") + assert isinstance(value, str) + assert value == "foo" + + # Option type is defined => return as bool. + self.set_module_option("rwoption5", False) + value = self.get_module_option("rwoption5") + assert isinstance(value, bool) + assert value is False + + # Specified module does not exist => return None. + assert self.get_module_option_ex("foo", "bar") is None + + # Specified key does not exist => return None. + assert self.get_module_option_ex("dashboard", "bar") is None + + self.set_module_option_ex("telemetry", "contact", "test@test.com") + assert self.get_module_option_ex("telemetry", "contact") == "test@test.com" + + # No option default value, so use the specified one. + assert self.get_module_option_ex("dashboard", "password") is None + assert self.get_module_option_ex("dashboard", "password", "foobar") == "foobar" + + # Option type is not defined => return as string. + self.set_module_option_ex("selftest", "rwoption1", 1234) + value = self.get_module_option_ex("selftest", "rwoption1") + assert isinstance(value, str) + assert value == "1234" + + # Option type is defined => return as integer. + self.set_module_option_ex("telemetry", "interval", 60) + value = self.get_module_option_ex("telemetry", "interval") + assert isinstance(value, int) + assert value == 60 + + # Option type is defined => return as bool. + self.set_module_option_ex("telemetry", "leaderboard", True) + value = self.get_module_option_ex("telemetry", "leaderboard") + assert isinstance(value, bool) + assert value is True + + def _self_test_store(self): + existing_keys = set(self.get_store_prefix("test").keys()) + self.set_store("testkey", "testvalue") + assert self.get_store("testkey") == "testvalue" + + assert sorted(self.get_store_prefix("test").keys()) == sorted( + list({"testkey"} | existing_keys)) + + + def _self_test_perf_counters(self): + self.get_perf_schema("osd", "0") + self.get_counter("osd", "0", "osd.op") + #get_counter + #get_all_perf_coutners + + def _self_test_misc(self): + self.set_uri("http://this.is.a.test.com") + self.set_health_checks({}) + + def _self_test_osdmap(self): + osdmap = self.get_osdmap() + osdmap.get_epoch() + osdmap.get_crush_version() + osdmap.dump() + + inc = osdmap.new_incremental() + osdmap.apply_incremental(inc) + inc.get_epoch() + inc.dump() + + crush = osdmap.get_crush() + crush.dump() + crush.get_item_name(-1) + crush.get_item_weight(-1) + crush.find_takes() + crush.get_take_weight_osd_map(-1) + + #osdmap.get_pools_by_take() + #osdmap.calc_pg_upmaps() + #osdmap.map_pools_pgs_up() + + #inc.set_osd_reweights + #inc.set_crush_compat_weight_set_weights + + self.log.info("Finished self-test procedure.") + + def _self_persistent_store_dict(self): + self.test_dict = PersistentStoreDict(self, 'test_dict') + for i in "abcde": + self.test_dict[i] = {i:1} + assert self.test_dict.keys() == set("abcde") + assert 'a' in self.test_dict + del self.test_dict['a'] + assert self.test_dict.keys() == set("bcde"), self.test_dict.keys() + assert 'a' not in self.test_dict + self.test_dict.clear() + assert not self.test_dict, dict(self.test_dict.items()) + self.set_store('test_dict.a', 'invalid json') + try: + self.test_dict['a'] + assert False + except ValueError: + pass + assert not self.test_dict, dict(self.test_dict.items()) + + def _test_remote_calls(self): + # Test making valid call + self.remote("influx", "handle_command", "", {"prefix": "influx self-test"}) + + # Test calling module that exists but isn't enabled + # (arbitrarily pick a non-always-on module to use) + disabled_module = "telegraf" + mgr_map = self.get("mgr_map") + assert disabled_module not in mgr_map['modules'] + + # (This works until the Z release in about 2027) + latest_release = sorted(mgr_map['always_on_modules'].keys())[-1] + assert disabled_module not in mgr_map['always_on_modules'][latest_release] + + try: + self.remote(disabled_module, "handle_command", {"prefix": "influx self-test"}) + except ImportError: + pass + else: + raise RuntimeError("ImportError not raised for disabled module") + + # Test calling module that doesn't exist + try: + self.remote("idontexist", "handle_command", {"prefix": "influx self-test"}) + except ImportError: + pass + else: + raise RuntimeError("ImportError not raised for nonexistent module") + + # Test calling method that doesn't exist + try: + self.remote("influx", "idontexist", {"prefix": "influx self-test"}) + except NameError: + pass + else: + raise RuntimeError("KeyError not raised") + + + def shutdown(self): + self._workload = self.SHUTDOWN + self._event.set() + + def _command_spam(self): + self.log.info("Starting command_spam workload...") + while not self._event.is_set(): + osdmap = self.get_osdmap() + dump = osdmap.dump() + count = len(dump['osds']) + i = int(random.random() * count) + w = random.random() + + result = CommandResult('') + self.send_command(result, 'mon', '', json.dumps({ + 'prefix': 'osd reweight', + 'id': i, + 'weight': w + }), '') + + crush = osdmap.get_crush().dump() + r, outb, outs = result.wait() + + self._event.clear() + self.log.info("Ended command_spam workload...") + + def serve(self): + while True: + if self._workload == self.WORKLOAD_COMMAND_SPAM: + self._command_spam() + elif self._workload == self.SHUTDOWN: + self.log.info("Shutting down...") + break + elif self._workload == self.WORKLOAD_THROW_EXCEPTION: + raise RuntimeError("Synthetic exception in serve") + else: + self.log.info("Waiting for workload request...") + self._event.wait() + self._event.clear() diff --git a/src/pybind/mgr/ssh/.gitignore b/src/pybind/mgr/ssh/.gitignore new file mode 100644 index 00000000..8000dd9d --- /dev/null +++ b/src/pybind/mgr/ssh/.gitignore @@ -0,0 +1 @@ +.vagrant diff --git a/src/pybind/mgr/ssh/README.md b/src/pybind/mgr/ssh/README.md new file mode 100644 index 00000000..10f268cd --- /dev/null +++ b/src/pybind/mgr/ssh/README.md @@ -0,0 +1,93 @@ +# dev environment setup + +1. start vms with _only_ the ceph packages installed + +In `src/pybind/mgr/ssh` run `vagrant up` to create a cluster with a monitor, +manager, and osd nodes. The osd node will have two small extra disks attached. + +2. generate an `ssh_config` file for the vm hosts + +Execute `vagrant ssh-config > /path/to/ssh_config` to generate a ssh +configuration file that contains hosts, usernames, and keys that will be used by +the bootstrap cluster / ssh orchestrator to establish ssh connections to the +vagrant vms. + +3. install ssh orchestrator dependencies + +The primary dependency is the `remoto` package that contains a Python SSH client +for connecting to remote nodes and executing commands. + +Install with `dnf install python3-remoto`. The version must be >= 0.0.35. At the +time of writing this version is being packaged and is not available. To install +from source: + +``` +git clone https://github.com/ceph/remoto +cd remoto +python3 setup.py sdist +pip3 install --prefix=/usr dist/remoto-0.0.35.tar.gz +``` + +4. start the bootstrap cluster (in this case a `vstart.sh` cluster) + +Start with a network binding to which the vms can route traffic: + + `vstart.sh -n -i 192.168.121.1` + +The following is a manual method for finding this address. TODO: documenting a +automated/deterministic method would be very helpful. + +First, ensure that your firewall settings permit each VM to communicate with the +host. On Fedora, the `trusted` profile is sufficient: `firewall-cmd +--set-default-zone trusted` and also allows traffic on Ceph ports. Then ssh into +one of the vm nodes and ping the default gateway, which happens to be setup as +the host machine. + +``` +[nwatkins@smash ssh]$ vagrant ssh mon0 -c "getent hosts gateway" +192.168.121.1 gateway +``` + +5. setup the ssh orchestrator backend + +Enable and configure the ssh orchestrator as the active backend: + +``` +ceph mgr module enable ssh +ceph orchestrator set backend ssh + +# optional: this document assumes the orchestrator CLI is enabled +ceph mgr module enable orchestrator_cli +``` + +Configure the ssh orchestrator by setting the `ssh_config` option to point at +the ssh configuration file generated above: + +``` +ceph config set mgr mgr/ssh/ssh_config_file /path/to/config +``` + +The setting can be confirmed by retrieving the configuration settings: + +``` +[nwatkins@smash build]$ ceph config get mgr. +WHO MASK LEVEL OPTION VALUE RO +mgr advanced mgr/orchestrator_cli/orchestrator ssh * +mgr advanced mgr/ssh/ssh_config_file /home/nwatkins/src/ceph/src/pybind/mgr/ssh/config * +``` + +An SSH config file can also be provided through standard input that avoids the +need to have an accessible file path. Use the following command: + + +``` +ceph ssh set-ssh-config -i +``` + +The next set of instructions we should move to the docs folder + +ceph orchestrator host add osd0 +ceph orchestrator host add mgr0 +ceph orchestrator host add mon0 +ceph orchestrator device ls +ceph orchestrator mgr update 3 mgr0 mgr1 diff --git a/src/pybind/mgr/ssh/Vagrantfile b/src/pybind/mgr/ssh/Vagrantfile new file mode 100644 index 00000000..0a2a6389 --- /dev/null +++ b/src/pybind/mgr/ssh/Vagrantfile @@ -0,0 +1,39 @@ +# vi: set ft=ruby : + +NUM_DAEMONS = ENV["NUM_DAEMONS"] ? ENV["NUM_DAEMONS"].to_i : 1 + +Vagrant.configure("2") do |config| + config.vm.synced_folder ".", "/vagrant", disabled: true + config.vm.network "private_network", type: "dhcp" + config.vm.box = "centos/7" + + (0..NUM_DAEMONS - 1).each do |i| + config.vm.define "mon#{i}" do |mon| + mon.vm.hostname = "mon#{i}" + end + config.vm.define "mgr#{i}" do |mgr| + mgr.vm.hostname = "mgr#{i}" + end + config.vm.define "osd#{i}" do |osd| + osd.vm.hostname = "osd#{i}" + osd.vm.provider :libvirt do |libvirt| + libvirt.storage :file, :size => '5G' + libvirt.storage :file, :size => '5G' + end + end + end + + config.vm.provision "shell" do |s| + ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip + s.inline = "echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys" + end + + config.vm.provision "shell", inline: <<-SHELL + sudo yum install -y yum-utils + sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm + sudo rpm --import 'https://download.ceph.com/keys/release.asc' + curl -L https://shaman.ceph.com/api/repos/ceph/master/latest/centos/7/repo/ | sudo tee /etc/yum.repos.d/shaman.repo + sudo yum install -y ceph python36 + sudo ln -s /usr/bin/python36 /usr/bin/python3 + SHELL +end diff --git a/src/pybind/mgr/ssh/__init__.py b/src/pybind/mgr/ssh/__init__.py new file mode 100644 index 00000000..3f41e016 --- /dev/null +++ b/src/pybind/mgr/ssh/__init__.py @@ -0,0 +1 @@ +from .module import SSHOrchestrator diff --git a/src/pybind/mgr/ssh/ceph.repo b/src/pybind/mgr/ssh/ceph.repo new file mode 100644 index 00000000..6f710e7c --- /dev/null +++ b/src/pybind/mgr/ssh/ceph.repo @@ -0,0 +1,23 @@ +[ceph] +name=Ceph packages for $basearch +baseurl=https://download.ceph.com/rpm-mimic/el7/$basearch +enabled=1 +priority=2 +gpgcheck=1 +gpgkey=https://download.ceph.com/keys/release.asc + +[ceph-noarch] +name=Ceph noarch packages +baseurl=https://download.ceph.com/rpm-mimic/el7/noarch +enabled=1 +priority=2 +gpgcheck=1 +gpgkey=https://download.ceph.com/keys/release.asc + +[ceph-source] +name=Ceph source packages +baseurl=https://download.ceph.com/rpm-mimic/el7/SRPMS +enabled=0 +priority=2 +gpgcheck=1 +gpgkey=https://download.ceph.com/keys/release.asc diff --git a/src/pybind/mgr/ssh/module.py b/src/pybind/mgr/ssh/module.py new file mode 100644 index 00000000..73675e52 --- /dev/null +++ b/src/pybind/mgr/ssh/module.py @@ -0,0 +1,740 @@ +import json +import errno +import logging +from functools import wraps + +import six +import os +import tempfile +import multiprocessing.pool + +from mgr_module import MgrModule +import orchestrator + +from . import remotes + +try: + import remoto + import remoto.process +except ImportError as e: + remoto = None + remoto_import_error = str(e) + +logger = logging.getLogger(__name__) + +# high-level TODO: +# - bring over some of the protections from ceph-deploy that guard against +# multiple bootstrapping / initialization + +class SSHCompletionmMixin(object): + def __init__(self, result): + if isinstance(result, multiprocessing.pool.AsyncResult): + self._result = [result] + else: + self._result = result + assert isinstance(self._result, list) + + @property + def result(self): + return list(map(lambda r: r.get(), self._result)) + +class SSHReadCompletion(SSHCompletionmMixin, orchestrator.ReadCompletion): + @property + def is_complete(self): + return all(map(lambda r: r.ready(), self._result)) + + +class SSHWriteCompletion(SSHCompletionmMixin, orchestrator.WriteCompletion): + + @property + def is_persistent(self): + return all(map(lambda r: r.ready(), self._result)) + + @property + def is_effective(self): + return all(map(lambda r: r.ready(), self._result)) + + @property + def is_errored(self): + for r in self._result: + if not r.ready(): + return False + if not r.successful(): + return True + return False + +class SSHWriteCompletionReady(SSHWriteCompletion): + def __init__(self, result): + orchestrator.WriteCompletion.__init__(self) + self._result = result + + @property + def result(self): + return self._result + + @property + def is_persistent(self): + return True + + @property + def is_effective(self): + return True + + @property + def is_errored(self): + return False + +class SSHConnection(object): + """ + Tie tempfile lifetime (e.g. ssh_config) to a remoto connection. + """ + def __init__(self): + self.conn = None + self.temp_file = None + + # proxy to the remoto connection + def __getattr__(self, name): + return getattr(self.conn, name) + + +def log_exceptions(f): + if six.PY3: + return f + else: + # Python 2 does no exception chaining, thus the + # real exception is lost + @wraps(f) + def wrapper(*args, **kwargs): + try: + return f(*args, **kwargs) + except Exception: + logger.exception('something went wrong.') + raise + return wrapper + + +class SSHOrchestrator(MgrModule, orchestrator.Orchestrator): + + _STORE_HOST_PREFIX = "host" + _DEFAULT_INVENTORY_CACHE_TIMEOUT_MIN = 10 + + MODULE_OPTIONS = [ + {'name': 'ssh_config_file'}, + {'name': 'inventory_cache_timeout_min'}, + ] + + COMMANDS = [ + { + 'cmd': 'ssh set-ssh-config', + 'desc': 'Set the ssh_config file (use -i )', + 'perm': 'rw' + }, + { + 'cmd': 'ssh clear-ssh-config', + 'desc': 'Clear the ssh_config file', + 'perm': 'rw' + }, + ] + + def __init__(self, *args, **kwargs): + super(SSHOrchestrator, self).__init__(*args, **kwargs) + self._cluster_fsid = None + self._worker_pool = multiprocessing.pool.ThreadPool(1) + + # the keys in inventory_cache are authoritative. + # You must not call remove_outdated() + # The values are cached by instance. + # cache is invalidated by + # 1. timeout + # 2. refresh parameter + self.inventory_cache = orchestrator.OutdatablePersistentDict(self, self._STORE_HOST_PREFIX) + + def handle_command(self, inbuf, command): + if command["prefix"] == "ssh set-ssh-config": + return self._set_ssh_config(inbuf, command) + elif command["prefix"] == "ssh clear-ssh-config": + return self._clear_ssh_config(inbuf, command) + else: + raise NotImplementedError(command["prefix"]) + + @staticmethod + def can_run(): + if remoto is not None: + return True, "" + else: + return False, "loading remoto library:{}".format( + remoto_import_error) + + def available(self): + """ + The SSH orchestrator is always available. + """ + return self.can_run() + + def wait(self, completions): + self.log.info("wait: completions={}".format(completions)) + + complete = True + for c in completions: + if c.is_complete: + continue + + if not isinstance(c, SSHReadCompletion) and \ + not isinstance(c, SSHWriteCompletion): + raise TypeError("unexpected completion: {}".format(c.__class__)) + + complete = False + + return complete + + def _get_cluster_fsid(self): + """ + Fetch and cache the cluster fsid. + """ + if not self._cluster_fsid: + self._cluster_fsid = self.get("mon_map")["fsid"] + assert isinstance(self._cluster_fsid, six.string_types) + return self._cluster_fsid + + def _require_hosts(self, hosts): + """ + Raise an error if any of the given hosts are unregistered. + """ + if isinstance(hosts, six.string_types): + hosts = [hosts] + keys = self.inventory_cache.keys() + unregistered_hosts = set(hosts) - keys + if unregistered_hosts: + logger.warning('keys = {}'.format(keys)) + raise RuntimeError("Host(s) {} not registered".format( + ", ".join(map(lambda h: "'{}'".format(h), + unregistered_hosts)))) + + def _set_ssh_config(self, inbuf, command): + """ + Set an ssh_config file provided from stdin + + TODO: + - validation + """ + if len(inbuf) == 0: + return errno.EINVAL, "", "empty ssh config provided" + self.set_store("ssh_config", inbuf) + return 0, "", "" + + def _clear_ssh_config(self, inbuf, command): + """ + Clear the ssh_config file provided from stdin + """ + self.set_store("ssh_config", None) + self.ssh_config_tmp = None + return 0, "", "" + + def _get_connection(self, host): + """ + Setup a connection for running commands on remote host. + """ + ssh_options = None + + conn = SSHConnection() + + ssh_config = self.get_store("ssh_config") + if ssh_config is not None: + conn.temp_file = tempfile.NamedTemporaryFile() + conn.temp_file.write(ssh_config.encode('utf-8')) + conn.temp_file.flush() # make visible to other processes + ssh_config_fname = conn.temp_file.name + else: + ssh_config_fname = self.get_localized_module_option("ssh_config_file") + + if ssh_config_fname: + if not os.path.isfile(ssh_config_fname): + raise Exception("ssh_config \"{}\" does not exist".format(ssh_config_fname)) + ssh_options = "-F {}".format(ssh_config_fname) + + self.log.info("opening connection to host '{}' with ssh " + "options '{}'".format(host, ssh_options)) + + conn.conn = remoto.Connection(host, + logger=self.log, + detect_sudo=True, + ssh_options=ssh_options) + + conn.conn.import_module(remotes) + + return conn + + def _executable_path(self, conn, executable): + """ + Remote validator that accepts a connection object to ensure that a certain + executable is available returning its full path if so. + + Otherwise an exception with thorough details will be raised, informing the + user that the executable was not found. + """ + executable_path = conn.remote_module.which(executable) + if not executable_path: + raise RuntimeError("Executable '{}' not found on host '{}'".format( + executable, conn.hostname)) + self.log.info("Found executable '{}' at path '{}'".format(executable, + executable_path)) + return executable_path + + def _build_ceph_conf(self): + """ + Build a minimal `ceph.conf` containing the current monitor hosts. + + Notes: + - ceph-volume complains if no section header (e.g. global) exists + - other ceph cli tools complained about no EOF newline + + TODO: + - messenger v2 syntax? + """ + mon_map = self.get("mon_map") + mon_addrs = map(lambda m: m["addr"], mon_map["mons"]) + mon_hosts = ", ".join(mon_addrs) + return "[global]\nmon host = {}\n".format(mon_hosts) + + def _ensure_ceph_conf(self, conn, network=False): + """ + Install ceph.conf on remote node if it doesn't exist. + """ + conf = self._build_ceph_conf() + if network: + conf += "public_network = {}\n".format(network) + conn.remote_module.write_conf("/etc/ceph/ceph.conf", conf) + + def _get_bootstrap_key(self, service_type): + """ + Fetch a bootstrap key for a service type. + + :param service_type: name (e.g. mds, osd, mon, ...) + """ + identity_dict = { + 'admin' : 'client.admin', + 'mds' : 'client.bootstrap-mds', + 'mgr' : 'client.bootstrap-mgr', + 'osd' : 'client.bootstrap-osd', + 'rgw' : 'client.bootstrap-rgw', + 'mon' : 'mon.' + } + + identity = identity_dict[service_type] + + ret, out, err = self.mon_command({ + "prefix": "auth get", + "entity": identity + }) + + if ret == -errno.ENOENT: + raise RuntimeError("Entity '{}' not found: '{}'".format(identity, err)) + elif ret != 0: + raise RuntimeError("Error retrieving key for '{}' ret {}: '{}'".format( + identity, ret, err)) + + return out + + def _bootstrap_mgr(self, conn): + """ + Bootstrap a manager. + + 1. install a copy of ceph.conf + 2. install the manager bootstrap key + + :param conn: remote host connection + """ + self._ensure_ceph_conf(conn) + keyring = self._get_bootstrap_key("mgr") + keyring_path = "/var/lib/ceph/bootstrap-mgr/ceph.keyring" + conn.remote_module.write_keyring(keyring_path, keyring) + return keyring_path + + def _bootstrap_osd(self, conn): + """ + Bootstrap an osd. + + 1. install a copy of ceph.conf + 2. install the osd bootstrap key + + :param conn: remote host connection + """ + self._ensure_ceph_conf(conn) + keyring = self._get_bootstrap_key("osd") + keyring_path = "/var/lib/ceph/bootstrap-osd/ceph.keyring" + conn.remote_module.write_keyring(keyring_path, keyring) + return keyring_path + + def _get_hosts(self, wanted=None): + return self.inventory_cache.items_filtered(wanted) + + def add_host(self, host): + """ + Add a host to be managed by the orchestrator. + + :param host: host name + """ + @log_exceptions + def run(host): + self.inventory_cache[host] = orchestrator.OutdatableData() + return "Added host '{}'".format(host) + + return SSHWriteCompletion( + self._worker_pool.apply_async(run, (host,))) + + def remove_host(self, host): + """ + Remove a host from orchestrator management. + + :param host: host name + """ + @log_exceptions + def run(host): + del self.inventory_cache[host] + return "Removed host '{}'".format(host) + + return SSHWriteCompletion( + self._worker_pool.apply_async(run, (host,))) + + def get_hosts(self): + """ + Return a list of hosts managed by the orchestrator. + + Notes: + - skip async: manager reads from cache. + + TODO: + - InventoryNode probably needs to be able to report labels + """ + nodes = [orchestrator.InventoryNode(host_name, []) for host_name in self.inventory_cache] + return orchestrator.TrivialReadCompletion(nodes) + + def _get_device_inventory(self, host): + """ + Query storage devices on a remote node. + + :return: list of InventoryDevice + """ + conn = self._get_connection(host) + + try: + ceph_volume_executable = self._executable_path(conn, 'ceph-volume') + command = [ + ceph_volume_executable, + "inventory", + "--format=json" + ] + + out, err, code = remoto.process.check(conn, command) + host_devices = json.loads(out[0]) + return host_devices + + except Exception as ex: + self.log.exception(ex) + raise + + finally: + conn.exit() + + def get_inventory(self, node_filter=None, refresh=False): + """ + Return the storage inventory of nodes matching the given filter. + + :param node_filter: node filter + + TODO: + - add filtering by label + """ + if node_filter: + hosts = node_filter.nodes + self._require_hosts(hosts) + hosts = self._get_hosts(hosts) + else: + # this implies the returned hosts are registered + hosts = self._get_hosts() + + @log_exceptions + def run(host, host_info): + # type: (str, orchestrator.OutdatableData) -> orchestrator.InventoryNode + + timeout_min = int(self.get_module_option( + "inventory_cache_timeout_min", + self._DEFAULT_INVENTORY_CACHE_TIMEOUT_MIN)) + + if host_info.outdated(timeout_min) or refresh: + self.log.info("refresh stale inventory for '{}'".format(host)) + data = self._get_device_inventory(host) + host_info = orchestrator.OutdatableData(data) + self.inventory_cache[host] = host_info + else: + self.log.debug("reading cached inventory for '{}'".format(host)) + + devices = orchestrator.InventoryDevice.from_ceph_volume_inventory_list(host_info.data) + return orchestrator.InventoryNode(host, devices) + + results = [] + for key, host_info in hosts: + result = self._worker_pool.apply_async(run, (key, host_info)) + results.append(result) + + return SSHReadCompletion(results) + + @log_exceptions + def _create_osd(self, host, drive_group): + conn = self._get_connection(host) + try: + devices = drive_group.data_devices.paths + self._bootstrap_osd(conn) + + for device in devices: + ceph_volume_executable = self._executable_path(conn, "ceph-volume") + command = [ + ceph_volume_executable, + "lvm", + "create", + "--cluster-fsid", self._get_cluster_fsid(), + "--{}".format(drive_group.objectstore), + "--data", device + ] + remoto.process.run(conn, command) + + return "Created osd on host '{}'".format(host) + + except: + raise + + finally: + conn.exit() + + def create_osds(self, drive_group, all_hosts=None): + """ + Create a new osd. + + The orchestrator CLI currently handles a narrow form of drive + specification defined by a single block device using bluestore. + + :param drive_group: osd specification + + TODO: + - support full drive_group specification + - support batch creation + """ + assert len(drive_group.hosts(all_hosts)) == 1 + assert len(drive_group.data_devices.paths) > 0 + assert all(map(lambda p: isinstance(p, six.string_types), + drive_group.data_devices.paths)) + + host = drive_group.hosts(all_hosts)[0] + self._require_hosts(host) + + result = self._worker_pool.apply_async(self._create_osd, (host, + drive_group)) + + return SSHWriteCompletion(result) + + def _create_mon(self, host, network): + """ + Create a new monitor on the given host. + """ + self.log.info("create_mon({}:{}): starting".format(host, network)) + + conn = self._get_connection(host) + + try: + self._ensure_ceph_conf(conn, network) + + uid = conn.remote_module.path_getuid("/var/lib/ceph") + gid = conn.remote_module.path_getgid("/var/lib/ceph") + + # install client admin key on target mon host + admin_keyring = self._get_bootstrap_key("admin") + admin_keyring_path = '/etc/ceph/ceph.client.admin.keyring' + conn.remote_module.write_keyring(admin_keyring_path, admin_keyring, uid, gid) + + mon_path = "/var/lib/ceph/mon/ceph-{name}".format(name=host) + conn.remote_module.create_mon_path(mon_path, uid, gid) + + # bootstrap key + conn.remote_module.safe_makedirs("/var/lib/ceph/tmp") + monitor_keyring = self._get_bootstrap_key("mon") + mon_keyring_path = "/var/lib/ceph/tmp/ceph-{name}.mon.keyring".format(name=host) + conn.remote_module.write_file( + mon_keyring_path, + monitor_keyring, + 0o600, + None, + uid, + gid + ) + + # monitor map + monmap_path = "/var/lib/ceph/tmp/ceph.{name}.monmap".format(name=host) + remoto.process.run(conn, + ['ceph', 'mon', 'getmap', '-o', monmap_path], + ) + + user_args = [] + if uid != 0: + user_args = user_args + [ '--setuser', str(uid) ] + if gid != 0: + user_args = user_args + [ '--setgroup', str(gid) ] + + remoto.process.run(conn, + ['ceph-mon', '--mkfs', '-i', host, + '--monmap', monmap_path, '--keyring', mon_keyring_path + ] + user_args + ) + + remoto.process.run(conn, + ['systemctl', 'enable', 'ceph.target'], + timeout=7, + ) + + remoto.process.run(conn, + ['systemctl', 'enable', 'ceph-mon@{name}'.format(name=host)], + timeout=7, + ) + + remoto.process.run(conn, + ['systemctl', 'start', 'ceph-mon@{name}'.format(name=host)], + timeout=7, + ) + + return "Created mon on host '{}'".format(host) + + except Exception as e: + self.log.error("create_mon({}:{}): error: {}".format(host, network, e)) + raise + + finally: + self.log.info("create_mon({}:{}): finished".format(host, network)) + conn.exit() + + def update_mons(self, num, hosts): + """ + Adjust the number of cluster monitors. + """ + # current support limited to adding monitors. + mon_map = self.get("mon_map") + num_mons = len(mon_map["mons"]) + if num == num_mons: + return SSHWriteCompletionReady("The requested number of monitors exist.") + if num < num_mons: + raise NotImplementedError("Removing monitors is not supported.") + + # check that all the hostnames are registered + self._require_hosts(map(lambda h: h[0], hosts)) + + # current support requires a network to be specified + for host, network in hosts: + if not network: + raise RuntimeError("Host '{}' missing network " + "part".format(host)) + + # explicit placement: enough hosts provided? + num_new_mons = num - num_mons + if len(hosts) < num_new_mons: + raise RuntimeError("Error: {} hosts provided, expected {}".format( + len(hosts), num_new_mons)) + + self.log.info("creating {} monitors on hosts: '{}'".format( + num_new_mons, ",".join(map(lambda h: ":".join(h), hosts)))) + + # TODO: we may want to chain the creation of the monitors so they join + # the quroum one at a time. + results = [] + for host, network in hosts: + result = self._worker_pool.apply_async(self._create_mon, (host, + network)) + results.append(result) + + return SSHWriteCompletion(results) + + def _create_mgr(self, host): + """ + Create a new manager instance on a host. + """ + self.log.info("create_mgr({}): starting".format(host)) + + conn = self._get_connection(host) + + try: + bootstrap_keyring_path = self._bootstrap_mgr(conn) + + mgr_path = "/var/lib/ceph/mgr/ceph-{name}".format(name=host) + conn.remote_module.safe_makedirs(mgr_path) + keyring_path = os.path.join(mgr_path, "keyring") + + command = [ + 'ceph', + '--name', 'client.bootstrap-mgr', + '--keyring', bootstrap_keyring_path, + 'auth', 'get-or-create', 'mgr.{name}'.format(name=host), + 'mon', 'allow profile mgr', + 'osd', 'allow *', + 'mds', 'allow *', + '-o', + keyring_path + ] + + out, err, ret = remoto.process.check(conn, command) + if ret != 0: + raise Exception("oops") + + remoto.process.run(conn, + ['systemctl', 'enable', 'ceph-mgr@{name}'.format(name=host)], + timeout=7 + ) + + remoto.process.run(conn, + ['systemctl', 'start', 'ceph-mgr@{name}'.format(name=host)], + timeout=7 + ) + + remoto.process.run(conn, + ['systemctl', 'enable', 'ceph.target'], + timeout=7 + ) + + return "Created mgr on host '{}'".format(host) + + except Exception as e: + self.log.error("create_mgr({}): error: {}".format(host, e)) + raise + + finally: + self.log.info("create_mgr({}): finished".format(host)) + conn.exit() + + def update_mgrs(self, num, hosts): + """ + Adjust the number of cluster managers. + """ + # current support limited to adding managers. + mgr_map = self.get("mgr_map") + num_mgrs = 1 if mgr_map["active_name"] else 0 + num_mgrs += len(mgr_map["standbys"]) + if num == num_mgrs: + return SSHWriteCompletionReady("The requested number of managers exist.") + if num < num_mgrs: + raise NotImplementedError("Removing managers is not supported") + + # check that all the hosts are registered + self._require_hosts(hosts) + + # we assume explicit placement by which there are the same number of + # hosts specified as the size of increase in number of daemons. + num_new_mgrs = num - num_mgrs + if len(hosts) < num_new_mgrs: + raise RuntimeError("Error: {} hosts provided, expected {}".format( + len(hosts), num_new_mgrs)) + + self.log.info("creating {} managers on hosts: '{}'".format( + num_new_mgrs, ",".join(hosts))) + + results = [] + for i in range(num_new_mgrs): + result = self._worker_pool.apply_async(self._create_mgr, (hosts[i],)) + results.append(result) + + return SSHWriteCompletion(results) diff --git a/src/pybind/mgr/ssh/remotes.py b/src/pybind/mgr/ssh/remotes.py new file mode 100644 index 00000000..da057e83 --- /dev/null +++ b/src/pybind/mgr/ssh/remotes.py @@ -0,0 +1,81 @@ +# ceph-deploy ftw +import os +import errno +import tempfile +import shutil + +def safe_makedirs(path, uid=-1, gid=-1): + """ create path recursively if it doesn't exist """ + try: + os.makedirs(path) + except OSError as e: + if e.errno == errno.EEXIST: + pass + else: + raise + else: + os.chown(path, uid, gid) + +def write_conf(path, conf): + if not os.path.exists(path): + dirpath = os.path.dirname(path) + if os.path.exists(dirpath): + with open(path, "w") as f: + f.write(conf) + os.chmod(path, 0o644) + else: + raise RuntimeError( + "{0} does not exist".format(dirpath)) + +def write_keyring(path, key, overwrite=False, uid=-1, gid=-1): + dirname = os.path.dirname(path) + if not os.path.exists(dirname): + safe_makedirs(dirname, uid, gid) + if not overwrite and os.path.exists(path): + return + with open(path, "wb") as f: + f.write(key.encode('utf-8')) + +def create_mon_path(path, uid=-1, gid=-1): + """create the mon path if it does not exist""" + if not os.path.exists(path): + os.makedirs(path) + os.chown(path, uid, gid); + +def write_file(path, content, mode=0o644, directory=None, uid=-1, gid=-1): + if directory: + if path.startswith("/"): + path = path[1:] + path = os.path.join(directory, path) + if os.path.exists(path): + # Delete file in case we are changing its mode + os.unlink(path) + with os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, mode), 'wb') as f: + f.write(content.encode('utf-8')) + os.chown(path, uid, gid) + +def path_getuid(path): + return os.stat(path).st_uid + +def path_getgid(path): + return os.stat(path).st_gid + +def which(executable): + """find the location of an executable""" + locations = ( + '/usr/local/bin', + '/bin', + '/usr/bin', + '/usr/local/sbin', + '/usr/sbin', + '/sbin', + ) + + for location in locations: + executable_path = os.path.join(location, executable) + if os.path.exists(executable_path) and os.path.isfile(executable_path): + return executable_path + +if __name__ == '__channelexec__': + for item in channel: + channel.send(eval(item)) diff --git a/src/pybind/mgr/status/__init__.py b/src/pybind/mgr/status/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/status/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/status/module.py b/src/pybind/mgr/status/module.py new file mode 100644 index 00000000..f8509296 --- /dev/null +++ b/src/pybind/mgr/status/module.py @@ -0,0 +1,261 @@ + +""" +High level status display commands +""" + +from collections import defaultdict +from prettytable import PrettyTable +import errno +import fnmatch +import mgr_util +import prettytable +import six + +from mgr_module import MgrModule + + +class Module(MgrModule): + COMMANDS = [ + { + "cmd": "fs status " + "name=fs,type=CephString,req=false", + "desc": "Show the status of a CephFS filesystem", + "perm": "r" + }, + { + "cmd": "osd status " + "name=bucket,type=CephString,req=false", + "desc": "Show the status of OSDs within a bucket, or all", + "perm": "r" + }, + ] + + + def get_latest(self, daemon_type, daemon_name, stat): + data = self.get_counter(daemon_type, daemon_name, stat)[stat] + #self.log.error("get_latest {0} data={1}".format(stat, data)) + if data: + return data[-1][1] + else: + return 0 + + def get_rate(self, daemon_type, daemon_name, stat): + data = self.get_counter(daemon_type, daemon_name, stat)[stat] + + #self.log.error("get_latest {0} data={1}".format(stat, data)) + if data and len(data) > 1: + return (data[-1][1] - data[-2][1]) / float(data[-1][0] - data[-2][0]) + else: + return 0 + + def handle_fs_status(self, cmd): + output = "" + + fs_filter = cmd.get('fs', None) + + mds_versions = defaultdict(list) + + fsmap = self.get("fs_map") + for filesystem in fsmap['filesystems']: + if fs_filter and filesystem['mdsmap']['fs_name'] != fs_filter: + continue + + rank_table = PrettyTable( + ("Rank", "State", "MDS", "Activity", "dns", "inos"), + hrules=prettytable.FRAME + ) + + mdsmap = filesystem['mdsmap'] + + client_count = 0 + + for rank in mdsmap["in"]: + up = "mds_{0}".format(rank) in mdsmap["up"] + if up: + gid = mdsmap['up']["mds_{0}".format(rank)] + info = mdsmap['info']['gid_{0}'.format(gid)] + dns = self.get_latest("mds", info['name'], "mds_mem.dn") + inos = self.get_latest("mds", info['name'], "mds_mem.ino") + + if rank == 0: + client_count = self.get_latest("mds", info['name'], + "mds_sessions.session_count") + elif client_count == 0: + # In case rank 0 was down, look at another rank's + # sessionmap to get an indication of clients. + client_count = self.get_latest("mds", info['name'], + "mds_sessions.session_count") + + laggy = "laggy_since" in info + + state = info['state'].split(":")[1] + if laggy: + state += "(laggy)" + if state == "active" and not laggy: + c_state = mgr_util.colorize(state, mgr_util.GREEN) + else: + c_state = mgr_util.colorize(state, mgr_util.YELLOW) + + # Populate based on context of state, e.g. client + # ops for an active daemon, replay progress, reconnect + # progress + activity = "" + + if state == "active": + activity = "Reqs: " + mgr_util.format_dimless( + self.get_rate("mds", info['name'], "mds_server.handle_client_request"), + 5 + ) + "/s" + + defaults = defaultdict(lambda: None, {'version' : 'unknown'}) + metadata = self.get_metadata('mds', info['name'], default=defaults) + mds_versions[metadata['ceph_version']].append(info['name']) + rank_table.add_row([ + mgr_util.bold(rank.__str__()), c_state, info['name'], + activity, + mgr_util.format_dimless(dns, 5), + mgr_util.format_dimless(inos, 5) + ]) + + else: + rank_table.add_row([ + rank, "failed", "", "", "", "" + ]) + + # Find the standby replays + for gid_str, daemon_info in six.iteritems(mdsmap['info']): + if daemon_info['state'] != "up:standby-replay": + continue + + inos = self.get_latest("mds", daemon_info['name'], "mds_mem.ino") + dns = self.get_latest("mds", daemon_info['name'], "mds_mem.dn") + + activity = "Evts: " + mgr_util.format_dimless( + self.get_rate("mds", daemon_info['name'], "mds_log.replayed"), + 5 + ) + "/s" + + defaults = defaultdict(lambda: None, {'version' : 'unknown'}) + metadata = self.get_metadata('mds', daemon_info['name'], default=defaults) + mds_versions[metadata['ceph_version']].append(daemon_info['name']) + + rank_table.add_row([ + "{0}-s".format(daemon_info['rank']), "standby-replay", + daemon_info['name'], activity, + mgr_util.format_dimless(dns, 5), + mgr_util.format_dimless(inos, 5) + ]) + + df = self.get("df") + pool_stats = dict([(p['id'], p['stats']) for p in df['pools']]) + osdmap = self.get("osd_map") + pools = dict([(p['pool'], p) for p in osdmap['pools']]) + metadata_pool_id = mdsmap['metadata_pool'] + data_pool_ids = mdsmap['data_pools'] + + pools_table = PrettyTable(["Pool", "type", "used", "avail"]) + for pool_id in [metadata_pool_id] + data_pool_ids: + pool_type = "metadata" if pool_id == metadata_pool_id else "data" + stats = pool_stats[pool_id] + pools_table.add_row([ + pools[pool_id]['pool_name'], pool_type, + mgr_util.format_bytes(stats['bytes_used'], 5), + mgr_util.format_bytes(stats['max_avail'], 5) + ]) + + output += "{0} - {1} clients\n".format( + mdsmap['fs_name'], client_count) + output += "=" * len(mdsmap['fs_name']) + "\n" + output += rank_table.get_string() + output += "\n" + pools_table.get_string() + "\n" + + if not output and fs_filter is not None: + return errno.EINVAL, "", "Invalid filesystem: " + fs_filter + + standby_table = PrettyTable(["Standby MDS"]) + for standby in fsmap['standbys']: + defaults = defaultdict(lambda: None, {'version' : 'unknown'}) + metadata = self.get_metadata('mds', standby['name'], default=defaults) + mds_versions[metadata['ceph_version']].append(standby['name']) + + standby_table.add_row([standby['name']]) + + output += "\n" + standby_table.get_string() + "\n" + + if len(mds_versions) == 1: + output += "MDS version: {0}".format(list(mds_versions)[0]) + else: + version_table = PrettyTable(["version", "daemons"]) + for version, daemons in six.iteritems(mds_versions): + version_table.add_row([ + version, + ", ".join(daemons) + ]) + output += version_table.get_string() + "\n" + + return 0, output, "" + + def handle_osd_status(self, cmd): + osd_table = PrettyTable(['id', 'host', 'used', 'avail', 'wr ops', 'wr data', 'rd ops', 'rd data', 'state']) + osdmap = self.get("osd_map") + + filter_osds = set() + bucket_filter = None + if 'bucket' in cmd: + self.log.debug("Filtering to bucket '{0}'".format(cmd['bucket'])) + bucket_filter = cmd['bucket'] + crush = self.get("osd_map_crush") + found = False + for bucket in crush['buckets']: + if fnmatch.fnmatch(bucket['name'], bucket_filter): + found = True + filter_osds.update([i['id'] for i in bucket['items']]) + + if not found: + msg = "Bucket '{0}' not found".format(bucket_filter) + return errno.ENOENT, msg, "" + + # Build dict of OSD ID to stats + osd_stats = dict([(o['osd'], o) for o in self.get("osd_stats")['osd_stats']]) + + for osd in osdmap['osds']: + osd_id = osd['osd'] + if bucket_filter and osd_id not in filter_osds: + continue + + hostname = "" + kb_used = 0 + kb_avail = 0 + + if osd_id in osd_stats: + defaults = defaultdict(lambda: None, {'hostname' : ''}) + metadata = self.get_metadata('osd', str(osd_id), default=defaults) + stats = osd_stats[osd_id] + hostname = metadata['hostname'] + kb_used = stats['kb_used'] * 1024 + kb_avail = stats['kb_avail'] * 1024 + + osd_table.add_row([osd_id, hostname, + mgr_util.format_bytes(kb_used, 5), + mgr_util.format_bytes(kb_avail, 5), + mgr_util.format_dimless(self.get_rate("osd", osd_id.__str__(), "osd.op_w") + + self.get_rate("osd", osd_id.__str__(), "osd.op_rw"), 5), + mgr_util.format_bytes(self.get_rate("osd", osd_id.__str__(), "osd.op_in_bytes"), 5), + mgr_util.format_dimless(self.get_rate("osd", osd_id.__str__(), "osd.op_r"), 5), + mgr_util.format_bytes(self.get_rate("osd", osd_id.__str__(), "osd.op_out_bytes"), 5), + ','.join(osd['state']), + ]) + + return 0, osd_table.get_string(), "" + + def handle_command(self, inbuf, cmd): + self.log.error("handle_command") + + if cmd['prefix'] == "fs status": + return self.handle_fs_status(cmd) + elif cmd['prefix'] == "osd status": + return self.handle_osd_status(cmd) + else: + # mgr should respect our self.COMMANDS and not call us for + # any prefix we don't advertise + raise NotImplementedError(cmd['prefix']) diff --git a/src/pybind/mgr/telegraf/__init__.py b/src/pybind/mgr/telegraf/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/telegraf/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/telegraf/basesocket.py b/src/pybind/mgr/telegraf/basesocket.py new file mode 100644 index 00000000..43599466 --- /dev/null +++ b/src/pybind/mgr/telegraf/basesocket.py @@ -0,0 +1,45 @@ +import socket + + +class BaseSocket(object): + schemes = { + 'unixgram': (socket.AF_UNIX, socket.SOCK_DGRAM), + 'unix': (socket.AF_UNIX, socket.SOCK_STREAM), + 'tcp': (socket.AF_INET, socket.SOCK_STREAM), + 'tcp6': (socket.AF_INET6, socket.SOCK_STREAM), + 'udp': (socket.AF_INET, socket.SOCK_DGRAM), + 'udp6': (socket.AF_INET6, socket.SOCK_DGRAM), + } + + def __init__(self, url): + self.url = url + + try: + socket_family, socket_type = self.schemes[self.url.scheme] + except KeyError: + raise RuntimeError('Unsupported socket type: %s', self.url.scheme) + + self.sock = socket.socket(family=socket_family, type=socket_type) + if self.sock.family == socket.AF_UNIX: + self.address = self.url.path + else: + self.address = (self.url.hostname, self.url.port) + + def connect(self): + return self.sock.connect(self.address) + + def close(self): + self.sock.close() + + def send(self, data, flags=0): + return self.sock.send(data.encode('utf-8') + b'\n', flags) + + def __del__(self): + self.sock.close() + + def __enter__(self): + self.connect() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() diff --git a/src/pybind/mgr/telegraf/module.py b/src/pybind/mgr/telegraf/module.py new file mode 100644 index 00000000..8264fdf3 --- /dev/null +++ b/src/pybind/mgr/telegraf/module.py @@ -0,0 +1,301 @@ +import errno +import json +import itertools +import six +import socket +import time +from threading import Event + +from telegraf.basesocket import BaseSocket +from telegraf.protocol import Line +from mgr_module import MgrModule, PG_STATES + +try: + from urllib.parse import urlparse +except ImportError: + from urlparse import urlparse + + +class Module(MgrModule): + COMMANDS = [ + { + "cmd": "telegraf config-set name=key,type=CephString " + "name=value,type=CephString", + "desc": "Set a configuration value", + "perm": "rw" + }, + { + "cmd": "telegraf config-show", + "desc": "Show current configuration", + "perm": "r" + }, + { + "cmd": "telegraf send", + "desc": "Force sending data to Telegraf", + "perm": "rw" + }, + ] + + MODULE_OPTIONS = [ + { + 'name': 'address', + 'default': 'unixgram:///tmp/telegraf.sock', + }, + { + 'name': 'interval', + 'type': 'secs', + 'default': 15 + } + ] + + ceph_health_mapping = {'HEALTH_OK': 0, 'HEALTH_WARN': 1, 'HEALTH_ERR': 2} + + @property + def config_keys(self): + return dict((o['name'], o.get('default', None)) for o in self.MODULE_OPTIONS) + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.event = Event() + self.run = True + self.fsid = None + self.config = dict() + + def get_fsid(self): + if not self.fsid: + self.fsid = self.get('mon_map')['fsid'] + + return self.fsid + + def get_pool_stats(self): + df = self.get('df') + + df_types = [ + 'bytes_used', + 'kb_used', + 'dirty', + 'rd', + 'rd_bytes', + 'stored_raw', + 'wr', + 'wr_bytes', + 'objects', + 'max_avail', + 'quota_objects', + 'quota_bytes' + ] + + for df_type in df_types: + for pool in df['pools']: + yield { + 'measurement': 'ceph_pool_stats', + 'tags': { + 'pool_name': pool['name'], + 'pool_id': pool['id'], + 'type_instance': df_type, + 'fsid': self.get_fsid() + }, + 'value': pool['stats'][df_type], + } + + def get_daemon_stats(self): + for daemon, counters in six.iteritems(self.get_all_perf_counters()): + svc_type, svc_id = daemon.split('.', 1) + metadata = self.get_metadata(svc_type, svc_id) + if not metadata: + continue + + for path, counter_info in counters.items(): + if counter_info['type'] & self.PERFCOUNTER_HISTOGRAM: + continue + + yield { + 'measurement': 'ceph_daemon_stats', + 'tags': { + 'ceph_daemon': daemon, + 'type_instance': path, + 'host': metadata['hostname'], + 'fsid': self.get_fsid() + }, + 'value': counter_info['value'] + } + + def get_pg_stats(self): + stats = dict() + + pg_status = self.get('pg_status') + for key in ['bytes_total', 'data_bytes', 'bytes_used', 'bytes_avail', + 'num_pgs', 'num_objects', 'num_pools']: + stats[key] = pg_status[key] + + for state in PG_STATES: + stats['num_pgs_{0}'.format(state)] = 0 + + stats['num_pgs'] = pg_status['num_pgs'] + for state in pg_status['pgs_by_state']: + states = state['state_name'].split('+') + for s in PG_STATES: + key = 'num_pgs_{0}'.format(s) + if s in states: + stats[key] += state['count'] + + return stats + + def get_cluster_stats(self): + stats = dict() + + health = json.loads(self.get('health')['json']) + stats['health'] = self.ceph_health_mapping.get(health['status']) + + mon_status = json.loads(self.get('mon_status')['json']) + stats['num_mon'] = len(mon_status['monmap']['mons']) + + stats['mon_election_epoch'] = mon_status['election_epoch'] + stats['mon_outside_quorum'] = len(mon_status['outside_quorum']) + stats['mon_quorum'] = len(mon_status['quorum']) + + osd_map = self.get('osd_map') + stats['num_osd'] = len(osd_map['osds']) + stats['num_pg_temp'] = len(osd_map['pg_temp']) + stats['osd_epoch'] = osd_map['epoch'] + + mgr_map = self.get('mgr_map') + stats['mgr_available'] = int(mgr_map['available']) + stats['num_mgr_standby'] = len(mgr_map['standbys']) + stats['mgr_epoch'] = mgr_map['epoch'] + + num_up = 0 + num_in = 0 + for osd in osd_map['osds']: + if osd['up'] == 1: + num_up += 1 + + if osd['in'] == 1: + num_in += 1 + + stats['num_osd_up'] = num_up + stats['num_osd_in'] = num_in + + fs_map = self.get('fs_map') + stats['num_mds_standby'] = len(fs_map['standbys']) + stats['num_fs'] = len(fs_map['filesystems']) + stats['mds_epoch'] = fs_map['epoch'] + + num_mds_up = 0 + for fs in fs_map['filesystems']: + num_mds_up += len(fs['mdsmap']['up']) + + stats['num_mds_up'] = num_mds_up + stats['num_mds'] = num_mds_up + stats['num_mds_standby'] + + stats.update(self.get_pg_stats()) + + for key, value in stats.items(): + yield { + 'measurement': 'ceph_cluster_stats', + 'tags': { + 'type_instance': key, + 'fsid': self.get_fsid() + }, + 'value': int(value) + } + + def set_config_option(self, option, value): + if option not in self.config_keys.keys(): + raise RuntimeError('{0} is a unknown configuration ' + 'option'.format(option)) + + if option in ['interval']: + try: + value = int(value) + except (ValueError, TypeError): + raise RuntimeError('invalid {0} configured. Please specify ' + 'a valid integer'.format(option)) + + if option == 'interval' and value < 5: + raise RuntimeError('interval should be set to at least 5 seconds') + + self.config[option] = value + + def init_module_config(self): + self.config['address'] = \ + self.get_module_option("address", default=self.config_keys['address']) + self.config['interval'] = \ + int(self.get_module_option("interval", + default=self.config_keys['interval'])) + + def now(self): + return int(round(time.time() * 1000000000)) + + def gather_measurements(self): + return itertools.chain( + self.get_pool_stats(), + self.get_daemon_stats(), + self.get_cluster_stats() + ) + + def send_to_telegraf(self): + url = urlparse(self.config['address']) + + sock = BaseSocket(url) + self.log.debug('Sending data to Telegraf at %s', sock.address) + now = self.now() + try: + with sock as s: + for measurement in self.gather_measurements(): + self.log.debug(measurement) + line = Line(measurement['measurement'], + measurement['value'], + measurement['tags'], now) + self.log.debug(line.to_line_protocol()) + s.send(line.to_line_protocol()) + except (socket.error, RuntimeError, IOError, OSError): + self.log.exception('Failed to send statistics to Telegraf:') + except FileNotFoundError: + self.log.exception('Failed to open Telegraf at: %s', url.geturl()) + + def shutdown(self): + self.log.info('Stopping Telegraf module') + self.run = False + self.event.set() + + def handle_command(self, inbuf, cmd): + if cmd['prefix'] == 'telegraf config-show': + return 0, json.dumps(self.config), '' + elif cmd['prefix'] == 'telegraf config-set': + key = cmd['key'] + value = cmd['value'] + if not value: + return -errno.EINVAL, '', 'Value should not be empty or None' + + self.log.debug('Setting configuration option %s to %s', key, value) + self.set_config_option(key, value) + self.set_module_option(key, value) + return 0, 'Configuration option {0} updated'.format(key), '' + elif cmd['prefix'] == 'telegraf send': + self.send_to_telegraf() + return 0, 'Sending data to Telegraf', '' + + return (-errno.EINVAL, '', + "Command not found '{0}'".format(cmd['prefix'])) + + def self_test(self): + measurements = list(self.gather_measurements()) + if len(measurements) == 0: + raise RuntimeError('No measurements found') + + def serve(self): + self.log.info('Starting Telegraf module') + self.init_module_config() + self.run = True + + self.log.debug('Waiting 10 seconds before starting') + self.event.wait(10) + + while self.run: + start = self.now() + self.send_to_telegraf() + runtime = (self.now() - start) / 1000000 + self.log.debug('Sending data to Telegraf took %d ms', runtime) + self.log.debug("Sleeping for %d seconds", self.config['interval']) + self.event.wait(self.config['interval']) diff --git a/src/pybind/mgr/telegraf/protocol.py b/src/pybind/mgr/telegraf/protocol.py new file mode 100644 index 00000000..d243e0c1 --- /dev/null +++ b/src/pybind/mgr/telegraf/protocol.py @@ -0,0 +1,44 @@ +from telegraf.utils import format_string, format_value + + +class Line(object): + def __init__(self, measurement, values, tags=None, timestamp=None): + self.measurement = measurement + self.values = values + self.tags = tags + self.timestamp = timestamp + + def get_output_measurement(self): + return format_string(self.measurement) + + def get_output_values(self): + if not isinstance(self.values, dict): + metric_values = {'value': self.values} + else: + metric_values = self.values + + sorted_values = sorted(metric_values.items()) + sorted_values = [(k, v) for k, v in sorted_values if v is not None] + + return u','.join(u'{0}={1}'.format(format_string(k), format_value(v)) for k, v in sorted_values) + + def get_output_tags(self): + if not self.tags: + self.tags = dict() + + sorted_tags = sorted(self.tags.items()) + + return u','.join(u'{0}={1}'.format(format_string(k), format_string(v)) for k, v in sorted_tags) + + def get_output_timestamp(self): + return ' {0}'.format(self.timestamp) if self.timestamp else '' + + def to_line_protocol(self): + tags = self.get_output_tags() + + return u'{0}{1} {2}{3}'.format( + self.get_output_measurement(), + "," + tags if tags else '', + self.get_output_values(), + self.get_output_timestamp() + ) diff --git a/src/pybind/mgr/telegraf/utils.py b/src/pybind/mgr/telegraf/utils.py new file mode 100644 index 00000000..4c7fd1ca --- /dev/null +++ b/src/pybind/mgr/telegraf/utils.py @@ -0,0 +1,20 @@ +def format_string(key): + if isinstance(key, str): + key = key.replace(',', r'\,') + key = key.replace(' ', r'\ ') + key = key.replace('=', r'\=') + return key + + +def format_value(value): + if isinstance(value, str): + value = value.replace('"', '\"') + value = u'"{0}"'.format(value) + elif isinstance(value, bool): + value = str(value) + elif isinstance(value, int): + value = "{0}i".format(value) + elif isinstance(value, float): + value = str(value) + return value + diff --git a/src/pybind/mgr/telemetry/__init__.py b/src/pybind/mgr/telemetry/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/telemetry/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/telemetry/module.py b/src/pybind/mgr/telemetry/module.py new file mode 100644 index 00000000..c21e2340 --- /dev/null +++ b/src/pybind/mgr/telemetry/module.py @@ -0,0 +1,854 @@ +""" +Telemetry module for ceph-mgr + +Collect statistics from Ceph cluster and send this back to the Ceph project +when user has opted-in +""" +import errno +import hashlib +import json +import rbd +import re +import requests +import uuid +import time +from datetime import datetime, timedelta +from threading import Event +from collections import defaultdict + +from mgr_module import MgrModule + + +ALL_CHANNELS = ['basic', 'ident', 'crash', 'device'] + +LICENSE='sharing-1-0' +LICENSE_NAME='Community Data License Agreement - Sharing - Version 1.0' +LICENSE_URL='https://cdla.io/sharing-1-0/' + +# If the telemetry revision has changed since this point, re-require +# an opt-in. This should happen each time we add new information to +# the telemetry report. +LAST_REVISION_RE_OPT_IN = 2 + +# Latest revision of the telemetry report. Bump this each time we make +# *any* change. +REVISION = 3 + +# History of revisions +# -------------------- +# +# Version 1: +# Mimic and/or nautilus are lumped together here, since +# we didn't track revisions yet. +# +# Version 2: +# - added revision tracking, nagging, etc. +# - added config option changes +# - added channels +# - added explicit license acknowledgement to the opt-in process +# +# Version 3: +# - added device health metrics (i.e., SMART data, minus serial number) +# - remove crush_rule +# - added CephFS metadata (how many MDSs, fs features, how many data pools, +# how much metadata is cached, rfiles, rbytes, rsnapshots) +# - added more pool metadata (rep vs ec, cache tiering mode, ec profile) +# - added host count, and counts for hosts with each of (mon, osd, mds, mgr) +# - whether an OSD cluster network is in use +# - rbd pool and image count, and rbd mirror mode (pool-level) +# - rgw daemons, zones, zonegroups; which rgw frontends +# - crush map stats + +class Module(MgrModule): + config = dict() + + metadata_keys = [ + "arch", + "ceph_version", + "os", + "cpu", + "kernel_description", + "kernel_version", + "distro_description", + "distro" + ] + + MODULE_OPTIONS = [ + { + 'name': 'url', + 'type': 'str', + 'default': 'https://telemetry.ceph.com/report' + }, + { + 'name': 'device_url', + 'type': 'str', + 'default': 'https://telemetry.ceph.com/device' + }, + { + 'name': 'enabled', + 'type': 'bool', + 'default': False + }, + { + 'name': 'last_opt_revision', + 'type': 'int', + 'default': 1, + }, + { + 'name': 'leaderboard', + 'type': 'bool', + 'default': False + }, + { + 'name': 'description', + 'type': 'str', + 'default': None + }, + { + 'name': 'contact', + 'type': 'str', + 'default': None + }, + { + 'name': 'organization', + 'type': 'str', + 'default': None + }, + { + 'name': 'proxy', + 'type': 'str', + 'default': None + }, + { + 'name': 'interval', + 'type': 'int', + 'default': 24, + 'min': 8 + }, + { + 'name': 'channel_basic', + 'type': 'bool', + 'default': True, + 'desc': 'Share basic cluster information (size, version)', + }, + { + 'name': 'channel_ident', + 'type': 'bool', + 'default': False, + 'description': 'Share a user-provided description and/or contact email for the cluster', + }, + { + 'name': 'channel_crash', + 'type': 'bool', + 'default': True, + 'description': 'Share metadata about Ceph daemon crashes (version, stack straces, etc)', + }, + { + 'name': 'channel_device', + 'type': 'bool', + 'default': True, + 'description': 'Share device health metrics (e.g., SMART data, minus potentially identifying info like serial numbers)', + }, + ] + + COMMANDS = [ + { + "cmd": "telemetry status", + "desc": "Show current configuration", + "perm": "r" + }, + { + "cmd": "telemetry send " + "name=endpoint,type=CephChoices,strings=ceph|device,n=N,req=false " + "name=license,type=CephString,req=false", + "desc": "Force sending data to Ceph telemetry", + "perm": "rw" + }, + { + "cmd": "telemetry show " + "name=channels,type=CephString,n=N,req=False", + "desc": "Show last report or report to be sent", + "perm": "r" + }, + { + "cmd": "telemetry show-device", + "desc": "Show last device report or device report to be sent", + "perm": "r" + }, + { + "cmd": "telemetry on name=license,type=CephString,req=false", + "desc": "Enable telemetry reports from this cluster", + "perm": "rw", + }, + { + "cmd": "telemetry off", + "desc": "Disable telemetry reports from this cluster", + "perm": "rw", + }, + ] + + @property + def config_keys(self): + return dict((o['name'], o.get('default', None)) for o in self.MODULE_OPTIONS) + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.event = Event() + self.run = False + self.last_upload = None + self.last_report = dict() + self.report_id = None + self.salt = None + + def config_notify(self): + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], + self.get_module_option(opt['name'])) + self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name'])) + # wake up serve() thread + self.event.set() + + @staticmethod + def parse_timestamp(timestamp): + return datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S.%f') + + def load(self): + self.last_upload = self.get_store('last_upload', None) + if self.last_upload is not None: + self.last_upload = int(self.last_upload) + + self.report_id = self.get_store('report_id', None) + if self.report_id is None: + self.report_id = str(uuid.uuid4()) + self.set_store('report_id', self.report_id) + + self.salt = self.get_store('salt', None) + if not self.salt: + self.salt = str(uuid.uuid4()) + self.set_store('salt', self.salt) + + def gather_osd_metadata(self, osd_map): + keys = ["osd_objectstore", "rotational"] + keys += self.metadata_keys + + metadata = dict() + for key in keys: + metadata[key] = defaultdict(int) + + for osd in osd_map['osds']: + res = self.get_metadata('osd', str(osd['osd'])).items() + if res is None: + self.log.debug('Could not get metadata for osd.%s' % str(osd['osd'])) + continue + for k, v in res: + if k not in keys: + continue + + metadata[k][v] += 1 + + return metadata + + def gather_mon_metadata(self, mon_map): + keys = list() + keys += self.metadata_keys + + metadata = dict() + for key in keys: + metadata[key] = defaultdict(int) + + for mon in mon_map['mons']: + res = self.get_metadata('mon', mon['name']).items() + if res is None: + self.log.debug('Could not get metadata for mon.%s' % (mon['name'])) + continue + for k, v in res: + if k not in keys: + continue + + metadata[k][v] += 1 + + return metadata + + def gather_crush_info(self): + osdmap = self.get_osdmap() + crush_raw = osdmap.get_crush() + crush = crush_raw.dump() + + def inc(d, k): + if k in d: + d[k] += 1 + else: + d[k] = 1 + + device_classes = {} + for dev in crush['devices']: + inc(device_classes, dev.get('class', '')) + + bucket_algs = {} + bucket_types = {} + bucket_sizes = {} + for bucket in crush['buckets']: + if '~' in bucket['name']: # ignore shadow buckets + continue + inc(bucket_algs, bucket['alg']) + inc(bucket_types, bucket['type_id']) + inc(bucket_sizes, len(bucket['items'])) + + return { + 'num_devices': len(crush['devices']), + 'num_types': len(crush['types']), + 'num_buckets': len(crush['buckets']), + 'num_rules': len(crush['rules']), + 'device_classes': list(device_classes.values()), + 'tunables': crush['tunables'], + 'compat_weight_set': '-1' in crush['choose_args'], + 'num_weight_sets': len(crush['choose_args']), + 'bucket_algs': bucket_algs, + 'bucket_sizes': bucket_sizes, + 'bucket_types': bucket_types, + } + + def gather_configs(self): + # cluster config options + cluster = set() + r, outb, outs = self.mon_command({ + 'prefix': 'config dump', + 'format': 'json' + }); + if r != 0: + return {} + try: + dump = json.loads(outb) + except json.decoder.JSONDecodeError: + return {} + for opt in dump: + name = opt.get('name') + if name: + cluster.add(name) + # daemon-reported options (which may include ceph.conf) + active = set() + ls = self.get("modified_config_options"); + for opt in ls.get('options', {}): + active.add(opt) + return { + 'cluster_changed': sorted(list(cluster)), + 'active_changed': sorted(list(active)), + } + + def gather_crashinfo(self): + crashlist = list() + errno, crashids, err = self.remote('crash', 'ls') + if errno: + return '' + for crashid in crashids.split(): + cmd = {'id': crashid} + errno, crashinfo, err = self.remote('crash', 'do_info', cmd, '') + if errno: + continue + c = json.loads(crashinfo) + del c['utsname_hostname'] + # entity_name might have more than one '.', beware + (etype, eid) = c.get('entity_name', '').split('.', 1) + m = hashlib.sha1() + m.update(self.salt.encode('utf-8')) + m.update(eid.encode('utf-8')) + m.update(self.salt.encode('utf-8')) + c['entity_name'] = etype + '.' + m.hexdigest() + crashlist.append(c) + return crashlist + + def get_active_channels(self): + r = [] + if self.channel_basic: + r.append('basic') + if self.channel_crash: + r.append('crash') + if self.channel_device: + r.append('device') + return r + + def gather_device_report(self): + try: + time_format = self.remote('devicehealth', 'get_time_format') + except: + return None + cutoff = datetime.utcnow() - timedelta(hours=self.interval * 2) + min_sample = cutoff.strftime(time_format) + + devices = self.get('devices')['devices'] + + res = {} # anon-host-id -> anon-devid -> { timestamp -> record } + for d in devices: + devid = d['devid'] + try: + # this is a map of stamp -> {device info} + m = self.remote('devicehealth', 'get_recent_device_metrics', + devid, min_sample) + except: + continue + + # anonymize host id + try: + host = d['location'][0]['host'] + except: + continue + anon_host = self.get_store('host-id/%s' % host) + if not anon_host: + anon_host = str(uuid.uuid1()) + self.set_store('host-id/%s' % host, anon_host) + serial = None + for dev, rep in m.items(): + rep['host_id'] = anon_host + if serial is None and 'serial_number' in rep: + serial = rep['serial_number'] + + # anonymize device id + anon_devid = self.get_store('devid-id/%s' % devid) + if not anon_devid: + # ideally devid is 'vendor_model_serial', + # but can also be 'model_serial', 'serial' + if '_' in devid: + anon_devid = devid[:devid.rfind('_')] + '_' + str(uuid.uuid1()) + else: + anon_devid = str(uuid.uuid1()) + self.set_store('devid-id/%s' % devid, anon_devid) + self.log.info('devid %s / %s, host %s / %s' % (devid, anon_devid, + host, anon_host)) + + # anonymize the smartctl report itself + if serial: + m_str = json.dumps(m) + m = json.loads(m_str.replace(serial, 'deleted')) + + if anon_host not in res: + res[anon_host] = {} + res[anon_host][anon_devid] = m + return res + + def get_latest(self, daemon_type, daemon_name, stat): + data = self.get_counter(daemon_type, daemon_name, stat)[stat] + #self.log.error("get_latest {0} data={1}".format(stat, data)) + if data: + return data[-1][1] + else: + return 0 + + def compile_report(self, channels=[]): + if not channels: + channels = self.get_active_channels() + report = { + 'leaderboard': False, + 'report_version': 1, + 'report_timestamp': datetime.utcnow().isoformat(), + 'report_id': self.report_id, + 'channels': channels, + 'channels_available': ALL_CHANNELS, + 'license': LICENSE, + } + + if 'ident' in channels: + if self.leaderboard: + report['leaderboard'] = True + for option in ['description', 'contact', 'organization']: + report[option] = getattr(self, option) + + if 'basic' in channels: + mon_map = self.get('mon_map') + osd_map = self.get('osd_map') + service_map = self.get('service_map') + fs_map = self.get('fs_map') + df = self.get('df') + + report['created'] = self.parse_timestamp(mon_map['created']).isoformat() + + # mons + v1_mons = 0 + v2_mons = 0 + ipv4_mons = 0 + ipv6_mons = 0 + for mon in mon_map['mons']: + for a in mon['public_addrs']['addrvec']: + if a['type'] == 'v2': + v2_mons += 1 + elif a['type'] == 'v1': + v1_mons += 1 + if a['addr'].startswith('['): + ipv6_mons += 1 + else: + ipv4_mons += 1 + report['mon'] = { + 'count': len(mon_map['mons']), + 'features': mon_map['features'], + 'min_mon_release': mon_map['min_mon_release'], + 'v1_addr_mons': v1_mons, + 'v2_addr_mons': v2_mons, + 'ipv4_addr_mons': ipv4_mons, + 'ipv6_addr_mons': ipv6_mons, + } + + report['config'] = self.gather_configs() + + # pools + report['rbd'] = { + 'num_pools': 0, + 'num_images_by_pool': [], + 'mirroring_by_pool': [], + } + num_pg = 0 + report['pools'] = list() + for pool in osd_map['pools']: + num_pg += pool['pg_num'] + ec_profile = {} + if pool['erasure_code_profile']: + orig = osd_map['erasure_code_profiles'].get( + pool['erasure_code_profile'], {}) + ec_profile = { + k: orig[k] for k in orig.keys() + if k in ['k', 'm', 'plugin', 'technique', + 'crush-failure-domain', 'l'] + } + report['pools'].append( + { + 'pool': pool['pool'], + 'type': pool['type'], + 'pg_num': pool['pg_num'], + 'pgp_num': pool['pg_placement_num'], + 'size': pool['size'], + 'min_size': pool['min_size'], + 'pg_autoscale_mode': pool['pg_autoscale_mode'], + 'target_max_bytes': pool['target_max_bytes'], + 'target_max_objects': pool['target_max_objects'], + 'type': ['', 'replicated', '', 'erasure'][pool['type']], + 'erasure_code_profile': ec_profile, + 'cache_mode': pool['cache_mode'], + } + ) + if 'rbd' in pool['application_metadata']: + report['rbd']['num_pools'] += 1 + ioctx = self.rados.open_ioctx(pool['pool_name']) + report['rbd']['num_images_by_pool'].append( + sum(1 for _ in rbd.RBD().list2(ioctx))) + report['rbd']['mirroring_by_pool'].append( + rbd.RBD().mirror_mode_get(ioctx) != rbd.RBD_MIRROR_MODE_DISABLED) + + # osds + cluster_network = False + for osd in osd_map['osds']: + if osd['up'] and not cluster_network: + front_ip = osd['public_addrs']['addrvec'][0]['addr'].split(':')[0] + back_ip = osd['cluster_addrs']['addrvec'][0]['addr'].split(':')[0] + if front_ip != back_ip: + cluster_network = True + report['osd'] = { + 'count': len(osd_map['osds']), + 'require_osd_release': osd_map['require_osd_release'], + 'require_min_compat_client': osd_map['require_min_compat_client'], + 'cluster_network': cluster_network, + } + + # crush + report['crush'] = self.gather_crush_info() + + # cephfs + report['fs'] = { + 'count': len(fs_map['filesystems']), + 'feature_flags': fs_map['feature_flags'], + 'num_standby_mds': len(fs_map['standbys']), + 'filesystems': [], + } + num_mds = len(fs_map['standbys']) + for fsm in fs_map['filesystems']: + fs = fsm['mdsmap'] + num_sessions = 0 + cached_ino = 0 + cached_dn = 0 + cached_cap = 0 + subtrees = 0 + rfiles = 0 + rbytes = 0 + rsnaps = 0 + for gid, mds in fs['info'].items(): + num_sessions += self.get_latest('mds', mds['name'], + 'mds_sessions.session_count') + cached_ino += self.get_latest('mds', mds['name'], + 'mds_mem.ino') + cached_dn += self.get_latest('mds', mds['name'], + 'mds_mem.dn') + cached_cap += self.get_latest('mds', mds['name'], + 'mds_mem.cap') + subtrees += self.get_latest('mds', mds['name'], + 'mds.subtrees') + if mds['rank'] == 0: + rfiles = self.get_latest('mds', mds['name'], + 'mds.root_rfiles') + rbytes = self.get_latest('mds', mds['name'], + 'mds.root_rbytes') + rsnaps = self.get_latest('mds', mds['name'], + 'mds.root_rsnaps') + report['fs']['filesystems'].append({ + 'max_mds': fs['max_mds'], + 'ever_allowed_features': fs['ever_allowed_features'], + 'explicitly_allowed_features': fs['explicitly_allowed_features'], + 'num_in': len(fs['in']), + 'num_up': len(fs['up']), + 'num_standby_replay': len( + [mds for gid, mds in fs['info'].items() + if mds['state'] == 'up:standby-replay']), + 'num_mds': len(fs['info']), + 'num_sessions': num_sessions, + 'cached_inos': cached_ino, + 'cached_dns': cached_dn, + 'cached_caps': cached_cap, + 'cached_subtrees': subtrees, + 'balancer_enabled': len(fs['balancer']) > 0, + 'num_data_pools': len(fs['data_pools']), + 'standby_count_wanted': fs['standby_count_wanted'], + 'approx_ctime': fs['created'][0:7], + 'files': rfiles, + 'bytes': rbytes, + 'snaps': rsnaps, + }) + num_mds += len(fs['info']) + report['fs']['total_num_mds'] = num_mds + + # daemons + report['metadata'] = dict() + report['metadata']['osd'] = self.gather_osd_metadata(osd_map) + report['metadata']['mon'] = self.gather_mon_metadata(mon_map) + + # host counts + servers = self.list_servers() + self.log.debug('servers %s' % servers) + report['hosts'] = { + 'num': len([h for h in servers if h['hostname']]), + } + for t in ['mon', 'mds', 'osd', 'mgr']: + report['hosts']['num_with_' + t] = len( + [h for h in servers + if len([s for s in h['services'] if s['type'] == t])] + ) + + report['usage'] = { + 'pools': len(df['pools']), + 'pg_num': num_pg, + 'total_used_bytes': df['stats']['total_used_bytes'], + 'total_bytes': df['stats']['total_bytes'], + 'total_avail_bytes': df['stats']['total_avail_bytes'] + } + + report['services'] = defaultdict(int) + for key, value in service_map['services'].items(): + report['services'][key] += 1 + if key == 'rgw': + report['rgw'] = { + 'count': 0, + } + zones = set() + realms = set() + zonegroups = set() + frontends = set() + d = value.get('daemons', dict()) + + for k,v in d.items(): + if k == 'summary' and v: + report['rgw'][k] = v + elif isinstance(v, dict) and 'metadata' in v: + report['rgw']['count'] += 1 + zones.add(v['metadata']['zone_id']) + zonegroups.add(v['metadata']['zonegroup_id']) + frontends.add(v['metadata']['frontend_type#0']) + + # we could actually iterate over all the keys of + # the dict and check for how many frontends there + # are, but it is unlikely that one would be running + # more than 2 supported ones + f2 = v['metadata'].get('frontend_type#1', None) + if f2: + frontends.add(f2) + + report['rgw']['zones'] = len(zones) + report['rgw']['zonegroups'] = len(zonegroups) + report['rgw']['frontends'] = list(frontends) # sets aren't json-serializable + + try: + report['balancer'] = self.remote('balancer', 'gather_telemetry') + except ImportError: + report['balancer'] = { + 'active': False + } + + if 'crash' in channels: + report['crashes'] = self.gather_crashinfo() + + # NOTE: We do not include the 'device' channel in this report; it is + # sent to a different endpoint. + + return report + + def _try_post(self, what, url, report): + self.log.info('Sending %s to: %s' % (what, url)) + proxies = dict() + if self.proxy: + self.log.info('Send using HTTP(S) proxy: %s', self.proxy) + proxies['http'] = self.proxy + proxies['https'] = self.proxy + try: + resp = requests.put(url=url, json=report, proxies=proxies) + resp.raise_for_status() + except Exception as e: + fail_reason = 'Failed to send %s to %s: %s' % (what, url, str(e)) + self.log.error(fail_reason) + return fail_reason + return None + + def send(self, report, endpoint=None): + if not endpoint: + endpoint = ['ceph', 'device'] + failed = [] + success = [] + self.log.debug('Send endpoints %s' % endpoint) + for e in endpoint: + if e == 'ceph': + fail_reason = self._try_post('ceph report', self.url, report) + if fail_reason: + failed.append(fail_reason) + else: + now = int(time.time()) + self.last_upload = now + self.set_store('last_upload', str(now)) + success.append('Ceph report sent to {0}'.format(self.url)) + self.log.info('Sent report to {0}'.format(self.url)) + elif e == 'device': + if 'device' in self.get_active_channels(): + devices = self.gather_device_report() + num_devs = 0 + num_hosts = 0 + for host, ls in devices.items(): + self.log.debug('host %s devices %s' % (host, ls)) + if not len(ls): + continue + fail_reason = self._try_post('devices', self.device_url, + ls) + if fail_reason: + failed.append(fail_reason) + else: + num_devs += len(ls) + num_hosts += 1 + if num_devs: + success.append('Reported %d devices across %d hosts' % ( + num_devs, len(devices))) + if failed: + return 1, '', '\n'.join(success + failed) + return 0, '', '\n'.join(success) + + def handle_command(self, inbuf, command): + if command['prefix'] == 'telemetry status': + r = {} + for opt in self.MODULE_OPTIONS: + r[opt['name']] = getattr(self, opt['name']) + r['last_upload'] = time.ctime(self.last_upload) if self.last_upload else self.last_upload + return 0, json.dumps(r, indent=4), '' + elif command['prefix'] == 'telemetry on': + if command.get('license') != LICENSE: + return -errno.EPERM, '', "Telemetry data is licensed under the " + LICENSE_NAME + " (" + LICENSE_URL + ").\nTo enable, add '--license " + LICENSE + "' to the 'ceph telemetry on' command." + self.set_module_option('enabled', True) + self.set_module_option('last_opt_revision', REVISION) + return 0, '', '' + elif command['prefix'] == 'telemetry off': + self.set_module_option('enabled', False) + self.set_module_option('last_opt_revision', 1) + return 0, '', '' + elif command['prefix'] == 'telemetry send': + if self.last_opt_revision < LAST_REVISION_RE_OPT_IN and command.get('license') != LICENSE: + self.log.debug('A telemetry send attempt while opted-out. Asking for license agreement') + return -errno.EPERM, '', "Telemetry data is licensed under the " + LICENSE_NAME + " (" + LICENSE_URL + ").\nTo manually send telemetry data, add '--license " + LICENSE + "' to the 'ceph telemetry send' command.\nPlease consider enabling the telemetry module with 'ceph telemetry on'." + self.last_report = self.compile_report() + return self.send(self.last_report, command.get('endpoint')) + + elif command['prefix'] == 'telemetry show': + report = self.compile_report( + channels=command.get('channels', None) + ) + report = json.dumps(report, indent=4) + if self.channel_device: + report += '\n \nDevice report is generated separately. To see it run \'ceph telemetry show-device\'.' + return 0, report, '' + elif command['prefix'] == 'telemetry show-device': + return 0, json.dumps(self.gather_device_report(), indent=4, sort_keys=True), '' + else: + return (-errno.EINVAL, '', + "Command not found '{0}'".format(command['prefix'])) + + def self_test(self): + report = self.compile_report() + if len(report) == 0: + raise RuntimeError('Report is empty') + + if 'report_id' not in report: + raise RuntimeError('report_id not found in report') + + def shutdown(self): + self.run = False + self.event.set() + + def refresh_health_checks(self): + health_checks = {} + if self.enabled and self.last_opt_revision < LAST_REVISION_RE_OPT_IN: + health_checks['TELEMETRY_CHANGED'] = { + 'severity': 'warning', + 'summary': 'Telemetry requires re-opt-in', + 'detail': [ + 'telemetry report includes new information; must re-opt-in (or out)' + ] + } + self.set_health_checks(health_checks) + + def serve(self): + self.load() + self.config_notify() + self.run = True + + self.log.debug('Waiting for mgr to warm up') + self.event.wait(10) + + while self.run: + self.event.clear() + + self.refresh_health_checks() + + if self.last_opt_revision < LAST_REVISION_RE_OPT_IN: + self.log.debug('Not sending report until user re-opts-in') + self.event.wait(1800) + continue + if not self.enabled: + self.log.debug('Not sending report until configured to do so') + self.event.wait(1800) + continue + + now = int(time.time()) + if not self.last_upload or (now - self.last_upload) > \ + self.interval * 3600: + self.log.info('Compiling and sending report to %s', + self.url) + + try: + self.last_report = self.compile_report() + except: + self.log.exception('Exception while compiling report:') + + self.send(self.last_report) + else: + self.log.debug('Interval for sending new report has not expired') + + sleep = 3600 + self.log.debug('Sleeping for %d seconds', sleep) + self.event.wait(sleep) + + def self_test(self): + self.compile_report() + return True + + @staticmethod + def can_run(): + return True, '' diff --git a/src/pybind/mgr/test_orchestrator/__init__.py b/src/pybind/mgr/test_orchestrator/__init__.py new file mode 100644 index 00000000..2c4d3097 --- /dev/null +++ b/src/pybind/mgr/test_orchestrator/__init__.py @@ -0,0 +1 @@ +from .module import TestOrchestrator diff --git a/src/pybind/mgr/test_orchestrator/module.py b/src/pybind/mgr/test_orchestrator/module.py new file mode 100644 index 00000000..0112ba4c --- /dev/null +++ b/src/pybind/mgr/test_orchestrator/module.py @@ -0,0 +1,259 @@ +import json +import re +import os +import threading +import functools +import uuid +from subprocess import check_output, CalledProcessError + +from mgr_module import MgrModule, PersistentStoreDict + +import orchestrator + + + + +class TestCompletionMixin(object): + all_completions = [] # Hacky global + + def __init__(self, cb, message, *args, **kwargs): + super(TestCompletionMixin, self).__init__(*args, **kwargs) + self.cb = cb + self._result = None + self._complete = False + + self.message = message + self.id = str(uuid.uuid4()) + + TestCompletionMixin.all_completions.append(self) + + @property + def result(self): + return self._result + + @property + def is_complete(self): + return self._complete + + def execute(self): + self._result = self.cb() + self.executed = True + self._complete = True + + def __str__(self): + return "{}(result={} message={}, exception={})".format(self.__class__.__name__, self.result, + self.message, self.exception) + + +class TestReadCompletion(TestCompletionMixin, orchestrator.ReadCompletion): + def __init__(self, cb): + super(TestReadCompletion, self).__init__(cb, "") + + +class TestWriteCompletion(TestCompletionMixin, orchestrator.WriteCompletion): + def __init__(self, cb, message): + super(TestWriteCompletion, self).__init__(cb, message) + + @property + def is_persistent(self): + return (not self.is_errored) and self.executed + + @property + def is_effective(self): + return self._complete + + +def deferred_write(message): + def wrapper(f): + @functools.wraps(f) + def inner(*args, **kwargs): + return TestWriteCompletion(lambda: f(*args, **kwargs), + '{}, args={}, kwargs={}'.format(message, args, kwargs)) + return inner + return wrapper + + +def deferred_read(f): + """ + Decorator to make TestOrchestrator methods return + a completion object that executes themselves. + """ + + @functools.wraps(f) + def wrapper(*args, **kwargs): + return TestReadCompletion(lambda: f(*args, **kwargs)) + + return wrapper + + +class TestOrchestrator(MgrModule, orchestrator.Orchestrator): + """ + This is an orchestrator implementation used for internal testing. It's meant for + development environments and integration testing. + + It does not actually do anything. + + The implementation is similar to the Rook orchestrator, but simpler. + """ + + def wait(self, completions): + self.log.info("wait: completions={0}".format(completions)) + + # Our `wait` implementation is very simple because everything's + # just an API call. + for c in completions: + if not isinstance(c, TestReadCompletion) and \ + not isinstance(c, TestWriteCompletion): + raise TypeError( + "wait() requires list of completions, not {0}".format( + c.__class__ + )) + + if c.is_complete: + continue + + try: + c.execute() + except Exception as e: + self.log.exception("Completion {0} threw an exception:".format( + c.message + )) + c.exception = e + c._complete = True + + return all(c.is_complete for c in completions) + + def available(self): + return True, "" + + def __init__(self, *args, **kwargs): + super(TestOrchestrator, self).__init__(*args, **kwargs) + + self._initialized = threading.Event() + self._shutdown = threading.Event() + + def shutdown(self): + self._shutdown.set() + + def serve(self): + + self._initialized.set() + + while not self._shutdown.is_set(): + # XXX hack (or is it?) to kick all completions periodically, + # in case we had a caller that wait()'ed on them long enough + # to get persistence but not long enough to get completion + + self.wait(TestCompletionMixin.all_completions) + TestCompletionMixin.all_completions = [c for c in TestCompletionMixin.all_completions if + not c.is_complete] + + self._shutdown.wait(5) + + @deferred_read + def get_inventory(self, node_filter=None, refresh=False): + """ + There is no guarantee which devices are returned by get_inventory. + """ + if node_filter and node_filter.nodes is not None: + assert isinstance(node_filter.nodes, list) + try: + c_v_out = check_output(['ceph-volume', 'inventory', '--format', 'json']) + except OSError: + cmd = """ + . {tmpdir}/ceph-volume-virtualenv/bin/activate + ceph-volume inventory --format json + """ + try: + c_v_out = check_output(cmd.format(tmpdir=os.environ.get('TMPDIR', '/tmp')), shell=True) + except (OSError, CalledProcessError): + c_v_out = check_output(cmd.format(tmpdir='.'),shell=True) + + for out in c_v_out.splitlines(): + self.log.error(out) + devs = [] + for device in json.loads(out): + dev = orchestrator.InventoryDevice.from_ceph_volume_inventory(device) + devs.append(dev) + return [orchestrator.InventoryNode('localhost', devs)] + self.log.error('c-v failed: ' + str(c_v_out)) + raise Exception('c-v failed') + + @deferred_read + def describe_service(self, service_type=None, service_id=None, node_name=None, refresh=False): + """ + There is no guarantee which daemons are returned by describe_service, except that + it returns the mgr we're running in. + """ + if service_type: + assert service_type in ("mds", "osd", "mon", "rgw", "mgr"), service_type + " unsupported" + + out = map(str, check_output(['ps', 'aux']).splitlines()) + types = [service_type] if service_type else ("mds", "osd", "mon", "rgw", "mgr") + processes = [p for p in out if any([('ceph-' + t in p) for t in types])] + + result = [] + for p in processes: + sd = orchestrator.ServiceDescription() + sd.nodename = 'localhost' + sd.service_instance = re.search('ceph-[^ ]+', p).group() + result.append(sd) + + return result + + @deferred_write("Adding stateless service") + def add_stateless_service(self, service_type, spec): + pass + + @deferred_write("create_osds") + def create_osds(self, drive_group, all_hosts): + drive_group.validate(all_hosts) + + @deferred_write("remove_osds") + def remove_osds(self, osd_ids): + assert isinstance(osd_ids, list) + + @deferred_write("service_action") + def service_action(self, action, service_type, service_name=None, service_id=None): + pass + + @deferred_write("remove_stateless_service") + def remove_stateless_service(self, service_type, id_): + pass + + @deferred_write("update_stateless_service") + def update_stateless_service(self, service_type, spec): + pass + + @deferred_read + def get_hosts(self): + return [orchestrator.InventoryNode('localhost', [])] + + @deferred_write("add_host") + def add_host(self, host): + if host == 'raise_no_support': + raise orchestrator.OrchestratorValidationError("MON count must be either 1, 3 or 5") + if host == 'raise_bug': + raise ZeroDivisionError() + if host == 'raise_not_implemented': + raise NotImplementedError() + if host == 'raise_no_orchestrator': + raise orchestrator.NoOrchestrator() + if host == 'raise_import_error': + raise ImportError("test_orchestrator not enabled") + assert isinstance(host, str) + + @deferred_write("remove_host") + def remove_host(self, host): + assert isinstance(host, str) + + @deferred_write("update_mgrs") + def update_mgrs(self, num, hosts): + assert not hosts or len(hosts) == num + assert all([isinstance(h, str) for h in hosts]) + + @deferred_write("update_mons") + def update_mons(self, num, hosts): + assert not hosts or len(hosts) == num + assert all([isinstance(h[0], str) for h in hosts]) + assert all([isinstance(h[1], str) or h[1] is None for h in hosts]) diff --git a/src/pybind/mgr/volumes/__init__.py b/src/pybind/mgr/volumes/__init__.py new file mode 100644 index 00000000..4c5b97ce --- /dev/null +++ b/src/pybind/mgr/volumes/__init__.py @@ -0,0 +1,2 @@ + +from .module import Module diff --git a/src/pybind/mgr/volumes/fs/__init__.py b/src/pybind/mgr/volumes/fs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/pybind/mgr/volumes/fs/async_cloner.py b/src/pybind/mgr/volumes/fs/async_cloner.py new file mode 100644 index 00000000..0c5155e7 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/async_cloner.py @@ -0,0 +1,345 @@ +import os +import stat +import time +import errno +import logging +from contextlib import contextmanager + +import cephfs + +from .async_job import AsyncJobs +from .exception import IndexException, MetadataMgrException, OpSmException, VolumeException +from .fs_util import copy_file +from .operations.versions.op_sm import SubvolumeOpSm +from .operations.versions.subvolume_attrs import SubvolumeTypes, SubvolumeStates, SubvolumeActions +from .operations.resolver import resolve +from .operations.volume import open_volume, open_volume_lockless +from .operations.group import open_group +from .operations.subvolume import open_subvol +from .operations.clone_index import open_clone_index +from .operations.template import SubvolumeOpType + +log = logging.getLogger(__name__) + +# helper for fetching a clone entry for a given volume +def get_next_clone_entry(volume_client, volname, running_jobs): + log.debug("fetching clone entry for volume '{0}'".format(volname)) + + try: + with open_volume_lockless(volume_client, volname) as fs_handle: + try: + with open_clone_index(fs_handle, volume_client.volspec) as clone_index: + job = clone_index.get_oldest_clone_entry(running_jobs) + return 0, job + except IndexException as ve: + if ve.errno == -errno.ENOENT: + return 0, None + raise ve + except VolumeException as ve: + log.error("error fetching clone entry for volume '{0}' ({1})".format(volname, ve)) + return ve.errno, None + +@contextmanager +def open_at_volume(volume_client, volname, groupname, subvolname, op_type): + with open_volume(volume_client, volname) as fs_handle: + with open_group(fs_handle, volume_client.volspec, groupname) as group: + with open_subvol(volume_client.mgr, fs_handle, volume_client.volspec, group, subvolname, op_type) as subvolume: + yield subvolume + +@contextmanager +def open_at_group(volume_client, fs_handle, groupname, subvolname, op_type): + with open_group(fs_handle, volume_client.volspec, groupname) as group: + with open_subvol(volume_client.mgr, fs_handle, volume_client.volspec, group, subvolname, op_type) as subvolume: + yield subvolume + +@contextmanager +def open_at_group_unique(volume_client, fs_handle, s_groupname, s_subvolname, c_subvolume, c_groupname, c_subvolname, op_type): + # if a snapshot of a retained subvolume is being cloned to recreate the same subvolume, return + # the clone subvolume as the source subvolume + if s_groupname == c_groupname and s_subvolname == c_subvolname: + yield c_subvolume + else: + with open_at_group(volume_client, fs_handle, s_groupname, s_subvolname, op_type) as s_subvolume: + yield s_subvolume + + +@contextmanager +def open_clone_subvolume_pair(volume_client, fs_handle, volname, groupname, subvolname): + with open_at_group(volume_client, fs_handle, groupname, subvolname, SubvolumeOpType.CLONE_INTERNAL) as clone_subvolume: + s_volname, s_groupname, s_subvolname, s_snapname = get_clone_source(clone_subvolume) + if groupname == s_groupname and subvolname == s_subvolname: + # use the same subvolume to avoid metadata overwrites + yield (clone_subvolume, clone_subvolume, s_snapname) + else: + with open_at_group(volume_client, fs_handle, s_groupname, s_subvolname, SubvolumeOpType.CLONE_SOURCE) as source_subvolume: + yield (clone_subvolume, source_subvolume, s_snapname) + +def get_clone_state(volume_client, volname, groupname, subvolname): + with open_at_volume(volume_client, volname, groupname, subvolname, SubvolumeOpType.CLONE_INTERNAL) as subvolume: + return subvolume.state + +def set_clone_state(volume_client, volname, groupname, subvolname, state): + with open_at_volume(volume_client, volname, groupname, subvolname, SubvolumeOpType.CLONE_INTERNAL) as subvolume: + subvolume.state = (state, True) + +def get_clone_source(clone_subvolume): + source = clone_subvolume._get_clone_source() + return (source['volume'], source.get('group', None), source['subvolume'], source['snapshot']) + +def get_next_state_on_error(errnum): + if errnum == -errno.EINTR: + next_state = SubvolumeOpSm.transition(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_INPROGRESS, + SubvolumeActions.ACTION_CANCELLED) + else: + # jump to failed state, on all other errors + next_state = SubvolumeOpSm.transition(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_INPROGRESS, + SubvolumeActions.ACTION_FAILED) + return next_state + +def handle_clone_pending(volume_client, volname, index, groupname, subvolname, should_cancel): + try: + if should_cancel(): + next_state = SubvolumeOpSm.transition(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_PENDING, + SubvolumeActions.ACTION_CANCELLED) + else: + next_state = SubvolumeOpSm.transition(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_PENDING, + SubvolumeActions.ACTION_SUCCESS) + except OpSmException as oe: + raise VolumeException(oe.errno, oe.error_str) + return (next_state, False) + +def sync_attrs(fs_handle, target_path, source_statx): + try: + fs_handle.lchown(target_path, int(source_statx["uid"]), int(source_statx["gid"])) + fs_handle.lutimes(target_path, (time.mktime(source_statx["atime"].timetuple()), + time.mktime(source_statx["mtime"].timetuple()))) + except cephfs.Error as e: + log.warn("error synchronizing attrs for {0} ({1})".format(target_path, e)) + raise e + +def bulk_copy(fs_handle, source_path, dst_path, should_cancel): + """ + bulk copy data from source to destination -- only directories, symlinks + and regular files are synced. + """ + log.info("copying data from {0} to {1}".format(source_path, dst_path)) + def cptree(src_root_path, dst_root_path): + log.debug("cptree: {0} -> {1}".format(src_root_path, dst_root_path)) + try: + with fs_handle.opendir(src_root_path) as dir_handle: + d = fs_handle.readdir(dir_handle) + while d and not should_cancel(): + if d.d_name not in (b".", b".."): + log.debug("d={0}".format(d)) + d_full_src = os.path.join(src_root_path, d.d_name) + d_full_dst = os.path.join(dst_root_path, d.d_name) + stx = fs_handle.statx(d_full_src, cephfs.CEPH_STATX_MODE | + cephfs.CEPH_STATX_UID | + cephfs.CEPH_STATX_GID | + cephfs.CEPH_STATX_ATIME | + cephfs.CEPH_STATX_MTIME | + cephfs.CEPH_STATX_SIZE, + cephfs.AT_SYMLINK_NOFOLLOW) + handled = True + mo = stx["mode"] & ~stat.S_IFMT(stx["mode"]) + if stat.S_ISDIR(stx["mode"]): + log.debug("cptree: (DIR) {0}".format(d_full_src)) + try: + fs_handle.mkdir(d_full_dst, mo) + except cephfs.Error as e: + if not e.args[0] == errno.EEXIST: + raise + cptree(d_full_src, d_full_dst) + elif stat.S_ISLNK(stx["mode"]): + log.debug("cptree: (SYMLINK) {0}".format(d_full_src)) + target = fs_handle.readlink(d_full_src, 4096) + try: + fs_handle.symlink(target[:stx["size"]], d_full_dst) + except cephfs.Error as e: + if not e.args[0] == errno.EEXIST: + raise + elif stat.S_ISREG(stx["mode"]): + log.debug("cptree: (REG) {0}".format(d_full_src)) + copy_file(fs_handle, d_full_src, d_full_dst, mo, cancel_check=should_cancel) + else: + handled = False + log.warn("cptree: (IGNORE) {0}".format(d_full_src)) + if handled: + sync_attrs(fs_handle, d_full_dst, stx) + d = fs_handle.readdir(dir_handle) + stx_root = fs_handle.statx(src_root_path, cephfs.CEPH_STATX_ATIME | + cephfs.CEPH_STATX_MTIME, + cephfs.AT_SYMLINK_NOFOLLOW) + fs_handle.lutimes(dst_root_path, (time.mktime(stx_root["atime"].timetuple()), + time.mktime(stx_root["mtime"].timetuple()))) + except cephfs.Error as e: + if not e.args[0] == errno.ENOENT: + raise VolumeException(-e.args[0], e.args[1]) + cptree(source_path, dst_path) + if should_cancel(): + raise VolumeException(-errno.EINTR, "clone operation interrupted") + +def do_clone(volume_client, volname, groupname, subvolname, should_cancel): + with open_volume_lockless(volume_client, volname) as fs_handle: + with open_clone_subvolume_pair(volume_client, fs_handle, volname, groupname, subvolname) as clone_volumes: + src_path = clone_volumes[1].snapshot_data_path(clone_volumes[2]) + dst_path = clone_volumes[0].path + bulk_copy(fs_handle, src_path, dst_path, should_cancel) + +def handle_clone_in_progress(volume_client, volname, index, groupname, subvolname, should_cancel): + try: + do_clone(volume_client, volname, groupname, subvolname, should_cancel) + next_state = SubvolumeOpSm.transition(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_INPROGRESS, + SubvolumeActions.ACTION_SUCCESS) + except VolumeException as ve: + next_state = get_next_state_on_error(ve.errno) + except OpSmException as oe: + raise VolumeException(oe.errno, oe.error_str) + return (next_state, False) + +def handle_clone_failed(volume_client, volname, index, groupname, subvolname, should_cancel): + try: + with open_volume(volume_client, volname) as fs_handle: + # detach source but leave the clone section intact for later inspection + with open_clone_subvolume_pair(volume_client, fs_handle, volname, groupname, subvolname) as clone_volumes: + clone_volumes[1].detach_snapshot(clone_volumes[2], index) + except (MetadataMgrException, VolumeException) as e: + log.error("failed to detach clone from snapshot: {0}".format(e)) + return (None, True) + +def handle_clone_complete(volume_client, volname, index, groupname, subvolname, should_cancel): + try: + with open_volume(volume_client, volname) as fs_handle: + with open_clone_subvolume_pair(volume_client, fs_handle, volname, groupname, subvolname) as clone_volumes: + clone_volumes[1].detach_snapshot(clone_volumes[2], index) + clone_volumes[0].remove_clone_source(flush=True) + except (MetadataMgrException, VolumeException) as e: + log.error("failed to detach clone from snapshot: {0}".format(e)) + return (None, True) + +def start_clone_sm(volume_client, volname, index, groupname, subvolname, state_table, should_cancel): + finished = False + current_state = None + try: + current_state = get_clone_state(volume_client, volname, groupname, subvolname) + log.debug("cloning ({0}, {1}, {2}) -- starting state \"{3}\"".format(volname, groupname, subvolname, current_state)) + while not finished: + handler = state_table.get(current_state, None) + if not handler: + raise VolumeException(-errno.EINVAL, "invalid clone state: \"{0}\"".format(current_state)) + (next_state, finished) = handler(volume_client, volname, index, groupname, subvolname, should_cancel) + if next_state: + log.debug("({0}, {1}, {2}) transition state [\"{3}\" => \"{4}\"]".format(volname, groupname, subvolname,\ + current_state, next_state)) + set_clone_state(volume_client, volname, groupname, subvolname, next_state) + current_state = next_state + except VolumeException as ve: + log.error("clone failed for ({0}, {1}, {2}) (current_state: {3}, reason: {4})".format(volname, groupname,\ + subvolname, current_state, ve)) + +def clone(volume_client, volname, index, clone_path, state_table, should_cancel): + log.info("cloning to subvolume path: {0}".format(clone_path)) + resolved = resolve(volume_client.volspec, clone_path) + + groupname = resolved[0] + subvolname = resolved[1] + log.debug("resolved to [group: {0}, subvolume: {1}]".format(groupname, subvolname)) + + try: + log.info("starting clone: ({0}, {1}, {2})".format(volname, groupname, subvolname)) + start_clone_sm(volume_client, volname, index, groupname, subvolname, state_table, should_cancel) + log.info("finished clone: ({0}, {1}, {2})".format(volname, groupname, subvolname)) + except VolumeException as ve: + log.error("clone failed for ({0}, {1}, {2}), reason: {3}".format(volname, groupname, subvolname, ve)) + +class Cloner(AsyncJobs): + """ + Asynchronous cloner: pool of threads to copy data from a snapshot to a subvolume. + this relies on a simple state machine (which mimics states from SubvolumeOpSm class) as + the driver. file types supported are directories, symbolic links and regular files. + """ + def __init__(self, volume_client, tp_size): + self.vc = volume_client + self.state_table = { + SubvolumeStates.STATE_PENDING : handle_clone_pending, + SubvolumeStates.STATE_INPROGRESS : handle_clone_in_progress, + SubvolumeStates.STATE_COMPLETE : handle_clone_complete, + SubvolumeStates.STATE_FAILED : handle_clone_failed, + SubvolumeStates.STATE_CANCELED : handle_clone_failed, + } + super(Cloner, self).__init__(volume_client, "cloner", tp_size) + + def reconfigure_max_concurrent_clones(self, tp_size): + super(Cloner, self).reconfigure_max_concurrent_clones("cloner", tp_size) + + def is_clone_cancelable(self, clone_state): + return not (SubvolumeOpSm.is_complete_state(clone_state) or SubvolumeOpSm.is_failed_state(clone_state)) + + def get_clone_tracking_index(self, fs_handle, clone_subvolume): + with open_clone_index(fs_handle, self.vc.volspec) as index: + return index.find_clone_entry_index(clone_subvolume.base_path) + + def _cancel_pending_clone(self, fs_handle, clone_subvolume, clone_subvolname, clone_groupname, status, track_idx): + clone_state = SubvolumeStates.from_value(status['state']) + assert self.is_clone_cancelable(clone_state) + + s_groupname = status['source'].get('group', None) + s_subvolname = status['source']['subvolume'] + s_snapname = status['source']['snapshot'] + + with open_at_group_unique(self.vc, fs_handle, s_groupname, s_subvolname, clone_subvolume, clone_groupname, + clone_subvolname, SubvolumeOpType.CLONE_SOURCE) as s_subvolume: + next_state = SubvolumeOpSm.transition(SubvolumeTypes.TYPE_CLONE, + clone_state, + SubvolumeActions.ACTION_CANCELLED) + clone_subvolume.state = (next_state, True) + s_subvolume.detach_snapshot(s_snapname, track_idx.decode('utf-8')) + + def cancel_job(self, volname, job): + """ + override base class `cancel_job`. interpret @job as (clone, group) tuple. + """ + clonename = job[0] + groupname = job[1] + track_idx = None + + try: + with open_volume(self.vc, volname) as fs_handle: + with open_group(fs_handle, self.vc.volspec, groupname) as group: + with open_subvol(self.vc.mgr, fs_handle, self.vc.volspec, group, clonename, SubvolumeOpType.CLONE_CANCEL) as clone_subvolume: + status = clone_subvolume.status + clone_state = SubvolumeStates.from_value(status['state']) + if not self.is_clone_cancelable(clone_state): + raise VolumeException(-errno.EINVAL, "cannot cancel -- clone finished (check clone status)") + track_idx = self.get_clone_tracking_index(fs_handle, clone_subvolume) + if not track_idx: + log.warn("cannot lookup clone tracking index for {0}".format(clone_subvolume.base_path)) + raise VolumeException(-errno.EINVAL, "error canceling clone") + if SubvolumeOpSm.is_init_state(SubvolumeTypes.TYPE_CLONE, clone_state): + # clone has not started yet -- cancel right away. + self._cancel_pending_clone(fs_handle, clone_subvolume, clonename, groupname, status, track_idx) + return + # cancelling an on-going clone would persist "canceled" state in subvolume metadata. + # to persist the new state, async cloner accesses the volume in exclusive mode. + # accessing the volume in exclusive mode here would lead to deadlock. + assert track_idx is not None + with self.lock: + with open_volume_lockless(self.vc, volname) as fs_handle: + with open_group(fs_handle, self.vc.volspec, groupname) as group: + with open_subvol(self.vc.mgr, fs_handle, self.vc.volspec, group, clonename, SubvolumeOpType.CLONE_CANCEL) as clone_subvolume: + if not self._cancel_job(volname, (track_idx, clone_subvolume.base_path)): + raise VolumeException(-errno.EINVAL, "cannot cancel -- clone finished (check clone status)") + except (IndexException, MetadataMgrException) as e: + log.error("error cancelling clone {0}: ({1})".format(job, e)) + raise VolumeException(-errno.EINVAL, "error canceling clone") + + def get_next_job(self, volname, running_jobs): + return get_next_clone_entry(self.vc, volname, running_jobs) + + def execute_job(self, volname, job, should_cancel): + clone(self.vc, volname, job[0].decode('utf-8'), job[1].decode('utf-8'), self.state_table, should_cancel) diff --git a/src/pybind/mgr/volumes/fs/async_job.py b/src/pybind/mgr/volumes/fs/async_job.py new file mode 100644 index 00000000..954e89c4 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/async_job.py @@ -0,0 +1,279 @@ +import sys +import time +import logging +import threading +import traceback +from collections import deque + +from .exception import NotImplementedException + +log = logging.getLogger(__name__) + +class JobThread(threading.Thread): + # this is "not" configurable and there is no need for it to be + # configurable. if a thread encounters an exception, we retry + # until it hits this many consecutive exceptions. + MAX_RETRIES_ON_EXCEPTION = 10 + + def __init__(self, async_job, volume_client, name): + self.vc = volume_client + self.async_job = async_job + # event object to cancel jobs + self.cancel_event = threading.Event() + threading.Thread.__init__(self, name=name) + + def run(self): + retries = 0 + thread_id = threading.currentThread() + assert isinstance(thread_id, JobThread) + thread_name = thread_id.getName() + log.debug("thread [{0}] starting".format(thread_name)) + + while retries < JobThread.MAX_RETRIES_ON_EXCEPTION: + vol_job = None + try: + # fetch next job to execute + with self.async_job.lock: + while True: + if self.should_reconfigure_num_threads(): + log.info("thread [{0}] terminating due to reconfigure".format(thread_name)) + self.async_job.threads.remove(self) + return + vol_job = self.async_job.get_job() + if vol_job: + break + self.async_job.cv.wait() + self.async_job.register_async_job(vol_job[0], vol_job[1], thread_id) + + # execute the job (outside lock) + self.async_job.execute_job(vol_job[0], vol_job[1], should_cancel=lambda: thread_id.should_cancel()) + retries = 0 + except NotImplementedException: + raise + except Exception: + # unless the jobs fetching and execution routines are not implemented + # retry till we hit cap limit. + retries += 1 + log.warning("thread [{0}] encountered fatal error: (attempt#" \ + " {1}/{2})".format(thread_name, retries, JobThread.MAX_RETRIES_ON_EXCEPTION)) + exc_type, exc_value, exc_traceback = sys.exc_info() + log.warning("traceback: {0}".format("".join( + traceback.format_exception(exc_type, exc_value, exc_traceback)))) + finally: + # when done, unregister the job + if vol_job: + with self.async_job.lock: + self.async_job.unregister_async_job(vol_job[0], vol_job[1], thread_id) + time.sleep(1) + log.error("thread [{0}] reached exception limit, bailing out...".format(thread_name)) + self.vc.cluster_log("thread {0} bailing out due to exception".format(thread_name)) + with self.async_job.lock: + self.async_job.threads.remove(self) + + def should_reconfigure_num_threads(self): + # reconfigure of max_concurrent_clones + return len(self.async_job.threads) > self.async_job.nr_concurrent_jobs + + def cancel_job(self): + self.cancel_event.set() + + def should_cancel(self): + return self.cancel_event.is_set() + + def reset_cancel(self): + self.cancel_event.clear() + +class AsyncJobs(object): + """ + Class providing asynchronous execution of jobs via worker threads. + `jobs` are grouped by `volume`, so a `volume` can have N number of + `jobs` executing concurrently (capped by number of concurrent jobs). + + Usability is simple: subclass this and implement the following: + - get_next_job(volname, running_jobs) + - execute_job(volname, job, should_cancel) + + ... and do not forget to invoke base class constructor. + + Job cancelation is for a volume as a whole, i.e., all executing jobs + for a volume are canceled. Cancelation is poll based -- jobs need to + periodically check if cancelation is requested, after which the job + should return as soon as possible. Cancelation check is provided + via `should_cancel()` lambda passed to `execute_job()`. + """ + + def __init__(self, volume_client, name_pfx, nr_concurrent_jobs): + self.vc = volume_client + # queue of volumes for starting async jobs + self.q = deque() + # volume => job tracking + self.jobs = {} + # lock, cv for kickstarting jobs + self.lock = threading.Lock() + self.cv = threading.Condition(self.lock) + # cv for job cancelation + self.waiting = False + self.cancel_cv = threading.Condition(self.lock) + self.nr_concurrent_jobs = nr_concurrent_jobs + + self.threads = [] + for i in range(nr_concurrent_jobs): + self.threads.append(JobThread(self, volume_client, name="{0}.{1}".format(name_pfx, i))) + self.threads[-1].start() + + def reconfigure_max_concurrent_clones(self, name_pfx, nr_concurrent_jobs): + """ + reconfigure number of cloner threads + """ + with self.lock: + self.nr_concurrent_jobs = nr_concurrent_jobs + # Decrease in concurrency. Notify threads which are waiting for a job to terminate. + if len(self.threads) > nr_concurrent_jobs: + self.cv.notifyAll() + # Increase in concurrency + if len(self.threads) < nr_concurrent_jobs: + for i in range(len(self.threads), nr_concurrent_jobs): + self.threads.append(JobThread(self, self.vc, name="{0}.{1}.{2}".format(name_pfx, time.time(), i))) + self.threads[-1].start() + + def get_job(self): + log.debug("processing {0} volume entries".format(len(self.q))) + nr_vols = len(self.q) + to_remove = [] + next_job = None + while nr_vols > 0: + volname = self.q[0] + # do this now so that the other thread pick up jobs for other volumes + self.q.rotate(1) + running_jobs = [j[0] for j in self.jobs[volname]] + (ret, job) = self.get_next_job(volname, running_jobs) + if job: + next_job = (volname, job) + break + # this is an optimization when for a given volume there are no more + # jobs and no jobs are in progress. in such cases we remove the volume + # from the tracking list so as to: + # + # a. not query the filesystem for jobs over and over again + # b. keep the filesystem connection idle so that it can be freed + # from the connection pool + # + # if at all there are jobs for a volume, the volume gets added again + # to the tracking list and the jobs get kickstarted. + # note that, we do not iterate the volume list fully if there is a + # jobs to process (that will take place eventually). + if ret == 0 and not job and not running_jobs: + to_remove.append(volname) + nr_vols -= 1 + for vol in to_remove: + log.debug("auto removing volume '{0}' from tracked volumes".format(vol)) + self.q.remove(vol) + self.jobs.pop(vol) + return next_job + + def register_async_job(self, volname, job, thread_id): + log.debug("registering async job {0}.{1} with thread {2}".format(volname, job, thread_id)) + self.jobs[volname].append((job, thread_id)) + + def unregister_async_job(self, volname, job, thread_id): + log.debug("unregistering async job {0}.{1} from thread {2}".format(volname, job, thread_id)) + self.jobs[volname].remove((job, thread_id)) + + cancelled = thread_id.should_cancel() + thread_id.reset_cancel() + + # wake up cancellation waiters if needed + if cancelled: + logging.info("waking up cancellation waiters") + self.cancel_cv.notifyAll() + + def queue_job(self, volname): + """ + queue a volume for asynchronous job execution. + """ + log.info("queuing job for volume '{0}'".format(volname)) + with self.lock: + if not volname in self.q: + self.q.append(volname) + self.jobs[volname] = [] + self.cv.notifyAll() + + def _cancel_jobs(self, volname): + """ + cancel all jobs for the volume. do nothing is the no jobs are + executing for the given volume. this would wait until all jobs + get interrupted and finish execution. + """ + log.info("cancelling jobs for volume '{0}'".format(volname)) + try: + if not volname in self.q and not volname in self.jobs: + return + self.q.remove(volname) + # cancel in-progress operation and wait until complete + for j in self.jobs[volname]: + j[1].cancel_job() + # wait for cancellation to complete + while self.jobs[volname]: + log.debug("waiting for {0} in-progress jobs for volume '{1}' to " \ + "cancel".format(len(self.jobs[volname]), volname)) + self.cancel_cv.wait() + self.jobs.pop(volname) + except (KeyError, ValueError): + pass + + def _cancel_job(self, volname, job): + """ + cancel a executing job for a given volume. return True if canceled, False + otherwise (volume/job not found). + """ + canceled = False + log.info("canceling job {0} for volume {1}".format(job, volname)) + try: + if not volname in self.q and not volname in self.jobs and not job in self.jobs[volname]: + return canceled + for j in self.jobs[volname]: + if j[0] == job: + j[1].cancel_job() + # be safe against _cancel_jobs() running concurrently + while j in self.jobs.get(volname, []): + self.cancel_cv.wait() + canceled = True + break + except (KeyError, ValueError): + pass + return canceled + + def cancel_job(self, volname, job): + with self.lock: + return self._cancel_job(volname, job) + + def cancel_jobs(self, volname): + """ + cancel all executing jobs for a given volume. + """ + with self.lock: + self._cancel_jobs(volname) + + def cancel_all_jobs(self): + """ + call all executing jobs for all volumes. + """ + with self.lock: + for volname in list(self.q): + self._cancel_jobs(volname) + + def get_next_job(self, volname, running_jobs): + """ + get the next job for asynchronous execution as (retcode, job) tuple. if no + jobs are available return (0, None) else return (0, job). on error return + (-ret, None). called under `self.lock`. + """ + raise NotImplementedException() + + def execute_job(self, volname, job, should_cancel): + """ + execute a job for a volume. the job can block on I/O operations, sleep for long + hours and do all kinds of synchronous work. called outside `self.lock`. + """ + raise NotImplementedException() + diff --git a/src/pybind/mgr/volumes/fs/exception.py b/src/pybind/mgr/volumes/fs/exception.py new file mode 100644 index 00000000..4f903b99 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/exception.py @@ -0,0 +1,63 @@ +class VolumeException(Exception): + def __init__(self, error_code, error_message): + self.errno = error_code + self.error_str = error_message + + def to_tuple(self): + return self.errno, "", self.error_str + + def __str__(self): + return "{0} ({1})".format(self.errno, self.error_str) + +class MetadataMgrException(Exception): + def __init__(self, error_code, error_message): + self.errno = error_code + self.error_str = error_message + + def __str__(self): + return "{0} ({1})".format(self.errno, self.error_str) + +class IndexException(Exception): + def __init__(self, error_code, error_message): + self.errno = error_code + self.error_str = error_message + + def __str__(self): + return "{0} ({1})".format(self.errno, self.error_str) + +class OpSmException(Exception): + def __init__(self, error_code, error_message): + self.errno = error_code + self.error_str = error_message + + def __str__(self): + return "{0} ({1})".format(self.errno, self.error_str) + +class NotImplementedException(Exception): + pass + +class ClusterTimeout(Exception): + """ + Exception indicating that we timed out trying to talk to the Ceph cluster, + either to the mons, or to any individual daemon that the mons indicate ought + to be up but isn't responding to us. + """ + pass + +class ClusterError(Exception): + """ + Exception indicating that the cluster returned an error to a command that + we thought should be successful based on our last knowledge of the cluster + state. + """ + def __init__(self, action, result_code, result_str): + self._action = action + self._result_code = result_code + self._result_str = result_str + + def __str__(self): + return "Error {0} (\"{1}\") while {2}".format( + self._result_code, self._result_str, self._action) + +class EvictionError(Exception): + pass diff --git a/src/pybind/mgr/volumes/fs/fs_util.py b/src/pybind/mgr/volumes/fs/fs_util.py new file mode 100644 index 00000000..6fe02f58 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/fs_util.py @@ -0,0 +1,161 @@ +import os +import errno +import logging + +import cephfs +import orchestrator + +from .exception import VolumeException + +log = logging.getLogger(__name__) + +def create_pool(mgr, pool_name, pg_num): + # create the given pool + command = {'prefix': 'osd pool create', 'pool': pool_name, 'pg_num': pg_num} + return mgr.mon_command(command) + +def remove_pool(mgr, pool_name): + command = {'prefix': 'osd pool rm', 'pool': pool_name, 'pool2': pool_name, + 'yes_i_really_really_mean_it': True} + return mgr.mon_command(command) + +def create_filesystem(mgr, fs_name, metadata_pool, data_pool): + command = {'prefix': 'fs new', 'fs_name': fs_name, 'metadata': metadata_pool, + 'data': data_pool} + return mgr.mon_command(command) + +def remove_filesystem(mgr, fs_name): + command = {'prefix': 'fs fail', 'fs_name': fs_name} + r, outb, outs = mgr.mon_command(command) + if r != 0: + return r, outb, outs + + command = {'prefix': 'fs rm', 'fs_name': fs_name, 'yes_i_really_mean_it': True} + return mgr.mon_command(command) + +def create_mds(mgr, fs_name): + spec = orchestrator.StatelessServiceSpec() + spec.name = fs_name + try: + completion = mgr.add_stateless_service("mds", spec) + mgr._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + except (ImportError, orchestrator.OrchestratorError): + return 0, "", "Volume created successfully (no MDS daemons created)" + except Exception as e: + # Don't let detailed orchestrator exceptions (python backtraces) + # bubble out to the user + log.exception("Failed to create MDS daemons") + return -errno.EINVAL, "", str(e) + return 0, "", "" + +def volume_exists(mgr, fs_name): + fs_map = mgr.get('fs_map') + for fs in fs_map['filesystems']: + if fs['mdsmap']['fs_name'] == fs_name: + return True + return False + +def listdir(fs, dirpath): + """ + Get the directory names (only dirs) for a given path + """ + dirs = [] + try: + with fs.opendir(dirpath) as dir_handle: + d = fs.readdir(dir_handle) + while d: + if (d.d_name not in (b".", b"..")) and d.is_dir(): + dirs.append(d.d_name) + d = fs.readdir(dir_handle) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + return dirs + +def is_inherited_snap(snapname): + """ + Returns True if the snapname is inherited else False + """ + return snapname.startswith("_") + +def listsnaps(fs, volspec, snapdirpath, filter_inherited_snaps=False): + """ + Get the snap names from a given snap directory path + """ + if os.path.basename(snapdirpath) != volspec.snapshot_prefix.encode('utf-8'): + raise VolumeException(-errno.EINVAL, "Not a snap directory: {0}".format(snapdirpath)) + snaps = [] + try: + with fs.opendir(snapdirpath) as dir_handle: + d = fs.readdir(dir_handle) + while d: + if (d.d_name not in (b".", b"..")) and d.is_dir(): + d_name = d.d_name.decode('utf-8') + if not is_inherited_snap(d_name): + snaps.append(d.d_name) + elif is_inherited_snap(d_name) and not filter_inherited_snaps: + snaps.append(d.d_name) + d = fs.readdir(dir_handle) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + return snaps + +def list_one_entry_at_a_time(fs, dirpath): + """ + Get a directory entry (one entry a time) + """ + try: + with fs.opendir(dirpath) as dir_handle: + d = fs.readdir(dir_handle) + while d: + if d.d_name not in (b".", b".."): + yield d + d = fs.readdir(dir_handle) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + +def copy_file(fs, src, dst, mode, cancel_check=None): + """ + Copy a regular file from @src to @dst. @dst is overwritten if it exists. + """ + src_fd = dst_fd = None + try: + src_fd = fs.open(src, os.O_RDONLY); + dst_fd = fs.open(dst, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, mode) + except cephfs.Error as e: + if src_fd is not None: + fs.close(src_fd) + if dst_fd is not None: + fs.close(dst_fd) + raise VolumeException(-e.args[0], e.args[1]) + + IO_SIZE = 8 * 1024 * 1024 + try: + while True: + if cancel_check and cancel_check(): + raise VolumeException(-errno.EINTR, "copy operation interrupted") + data = fs.read(src_fd, -1, IO_SIZE) + if not len(data): + break + written = 0 + while written < len(data): + written += fs.write(dst_fd, data[written:], -1) + fs.fsync(dst_fd, 0) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + finally: + fs.close(src_fd) + fs.close(dst_fd) + +def get_ancestor_xattr(fs, path, attr): + """ + Helper for reading layout information: if this xattr is missing + on the requested path, keep checking parents until we find it. + """ + try: + return fs.getxattr(path, attr).decode('utf-8') + except cephfs.NoData as e: + if path == "/": + raise VolumeException(-e.args[0], e.args[1]) + else: + return get_ancestor_xattr(fs, os.path.split(path)[0], attr) diff --git a/src/pybind/mgr/volumes/fs/operations/__init__.py b/src/pybind/mgr/volumes/fs/operations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/pybind/mgr/volumes/fs/operations/access.py b/src/pybind/mgr/volumes/fs/operations/access.py new file mode 100644 index 00000000..44430f59 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/access.py @@ -0,0 +1,142 @@ +import errno +import json +try: + from typing import List +except ImportError: + pass # For typing only + +def prepare_updated_caps_list(existing_caps, mds_cap_str, osd_cap_str, authorize=True): + caps_list = [] # type: List[str] + for k, v in existing_caps['caps'].items(): + if k == 'mds' or k == 'osd': + continue + elif k == 'mon': + if not authorize and v == 'allow r': + continue + caps_list.extend((k,v)) + + if mds_cap_str: + caps_list.extend(('mds', mds_cap_str)) + if osd_cap_str: + caps_list.extend(('osd', osd_cap_str)) + + if authorize and 'mon' not in caps_list: + caps_list.extend(('mon', 'allow r')) + + return caps_list + + +def allow_access(mgr, client_entity, want_mds_cap, want_osd_cap, + unwanted_mds_cap, unwanted_osd_cap, existing_caps): + if existing_caps is None: + ret, out, err = mgr.mon_command({ + "prefix": "auth get-or-create", + "entity": client_entity, + "caps": ['mds', want_mds_cap, 'osd', want_osd_cap, 'mon', 'allow r'], + "format": "json"}) + else: + cap = existing_caps[0] + + def cap_update( + orig_mds_caps, orig_osd_caps, want_mds_cap, + want_osd_cap, unwanted_mds_cap, unwanted_osd_cap): + + if not orig_mds_caps: + return want_mds_cap, want_osd_cap + + mds_cap_tokens = [x.strip() for x in orig_mds_caps.split(",")] + osd_cap_tokens = [x.strip() for x in orig_osd_caps.split(",")] + + if want_mds_cap in mds_cap_tokens: + return orig_mds_caps, orig_osd_caps + + if unwanted_mds_cap in mds_cap_tokens: + mds_cap_tokens.remove(unwanted_mds_cap) + osd_cap_tokens.remove(unwanted_osd_cap) + + mds_cap_tokens.append(want_mds_cap) + osd_cap_tokens.append(want_osd_cap) + + return ",".join(mds_cap_tokens), ",".join(osd_cap_tokens) + + orig_mds_caps = cap['caps'].get('mds', "") + orig_osd_caps = cap['caps'].get('osd', "") + + mds_cap_str, osd_cap_str = cap_update( + orig_mds_caps, orig_osd_caps, want_mds_cap, want_osd_cap, + unwanted_mds_cap, unwanted_osd_cap) + + caps_list = prepare_updated_caps_list(cap, mds_cap_str, osd_cap_str) + mgr.mon_command( + { + "prefix": "auth caps", + 'entity': client_entity, + 'caps': caps_list + }) + ret, out, err = mgr.mon_command( + { + 'prefix': 'auth get', + 'entity': client_entity, + 'format': 'json' + }) + + # Result expected like this: + # [ + # { + # "entity": "client.foobar", + # "key": "AQBY0\/pViX\/wBBAAUpPs9swy7rey1qPhzmDVGQ==", + # "caps": { + # "mds": "allow *", + # "mon": "allow *" + # } + # } + # ] + + caps = json.loads(out) + assert len(caps) == 1 + assert caps[0]['entity'] == client_entity + return caps[0]['key'] + +def deny_access(mgr, client_entity, want_mds_caps, want_osd_caps): + ret, out, err = mgr.mon_command({ + "prefix": "auth get", + "entity": client_entity, + "format": "json", + }) + + if ret == -errno.ENOENT: + # Already gone, great. + return + + def cap_remove(orig_mds_caps, orig_osd_caps, want_mds_caps, want_osd_caps): + mds_cap_tokens = [x.strip() for x in orig_mds_caps.split(",")] + osd_cap_tokens = [x.strip() for x in orig_osd_caps.split(",")] + + for want_mds_cap, want_osd_cap in zip(want_mds_caps, want_osd_caps): + if want_mds_cap in mds_cap_tokens: + mds_cap_tokens.remove(want_mds_cap) + osd_cap_tokens.remove(want_osd_cap) + break + + return ",".join(mds_cap_tokens), ",".join(osd_cap_tokens) + + cap = json.loads(out)[0] + orig_mds_caps = cap['caps'].get('mds', "") + orig_osd_caps = cap['caps'].get('osd', "") + mds_cap_str, osd_cap_str = cap_remove(orig_mds_caps, orig_osd_caps, + want_mds_caps, want_osd_caps) + + caps_list = prepare_updated_caps_list(cap, mds_cap_str, osd_cap_str, authorize=False) + if not caps_list: + mgr.mon_command( + { + 'prefix': 'auth rm', + 'entity': client_entity + }) + else: + mgr.mon_command( + { + "prefix": "auth caps", + 'entity': client_entity, + 'caps': caps_list + }) diff --git a/src/pybind/mgr/volumes/fs/operations/clone_index.py b/src/pybind/mgr/volumes/fs/operations/clone_index.py new file mode 100644 index 00000000..a2b31f85 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/clone_index.py @@ -0,0 +1,98 @@ +import os +import uuid +import stat +import errno +import logging +from contextlib import contextmanager + +import cephfs + +from .index import Index +from ..exception import IndexException, VolumeException +from ..fs_util import list_one_entry_at_a_time + +log = logging.getLogger(__name__) + +class CloneIndex(Index): + SUB_GROUP_NAME = "clone" + PATH_MAX = 4096 + + @property + def path(self): + return os.path.join(super(CloneIndex, self).path, CloneIndex.SUB_GROUP_NAME.encode('utf-8')) + + def _track(self, sink_path): + tracking_id = str(uuid.uuid4()) + source_path = os.path.join(self.path, tracking_id.encode('utf-8')) + log.info("tracking-id {0} for path {1}".format(tracking_id, sink_path)) + + self.fs.symlink(sink_path, source_path) + return tracking_id + + def track(self, sink_path): + try: + return self._track(sink_path) + except (VolumeException, cephfs.Error) as e: + if isinstance(e, cephfs.Error): + e = IndexException(-e.args[0], e.args[1]) + elif isinstance(e, VolumeException): + e = IndexException(e.errno, e.error_str) + raise e + + def untrack(self, tracking_id): + log.info("untracking {0}".format(tracking_id)) + source_path = os.path.join(self.path, tracking_id.encode('utf-8')) + try: + self.fs.unlink(source_path) + except cephfs.Error as e: + raise IndexException(-e.args[0], e.args[1]) + + def get_oldest_clone_entry(self, exclude=[]): + min_ctime_entry = None + exclude_tracking_ids = [v[0] for v in exclude] + log.debug("excluded tracking ids: {0}".format(exclude_tracking_ids)) + for entry in list_one_entry_at_a_time(self.fs, self.path): + dname = entry.d_name + dpath = os.path.join(self.path, dname) + st = self.fs.lstat(dpath) + if dname not in exclude_tracking_ids and stat.S_ISLNK(st.st_mode): + if min_ctime_entry is None or st.st_ctime < min_ctime_entry[1].st_ctime: + min_ctime_entry = (dname, st) + if min_ctime_entry: + try: + linklen = min_ctime_entry[1].st_size + sink_path = self.fs.readlink(os.path.join(self.path, min_ctime_entry[0]), CloneIndex.PATH_MAX) + return (min_ctime_entry[0], sink_path[:linklen]) + except cephfs.Error as e: + raise IndexException(-e.args[0], e.args[1]) + return None + + def find_clone_entry_index(self, sink_path): + try: + for entry in list_one_entry_at_a_time(self.fs, self.path): + dname = entry.d_name + dpath = os.path.join(self.path, dname) + st = self.fs.lstat(dpath) + if stat.S_ISLNK(st.st_mode): + target_path = self.fs.readlink(dpath, CloneIndex.PATH_MAX) + if sink_path == target_path[:st.st_size]: + return dname + return None + except cephfs.Error as e: + raise IndexException(-e.args[0], e.args[1]) + +def create_clone_index(fs, vol_spec): + clone_index = CloneIndex(fs, vol_spec) + try: + fs.mkdirs(clone_index.path, 0o700) + except cephfs.Error as e: + raise IndexException(-e.args[0], e.args[1]) + +@contextmanager +def open_clone_index(fs, vol_spec): + clone_index = CloneIndex(fs, vol_spec) + try: + fs.stat(clone_index.path) + except cephfs.Error as e: + raise IndexException(-e.args[0], e.args[1]) + yield clone_index diff --git a/src/pybind/mgr/volumes/fs/operations/group.py b/src/pybind/mgr/volumes/fs/operations/group.py new file mode 100644 index 00000000..ae334563 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/group.py @@ -0,0 +1,186 @@ +import os +import errno +import logging +from contextlib import contextmanager + +import cephfs + +from .snapshot_util import mksnap, rmsnap +from .template import GroupTemplate +from ..fs_util import listdir, listsnaps, get_ancestor_xattr +from ..exception import VolumeException + +log = logging.getLogger(__name__) + +class Group(GroupTemplate): + # Reserved subvolume group name which we use in paths for subvolumes + # that are not assigned to a group (i.e. created with group=None) + NO_GROUP_NAME = "_nogroup" + + def __init__(self, fs, vol_spec, groupname): + assert groupname != Group.NO_GROUP_NAME + self.fs = fs + self.user_id = None + self.group_id = None + self.vol_spec = vol_spec + self.groupname = groupname if groupname else Group.NO_GROUP_NAME + + @property + def path(self): + return os.path.join(self.vol_spec.base_dir.encode('utf-8'), self.groupname.encode('utf-8')) + + @property + def group_name(self): + return self.groupname + + @property + def uid(self): + return self.user_id + + @uid.setter + def uid(self, val): + self.user_id = val + + @property + def gid(self): + return self.group_id + + @gid.setter + def gid(self, val): + self.group_id = val + + def is_default_group(self): + return self.groupname == Group.NO_GROUP_NAME + + def list_subvolumes(self): + try: + return listdir(self.fs, self.path) + except VolumeException as ve: + # listing a default group when it's not yet created + if ve.errno == -errno.ENOENT and self.is_default_group(): + return [] + raise + + def create_snapshot(self, snapname): + snappath = os.path.join(self.path, + self.vol_spec.snapshot_dir_prefix.encode('utf-8'), + snapname.encode('utf-8')) + mksnap(self.fs, snappath) + + def remove_snapshot(self, snapname): + snappath = os.path.join(self.path, + self.vol_spec.snapshot_dir_prefix.encode('utf-8'), + snapname.encode('utf-8')) + rmsnap(self.fs, snappath) + + def list_snapshots(self): + try: + dirpath = os.path.join(self.path, + self.vol_spec.snapshot_dir_prefix.encode('utf-8')) + return listsnaps(self.fs, self.vol_spec, dirpath, filter_inherited_snaps=True) + except VolumeException as ve: + if ve.errno == -errno.ENOENT: + return [] + raise + +def create_group(fs, vol_spec, groupname, pool, mode, uid, gid): + """ + create a subvolume group. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :param groupname: subvolume group name + :param pool: the RADOS pool where the data objects of the subvolumes will be stored + :param mode: the user permissions + :param uid: the user identifier + :param gid: the group identifier + :return: None + """ + group = Group(fs, vol_spec, groupname) + path = group.path + fs.mkdirs(path, mode) + try: + if not pool: + pool = get_ancestor_xattr(fs, path, "ceph.dir.layout.pool") + try: + fs.setxattr(path, 'ceph.dir.layout.pool', pool.encode('utf-8'), 0) + except cephfs.InvalidValue: + raise VolumeException(-errno.EINVAL, + "Invalid pool layout '{0}'. It must be a valid data pool".format(pool)) + if uid is None: + uid = 0 + else: + try: + uid = int(uid) + if uid < 0: + raise ValueError + except ValueError: + raise VolumeException(-errno.EINVAL, "invalid UID") + if gid is None: + gid = 0 + else: + try: + gid = int(gid) + if gid < 0: + raise ValueError + except ValueError: + raise VolumeException(-errno.EINVAL, "invalid GID") + fs.chown(path, uid, gid) + except (cephfs.Error, VolumeException) as e: + try: + # cleanup group path on best effort basis + log.debug("cleaning up subvolume group path: {0}".format(path)) + fs.rmdir(path) + except cephfs.Error as ce: + log.debug("failed to clean up subvolume group {0} with path: {1} ({2})".format(groupname, path, ce)) + if isinstance(e, cephfs.Error): + e = VolumeException(-e.args[0], e.args[1]) + raise e + +def remove_group(fs, vol_spec, groupname): + """ + remove a subvolume group. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :param groupname: subvolume group name + :return: None + """ + group = Group(fs, vol_spec, groupname) + try: + fs.rmdir(group.path) + except cephfs.Error as e: + if e.args[0] == errno.ENOENT: + raise VolumeException(-errno.ENOENT, "subvolume group '{0}' does not exist".format(groupname)) + raise VolumeException(-e.args[0], e.args[1]) + +@contextmanager +def open_group(fs, vol_spec, groupname): + """ + open a subvolume group. This API is to be used as a context manager. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :param groupname: subvolume group name + :return: yields a group object (subclass of GroupTemplate) + """ + group = Group(fs, vol_spec, groupname) + try: + st = fs.stat(group.path) + group.uid = int(st.st_uid) + group.gid = int(st.st_gid) + except cephfs.Error as e: + if e.args[0] == errno.ENOENT: + if not group.is_default_group(): + raise VolumeException(-errno.ENOENT, "subvolume group '{0}' does not exist".format(groupname)) + else: + raise VolumeException(-e.args[0], e.args[1]) + yield group + +@contextmanager +def open_group_unique(fs, vol_spec, groupname, c_group, c_groupname): + if groupname == c_groupname: + yield c_group + else: + with open_group(fs, vol_spec, groupname) as group: + yield group diff --git a/src/pybind/mgr/volumes/fs/operations/index.py b/src/pybind/mgr/volumes/fs/operations/index.py new file mode 100644 index 00000000..0e4296d7 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/index.py @@ -0,0 +1,23 @@ +import errno +import os + +from ..exception import VolumeException +from .template import GroupTemplate + +class Index(GroupTemplate): + GROUP_NAME = "_index" + + def __init__(self, fs, vol_spec): + self.fs = fs + self.vol_spec = vol_spec + self.groupname = Index.GROUP_NAME + + @property + def path(self): + return os.path.join(self.vol_spec.base_dir.encode('utf-8'), self.groupname.encode('utf-8')) + + def track(self, *args): + raise VolumeException(-errno.EINVAL, "operation not supported.") + + def untrack(self, tracking_id): + raise VolumeException(-errno.EINVAL, "operation not supported.") diff --git a/src/pybind/mgr/volumes/fs/operations/lock.py b/src/pybind/mgr/volumes/fs/operations/lock.py new file mode 100644 index 00000000..ab5f1d04 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/lock.py @@ -0,0 +1,42 @@ +from contextlib import contextmanager +import logging +from threading import Lock + +log = logging.getLogger(__name__) + +# singleton design pattern taken from http://www.aleax.it/5ep.html + +class GlobalLock(object): + """ + Global lock to serialize operations in mgr/volumes. This lock + is currently held when accessing (opening) a volume to perform + group/subvolume operations. Since this is a big lock, it's rather + inefficient -- but right now it's ok since mgr/volumes does not + expect concurrent operations via its APIs. + + As and when features get added (such as clone, where mgr/volumes + would maintain subvolume states in the filesystem), there might + be a need to allow concurrent operations. In that case it would + be nice to implement an efficient path based locking mechanism. + + See: https://people.eecs.berkeley.edu/~kubitron/courses/cs262a-F14/projects/reports/project6_report.pdf + """ + _shared_state = { + 'lock' : Lock(), + 'init' : False + } + + def __init__(self): + with self._shared_state['lock']: + if not self._shared_state['init']: + self._shared_state['init'] = True + # share this state among all instances + self.__dict__ = self._shared_state + + @contextmanager + def lock_op(self): + log.debug("entering global lock") + with self._shared_state['lock']: + log.debug("acquired global lock") + yield + log.debug("exited global lock") diff --git a/src/pybind/mgr/volumes/fs/operations/rankevicter.py b/src/pybind/mgr/volumes/fs/operations/rankevicter.py new file mode 100644 index 00000000..5b945c38 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/rankevicter.py @@ -0,0 +1,114 @@ +import errno +import json +import logging +import threading +import time + +from .volume import get_mds_map +from ..exception import ClusterTimeout, ClusterError + +log = logging.getLogger(__name__) + +class RankEvicter(threading.Thread): + """ + Thread for evicting client(s) from a particular MDS daemon instance. + + This is more complex than simply sending a command, because we have to + handle cases where MDS daemons might not be fully up yet, and/or might + be transiently unresponsive to commands. + """ + class GidGone(Exception): + pass + + POLL_PERIOD = 5 + + def __init__(self, mgr, fs, client_spec, volname, rank, gid, mds_map, ready_timeout): + """ + :param client_spec: list of strings, used as filter arguments to "session evict" + pass ["id=123"] to evict a single client with session id 123. + """ + self.volname = volname + self.rank = rank + self.gid = gid + self._mds_map = mds_map + self._client_spec = client_spec + self._fs = fs + self._ready_timeout = ready_timeout + self._ready_waited = 0 + self.mgr = mgr + + self.success = False + self.exception = None + + super(RankEvicter, self).__init__() + + def _ready_to_evict(self): + if self._mds_map['up'].get("mds_{0}".format(self.rank), None) != self.gid: + log.info("Evicting {0} from {1}/{2}: rank no longer associated with gid, done.".format( + self._client_spec, self.rank, self.gid + )) + raise RankEvicter.GidGone() + + info = self._mds_map['info']["gid_{0}".format(self.gid)] + log.debug("_ready_to_evict: state={0}".format(info['state'])) + return info['state'] in ["up:active", "up:clientreplay"] + + def _wait_for_ready(self): + """ + Wait for that MDS rank to reach an active or clientreplay state, and + not be laggy. + """ + while not self._ready_to_evict(): + if self._ready_waited > self._ready_timeout: + raise ClusterTimeout() + + time.sleep(self.POLL_PERIOD) + self._ready_waited += self.POLL_PERIOD + self._mds_map = get_mds_map(self.mgr, self.volname) + + def _evict(self): + """ + Run the eviction procedure. Return true on success, false on errors. + """ + + # Wait til the MDS is believed by the mon to be available for commands + try: + self._wait_for_ready() + except self.GidGone: + return True + + # Then send it an evict + ret = -errno.ETIMEDOUT + while ret == -errno.ETIMEDOUT: + log.debug("mds_command: {0}, {1}".format( + "%s" % self.gid, ["session", "evict"] + self._client_spec + )) + ret, outb, outs = self._fs.mds_command( + "%s" % self.gid, + json.dumps({ + "prefix": "session evict", + "filters": self._client_spec + }), "") + log.debug("mds_command: complete {0} {1}".format(ret, outs)) + + # If we get a clean response, great, it's gone from that rank. + if ret == 0: + return True + elif ret == -errno.ETIMEDOUT: + # Oh no, the MDS went laggy (that's how libcephfs knows to emit this error) + self._mds_map = get_mds_map(self.mgr, self.volname) + try: + self._wait_for_ready() + except self.GidGone: + return True + else: + raise ClusterError("Sending evict to mds.{0}".format(self.gid), ret, outs) + + def run(self): + try: + self._evict() + except Exception as e: + self.success = False + self.exception = e + else: + self.success = True diff --git a/src/pybind/mgr/volumes/fs/operations/resolver.py b/src/pybind/mgr/volumes/fs/operations/resolver.py new file mode 100644 index 00000000..a9543654 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/resolver.py @@ -0,0 +1,26 @@ +import os + +from .group import Group + +def splitall(path): + if path == "/": + return ["/"] + s = os.path.split(path) + return splitall(s[0]) + [s[1]] + +def resolve(vol_spec, path): + parts = splitall(path) + if len(parts) != 4 or os.path.join(parts[0], parts[1]) != vol_spec.subvolume_prefix: + return None + groupname = None if parts[2] == Group.NO_GROUP_NAME else parts[2] + subvolname = parts[3] + return (groupname, subvolname) + +def resolve_trash(vol_spec, path): + parts = splitall(path) + if len(parts) != 6 or os.path.join(parts[0], parts[1]) != vol_spec.subvolume_prefix or \ + parts[4] != '.trash': + return None + groupname = None if parts[2] == Group.NO_GROUP_NAME else parts[2] + subvolname = parts[3] + return (groupname, subvolname) diff --git a/src/pybind/mgr/volumes/fs/operations/snapshot_util.py b/src/pybind/mgr/volumes/fs/operations/snapshot_util.py new file mode 100644 index 00000000..2223c58e --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/snapshot_util.py @@ -0,0 +1,30 @@ +import os +import errno + +import cephfs + +from ..exception import VolumeException + +def mksnap(fs, snappath): + """ + Create a snapshot, or do nothing if it already exists. + """ + try: + # snap create does not accept mode -- use default + fs.mkdir(snappath, 0o755) + except cephfs.ObjectExists: + return + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + +def rmsnap(fs, snappath): + """ + Remove a snapshot + """ + try: + fs.stat(snappath) + fs.rmdir(snappath) + except cephfs.ObjectNotFound: + raise VolumeException(-errno.ENOENT, "snapshot '{0}' does not exist".format(os.path.basename(snappath))) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) diff --git a/src/pybind/mgr/volumes/fs/operations/subvolume.py b/src/pybind/mgr/volumes/fs/operations/subvolume.py new file mode 100644 index 00000000..dc36477b --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/subvolume.py @@ -0,0 +1,74 @@ +import os +import errno +from contextlib import contextmanager + +from ..exception import VolumeException +from .template import SubvolumeOpType + +from .versions import loaded_subvolumes + +def create_subvol(mgr, fs, vol_spec, group, subvolname, size, isolate_nspace, pool, mode, uid, gid): + """ + create a subvolume (create a subvolume with the max known version). + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :param group: group object for the subvolume + :param size: In bytes, or None for no size limit + :param isolate_nspace: If true, use separate RADOS namespace for this subvolume + :param pool: the RADOS pool where the data objects of the subvolumes will be stored + :param mode: the user permissions + :param uid: the user identifier + :param gid: the group identifier + :return: None + """ + subvolume = loaded_subvolumes.get_subvolume_object_max(mgr, fs, vol_spec, group, subvolname) + subvolume.create(size, isolate_nspace, pool, mode, uid, gid) + +def create_clone(mgr, fs, vol_spec, group, subvolname, pool, source_volume, source_subvolume, snapname): + """ + create a cloned subvolume. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :param group: group object for the clone + :param subvolname: clone subvolume nam + :param pool: the RADOS pool where the data objects of the cloned subvolume will be stored + :param source_volume: source subvolumes volume name + :param source_subvolume: source (parent) subvolume object + :param snapname: source subvolume snapshot + :return None + """ + subvolume = loaded_subvolumes.get_subvolume_object_max(mgr, fs, vol_spec, group, subvolname) + subvolume.create_clone(pool, source_volume, source_subvolume, snapname) + +def remove_subvol(mgr, fs, vol_spec, group, subvolname, force=False, retainsnaps=False): + """ + remove a subvolume. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :param group: group object for the subvolume + :param subvolname: subvolume name + :param force: force remove subvolumes + :return: None + """ + op_type = SubvolumeOpType.REMOVE if not force else SubvolumeOpType.REMOVE_FORCE + with open_subvol(mgr, fs, vol_spec, group, subvolname, op_type) as subvolume: + subvolume.remove(retainsnaps) + +@contextmanager +def open_subvol(mgr, fs, vol_spec, group, subvolname, op_type): + """ + open a subvolume. This API is to be used as a context manager. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :param group: group object for the subvolume + :param subvolname: subvolume name + :param op_type: operation type for which subvolume is being opened + :return: yields a subvolume object (subclass of SubvolumeTemplate) + """ + subvolume = loaded_subvolumes.get_subvolume_object(mgr, fs, vol_spec, group, subvolname) + subvolume.open(op_type) + yield subvolume diff --git a/src/pybind/mgr/volumes/fs/operations/template.py b/src/pybind/mgr/volumes/fs/operations/template.py new file mode 100644 index 00000000..d35ad0de --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/template.py @@ -0,0 +1,173 @@ +import errno + +from enum import Enum, unique + +from ..exception import VolumeException + +class GroupTemplate(object): + def list_subvolumes(self): + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def create_snapshot(self, snapname): + """ + create a subvolume group snapshot. + + :param: group snapshot name + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def remove_snapshot(self, snapname): + """ + remove a subvolume group snapshot. + + :param: group snapshot name + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def list_snapshots(self): + """ + list all subvolume group snapshots. + + :param: None + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + +@unique +class SubvolumeOpType(Enum): + CREATE = 'create' + REMOVE = 'rm' + REMOVE_FORCE = 'rm-force' + PIN = 'pin' + LIST = 'ls' + GETPATH = 'getpath' + INFO = 'info' + RESIZE = 'resize' + SNAP_CREATE = 'snap-create' + SNAP_REMOVE = 'snap-rm' + SNAP_LIST = 'snap-ls' + SNAP_INFO = 'snap-info' + SNAP_PROTECT = 'snap-protect' + SNAP_UNPROTECT = 'snap-unprotect' + CLONE_SOURCE = 'clone-source' + CLONE_CREATE = 'clone-create' + CLONE_STATUS = 'clone-status' + CLONE_CANCEL = 'clone-cancel' + CLONE_INTERNAL = 'clone_internal' + ALLOW_ACCESS = 'allow-access' + DENY_ACCESS = 'deny-access' + AUTH_LIST = 'auth-list' + EVICT = 'evict' + +class SubvolumeTemplate(object): + VERSION = None # type: int + + @staticmethod + def version(): + return SubvolumeTemplate.VERSION + + def open(self, op_type): + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def status(self): + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def create(self, size, isolate_nspace, pool, mode, uid, gid): + """ + set up metadata, pools and auth for a subvolume. + + This function is idempotent. It is safe to call this again + for an already-created subvolume, even if it is in use. + + :param size: In bytes, or None for no size limit + :param isolate_nspace: If true, use separate RADOS namespace for this subvolume + :param pool: the RADOS pool where the data objects of the subvolumes will be stored + :param mode: the user permissions + :param uid: the user identifier + :param gid: the group identifier + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def create_clone(self, pool, source_volname, source_subvolume, snapname): + """ + prepare a subvolume to be cloned. + + :param pool: the RADOS pool where the data objects of the cloned subvolume will be stored + :param source_volname: source volume of snapshot + :param source_subvolume: source subvolume of snapshot + :param snapname: snapshot name to be cloned from + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def remove(self): + """ + make a subvolume inaccessible to guests. + + This function is idempotent. It is safe to call this again + + :param: None + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def resize(self, newsize, nshrink): + """ + resize a subvolume + + :param newsize: new size In bytes (or inf/infinite) + :return: new quota size and used bytes as a tuple + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def create_snapshot(self, snapname): + """ + snapshot a subvolume. + + :param: subvolume snapshot name + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def remove_snapshot(self, snapname): + """ + remove a subvolume snapshot. + + :param: subvolume snapshot name + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def list_snapshots(self): + """ + list all subvolume snapshots. + + :param: None + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def attach_snapshot(self, snapname, tgt_subvolume): + """ + attach a snapshot to a target cloned subvolume. the target subvolume + should be an empty subvolume (type "clone") in "pending" state. + + :param: snapname: snapshot to attach to a clone + :param: tgt_subvolume: target clone subvolume + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") + + def detach_snapshot(self, snapname, tgt_subvolume): + """ + detach a snapshot from a target cloned subvolume. the target subvolume + should either be in "failed" or "completed" state. + + :param: snapname: snapshot to detach from a clone + :param: tgt_subvolume: target clone subvolume + :return: None + """ + raise VolumeException(-errno.ENOTSUP, "operation not supported.") diff --git a/src/pybind/mgr/volumes/fs/operations/trash.py b/src/pybind/mgr/volumes/fs/operations/trash.py new file mode 100644 index 00000000..66f1d71c --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/trash.py @@ -0,0 +1,145 @@ +import os +import uuid +import logging +from contextlib import contextmanager + +import cephfs + +from .template import GroupTemplate +from ..fs_util import listdir +from ..exception import VolumeException + +log = logging.getLogger(__name__) + +class Trash(GroupTemplate): + GROUP_NAME = "_deleting" + + def __init__(self, fs, vol_spec): + self.fs = fs + self.vol_spec = vol_spec + self.groupname = Trash.GROUP_NAME + + @property + def path(self): + return os.path.join(self.vol_spec.base_dir.encode('utf-8'), self.groupname.encode('utf-8')) + + @property + def unique_trash_path(self): + """ + return a unique trash directory entry path + """ + return os.path.join(self.path, str(uuid.uuid4()).encode('utf-8')) + + def _get_single_dir_entry(self, exclude_list=[]): + exclude_list.extend((b".", b"..")) + try: + with self.fs.opendir(self.path) as d: + entry = self.fs.readdir(d) + while entry: + if entry.d_name not in exclude_list: + return entry.d_name + entry = self.fs.readdir(d) + return None + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def get_trash_entry(self, exclude_list): + """ + get a trash entry excluding entries provided. + + :praram exclude_list: entries to exclude + :return: trash entry + """ + return self._get_single_dir_entry(exclude_list) + + def purge(self, trashpath, should_cancel): + """ + purge a trash entry. + + :praram trash_entry: the trash entry to purge + :praram should_cancel: callback to check if the purge should be aborted + :return: None + """ + def rmtree(root_path): + log.debug("rmtree {0}".format(root_path)) + try: + with self.fs.opendir(root_path) as dir_handle: + d = self.fs.readdir(dir_handle) + while d and not should_cancel(): + if d.d_name not in (b".", b".."): + d_full = os.path.join(root_path, d.d_name) + if d.is_dir(): + rmtree(d_full) + else: + self.fs.unlink(d_full) + d = self.fs.readdir(dir_handle) + except cephfs.ObjectNotFound: + return + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + # remove the directory only if we were not asked to cancel + # (else we would fail to remove this anyway) + if not should_cancel(): + self.fs.rmdir(root_path) + + # catch any unlink errors + try: + rmtree(trashpath) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def dump(self, path): + """ + move an filesystem entity to trash can. + + :praram path: the filesystem path to be moved + :return: None + """ + try: + self.fs.rename(path, self.unique_trash_path) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def link(self, path, bname): + pth = os.path.join(self.path, bname) + try: + self.fs.symlink(path, pth) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def delink(self, bname): + pth = os.path.join(self.path, bname) + try: + self.fs.unlink(pth) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + +def create_trashcan(fs, vol_spec): + """ + create a trash can. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :return: None + """ + trashcan = Trash(fs, vol_spec) + try: + fs.mkdirs(trashcan.path, 0o700) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + +@contextmanager +def open_trashcan(fs, vol_spec): + """ + open a trash can. This API is to be used as a context manager. + + :param fs: ceph filesystem handle + :param vol_spec: volume specification + :return: yields a trash can object (subclass of GroupTemplate) + """ + trashcan = Trash(fs, vol_spec) + try: + fs.stat(trashcan.path) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + yield trashcan diff --git a/src/pybind/mgr/volumes/fs/operations/versions/__init__.py b/src/pybind/mgr/volumes/fs/operations/versions/__init__.py new file mode 100644 index 00000000..3dcdd7c1 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/__init__.py @@ -0,0 +1,109 @@ +import errno +import logging +import importlib + +import cephfs + +from .subvolume_base import SubvolumeBase +from .subvolume_attrs import SubvolumeTypes +from .subvolume_v1 import SubvolumeV1 +from .subvolume_v2 import SubvolumeV2 +from .metadata_manager import MetadataManager +from .op_sm import SubvolumeOpSm +from ..template import SubvolumeOpType +from ...exception import MetadataMgrException, OpSmException, VolumeException + +log = logging.getLogger(__name__) + +class SubvolumeLoader(object): + INVALID_VERSION = -1 + + SUPPORTED_MODULES = ['subvolume_v1.SubvolumeV1', 'subvolume_v2.SubvolumeV2'] + + def __init__(self): + self.max_version = SubvolumeLoader.INVALID_VERSION + self.versions = {} + + def _load_module(self, mod_cls): + mod_name, cls_name = mod_cls.split('.') + mod = importlib.import_module('.versions.{0}'.format(mod_name), package='volumes.fs.operations') + return getattr(mod, cls_name) + + def _load_supported_versions(self): + for mod_cls in SubvolumeLoader.SUPPORTED_MODULES: + cls = self._load_module(mod_cls) + log.info("loaded v{0} subvolume".format(cls.version())) + if self.max_version is not None or cls.version() > self.max_version: + self.max_version = cls.version() + self.versions[cls.version()] = cls + if self.max_version == SubvolumeLoader.INVALID_VERSION: + raise VolumeException(-errno.EINVAL, "no subvolume version available") + log.info("max subvolume version is v{0}".format(self.max_version)) + + def _get_subvolume_version(self, version): + try: + return self.versions[version] + except KeyError: + raise VolumeException(-errno.EINVAL, "subvolume class v{0} does not exist".format(version)) + + def get_subvolume_object_max(self, mgr, fs, vol_spec, group, subvolname): + return self._get_subvolume_version(self.max_version)(mgr, fs, vol_spec, group, subvolname) + + def upgrade_to_v2_subvolume(self, subvolume): + # legacy mode subvolumes cannot be upgraded to v2 + if subvolume.legacy_mode: + return + + version = int(subvolume.metadata_mgr.get_global_option('version')) + if version >= SubvolumeV2.version(): + return + + v1_subvolume = self._get_subvolume_version(version)(subvolume.mgr, subvolume.fs, subvolume.vol_spec, subvolume.group, subvolume.subvolname) + try: + v1_subvolume.open(SubvolumeOpType.SNAP_LIST) + except VolumeException as ve: + # if volume is not ready for snapshot listing, do not upgrade at present + if ve.errno == -errno.EAGAIN: + return + raise + + # v1 subvolumes with snapshots cannot be upgraded to v2 + if v1_subvolume.list_snapshots(): + return + + subvolume.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_VERSION, SubvolumeV2.version()) + subvolume.metadata_mgr.flush() + + def upgrade_legacy_subvolume(self, fs, subvolume): + assert subvolume.legacy_mode + try: + fs.mkdirs(subvolume.legacy_dir, 0o700) + except cephfs.Error as e: + raise VolumeException(-e.args[0], "error accessing subvolume") + subvolume_type = SubvolumeTypes.TYPE_NORMAL + try: + initial_state = SubvolumeOpSm.get_init_state(subvolume_type) + except OpSmException as oe: + raise VolumeException(-errno.EINVAL, "subvolume creation failed: internal error") + qpath = subvolume.base_path.decode('utf-8') + # legacy is only upgradable to v1 + subvolume.init_config(SubvolumeV1.version(), subvolume_type, qpath, initial_state) + + def get_subvolume_object(self, mgr, fs, vol_spec, group, subvolname, upgrade=True): + subvolume = SubvolumeBase(mgr, fs, vol_spec, group, subvolname) + try: + subvolume.discover() + self.upgrade_to_v2_subvolume(subvolume) + version = int(subvolume.metadata_mgr.get_global_option('version')) + return self._get_subvolume_version(version)(mgr, fs, vol_spec, group, subvolname, legacy=subvolume.legacy_mode) + except MetadataMgrException as me: + if me.errno == -errno.ENOENT and upgrade: + self.upgrade_legacy_subvolume(fs, subvolume) + return self.get_subvolume_object(mgr, fs, vol_spec, group, subvolname, upgrade=False) + else: + # log the actual error and generalize error string returned to user + log.error("error accessing subvolume metadata for '{0}' ({1})".format(subvolname, me)) + raise VolumeException(-errno.EINVAL, "error accessing subvolume metadata") + +loaded_subvolumes = SubvolumeLoader() +loaded_subvolumes._load_supported_versions() diff --git a/src/pybind/mgr/volumes/fs/operations/versions/auth_metadata.py b/src/pybind/mgr/volumes/fs/operations/versions/auth_metadata.py new file mode 100644 index 00000000..259dcd0e --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/auth_metadata.py @@ -0,0 +1,208 @@ +from contextlib import contextmanager +import os +import fcntl +import json +import logging +import struct +import uuid + +import cephfs + +from ..group import Group + +log = logging.getLogger(__name__) + +class AuthMetadataError(Exception): + pass + +class AuthMetadataManager(object): + + # Current version + version = 6 + + # Filename extensions for meta files. + META_FILE_EXT = ".meta" + DEFAULT_VOL_PREFIX = "/volumes" + + def __init__(self, fs): + self.fs = fs + self._id = struct.unpack(">Q", uuid.uuid1().bytes[0:8])[0] + self.volume_prefix = self.DEFAULT_VOL_PREFIX + + def _to_bytes(self, param): + ''' + Helper method that returns byte representation of the given parameter. + ''' + if isinstance(param, str): + return param.encode('utf-8') + elif param is None: + return param + else: + return str(param).encode('utf-8') + + def _subvolume_metadata_path(self, group_name, subvol_name): + return os.path.join(self.volume_prefix, "_{0}:{1}{2}".format( + group_name if group_name != Group.NO_GROUP_NAME else "", + subvol_name, + self.META_FILE_EXT)) + + def _check_compat_version(self, compat_version): + if self.version < compat_version: + msg = ("The current version of AuthMetadataManager, version {0} " + "does not support the required feature. Need version {1} " + "or greater".format(self.version, compat_version) + ) + log.error(msg) + raise AuthMetadataError(msg) + + def _metadata_get(self, path): + """ + Return a deserialized JSON object, or None + """ + fd = self.fs.open(path, "r") + # TODO iterate instead of assuming file < 4MB + read_bytes = self.fs.read(fd, 0, 4096 * 1024) + self.fs.close(fd) + if read_bytes: + return json.loads(read_bytes.decode()) + else: + return None + + def _metadata_set(self, path, data): + serialized = json.dumps(data) + fd = self.fs.open(path, "w") + try: + self.fs.write(fd, self._to_bytes(serialized), 0) + self.fs.fsync(fd, 0) + finally: + self.fs.close(fd) + + def _lock(self, path): + @contextmanager + def fn(): + while(1): + fd = self.fs.open(path, os.O_CREAT, 0o755) + self.fs.flock(fd, fcntl.LOCK_EX, self._id) + + # The locked file will be cleaned up sometime. It could be + # unlinked by consumer e.g., an another manila-share service + # instance, before lock was applied on it. Perform checks to + # ensure that this does not happen. + try: + statbuf = self.fs.stat(path) + except cephfs.ObjectNotFound: + self.fs.close(fd) + continue + + fstatbuf = self.fs.fstat(fd) + if statbuf.st_ino == fstatbuf.st_ino: + break + + try: + yield + finally: + self.fs.flock(fd, fcntl.LOCK_UN, self._id) + self.fs.close(fd) + + return fn() + + def _auth_metadata_path(self, auth_id): + return os.path.join(self.volume_prefix, "${0}{1}".format( + auth_id, self.META_FILE_EXT)) + + def auth_lock(self, auth_id): + return self._lock(self._auth_metadata_path(auth_id)) + + def auth_metadata_get(self, auth_id): + """ + Call me with the metadata locked! + + Check whether a auth metadata structure can be decoded by the current + version of AuthMetadataManager. + + Return auth metadata that the current version of AuthMetadataManager + can decode. + """ + auth_metadata = self._metadata_get(self._auth_metadata_path(auth_id)) + + if auth_metadata: + self._check_compat_version(auth_metadata['compat_version']) + + return auth_metadata + + def auth_metadata_set(self, auth_id, data): + """ + Call me with the metadata locked! + + Fsync the auth metadata. + + Add two version attributes to the auth metadata, + 'compat_version', the minimum AuthMetadataManager version that can + decode the metadata, and 'version', the AuthMetadataManager version + that encoded the metadata. + """ + data['compat_version'] = 6 + data['version'] = self.version + return self._metadata_set(self._auth_metadata_path(auth_id), data) + + def create_subvolume_metadata_file(self, group_name, subvol_name): + """ + Create a subvolume metadata file, if it does not already exist, to store + data about auth ids having access to the subvolume + """ + fd = self.fs.open(self._subvolume_metadata_path(group_name, subvol_name), + os.O_CREAT, 0o755) + self.fs.close(fd) + + def delete_subvolume_metadata_file(self, group_name, subvol_name): + vol_meta_path = self._subvolume_metadata_path(group_name, subvol_name) + try: + self.fs.unlink(vol_meta_path) + except cephfs.ObjectNotFound: + pass + + def subvol_metadata_lock(self, group_name, subvol_name): + """ + Return a ContextManager which locks the authorization metadata for + a particular subvolume, and persists a flag to the metadata indicating + that it is currently locked, so that we can detect dirty situations + during recovery. + + This lock isn't just to make access to the metadata safe: it's also + designed to be used over the two-step process of checking the + metadata and then responding to an authorization request, to + ensure that at the point we respond the metadata hasn't changed + in the background. It's key to how we avoid security holes + resulting from races during that problem , + """ + return self._lock(self._subvolume_metadata_path(group_name, subvol_name)) + + def subvol_metadata_get(self, group_name, subvol_name): + """ + Call me with the metadata locked! + + Check whether a subvolume metadata structure can be decoded by the current + version of AuthMetadataManager. + + Return a subvolume_metadata structure that the current version of + AuthMetadataManager can decode. + """ + subvolume_metadata = self._metadata_get(self._subvolume_metadata_path(group_name, subvol_name)) + + if subvolume_metadata: + self._check_compat_version(subvolume_metadata['compat_version']) + + return subvolume_metadata + + def subvol_metadata_set(self, group_name, subvol_name, data): + """ + Call me with the metadata locked! + + Add two version attributes to the subvolume metadata, + 'compat_version', the minimum AuthMetadataManager version that can + decode the metadata and 'version', the AuthMetadataManager version + that encoded the metadata. + """ + data['compat_version'] = 1 + data['version'] = self.version + return self._metadata_set(self._subvolume_metadata_path(group_name, subvol_name), data) diff --git a/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py b/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py new file mode 100644 index 00000000..1b6c4327 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py @@ -0,0 +1,144 @@ +import os +import errno +import logging +import sys + +if sys.version_info >= (3, 2): + import configparser +else: + import ConfigParser as configparser + +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + +import cephfs + +from ...exception import MetadataMgrException + +log = logging.getLogger(__name__) + +class MetadataManager(object): + GLOBAL_SECTION = "GLOBAL" + GLOBAL_META_KEY_VERSION = "version" + GLOBAL_META_KEY_TYPE = "type" + GLOBAL_META_KEY_PATH = "path" + GLOBAL_META_KEY_STATE = "state" + + MAX_IO_BYTES = 8 * 1024 + + def __init__(self, fs, config_path, mode): + self.fs = fs + self.mode = mode + self.config_path = config_path + if sys.version_info >= (3, 2): + self.config = configparser.ConfigParser() + else: + self.config = configparser.SafeConfigParser() + + def refresh(self): + fd = None + conf_data = StringIO() + try: + log.debug("opening config {0}".format(self.config_path)) + fd = self.fs.open(self.config_path, os.O_RDONLY) + while True: + data = self.fs.read(fd, -1, MetadataManager.MAX_IO_BYTES) + if not len(data): + break + conf_data.write(data.decode('utf-8')) + conf_data.seek(0) + self.config.readfp(conf_data) + except cephfs.ObjectNotFound: + raise MetadataMgrException(-errno.ENOENT, "metadata config '{0}' not found".format(self.config_path)) + except cephfs.Error as e: + raise MetadataMgrException(-e.args[0], e.args[1]) + finally: + if fd is not None: + self.fs.close(fd) + + def flush(self): + # cull empty sections + for section in list(self.config.sections()): + if len(self.config.items(section)) == 0: + self.config.remove_section(section) + + conf_data = StringIO() + self.config.write(conf_data) + conf_data.seek(0) + + fd = None + try: + fd = self.fs.open(self.config_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, self.mode) + wrote = 0 + while True: + data = conf_data.read() + if not len(data): + break + wrote += self.fs.write(fd, data.encode('utf-8'), -1) + self.fs.fsync(fd, 0) + log.info("wrote {0} bytes to config {1}".format(wrote, self.config_path)) + except cephfs.Error as e: + raise MetadataMgrException(-e.args[0], e.args[1]) + finally: + if fd is not None: + self.fs.close(fd) + + def init(self, version, typ, path, state): + # you may init just once before refresh (helps to overwrite conf) + if self.config.has_section(MetadataManager.GLOBAL_SECTION): + raise MetadataMgrException(-errno.EINVAL, "init called on an existing config") + + self.add_section(MetadataManager.GLOBAL_SECTION) + self.update_section_multi( + MetadataManager.GLOBAL_SECTION, {MetadataManager.GLOBAL_META_KEY_VERSION : str(version), + MetadataManager.GLOBAL_META_KEY_TYPE : str(typ), + MetadataManager.GLOBAL_META_KEY_PATH : str(path), + MetadataManager.GLOBAL_META_KEY_STATE : str(state) + }) + + def add_section(self, section): + try: + self.config.add_section(section) + except configparser.DuplicateSectionError: + return + except: + raise MetadataMgrException(-errno.EINVAL, "error adding section to config") + + def remove_option(self, section, key): + if not self.config.has_section(section): + raise MetadataMgrException(-errno.ENOENT, "section '{0}' does not exist".format(section)) + self.config.remove_option(section, key) + + def remove_section(self, section): + self.config.remove_section(section) + + def update_section(self, section, key, value): + if not self.config.has_section(section): + raise MetadataMgrException(-errno.ENOENT, "section '{0}' does not exist".format(section)) + self.config.set(section, key, str(value)) + + def update_section_multi(self, section, dct): + if not self.config.has_section(section): + raise MetadataMgrException(-errno.ENOENT, "section '{0}' does not exist".format(section)) + for key,value in dct.items(): + self.config.set(section, key, str(value)) + + def update_global_section(self, key, value): + self.update_section(MetadataManager.GLOBAL_SECTION, key, str(value)) + + def get_option(self, section, key): + if not self.config.has_section(section): + raise MetadataMgrException(-errno.ENOENT, "section '{0}' does not exist".format(section)) + if not self.config.has_option(section, key): + raise MetadataMgrException(-errno.ENOENT, "no config '{0}' in section '{1}'".format(key, section)) + return self.config.get(section, key) + + def get_global_option(self, key): + return self.get_option(MetadataManager.GLOBAL_SECTION, key) + + def section_has_item(self, section, item): + if not self.config.has_section(section): + raise MetadataMgrException(-errno.ENOENT, "section '{0}' does not exist".format(section)) + return item in [v[1] for v in self.config.items(section)] diff --git a/src/pybind/mgr/volumes/fs/operations/versions/op_sm.py b/src/pybind/mgr/volumes/fs/operations/versions/op_sm.py new file mode 100644 index 00000000..c2b5f582 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/op_sm.py @@ -0,0 +1,114 @@ +import errno + +from enum import Enum, unique + +from ...exception import OpSmException +from .subvolume_attrs import SubvolumeTypes, SubvolumeStates, SubvolumeActions + +class TransitionKey(object): + def __init__(self, subvol_type, state, action_type): + self.transition_key = [subvol_type, state, action_type] + + def __hash__(self): + return hash(tuple(self.transition_key)) + + def __eq__(self, other): + return self.transition_key == other.transition_key + + def __neq__(self, other): + return not(self == other) + +class SubvolumeOpSm(object): + transition_table = {} + + @staticmethod + def is_complete_state(state): + if not isinstance(state, SubvolumeStates): + raise OpSmException(-errno.EINVAL, "unknown state '{0}'".format(state)) + return state == SubvolumeStates.STATE_COMPLETE + + @staticmethod + def is_failed_state(state): + if not isinstance(state, SubvolumeStates): + raise OpSmException(-errno.EINVAL, "unknown state '{0}'".format(state)) + return state == SubvolumeStates.STATE_FAILED or state == SubvolumeStates.STATE_CANCELED + + @staticmethod + def is_init_state(stm_type, state): + if not isinstance(state, SubvolumeStates): + raise OpSmException(-errno.EINVAL, "unknown state '{0}'".format(state)) + return state == SubvolumeOpSm.get_init_state(stm_type) + + @staticmethod + def get_init_state(stm_type): + if not isinstance(stm_type, SubvolumeTypes): + raise OpSmException(-errno.EINVAL, "unknown state machine '{0}'".format(stm_type)) + init_state = SubvolumeOpSm.transition_table[TransitionKey(stm_type, + SubvolumeStates.STATE_INIT, + SubvolumeActions.ACTION_NONE)] + if not init_state: + raise OpSmException(-errno.ENOENT, "initial state for state machine '{0}' not found".format(stm_type)) + return init_state + + @staticmethod + def transition(stm_type, current_state, action): + if not isinstance(stm_type, SubvolumeTypes): + raise OpSmException(-errno.EINVAL, "unknown state machine '{0}'".format(stm_type)) + if not isinstance(current_state, SubvolumeStates): + raise OpSmException(-errno.EINVAL, "unknown state '{0}'".format(current_state)) + if not isinstance(action, SubvolumeActions): + raise OpSmException(-errno.EINVAL, "unknown action '{0}'".format(action)) + + transition = SubvolumeOpSm.transition_table[TransitionKey(stm_type, current_state, action)] + if not transition: + raise OpSmException(-errno.EINVAL, "invalid action '{0}' on current state {1} for state machine '{2}'".format(action, current_state, stm_type)) + + return transition + +SubvolumeOpSm.transition_table = { + # state transitions for state machine type TYPE_NORMAL + TransitionKey(SubvolumeTypes.TYPE_NORMAL, + SubvolumeStates.STATE_INIT, + SubvolumeActions.ACTION_NONE) : SubvolumeStates.STATE_COMPLETE, + + TransitionKey(SubvolumeTypes.TYPE_NORMAL, + SubvolumeStates.STATE_COMPLETE, + SubvolumeActions.ACTION_RETAINED) : SubvolumeStates.STATE_RETAINED, + + # state transitions for state machine type TYPE_CLONE + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_INIT, + SubvolumeActions.ACTION_NONE) : SubvolumeStates.STATE_PENDING, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_PENDING, + SubvolumeActions.ACTION_SUCCESS) : SubvolumeStates.STATE_INPROGRESS, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_PENDING, + SubvolumeActions.ACTION_CANCELLED) : SubvolumeStates.STATE_CANCELED, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_INPROGRESS, + SubvolumeActions.ACTION_SUCCESS) : SubvolumeStates.STATE_COMPLETE, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_INPROGRESS, + SubvolumeActions.ACTION_CANCELLED) : SubvolumeStates.STATE_CANCELED, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_INPROGRESS, + SubvolumeActions.ACTION_FAILED) : SubvolumeStates.STATE_FAILED, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_COMPLETE, + SubvolumeActions.ACTION_RETAINED) : SubvolumeStates.STATE_RETAINED, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_CANCELED, + SubvolumeActions.ACTION_RETAINED) : SubvolumeStates.STATE_RETAINED, + + TransitionKey(SubvolumeTypes.TYPE_CLONE, + SubvolumeStates.STATE_FAILED, + SubvolumeActions.ACTION_RETAINED) : SubvolumeStates.STATE_RETAINED, +} diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_attrs.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_attrs.py new file mode 100644 index 00000000..ec7138cb --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_attrs.py @@ -0,0 +1,61 @@ +import errno +from enum import Enum, unique + +from ...exception import VolumeException + +@unique +class SubvolumeTypes(Enum): + TYPE_NORMAL = "subvolume" + TYPE_CLONE = "clone" + + @staticmethod + def from_value(value): + if value == "subvolume": + return SubvolumeTypes.TYPE_NORMAL + if value == "clone": + return SubvolumeTypes.TYPE_CLONE + + raise VolumeException(-errno.EINVAL, "invalid subvolume type '{0}'".format(value)) + +@unique +class SubvolumeStates(Enum): + STATE_INIT = 'init' + STATE_PENDING = 'pending' + STATE_INPROGRESS = 'in-progress' + STATE_FAILED = 'failed' + STATE_COMPLETE = 'complete' + STATE_CANCELED = 'canceled' + STATE_RETAINED = 'snapshot-retained' + + @staticmethod + def from_value(value): + if value == "init": + return SubvolumeStates.STATE_INIT + if value == "pending": + return SubvolumeStates.STATE_PENDING + if value == "in-progress": + return SubvolumeStates.STATE_INPROGRESS + if value == "failed": + return SubvolumeStates.STATE_FAILED + if value == "complete": + return SubvolumeStates.STATE_COMPLETE + if value == "canceled": + return SubvolumeStates.STATE_CANCELED + if value == "snapshot-retained": + return SubvolumeStates.STATE_RETAINED + + raise VolumeException(-errno.EINVAL, "invalid state '{0}'".format(value)) + +@unique +class SubvolumeActions(Enum): + ACTION_NONE = 0 + ACTION_SUCCESS = 1 + ACTION_FAILED = 2 + ACTION_CANCELLED = 3 + ACTION_RETAINED = 4 + +@unique +class SubvolumeFeatures(Enum): + FEATURE_SNAPSHOT_CLONE = "snapshot-clone" + FEATURE_SNAPSHOT_RETENTION = "snapshot-retention" + FEATURE_SNAPSHOT_AUTOPROTECT = "snapshot-autoprotect" diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py new file mode 100644 index 00000000..f193dabd --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_base.py @@ -0,0 +1,331 @@ +import os +import stat +import uuid +import errno +import logging +from hashlib import md5 + +import cephfs + +from .subvolume_attrs import SubvolumeTypes, SubvolumeStates +from .metadata_manager import MetadataManager +from ..trash import create_trashcan, open_trashcan +from ...fs_util import get_ancestor_xattr +from ...exception import MetadataMgrException, VolumeException +from .op_sm import SubvolumeOpSm +from .auth_metadata import AuthMetadataManager + +log = logging.getLogger(__name__) + +class SubvolumeBase(object): + LEGACY_CONF_DIR = "_legacy" + + def __init__(self, mgr, fs, vol_spec, group, subvolname, legacy=False): + self.mgr = mgr + self.fs = fs + self.auth_mdata_mgr = AuthMetadataManager(fs) + self.cmode = None + self.user_id = None + self.group_id = None + self.vol_spec = vol_spec + self.group = group + self.subvolname = subvolname + self.legacy_mode = legacy + self.load_config() + + @property + def uid(self): + return self.user_id + + @uid.setter + def uid(self, val): + self.user_id = val + + @property + def gid(self): + return self.group_id + + @gid.setter + def gid(self, val): + self.group_id = val + + @property + def mode(self): + return self.cmode + + @mode.setter + def mode(self, val): + self.cmode = val + + @property + def base_path(self): + return os.path.join(self.group.path, self.subvolname.encode('utf-8')) + + @property + def config_path(self): + return os.path.join(self.base_path, b".meta") + + @property + def legacy_dir(self): + return os.path.join(self.vol_spec.base_dir.encode('utf-8'), SubvolumeBase.LEGACY_CONF_DIR.encode('utf-8')) + + @property + def legacy_config_path(self): + m = md5() + m.update(self.base_path) + meta_config = "{0}.meta".format(m.hexdigest()) + return os.path.join(self.legacy_dir, meta_config.encode('utf-8')) + + @property + def namespace(self): + return "{0}{1}".format(self.vol_spec.fs_namespace, self.subvolname) + + @property + def group_name(self): + return self.group.group_name + + @property + def subvol_name(self): + return self.subvolname + + @property + def legacy_mode(self): + return self.legacy + + @legacy_mode.setter + def legacy_mode(self, mode): + self.legacy = mode + + @property + def path(self): + """ Path to subvolume data directory """ + raise NotImplementedError + + @property + def features(self): + """ List of features supported by the subvolume, containing items from SubvolumeFeatures """ + raise NotImplementedError + + @property + def state(self): + """ Subvolume state, one of SubvolumeStates """ + raise NotImplementedError + + @property + def subvol_type(self): + return SubvolumeTypes.from_value(self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_TYPE)) + + @property + def purgeable(self): + """ Boolean declaring if subvolume can be purged """ + raise NotImplementedError + + def load_config(self): + if self.legacy_mode: + self.metadata_mgr = MetadataManager(self.fs, self.legacy_config_path, 0o640) + else: + self.metadata_mgr = MetadataManager(self.fs, self.config_path, 0o640) + + def get_attrs(self, pathname): + # get subvolume attributes + attrs = {} + stx = self.fs.statx(pathname, + cephfs.CEPH_STATX_UID | cephfs.CEPH_STATX_GID | cephfs.CEPH_STATX_MODE, + cephfs.AT_SYMLINK_NOFOLLOW) + + attrs["uid"] = int(stx["uid"]) + attrs["gid"] = int(stx["gid"]) + attrs["mode"] = int(int(stx["mode"]) & ~stat.S_IFMT(stx["mode"])) + + try: + attrs["data_pool"] = self.fs.getxattr(pathname, 'ceph.dir.layout.pool').decode('utf-8') + except cephfs.NoData: + attrs["data_pool"] = None + + try: + attrs["pool_namespace"] = self.fs.getxattr(pathname, 'ceph.dir.layout.pool_namespace').decode('utf-8') + except cephfs.NoData: + attrs["pool_namespace"] = None + + try: + attrs["quota"] = int(self.fs.getxattr(pathname, 'ceph.quota.max_bytes').decode('utf-8')) + except cephfs.NoData: + attrs["quota"] = None + + return attrs + + def set_attrs(self, path, attrs): + # set subvolume attributes + # set size + quota = attrs.get("quota") + if quota is not None: + try: + self.fs.setxattr(path, 'ceph.quota.max_bytes', str(quota).encode('utf-8'), 0) + except cephfs.InvalidValue as e: + raise VolumeException(-errno.EINVAL, "invalid size specified: '{0}'".format(quota)) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + # set pool layout + data_pool = attrs.get("data_pool") + if data_pool is not None: + try: + self.fs.setxattr(path, 'ceph.dir.layout.pool', data_pool.encode('utf-8'), 0) + except cephfs.InvalidValue: + raise VolumeException(-errno.EINVAL, + "invalid pool layout '{0}' -- need a valid data pool".format(data_pool)) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + # isolate namespace + xattr_key = xattr_val = None + pool_namespace = attrs.get("pool_namespace") + if pool_namespace is not None: + # enforce security isolation, use separate namespace for this subvolume + xattr_key = 'ceph.dir.layout.pool_namespace' + xattr_val = pool_namespace + elif not data_pool: + # If subvolume's namespace layout is not set, then the subvolume's pool + # layout remains unset and will undesirably change with ancestor's + # pool layout changes. + xattr_key = 'ceph.dir.layout.pool' + xattr_val = None + try: + self.fs.getxattr(path, 'ceph.dir.layout.pool').decode('utf-8') + except cephfs.NoData as e: + xattr_val = get_ancestor_xattr(self.fs, os.path.split(path)[0], "ceph.dir.layout.pool") + if xattr_key and xattr_val: + try: + self.fs.setxattr(path, xattr_key, xattr_val.encode('utf-8'), 0) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + # set uid/gid + uid = attrs.get("uid") + if uid is None: + uid = self.group.uid + else: + try: + uid = int(uid) + if uid < 0: + raise ValueError + except ValueError: + raise VolumeException(-errno.EINVAL, "invalid UID") + + gid = attrs.get("gid") + if gid is None: + gid = self.group.gid + else: + try: + gid = int(gid) + if gid < 0: + raise ValueError + except ValueError: + raise VolumeException(-errno.EINVAL, "invalid GID") + + if uid is not None and gid is not None: + self.fs.chown(path, uid, gid) + + def _resize(self, path, newsize, noshrink): + try: + newsize = int(newsize) + if newsize <= 0: + raise VolumeException(-errno.EINVAL, "Invalid subvolume size") + except ValueError: + newsize = newsize.lower() + if not (newsize == "inf" or newsize == "infinite"): + raise VolumeException(-errno.EINVAL, "invalid size option '{0}'".format(newsize)) + newsize = 0 + noshrink = False + + try: + maxbytes = int(self.fs.getxattr(path, 'ceph.quota.max_bytes').decode('utf-8')) + except cephfs.NoData: + maxbytes = 0 + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + subvolstat = self.fs.stat(path) + if newsize > 0 and newsize < subvolstat.st_size: + if noshrink: + raise VolumeException(-errno.EINVAL, "Can't resize the subvolume. The new size '{0}' would be lesser than the current " + "used size '{1}'".format(newsize, subvolstat.st_size)) + + if not newsize == maxbytes: + try: + self.fs.setxattr(path, 'ceph.quota.max_bytes', str(newsize).encode('utf-8'), 0) + except cephfs.Error as e: + raise VolumeException(-e.args[0], "Cannot set new size for the subvolume. '{0}'".format(e.args[1])) + return newsize, subvolstat.st_size + + def init_config(self, version, subvolume_type, subvolume_path, subvolume_state): + self.metadata_mgr.init(version, subvolume_type.value, subvolume_path, subvolume_state.value) + self.metadata_mgr.flush() + + def discover(self): + log.debug("discovering subvolume '{0}' [mode: {1}]".format(self.subvolname, "legacy" if self.legacy_mode else "new")) + try: + self.fs.stat(self.base_path) + self.metadata_mgr.refresh() + log.debug("loaded subvolume '{0}'".format(self.subvolname)) + except MetadataMgrException as me: + if me.errno == -errno.ENOENT and not self.legacy_mode: + self.legacy_mode = True + self.load_config() + self.discover() + else: + raise + except cephfs.Error as e: + if e.args[0] == errno.ENOENT: + raise VolumeException(-errno.ENOENT, "subvolume '{0}' does not exist".format(self.subvolname)) + raise VolumeException(-e.args[0], "error accessing subvolume '{0}'".format(self.subvolname)) + + def _trash_dir(self, path): + create_trashcan(self.fs, self.vol_spec) + with open_trashcan(self.fs, self.vol_spec) as trashcan: + trashcan.dump(path) + log.info("subvolume path '{0}' moved to trashcan".format(path)) + + def _link_dir(self, path, bname): + create_trashcan(self.fs, self.vol_spec) + with open_trashcan(self.fs, self.vol_spec) as trashcan: + trashcan.link(path, bname) + log.info("subvolume path '{0}' linked in trashcan bname {1}".format(path, bname)) + + def trash_base_dir(self): + if self.legacy_mode: + self.fs.unlink(self.legacy_config_path) + self._trash_dir(self.base_path) + + def create_base_dir(self, mode): + try: + self.fs.mkdirs(self.base_path, mode) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def info (self): + subvolpath = self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_PATH) + etype = self.subvol_type + st = self.fs.statx(subvolpath, cephfs.CEPH_STATX_BTIME | cephfs.CEPH_STATX_SIZE | + cephfs.CEPH_STATX_UID | cephfs.CEPH_STATX_GID | + cephfs.CEPH_STATX_MODE | cephfs.CEPH_STATX_ATIME | + cephfs.CEPH_STATX_MTIME | cephfs.CEPH_STATX_CTIME, + cephfs.AT_SYMLINK_NOFOLLOW) + usedbytes = st["size"] + try: + nsize = int(self.fs.getxattr(subvolpath, 'ceph.quota.max_bytes').decode('utf-8')) + except cephfs.NoData: + nsize = 0 + + try: + data_pool = self.fs.getxattr(subvolpath, 'ceph.dir.layout.pool').decode('utf-8') + pool_namespace = self.fs.getxattr(subvolpath, 'ceph.dir.layout.pool_namespace').decode('utf-8') + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + return {'path': subvolpath, 'type': etype.value, 'uid': int(st["uid"]), 'gid': int(st["gid"]), + 'atime': str(st["atime"]), 'mtime': str(st["mtime"]), 'ctime': str(st["ctime"]), + 'mode': int(st["mode"]), 'data_pool': data_pool, 'created_at': str(st["btime"]), + 'bytes_quota': "infinite" if nsize == 0 else nsize, 'bytes_used': int(usedbytes), + 'bytes_pcent': "undefined" if nsize == 0 else '{0:.2f}'.format((float(usedbytes) / nsize) * 100.0), + 'pool_namespace': pool_namespace, 'features': self.features, 'state': self.state.value} diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py new file mode 100644 index 00000000..b4cca736 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py @@ -0,0 +1,780 @@ +import os +import sys +import stat +import uuid +import errno +import logging +import json +from datetime import datetime +try: + from typing import List, Dict +except ImportError: + pass # For typing only + +import cephfs + +from .metadata_manager import MetadataManager +from .subvolume_attrs import SubvolumeTypes, SubvolumeStates, SubvolumeFeatures +from .op_sm import SubvolumeOpSm +from .subvolume_base import SubvolumeBase +from ..template import SubvolumeTemplate +from ..snapshot_util import mksnap, rmsnap +from ..access import allow_access, deny_access +from ...exception import IndexException, OpSmException, VolumeException, MetadataMgrException, EvictionError +from ...fs_util import listsnaps, is_inherited_snap +from ..template import SubvolumeOpType +from ..group import Group +from ..rankevicter import RankEvicter +from ..volume import get_mds_map + +from ..clone_index import open_clone_index, create_clone_index + +log = logging.getLogger(__name__) + +class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): + """ + Version 1 subvolumes creates a subvolume with path as follows, + volumes//// + + - The directory under which user data resides is + - Snapshots of the subvolume are taken within the directory + - A meta file is maintained under the directory as a metadata store, typically storing, + - global information about the subvolume (version, path, type, state) + - snapshots attached to an ongoing clone operation + - clone snapshot source if subvolume is a clone of a snapshot + - It retains backward compatability with legacy subvolumes by creating the meta file for legacy subvolumes under + /volumes/_legacy/ (see legacy_config_path), thus allowing cloning of older legacy volumes that lack the + component in the path. + """ + VERSION = 1 + + @staticmethod + def version(): + return SubvolumeV1.VERSION + + @property + def path(self): + try: + # no need to stat the path -- open() does that + return self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_PATH).encode('utf-8') + except MetadataMgrException as me: + raise VolumeException(-errno.EINVAL, "error fetching subvolume metadata") + + @property + def features(self): + return [SubvolumeFeatures.FEATURE_SNAPSHOT_CLONE.value, SubvolumeFeatures.FEATURE_SNAPSHOT_AUTOPROTECT.value] + + def mark_subvolume(self): + # set subvolume attr, on subvolume root, marking it as a CephFS subvolume + # subvolume root is where snapshots would be taken, and hence is the dir for v1 subvolumes + try: + # MDS treats this as a noop for already marked subvolume + self.fs.setxattr(self.path, 'ceph.dir.subvolume', b'1', 0) + except cephfs.InvalidValue as e: + raise VolumeException(-errno.EINVAL, "invalid value specified for ceph.dir.subvolume") + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def snapshot_base_path(self): + """ Base path for all snapshots """ + return os.path.join(self.path, self.vol_spec.snapshot_dir_prefix.encode('utf-8')) + + def snapshot_path(self, snapname): + """ Path to a specific snapshot named 'snapname' """ + return os.path.join(self.snapshot_base_path(), snapname.encode('utf-8')) + + def snapshot_data_path(self, snapname): + """ Path to user data directory within a subvolume snapshot named 'snapname' """ + return self.snapshot_path(snapname) + + def create(self, size, isolate_nspace, pool, mode, uid, gid): + subvolume_type = SubvolumeTypes.TYPE_NORMAL + try: + initial_state = SubvolumeOpSm.get_init_state(subvolume_type) + except OpSmException as oe: + raise VolumeException(-errno.EINVAL, "subvolume creation failed: internal error") + + subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) + try: + # create directory and set attributes + self.fs.mkdirs(subvol_path, mode) + self.mark_subvolume() + attrs = { + 'uid': uid, + 'gid': gid, + 'data_pool': pool, + 'pool_namespace': self.namespace if isolate_nspace else None, + 'quota': size + } + self.set_attrs(subvol_path, attrs) + + # persist subvolume metadata + qpath = subvol_path.decode('utf-8') + self.init_config(SubvolumeV1.VERSION, subvolume_type, qpath, initial_state) + except (VolumeException, MetadataMgrException, cephfs.Error) as e: + try: + log.info("cleaning up subvolume with path: {0}".format(self.subvolname)) + self.remove() + except VolumeException as ve: + log.info("failed to cleanup subvolume '{0}' ({1})".format(self.subvolname, ve)) + + if isinstance(e, MetadataMgrException): + log.error("metadata manager exception: {0}".format(e)) + e = VolumeException(-errno.EINVAL, "exception in subvolume metadata") + elif isinstance(e, cephfs.Error): + e = VolumeException(-e.args[0], e.args[1]) + raise e + + def add_clone_source(self, volname, subvolume, snapname, flush=False): + self.metadata_mgr.add_section("source") + self.metadata_mgr.update_section("source", "volume", volname) + if not subvolume.group.is_default_group(): + self.metadata_mgr.update_section("source", "group", subvolume.group_name) + self.metadata_mgr.update_section("source", "subvolume", subvolume.subvol_name) + self.metadata_mgr.update_section("source", "snapshot", snapname) + if flush: + self.metadata_mgr.flush() + + def remove_clone_source(self, flush=False): + self.metadata_mgr.remove_section("source") + if flush: + self.metadata_mgr.flush() + + def create_clone(self, pool, source_volname, source_subvolume, snapname): + subvolume_type = SubvolumeTypes.TYPE_CLONE + try: + initial_state = SubvolumeOpSm.get_init_state(subvolume_type) + except OpSmException as oe: + raise VolumeException(-errno.EINVAL, "clone failed: internal error") + + subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) + try: + # source snapshot attrs are used to create clone subvolume. + # attributes of subvolume's content though, are synced during the cloning process. + attrs = source_subvolume.get_attrs(source_subvolume.snapshot_data_path(snapname)) + + # override snapshot pool setting, if one is provided for the clone + if pool is not None: + attrs["data_pool"] = pool + attrs["pool_namespace"] = None + + # create directory and set attributes + self.fs.mkdirs(subvol_path, attrs.get("mode")) + self.mark_subvolume() + self.set_attrs(subvol_path, attrs) + + # persist subvolume metadata and clone source + qpath = subvol_path.decode('utf-8') + self.metadata_mgr.init(SubvolumeV1.VERSION, subvolume_type.value, qpath, initial_state.value) + self.add_clone_source(source_volname, source_subvolume, snapname) + self.metadata_mgr.flush() + except (VolumeException, MetadataMgrException, cephfs.Error) as e: + try: + log.info("cleaning up subvolume with path: {0}".format(self.subvolname)) + self.remove() + except VolumeException as ve: + log.info("failed to cleanup subvolume '{0}' ({1})".format(self.subvolname, ve)) + + if isinstance(e, MetadataMgrException): + log.error("metadata manager exception: {0}".format(e)) + e = VolumeException(-errno.EINVAL, "exception in subvolume metadata") + elif isinstance(e, cephfs.Error): + e = VolumeException(-e.args[0], e.args[1]) + raise e + + def allowed_ops_by_type(self, vol_type): + if vol_type == SubvolumeTypes.TYPE_CLONE: + return {op_type for op_type in SubvolumeOpType} + + if vol_type == SubvolumeTypes.TYPE_NORMAL: + return {op_type for op_type in SubvolumeOpType} - {SubvolumeOpType.CLONE_STATUS, + SubvolumeOpType.CLONE_CANCEL, + SubvolumeOpType.CLONE_INTERNAL} + + return {} + + def allowed_ops_by_state(self, vol_state): + if vol_state == SubvolumeStates.STATE_COMPLETE: + return {op_type for op_type in SubvolumeOpType} + + return {SubvolumeOpType.REMOVE_FORCE, + SubvolumeOpType.CLONE_CREATE, + SubvolumeOpType.CLONE_STATUS, + SubvolumeOpType.CLONE_CANCEL, + SubvolumeOpType.CLONE_INTERNAL} + + def open(self, op_type): + if not isinstance(op_type, SubvolumeOpType): + raise VolumeException(-errno.ENOTSUP, "operation {0} not supported on subvolume '{1}'".format( + op_type.value, self.subvolname)) + try: + self.metadata_mgr.refresh() + + etype = self.subvol_type + if op_type not in self.allowed_ops_by_type(etype): + raise VolumeException(-errno.ENOTSUP, "operation '{0}' is not allowed on subvolume '{1}' of type {2}".format( + op_type.value, self.subvolname, etype.value)) + + estate = self.state + if op_type not in self.allowed_ops_by_state(estate): + raise VolumeException(-errno.EAGAIN, "subvolume '{0}' is not ready for operation {1}".format( + self.subvolname, op_type.value)) + + subvol_path = self.path + log.debug("refreshed metadata, checking subvolume path '{0}'".format(subvol_path)) + st = self.fs.stat(subvol_path) + # unconditionally mark as subvolume, to handle pre-existing subvolumes without the mark + self.mark_subvolume() + + self.uid = int(st.st_uid) + self.gid = int(st.st_gid) + self.mode = int(st.st_mode & ~stat.S_IFMT(st.st_mode)) + except MetadataMgrException as me: + if me.errno == -errno.ENOENT: + raise VolumeException(-errno.ENOENT, "subvolume '{0}' does not exist".format(self.subvolname)) + raise VolumeException(me.args[0], me.args[1]) + except cephfs.ObjectNotFound: + log.debug("missing subvolume path '{0}' for subvolume '{1}'".format(subvol_path, self.subvolname)) + raise VolumeException(-errno.ENOENT, "mount path missing for subvolume '{0}'".format(self.subvolname)) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def _recover_auth_meta(self, auth_id, auth_meta): + """ + Call me after locking the auth meta file. + """ + remove_subvolumes = [] + + for subvol, subvol_data in auth_meta['subvolumes'].items(): + if not subvol_data['dirty']: + continue + + (group_name, subvol_name) = subvol.split('/') + group_name = group_name if group_name != 'None' else Group.NO_GROUP_NAME + access_level = subvol_data['access_level'] + + with self.auth_mdata_mgr.subvol_metadata_lock(group_name, subvol_name): + subvol_meta = self.auth_mdata_mgr.subvol_metadata_get(group_name, subvol_name) + + # No SVMeta update indicates that there was no auth update + # in Ceph either. So it's safe to remove corresponding + # partial update in AMeta. + if not subvol_meta or auth_id not in subvol_meta['auths']: + remove_subvolumes.append(subvol) + continue + + want_auth = { + 'access_level': access_level, + 'dirty': False, + } + # SVMeta update looks clean. Ceph auth update must have been + # clean. Update the dirty flag and continue + if subvol_meta['auths'][auth_id] == want_auth: + auth_meta['subvolumes'][subvol]['dirty'] = False + self.auth_mdata_mgr.auth_metadata_set(auth_id, auth_meta) + continue + + client_entity = "client.{0}".format(auth_id) + ret, out, err = self.mgr.mon_command( + { + 'prefix': 'auth get', + 'entity': client_entity, + 'format': 'json' + }) + if ret == 0: + existing_caps = json.loads(out) + elif ret == -errno.ENOENT: + existing_caps = None + else: + log.error(err) + raise VolumeException(ret, err) + + self._authorize_subvolume(auth_id, access_level, existing_caps) + + # Recovered from partial auth updates for the auth ID's access + # to a subvolume. + auth_meta['subvolumes'][subvol]['dirty'] = False + self.auth_mdata_mgr.auth_metadata_set(auth_id, auth_meta) + + for subvol in remove_subvolumes: + del auth_meta['subvolumes'][subvol] + + if not auth_meta['subvolumes']: + # Clean up auth meta file + self.fs.unlink(self.auth_mdata_mgr._auth_metadata_path(auth_id)) + return + + # Recovered from all partial auth updates for the auth ID. + auth_meta['dirty'] = False + self.auth_mdata_mgr.auth_metadata_set(auth_id, auth_meta) + + def authorize(self, auth_id, access_level, tenant_id=None, allow_existing_id=False): + """ + Get-or-create a Ceph auth identity for `auth_id` and grant them access + to + :param auth_id: + :param access_level: + :param tenant_id: Optionally provide a stringizable object to + restrict any created cephx IDs to other callers + passing the same tenant ID. + :allow_existing_id: Optionally authorize existing auth-ids not + created by ceph_volume_client. + :return: + """ + + with self.auth_mdata_mgr.auth_lock(auth_id): + client_entity = "client.{0}".format(auth_id) + ret, out, err = self.mgr.mon_command( + { + 'prefix': 'auth get', + 'entity': client_entity, + 'format': 'json' + }) + + if ret == 0: + existing_caps = json.loads(out) + elif ret == -errno.ENOENT: + existing_caps = None + else: + log.error(err) + raise VolumeException(ret, err) + + # Existing meta, or None, to be updated + auth_meta = self.auth_mdata_mgr.auth_metadata_get(auth_id) + + # subvolume data to be inserted + group_name = self.group.groupname if self.group.groupname != Group.NO_GROUP_NAME else None + group_subvol_id = "{0}/{1}".format(group_name, self.subvolname) + subvolume = { + group_subvol_id : { + # The access level at which the auth_id is authorized to + # access the volume. + 'access_level': access_level, + 'dirty': True, + } + } + + if auth_meta is None: + if not allow_existing_id and existing_caps is not None: + msg = "auth ID: {0} exists and not created by mgr plugin. Not allowed to modify".format(auth_id) + log.error(msg) + raise VolumeException(-errno.EPERM, msg) + + # non-existent auth IDs + sys.stderr.write("Creating meta for ID {0} with tenant {1}\n".format( + auth_id, tenant_id + )) + log.debug("Authorize: no existing meta") + auth_meta = { + 'dirty': True, + 'tenant_id': str(tenant_id) if tenant_id else None, + 'subvolumes': subvolume + } + else: + # Update 'volumes' key (old style auth metadata file) to 'subvolumes' key + if 'volumes' in auth_meta: + auth_meta['subvolumes'] = auth_meta.pop('volumes') + + # Disallow tenants to share auth IDs + if str(auth_meta['tenant_id']) != str(tenant_id): + msg = "auth ID: {0} is already in use".format(auth_id) + log.error(msg) + raise VolumeException(-errno.EPERM, msg) + + if auth_meta['dirty']: + self._recover_auth_meta(auth_id, auth_meta) + + log.debug("Authorize: existing tenant {tenant}".format( + tenant=auth_meta['tenant_id'] + )) + auth_meta['dirty'] = True + auth_meta['subvolumes'].update(subvolume) + + self.auth_mdata_mgr.auth_metadata_set(auth_id, auth_meta) + + with self.auth_mdata_mgr.subvol_metadata_lock(self.group.groupname, self.subvolname): + key = self._authorize_subvolume(auth_id, access_level, existing_caps) + + auth_meta['dirty'] = False + auth_meta['subvolumes'][group_subvol_id]['dirty'] = False + self.auth_mdata_mgr.auth_metadata_set(auth_id, auth_meta) + + if tenant_id: + return key + else: + # Caller wasn't multi-tenant aware: be safe and don't give + # them a key + return "" + + def _authorize_subvolume(self, auth_id, access_level, existing_caps): + subvol_meta = self.auth_mdata_mgr.subvol_metadata_get(self.group.groupname, self.subvolname) + + auth = { + auth_id: { + 'access_level': access_level, + 'dirty': True, + } + } + + if subvol_meta is None: + subvol_meta = { + 'auths': auth + } + else: + subvol_meta['auths'].update(auth) + self.auth_mdata_mgr.subvol_metadata_set(self.group.groupname, self.subvolname, subvol_meta) + + key = self._authorize(auth_id, access_level, existing_caps) + + subvol_meta['auths'][auth_id]['dirty'] = False + self.auth_mdata_mgr.subvol_metadata_set(self.group.groupname, self.subvolname, subvol_meta) + + return key + + def _authorize(self, auth_id, access_level, existing_caps): + subvol_path = self.path + log.debug("Authorizing Ceph id '{0}' for path '{1}'".format(auth_id, subvol_path)) + + # First I need to work out what the data pool is for this share: + # read the layout + try: + pool = self.fs.getxattr(subvol_path, 'ceph.dir.layout.pool').decode('utf-8') + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + try: + namespace = self.fs.getxattr(subvol_path, 'ceph.dir.layout.pool_namespace').decode('utf-8') + except cephfs.NoData: + namespace = None + + # Now construct auth capabilities that give the guest just enough + # permissions to access the share + client_entity = "client.{0}".format(auth_id) + want_mds_cap = "allow {0} path={1}".format(access_level, subvol_path.decode('utf-8')) + want_osd_cap = "allow {0} pool={1}{2}".format( + access_level, pool, " namespace={0}".format(namespace) if namespace else "") + + # Construct auth caps that if present might conflict with the desired + # auth caps. + unwanted_access_level = 'r' if access_level is 'rw' else 'rw' + unwanted_mds_cap = 'allow {0} path={1}'.format(unwanted_access_level, subvol_path.decode('utf-8')) + unwanted_osd_cap = "allow {0} pool={1}{2}".format( + unwanted_access_level, pool, " namespace={0}".format(namespace) if namespace else "") + + return allow_access(self.mgr, client_entity, want_mds_cap, want_osd_cap, + unwanted_mds_cap, unwanted_osd_cap, existing_caps) + + def deauthorize(self, auth_id): + with self.auth_mdata_mgr.auth_lock(auth_id): + # Existing meta, or None, to be updated + auth_meta = self.auth_mdata_mgr.auth_metadata_get(auth_id) + + if auth_meta is None: + msg = "auth ID: {0} doesn't exist".format(auth_id) + log.error(msg) + raise VolumeException(-errno.ENOENT, msg) + + # Update 'volumes' key (old style auth metadata file) to 'subvolumes' key + if 'volumes' in auth_meta: + auth_meta['subvolumes'] = auth_meta.pop('volumes') + + group_name = self.group.groupname if self.group.groupname != Group.NO_GROUP_NAME else None + group_subvol_id = "{0}/{1}".format(group_name, self.subvolname) + if (auth_meta is None) or (not auth_meta['subvolumes']): + log.warning("deauthorized called for already-removed auth" + "ID '{auth_id}' for subvolume '{subvolume}'".format( + auth_id=auth_id, subvolume=self.subvolname + )) + # Clean up the auth meta file of an auth ID + self.fs.unlink(self.auth_mdata_mgr._auth_metadata_path(auth_id)) + return + + if group_subvol_id not in auth_meta['subvolumes']: + log.warning("deauthorized called for already-removed auth" + "ID '{auth_id}' for subvolume '{subvolume}'".format( + auth_id=auth_id, subvolume=self.subvolname + )) + return + + if auth_meta['dirty']: + self._recover_auth_meta(auth_id, auth_meta) + + auth_meta['dirty'] = True + auth_meta['subvolumes'][group_subvol_id]['dirty'] = True + self.auth_mdata_mgr.auth_metadata_set(auth_id, auth_meta) + + self._deauthorize_subvolume(auth_id) + + # Filter out the volume we're deauthorizing + del auth_meta['subvolumes'][group_subvol_id] + + # Clean up auth meta file + if not auth_meta['subvolumes']: + self.fs.unlink(self.auth_mdata_mgr._auth_metadata_path(auth_id)) + return + + auth_meta['dirty'] = False + self.auth_mdata_mgr.auth_metadata_set(auth_id, auth_meta) + + def _deauthorize_subvolume(self, auth_id): + with self.auth_mdata_mgr.subvol_metadata_lock(self.group.groupname, self.subvolname): + subvol_meta = self.auth_mdata_mgr.subvol_metadata_get(self.group.groupname, self.subvolname) + + if (subvol_meta is None) or (auth_id not in subvol_meta['auths']): + log.warning("deauthorized called for already-removed auth" + "ID '{auth_id}' for subvolume '{subvolume}'".format( + auth_id=auth_id, subvolume=self.subvolname + )) + return + + subvol_meta['auths'][auth_id]['dirty'] = True + self.auth_mdata_mgr.subvol_metadata_set(self.group.groupname, self.subvolname, subvol_meta) + + self._deauthorize(auth_id) + + # Remove the auth_id from the metadata *after* removing it + # from ceph, so that if we crashed here, we would actually + # recreate the auth ID during recovery (i.e. end up with + # a consistent state). + + # Filter out the auth we're removing + del subvol_meta['auths'][auth_id] + self.auth_mdata_mgr.subvol_metadata_set(self.group.groupname, self.subvolname, subvol_meta) + + def _deauthorize(self, auth_id): + """ + The volume must still exist. + """ + client_entity = "client.{0}".format(auth_id) + subvol_path = self.path + try: + pool_name = self.fs.getxattr(subvol_path, 'ceph.dir.layout.pool').decode('utf-8') + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + try: + namespace = self.fs.getxattr(subvol_path, 'ceph.dir.layout.pool_namespace').decode('utf-8') + except cephfs.NoData: + namespace = None + + # The auth_id might have read-only or read-write mount access for the + # subvolume path. + access_levels = ('r', 'rw') + want_mds_caps = ['allow {0} path={1}'.format(access_level, subvol_path.decode('utf-8')) + for access_level in access_levels] + want_osd_caps = ['allow {0} pool={1}{2}'.format( + access_level, pool_name, " namespace={0}".format(namespace) if namespace else "") + for access_level in access_levels] + deny_access(self.mgr, client_entity, want_mds_caps, want_osd_caps) + + def authorized_list(self): + """ + Expose a list of auth IDs that have access to a subvolume. + + return: a list of (auth_id, access_level) tuples, where + the access_level can be 'r' , or 'rw'. + None if no auth ID is given access to the subvolume. + """ + with self.auth_mdata_mgr.subvol_metadata_lock(self.group.groupname, self.subvolname): + meta = self.auth_mdata_mgr.subvol_metadata_get(self.group.groupname, self.subvolname) + auths = [] # type: List[Dict[str,str]] + if not meta or not meta['auths']: + return auths + + for auth, auth_data in meta['auths'].items(): + # Skip partial auth updates. + if not auth_data['dirty']: + auths.append({auth: auth_data['access_level']}) + + return auths + + def evict(self, volname, auth_id, timeout=30): + """ + Evict all clients based on the authorization ID and the subvolume path mounted. + Assumes that the authorization key has been revoked prior to calling this function. + + This operation can throw an exception if the mon cluster is unresponsive, or + any individual MDS daemon is unresponsive for longer than the timeout passed in. + """ + + client_spec = ["auth_name={0}".format(auth_id), ] + client_spec.append("client_metadata.root={0}". + format(self.path.decode('utf-8'))) + + log.info("evict clients with {0}".format(', '.join(client_spec))) + + mds_map = get_mds_map(self.mgr, volname) + if not mds_map: + raise VolumeException(-errno.ENOENT, "mdsmap for volume {0} not found".format(volname)) + + up = {} + for name, gid in mds_map['up'].items(): + # Quirk of the MDSMap JSON dump: keys in the up dict are like "mds_0" + assert name.startswith("mds_") + up[int(name[4:])] = gid + + # For all MDS ranks held by a daemon + # Do the parallelism in python instead of using "tell mds.*", because + # the latter doesn't give us per-mds output + threads = [] + for rank, gid in up.items(): + thread = RankEvicter(self.mgr, self.fs, client_spec, volname, rank, gid, mds_map, timeout) + thread.start() + threads.append(thread) + + for t in threads: + t.join() + + log.info("evict: joined all") + + for t in threads: + if not t.success: + msg = ("Failed to evict client with {0} from mds {1}/{2}: {3}". + format(', '.join(client_spec), t.rank, t.gid, t.exception) + ) + log.error(msg) + raise EvictionError(msg) + + def _get_clone_source(self): + try: + clone_source = { + 'volume' : self.metadata_mgr.get_option("source", "volume"), + 'subvolume': self.metadata_mgr.get_option("source", "subvolume"), + 'snapshot' : self.metadata_mgr.get_option("source", "snapshot"), + } + + try: + clone_source["group"] = self.metadata_mgr.get_option("source", "group") + except MetadataMgrException as me: + if me.errno == -errno.ENOENT: + pass + else: + raise + except MetadataMgrException as me: + raise VolumeException(-errno.EINVAL, "error fetching subvolume metadata") + return clone_source + + @property + def status(self): + state = SubvolumeStates.from_value(self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_STATE)) + subvolume_type = self.subvol_type + subvolume_status = { + 'state' : state.value + } + if not SubvolumeOpSm.is_complete_state(state) and subvolume_type == SubvolumeTypes.TYPE_CLONE: + subvolume_status["source"] = self._get_clone_source() + return subvolume_status + + @property + def state(self): + return SubvolumeStates.from_value(self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_STATE)) + + @state.setter + def state(self, val): + state = val[0].value + flush = val[1] + self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_STATE, state) + if flush: + self.metadata_mgr.flush() + + def remove(self, retainsnaps=False): + if retainsnaps: + raise VolumeException(-errno.EINVAL, "subvolume '{0}' does not support snapshot retention on delete".format(self.subvolname)) + if self.list_snapshots(): + raise VolumeException(-errno.ENOTEMPTY, "subvolume '{0}' has snapshots".format(self.subvolname)) + self.trash_base_dir() + + def resize(self, newsize, noshrink): + subvol_path = self.path + return self._resize(subvol_path, newsize, noshrink) + + def create_snapshot(self, snapname): + try: + group_snapshot_path = os.path.join(self.group.path, + self.vol_spec.snapshot_dir_prefix.encode('utf-8'), + snapname.encode('utf-8')) + self.fs.stat(group_snapshot_path) + except cephfs.Error as e: + if e.args[0] == errno.ENOENT: + snappath = self.snapshot_path(snapname) + mksnap(self.fs, snappath) + else: + raise VolumeException(-e.args[0], e.args[1]) + else: + raise VolumeException(-errno.EINVAL, "subvolumegroup and subvolume snapshot name can't be same") + + def has_pending_clones(self, snapname): + try: + return self.metadata_mgr.section_has_item('clone snaps', snapname) + except MetadataMgrException as me: + if me.errno == -errno.ENOENT: + return False + raise + + def remove_snapshot(self, snapname): + if self.has_pending_clones(snapname): + raise VolumeException(-errno.EAGAIN, "snapshot '{0}' has pending clones".format(snapname)) + snappath = self.snapshot_path(snapname) + rmsnap(self.fs, snappath) + + def snapshot_info(self, snapname): + if is_inherited_snap(snapname): + raise VolumeException(-errno.EINVAL, + "snapshot name '{0}' is invalid".format(snapname)) + snappath = self.snapshot_data_path(snapname) + snap_info = {} + try: + snap_attrs = {'created_at':'ceph.snap.btime', 'size':'ceph.dir.rbytes', + 'data_pool':'ceph.dir.layout.pool'} + for key, val in snap_attrs.items(): + snap_info[key] = self.fs.getxattr(snappath, val) + return {'size': int(snap_info['size']), + 'created_at': str(datetime.fromtimestamp(float(snap_info['created_at']))), + 'data_pool': snap_info['data_pool'].decode('utf-8'), + 'has_pending_clones': "yes" if self.has_pending_clones(snapname) else "no"} + except cephfs.Error as e: + if e.errno == errno.ENOENT: + raise VolumeException(-errno.ENOENT, + "snapshot '{0}' does not exist".format(snapname)) + raise VolumeException(-e.args[0], e.args[1]) + + def list_snapshots(self): + try: + dirpath = self.snapshot_base_path() + return listsnaps(self.fs, self.vol_spec, dirpath, filter_inherited_snaps=True) + except VolumeException as ve: + if ve.errno == -errno.ENOENT: + return [] + raise + + def _add_snap_clone(self, track_id, snapname): + self.metadata_mgr.add_section("clone snaps") + self.metadata_mgr.update_section("clone snaps", track_id, snapname) + self.metadata_mgr.flush() + + def _remove_snap_clone(self, track_id): + self.metadata_mgr.remove_option("clone snaps", track_id) + self.metadata_mgr.flush() + + def attach_snapshot(self, snapname, tgt_subvolume): + if not snapname.encode('utf-8') in self.list_snapshots(): + raise VolumeException(-errno.ENOENT, "snapshot '{0}' does not exist".format(snapname)) + try: + create_clone_index(self.fs, self.vol_spec) + with open_clone_index(self.fs, self.vol_spec) as index: + track_idx = index.track(tgt_subvolume.base_path) + self._add_snap_clone(track_idx, snapname) + except (IndexException, MetadataMgrException) as e: + log.warn("error creating clone index: {0}".format(e)) + raise VolumeException(-errno.EINVAL, "error cloning subvolume") + + def detach_snapshot(self, snapname, track_id): + if not snapname.encode('utf-8') in self.list_snapshots(): + raise VolumeException(-errno.ENOENT, "snapshot '{0}' does not exist".format(snapname)) + try: + with open_clone_index(self.fs, self.vol_spec) as index: + index.untrack(track_id) + self._remove_snap_clone(track_id) + except (IndexException, MetadataMgrException) as e: + log.warn("error delining snapshot from clone: {0}".format(e)) + raise VolumeException(-errno.EINVAL, "error delinking snapshot from clone") diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py new file mode 100644 index 00000000..1dd6f3fe --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py @@ -0,0 +1,370 @@ +import os +import stat +import uuid +import errno +import logging + +import cephfs + +from .metadata_manager import MetadataManager +from .subvolume_attrs import SubvolumeTypes, SubvolumeStates, SubvolumeFeatures +from .op_sm import SubvolumeOpSm +from .subvolume_v1 import SubvolumeV1 +from ..template import SubvolumeTemplate +from ...exception import OpSmException, VolumeException, MetadataMgrException +from ...fs_util import listdir +from ..template import SubvolumeOpType + +log = logging.getLogger(__name__) + +class SubvolumeV2(SubvolumeV1): + """ + Version 2 subvolumes creates a subvolume with path as follows, + volumes//// + + The distinguishing feature of V2 subvolume as compared to V1 subvolumes is its ability to retain snapshots + of a subvolume on removal. This is done by creating snapshots under the directory, + rather than under the directory, as is the case of V1 subvolumes. + + - The directory under which user data resides is + - Snapshots of the subvolume are taken within the directory + - A meta file is maintained under the directory as a metadata store, storing information similar + to V1 subvolumes + - On a request to remove subvolume but retain its snapshots, only the directory is moved to trash, retaining + the rest of the subvolume and its meta file. + - The directory, when present, is the current incarnation of the subvolume, which may have snapshots of + older incarnations of the same subvolume. + - V1 subvolumes that currently do not have any snapshots are upgraded to V2 subvolumes automatically, to support the + snapshot retention feature + """ + VERSION = 2 + + @staticmethod + def version(): + return SubvolumeV2.VERSION + + @property + def features(self): + return [SubvolumeFeatures.FEATURE_SNAPSHOT_CLONE.value, + SubvolumeFeatures.FEATURE_SNAPSHOT_AUTOPROTECT.value, + SubvolumeFeatures.FEATURE_SNAPSHOT_RETENTION.value] + + @property + def retained(self): + try: + self.metadata_mgr.refresh() + if self.state == SubvolumeStates.STATE_RETAINED: + return True + return False + except MetadataMgrException as me: + if me.errno != -errno.ENOENT: + raise VolumeException(me.errno, "internal error while processing subvolume '{0}'".format(self.subvolname)) + return False + + @property + def purgeable(self): + if not self.retained or self.list_snapshots() or self.has_pending_purges: + return False + return True + + @property + def has_pending_purges(self): + try: + return not listdir(self.fs, self.trash_dir) == [] + except VolumeException as ve: + if ve.errno == -errno.ENOENT: + return False + raise + + @property + def trash_dir(self): + return os.path.join(self.base_path, b".trash") + + def create_trashcan(self): + """per subvolume trash directory""" + try: + self.fs.stat(self.trash_dir) + except cephfs.Error as e: + if e.args[0] == errno.ENOENT: + try: + self.fs.mkdir(self.trash_dir, 0o700) + except cephfs.Error as ce: + raise VolumeException(-ce.args[0], ce.args[1]) + else: + raise VolumeException(-e.args[0], e.args[1]) + + def mark_subvolume(self): + # set subvolume attr, on subvolume root, marking it as a CephFS subvolume + # subvolume root is where snapshots would be taken, and hence is the base_path for v2 subvolumes + try: + # MDS treats this as a noop for already marked subvolume + self.fs.setxattr(self.base_path, 'ceph.dir.subvolume', b'1', 0) + except cephfs.InvalidValue as e: + raise VolumeException(-errno.EINVAL, "invalid value specified for ceph.dir.subvolume") + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + @staticmethod + def is_valid_uuid(uuid_str): + try: + uuid.UUID(uuid_str) + return True + except ValueError: + return False + + def snapshot_base_path(self): + return os.path.join(self.base_path, self.vol_spec.snapshot_dir_prefix.encode('utf-8')) + + def snapshot_data_path(self, snapname): + snap_base_path = self.snapshot_path(snapname) + uuid_str = None + try: + with self.fs.opendir(snap_base_path) as dir_handle: + d = self.fs.readdir(dir_handle) + while d: + if d.d_name not in (b".", b".."): + d_full_path = os.path.join(snap_base_path, d.d_name) + stx = self.fs.statx(d_full_path, cephfs.CEPH_STATX_MODE, cephfs.AT_SYMLINK_NOFOLLOW) + if stat.S_ISDIR(stx.get('mode')): + if self.is_valid_uuid(d.d_name.decode('utf-8')): + uuid_str = d.d_name + d = self.fs.readdir(dir_handle) + except cephfs.Error as e: + if e.errno == errno.ENOENT: + raise VolumeException(-errno.ENOENT, "snapshot '{0}' does not exist".format(snapname)) + raise VolumeException(-e.args[0], e.args[1]) + + if not uuid_str: + raise VolumeException(-errno.ENOENT, "snapshot '{0}' does not exist".format(snapname)) + + return os.path.join(snap_base_path, uuid_str) + + def _remove_on_failure(self, subvol_path, retained): + if retained: + log.info("cleaning up subvolume incarnation with path: {0}".format(subvol_path)) + try: + self.fs.rmdir(subvol_path) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + else: + log.info("cleaning up subvolume with path: {0}".format(self.subvolname)) + self.remove() + + def _set_incarnation_metadata(self, subvolume_type, qpath, initial_state): + self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_TYPE, subvolume_type.value) + self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_PATH, qpath) + self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_STATE, initial_state.value) + + def create(self, size, isolate_nspace, pool, mode, uid, gid): + subvolume_type = SubvolumeTypes.TYPE_NORMAL + try: + initial_state = SubvolumeOpSm.get_init_state(subvolume_type) + except OpSmException as oe: + raise VolumeException(-errno.EINVAL, "subvolume creation failed: internal error") + + retained = self.retained + if retained and self.has_pending_purges: + raise VolumeException(-errno.EAGAIN, "asynchronous purge of subvolume in progress") + subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) + try: + self.fs.mkdirs(subvol_path, mode) + self.mark_subvolume() + attrs = { + 'uid': uid, + 'gid': gid, + 'data_pool': pool, + 'pool_namespace': self.namespace if isolate_nspace else None, + 'quota': size + } + self.set_attrs(subvol_path, attrs) + + # persist subvolume metadata + qpath = subvol_path.decode('utf-8') + if retained: + self._set_incarnation_metadata(subvolume_type, qpath, initial_state) + self.metadata_mgr.flush() + else: + self.init_config(SubvolumeV2.VERSION, subvolume_type, qpath, initial_state) + + # Create the subvolume metadata file which manages auth-ids if it doesn't exist + self.auth_mdata_mgr.create_subvolume_metadata_file(self.group.groupname, self.subvolname) + except (VolumeException, MetadataMgrException, cephfs.Error) as e: + try: + self._remove_on_failure(subvol_path, retained) + except VolumeException as ve: + log.info("failed to cleanup subvolume '{0}' ({1})".format(self.subvolname, ve)) + + if isinstance(e, MetadataMgrException): + log.error("metadata manager exception: {0}".format(e)) + e = VolumeException(-errno.EINVAL, "exception in subvolume metadata") + elif isinstance(e, cephfs.Error): + e = VolumeException(-e.args[0], e.args[1]) + raise e + + def create_clone(self, pool, source_volname, source_subvolume, snapname): + subvolume_type = SubvolumeTypes.TYPE_CLONE + try: + initial_state = SubvolumeOpSm.get_init_state(subvolume_type) + except OpSmException as oe: + raise VolumeException(-errno.EINVAL, "clone failed: internal error") + + retained = self.retained + if retained and self.has_pending_purges: + raise VolumeException(-errno.EAGAIN, "asynchronous purge of subvolume in progress") + subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) + try: + # source snapshot attrs are used to create clone subvolume + # attributes of subvolume's content though, are synced during the cloning process. + attrs = source_subvolume.get_attrs(source_subvolume.snapshot_data_path(snapname)) + + # override snapshot pool setting, if one is provided for the clone + if pool is not None: + attrs["data_pool"] = pool + attrs["pool_namespace"] = None + + # create directory and set attributes + self.fs.mkdirs(subvol_path, attrs.get("mode")) + self.mark_subvolume() + self.set_attrs(subvol_path, attrs) + + # persist subvolume metadata and clone source + qpath = subvol_path.decode('utf-8') + if retained: + self._set_incarnation_metadata(subvolume_type, qpath, initial_state) + else: + self.metadata_mgr.init(SubvolumeV2.VERSION, subvolume_type.value, qpath, initial_state.value) + self.add_clone_source(source_volname, source_subvolume, snapname) + self.metadata_mgr.flush() + except (VolumeException, MetadataMgrException, cephfs.Error) as e: + try: + self._remove_on_failure(subvol_path, retained) + except VolumeException as ve: + log.info("failed to cleanup subvolume '{0}' ({1})".format(self.subvolname, ve)) + + if isinstance(e, MetadataMgrException): + log.error("metadata manager exception: {0}".format(e)) + e = VolumeException(-errno.EINVAL, "exception in subvolume metadata") + elif isinstance(e, cephfs.Error): + e = VolumeException(-e.args[0], e.args[1]) + raise e + + def allowed_ops_by_type(self, vol_type): + if vol_type == SubvolumeTypes.TYPE_CLONE: + return {op_type for op_type in SubvolumeOpType} + + if vol_type == SubvolumeTypes.TYPE_NORMAL: + return {op_type for op_type in SubvolumeOpType} - {SubvolumeOpType.CLONE_STATUS, + SubvolumeOpType.CLONE_CANCEL, + SubvolumeOpType.CLONE_INTERNAL} + + return {} + + def allowed_ops_by_state(self, vol_state): + if vol_state == SubvolumeStates.STATE_COMPLETE: + return {op_type for op_type in SubvolumeOpType} + + if vol_state == SubvolumeStates.STATE_RETAINED: + return { + SubvolumeOpType.REMOVE, + SubvolumeOpType.REMOVE_FORCE, + SubvolumeOpType.LIST, + SubvolumeOpType.INFO, + SubvolumeOpType.SNAP_REMOVE, + SubvolumeOpType.SNAP_LIST, + SubvolumeOpType.SNAP_INFO, + SubvolumeOpType.SNAP_PROTECT, + SubvolumeOpType.SNAP_UNPROTECT, + SubvolumeOpType.CLONE_SOURCE + } + + return {SubvolumeOpType.REMOVE_FORCE, + SubvolumeOpType.CLONE_CREATE, + SubvolumeOpType.CLONE_STATUS, + SubvolumeOpType.CLONE_CANCEL, + SubvolumeOpType.CLONE_INTERNAL, + SubvolumeOpType.CLONE_SOURCE} + + def open(self, op_type): + if not isinstance(op_type, SubvolumeOpType): + raise VolumeException(-errno.ENOTSUP, "operation {0} not supported on subvolume '{1}'".format( + op_type.value, self.subvolname)) + try: + self.metadata_mgr.refresh() + # unconditionally mark as subvolume, to handle pre-existing subvolumes without the mark + self.mark_subvolume() + + etype = self.subvol_type + if op_type not in self.allowed_ops_by_type(etype): + raise VolumeException(-errno.ENOTSUP, "operation '{0}' is not allowed on subvolume '{1}' of type {2}".format( + op_type.value, self.subvolname, etype.value)) + + estate = self.state + if op_type not in self.allowed_ops_by_state(estate) and estate == SubvolumeStates.STATE_RETAINED: + raise VolumeException(-errno.ENOENT, "subvolume '{0}' is removed and has only snapshots retained".format( + self.subvolname)) + + if op_type not in self.allowed_ops_by_state(estate) and estate != SubvolumeStates.STATE_RETAINED: + raise VolumeException(-errno.EAGAIN, "subvolume '{0}' is not ready for operation {1}".format( + self.subvolname, op_type.value)) + + if estate != SubvolumeStates.STATE_RETAINED: + subvol_path = self.path + log.debug("refreshed metadata, checking subvolume path '{0}'".format(subvol_path)) + st = self.fs.stat(subvol_path) + + self.uid = int(st.st_uid) + self.gid = int(st.st_gid) + self.mode = int(st.st_mode & ~stat.S_IFMT(st.st_mode)) + except MetadataMgrException as me: + if me.errno == -errno.ENOENT: + raise VolumeException(-errno.ENOENT, "subvolume '{0}' does not exist".format(self.subvolname)) + raise VolumeException(me.args[0], me.args[1]) + except cephfs.ObjectNotFound: + log.debug("missing subvolume path '{0}' for subvolume '{1}'".format(subvol_path, self.subvolname)) + raise VolumeException(-errno.ENOENT, "mount path missing for subvolume '{0}'".format(self.subvolname)) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def trash_incarnation_dir(self): + """rename subvolume (uuid component) to trash""" + self.create_trashcan() + try: + bname = os.path.basename(self.path) + tpath = os.path.join(self.trash_dir, bname) + log.debug("trash: {0} -> {1}".format(self.path, tpath)) + self.fs.rename(self.path, tpath) + self._link_dir(tpath, bname) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + + def remove(self, retainsnaps=False): + if self.list_snapshots(): + if not retainsnaps: + raise VolumeException(-errno.ENOTEMPTY, "subvolume '{0}' has snapshots".format(self.subvolname)) + else: + if not self.has_pending_purges: + self.trash_base_dir() + # Delete the volume meta file, if it's not already deleted + self.auth_mdata_mgr.delete_subvolume_metadata_file(self.group.groupname, self.subvolname) + return + if self.state != SubvolumeStates.STATE_RETAINED: + self.trash_incarnation_dir() + self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_PATH, "") + self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_STATE, SubvolumeStates.STATE_RETAINED.value) + self.metadata_mgr.flush() + # Delete the volume meta file, if it's not already deleted + self.auth_mdata_mgr.delete_subvolume_metadata_file(self.group.groupname, self.subvolname) + + def info(self): + if self.state != SubvolumeStates.STATE_RETAINED: + return super(SubvolumeV2, self).info() + + return {'type': self.subvol_type.value, 'features': self.features, 'state': SubvolumeStates.STATE_RETAINED.value} + + def remove_snapshot(self, snapname): + super(SubvolumeV2, self).remove_snapshot(snapname) + if self.purgeable: + self.trash_base_dir() + # tickle the volume purge job to purge this entry, using ESTALE + raise VolumeException(-errno.ESTALE, "subvolume '{0}' has been removed as the last retained snapshot is removed".format(self.subvolname)) + # if not purgeable, subvol is not retained, or has snapshots, or already has purge jobs that will garbage collect this subvol diff --git a/src/pybind/mgr/volumes/fs/operations/volume.py b/src/pybind/mgr/volumes/fs/operations/volume.py new file mode 100644 index 00000000..410e5c44 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/operations/volume.py @@ -0,0 +1,348 @@ +import time +import errno +import logging +import sys + +try: + from typing import List +except ImportError: + pass # For typing only + +from contextlib import contextmanager +from threading import Lock, Condition + +if sys.version_info >= (3, 3): + from threading import Timer +else: + from threading import _Timer as Timer + +import cephfs +import orchestrator + +from .lock import GlobalLock +from ..exception import VolumeException +from ..fs_util import create_pool, remove_pool, create_filesystem, \ + remove_filesystem, create_mds, volume_exists + +log = logging.getLogger(__name__) + +class ConnectionPool(object): + class Connection(object): + def __init__(self, mgr, fs_name): + self.fs = None + self.mgr = mgr + self.fs_name = fs_name + self.ops_in_progress = 0 + self.last_used = time.time() + self.fs_id = self.get_fs_id() + + def get_fs_id(self): + fs_map = self.mgr.get('fs_map') + for fs in fs_map['filesystems']: + if fs['mdsmap']['fs_name'] == self.fs_name: + return fs['id'] + raise VolumeException( + -errno.ENOENT, "Volume '{0}' not found".format(self.fs_name)) + + def get_fs_handle(self): + self.last_used = time.time() + self.ops_in_progress += 1 + return self.fs + + def put_fs_handle(self, notify): + assert self.ops_in_progress > 0 + self.ops_in_progress -= 1 + if self.ops_in_progress == 0: + notify() + + def del_fs_handle(self, waiter): + if waiter: + while self.ops_in_progress != 0: + waiter() + if self.is_connection_valid(): + self.disconnect() + else: + self.abort() + + def is_connection_valid(self): + fs_id = None + try: + fs_id = self.get_fs_id() + except: + # the filesystem does not exist now -- connection is not valid. + pass + log.debug("self.fs_id={0}, fs_id={1}".format(self.fs_id, fs_id)) + return self.fs_id == fs_id + + def is_connection_idle(self, timeout): + return (self.ops_in_progress == 0 and ((time.time() - self.last_used) >= timeout)) + + def connect(self): + assert self.ops_in_progress == 0 + log.debug("Connecting to cephfs '{0}'".format(self.fs_name)) + self.fs = cephfs.LibCephFS(rados_inst=self.mgr.rados) + log.debug("Setting user ID and group ID of CephFS mount as root...") + self.fs.conf_set("client_mount_uid", "0") + self.fs.conf_set("client_mount_gid", "0") + log.debug("CephFS initializing...") + self.fs.init() + log.debug("CephFS mounting...") + self.fs.mount(filesystem_name=self.fs_name.encode('utf-8')) + log.debug("Connection to cephfs '{0}' complete".format(self.fs_name)) + + def disconnect(self): + try: + assert self.fs + assert self.ops_in_progress == 0 + log.info("disconnecting from cephfs '{0}'".format(self.fs_name)) + self.fs.shutdown() + self.fs = None + except Exception as e: + log.debug("disconnect: ({0})".format(e)) + raise + + def abort(self): + assert self.fs + assert self.ops_in_progress == 0 + log.info("aborting connection from cephfs '{0}'".format(self.fs_name)) + self.fs.abort_conn() + log.info("abort done from cephfs '{0}'".format(self.fs_name)) + self.fs = None + + class RTimer(Timer): + """ + recurring timer variant of Timer + """ + def run(self): + try: + while not self.finished.is_set(): + self.finished.wait(self.interval) + self.function(*self.args, **self.kwargs) + self.finished.set() + except Exception as e: + log.error("ConnectionPool.RTimer: %s", e) + raise + + # TODO: make this configurable + TIMER_TASK_RUN_INTERVAL = 30.0 # seconds + CONNECTION_IDLE_INTERVAL = 60.0 # seconds + + def __init__(self, mgr): + self.mgr = mgr + self.connections = {} + self.lock = Lock() + self.cond = Condition(self.lock) + self.timer_task = ConnectionPool.RTimer(ConnectionPool.TIMER_TASK_RUN_INTERVAL, + self.cleanup_connections) + self.timer_task.start() + + def cleanup_connections(self): + with self.lock: + log.info("scanning for idle connections..") + idle_fs = [fs_name for fs_name,conn in self.connections.items() + if conn.is_connection_idle(ConnectionPool.CONNECTION_IDLE_INTERVAL)] + for fs_name in idle_fs: + log.info("cleaning up connection for '{}'".format(fs_name)) + self._del_fs_handle(fs_name) + + def get_fs_handle(self, fs_name): + with self.lock: + conn = None + try: + conn = self.connections.get(fs_name, None) + if conn: + if conn.is_connection_valid(): + return conn.get_fs_handle() + else: + # filesystem id changed beneath us (or the filesystem does not exist). + # this is possible if the filesystem got removed (and recreated with + # same name) via "ceph fs rm/new" mon command. + log.warning("filesystem id changed for volume '{0}', reconnecting...".format(fs_name)) + self._del_fs_handle(fs_name) + conn = ConnectionPool.Connection(self.mgr, fs_name) + conn.connect() + except cephfs.Error as e: + # try to provide a better error string if possible + if e.args[0] == errno.ENOENT: + raise VolumeException( + -errno.ENOENT, "Volume '{0}' not found".format(fs_name)) + raise VolumeException(-e.args[0], e.args[1]) + self.connections[fs_name] = conn + return conn.get_fs_handle() + + def put_fs_handle(self, fs_name): + with self.lock: + conn = self.connections.get(fs_name, None) + if conn: + conn.put_fs_handle(notify=lambda: self.cond.notifyAll()) + + def _del_fs_handle(self, fs_name, wait=False): + conn = self.connections.pop(fs_name, None) + if conn: + conn.del_fs_handle(waiter=None if not wait else lambda: self.cond.wait()) + + def del_fs_handle(self, fs_name, wait=False): + with self.lock: + self._del_fs_handle(fs_name, wait) + + def del_all_handles(self): + with self.lock: + for fs_name in list(self.connections.keys()): + log.info("waiting for pending ops for '{}'".format(fs_name)) + self._del_fs_handle(fs_name, wait=True) + log.info("pending ops completed for '{}'".format(fs_name)) + # no new connections should have been initialized since its + # guarded on shutdown. + assert len(self.connections) == 0 + +def gen_pool_names(volname): + """ + return metadata and data pool name (from a filesystem/volume name) as a tuple + """ + return "cephfs.{}.meta".format(volname), "cephfs.{}.data".format(volname) + +def get_mds_map(mgr, volname): + """ + return mdsmap for a volname + """ + mds_map = None + fs_map = mgr.get("fs_map") + for f in fs_map['filesystems']: + if volname == f['mdsmap']['fs_name']: + return f['mdsmap'] + return mds_map + +def get_pool_names(mgr, volname): + """ + return metadata and data pools (list) names of volume as a tuple + """ + fs_map = mgr.get("fs_map") + metadata_pool_id = None + data_pool_ids = [] # type: List[int] + for f in fs_map['filesystems']: + if volname == f['mdsmap']['fs_name']: + metadata_pool_id = f['mdsmap']['metadata_pool'] + data_pool_ids = f['mdsmap']['data_pools'] + break + if metadata_pool_id is None: + return None, None + + osdmap = mgr.get("osd_map") + pools = dict([(p['pool'], p['pool_name']) for p in osdmap['pools']]) + metadata_pool = pools[metadata_pool_id] + data_pools = [pools[id] for id in data_pool_ids] + return metadata_pool, data_pools + +def create_volume(mgr, volname): + """ + create volume (pool, filesystem and mds) + """ + metadata_pool, data_pool = gen_pool_names(volname) + # create pools + r, outs, outb = create_pool(mgr, metadata_pool, 16) + if r != 0: + return r, outb, outs + r, outb, outs = create_pool(mgr, data_pool, 8) + if r != 0: + #cleanup + remove_pool(mgr, metadata_pool) + return r, outb, outs + # create filesystem + r, outb, outs = create_filesystem(mgr, volname, metadata_pool, data_pool) + if r != 0: + log.error("Filesystem creation error: {0} {1} {2}".format(r, outb, outs)) + #cleanup + remove_pool(mgr, data_pool) + remove_pool(mgr, metadata_pool) + return r, outb, outs + # create mds + return create_mds(mgr, volname) + +def delete_volume(mgr, volname, metadata_pool, data_pools): + """ + delete the given module (tear down mds, remove filesystem, remove pools) + """ + # Tear down MDS daemons + try: + completion = mgr.remove_stateless_service("mds", volname) + mgr._orchestrator_wait([completion]) + orchestrator.raise_if_exception(completion) + except (ImportError, orchestrator.OrchestratorError): + log.warning("OrchestratorError, not tearing down MDS daemons") + except Exception as e: + # Don't let detailed orchestrator exceptions (python backtraces) + # bubble out to the user + log.exception("Failed to tear down MDS daemons") + return -errno.EINVAL, "", str(e) + + # In case orchestrator didn't tear down MDS daemons cleanly, or + # there was no orchestrator, we force the daemons down. + if volume_exists(mgr, volname): + r, outb, outs = remove_filesystem(mgr, volname) + if r != 0: + return r, outb, outs + else: + err = "Filesystem not found for volume '{0}'".format(volname) + log.warning(err) + return -errno.ENOENT, "", err + r, outb, outs = remove_pool(mgr, metadata_pool) + if r != 0: + return r, outb, outs + + for data_pool in data_pools: + r, outb, outs = remove_pool(mgr, data_pool) + if r != 0: + return r, outb, outs + result_str = "metadata pool: {0} data pool: {1} removed".format(metadata_pool, str(data_pools)) + return r, result_str, "" + +def list_volumes(mgr): + """ + list all filesystem volumes. + + :param: None + :return: None + """ + result = [] + fs_map = mgr.get("fs_map") + for f in fs_map['filesystems']: + result.append({'name': f['mdsmap']['fs_name']}) + return result + +@contextmanager +def open_volume(vc, volname): + """ + open a volume for exclusive access. This API is to be used as a context manager. + + :param vc: volume client instance + :param volname: volume name + :return: yields a volume handle (ceph filesystem handle) + """ + if vc.is_stopping(): + raise VolumeException(-errno.ESHUTDOWN, "shutdown in progress") + + g_lock = GlobalLock() + fs_handle = vc.connection_pool.get_fs_handle(volname) + try: + with g_lock.lock_op(): + yield fs_handle + finally: + vc.connection_pool.put_fs_handle(volname) + +@contextmanager +def open_volume_lockless(vc, volname): + """ + open a volume with shared access. This API is to be used as a context manager. + + :param vc: volume client instance + :param volname: volume name + :return: yields a volume handle (ceph filesystem handle) + """ + if vc.is_stopping(): + raise VolumeException(-errno.ESHUTDOWN, "shutdown in progress") + + fs_handle = vc.connection_pool.get_fs_handle(volname) + try: + yield fs_handle + finally: + vc.connection_pool.put_fs_handle(volname) diff --git a/src/pybind/mgr/volumes/fs/purge_queue.py b/src/pybind/mgr/volumes/fs/purge_queue.py new file mode 100644 index 00000000..7c902572 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/purge_queue.py @@ -0,0 +1,109 @@ +import errno +import logging +import os +import stat + +import cephfs + +from .async_job import AsyncJobs +from .exception import VolumeException +from .operations.resolver import resolve_trash +from .operations.template import SubvolumeOpType +from .operations.group import open_group +from .operations.subvolume import open_subvol +from .operations.volume import open_volume, open_volume_lockless +from .operations.trash import open_trashcan + +log = logging.getLogger(__name__) + +# helper for fetching a trash entry for a given volume +def get_trash_entry_for_volume(volume_client, volname, running_jobs): + log.debug("fetching trash entry for volume '{0}'".format(volname)) + + try: + with open_volume_lockless(volume_client, volname) as fs_handle: + try: + with open_trashcan(fs_handle, volume_client.volspec) as trashcan: + path = trashcan.get_trash_entry(running_jobs) + return 0, path + except VolumeException as ve: + if ve.errno == -errno.ENOENT: + return 0, None + raise ve + except VolumeException as ve: + log.error("error fetching trash entry for volume '{0}' ({1})".format(volname, ve)) + return ve.errno, None + +def subvolume_purge(volume_client, volname, trashcan, subvolume_trash_entry, should_cancel): + groupname, subvolname = resolve_trash(volume_client.volspec, subvolume_trash_entry.decode('utf-8')) + log.debug("subvolume resolved to {0}/{1}".format(groupname, subvolname)) + + try: + with open_volume(volume_client, volname) as fs_handle: + with open_group(fs_handle, volume_client.volspec, groupname) as group: + with open_subvol(volume_client.mgr, fs_handle, volume_client.volspec, group, subvolname, SubvolumeOpType.REMOVE) as subvolume: + log.debug("subvolume.path={0}, purgeable={1}".format(subvolume.path, subvolume.purgeable)) + if not subvolume.purgeable: + return + # this is fine under the global lock -- there are just a handful + # of entries in the subvolume to purge. moreover, the purge needs + # to be guarded since a create request might sneak in. + trashcan.purge(subvolume.base_path, should_cancel) + except VolumeException as ve: + if not ve.errno == -errno.ENOENT: + raise + +# helper for starting a purge operation on a trash entry +def purge_trash_entry_for_volume(volume_client, volname, purge_entry, should_cancel): + log.debug("purging trash entry '{0}' for volume '{1}'".format(purge_entry, volname)) + + ret = 0 + try: + with open_volume_lockless(volume_client, volname) as fs_handle: + with open_trashcan(fs_handle, volume_client.volspec) as trashcan: + try: + pth = os.path.join(trashcan.path, purge_entry) + stx = fs_handle.statx(pth, cephfs.CEPH_STATX_MODE | cephfs.CEPH_STATX_SIZE, + cephfs.AT_SYMLINK_NOFOLLOW) + if stat.S_ISLNK(stx['mode']): + tgt = fs_handle.readlink(pth, 4096) + tgt = tgt[:stx['size']] + log.debug("purging entry pointing to subvolume trash: {0}".format(tgt)) + delink = True + try: + trashcan.purge(tgt, should_cancel) + except VolumeException as ve: + if not ve.errno == -errno.ENOENT: + delink = False + return ve.errno + finally: + if delink: + subvolume_purge(volume_client, volname, trashcan, tgt, should_cancel) + log.debug("purging trash link: {0}".format(purge_entry)) + trashcan.delink(purge_entry) + else: + log.debug("purging entry pointing to trash: {0}".format(pth)) + trashcan.purge(pth, should_cancel) + except cephfs.Error as e: + log.warn("failed to remove trash entry: {0}".format(e)) + except VolumeException as ve: + ret = ve.errno + return ret + +class ThreadPoolPurgeQueueMixin(AsyncJobs): + """ + Purge queue mixin class maintaining a pool of threads for purging trash entries. + Subvolumes are chosen from volumes in a round robin fashion. If some of the purge + entries (belonging to a set of volumes) have huge directory tree's (such as, lots + of small files in a directory w/ deep directory trees), this model may lead to + _all_ threads purging entries for one volume (starving other volumes). + """ + def __init__(self, volume_client, tp_size): + self.vc = volume_client + super(ThreadPoolPurgeQueueMixin, self).__init__(volume_client, "puregejob", tp_size) + + def get_next_job(self, volname, running_jobs): + return get_trash_entry_for_volume(self.vc, volname, running_jobs) + + def execute_job(self, volname, job, should_cancel): + purge_trash_entry_for_volume(self.vc, volname, job, should_cancel) diff --git a/src/pybind/mgr/volumes/fs/vol_spec.py b/src/pybind/mgr/volumes/fs/vol_spec.py new file mode 100644 index 00000000..e18ab069 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/vol_spec.py @@ -0,0 +1,37 @@ +import os + +class VolSpec(object): + """ + specification of a "volume" -- base directory and various prefixes. + """ + + # where shall we (by default) create subvolumes + DEFAULT_SUBVOL_PREFIX = "/volumes" + # and the default namespace + DEFAULT_NS_PREFIX = "fsvolumens_" + + def __init__(self, snapshot_prefix, subvolume_prefix=None, pool_ns_prefix=None): + self.snapshot_prefix = snapshot_prefix + self.subvolume_prefix = subvolume_prefix if subvolume_prefix else VolSpec.DEFAULT_SUBVOL_PREFIX + self.pool_ns_prefix = pool_ns_prefix if pool_ns_prefix else VolSpec.DEFAULT_NS_PREFIX + + @property + def snapshot_dir_prefix(self): + """ + Return the snapshot directory prefix + """ + return self.snapshot_prefix + + @property + def base_dir(self): + """ + Return the top level directory under which subvolumes/groups are created + """ + return self.subvolume_prefix + + @property + def fs_namespace(self): + """ + return a filesystem namespace by stashing pool namespace prefix and subvolume-id + """ + return self.pool_ns_prefix diff --git a/src/pybind/mgr/volumes/fs/volume.py b/src/pybind/mgr/volumes/fs/volume.py new file mode 100644 index 00000000..ab287539 --- /dev/null +++ b/src/pybind/mgr/volumes/fs/volume.py @@ -0,0 +1,660 @@ +import json +import errno +import logging +from threading import Event + +import cephfs + +from .fs_util import listdir + +from .operations.volume import ConnectionPool, open_volume, create_volume, \ + delete_volume, list_volumes, get_pool_names +from .operations.group import open_group, create_group, remove_group, open_group_unique +from .operations.subvolume import open_subvol, create_subvol, remove_subvol, \ + create_clone + +from .vol_spec import VolSpec +from .exception import VolumeException, ClusterError, ClusterTimeout, EvictionError +from .async_cloner import Cloner +from .purge_queue import ThreadPoolPurgeQueueMixin +from .operations.template import SubvolumeOpType + +log = logging.getLogger(__name__) + +ALLOWED_ACCESS_LEVELS = ('r', 'rw') + + +def octal_str_to_decimal_int(mode): + try: + return int(mode, 8) + except ValueError: + raise VolumeException(-errno.EINVAL, "Invalid mode '{0}'".format(mode)) + +def name_to_json(names): + """ + convert the list of names to json + """ + namedict = [] + for i in range(len(names)): + namedict.append({'name': names[i].decode('utf-8')}) + return json.dumps(namedict, indent=4, sort_keys=True) + +class VolumeClient(object): + def __init__(self, mgr): + self.mgr = mgr + self.stopping = Event() + # volume specification + self.volspec = VolSpec(mgr.rados.conf_get('client_snapdir')) + self.connection_pool = ConnectionPool(self.mgr) + self.cloner = Cloner(self, self.mgr.max_concurrent_clones) + self.purge_queue = ThreadPoolPurgeQueueMixin(self, 4) + # on startup, queue purge job for available volumes to kickstart + # purge for leftover subvolume entries in trash. note that, if the + # trash directory does not exist or if there are no purge entries + # available for a volume, the volume is removed from the purge + # job list. + fs_map = self.mgr.get('fs_map') + for fs in fs_map['filesystems']: + self.cloner.queue_job(fs['mdsmap']['fs_name']) + self.purge_queue.queue_job(fs['mdsmap']['fs_name']) + + def is_stopping(self): + return self.stopping.is_set() + + def shutdown(self): + log.info("shutting down") + # first, note that we're shutting down + self.stopping.set() + # second, ask purge threads to quit + self.purge_queue.cancel_all_jobs() + # third, delete all libcephfs handles from connection pool + self.connection_pool.del_all_handles() + + def cluster_log(self, msg, lvl=None): + """ + log to cluster log with default log level as WARN. + """ + if not lvl: + lvl = self.mgr.CLUSTER_LOG_PRIO_WARN + self.mgr.cluster_log("cluster", lvl, msg) + + def volume_exception_to_retval(self, ve): + """ + return a tuple representation from a volume exception + """ + return ve.to_tuple() + + ### volume operations -- create, rm, ls + + def create_fs_volume(self, volname): + if self.is_stopping(): + return -errno.ESHUTDOWN, "", "shutdown in progress" + return create_volume(self.mgr, volname) + + def delete_fs_volume(self, volname, confirm): + if self.is_stopping(): + return -errno.ESHUTDOWN, "", "shutdown in progress" + + if confirm != "--yes-i-really-mean-it": + return -errno.EPERM, "", "WARNING: this will *PERMANENTLY DESTROY* all data " \ + "stored in the filesystem '{0}'. If you are *ABSOLUTELY CERTAIN* " \ + "that is what you want, re-issue the command followed by " \ + "--yes-i-really-mean-it.".format(volname) + + ret, out, err = self.mgr.mon_command({ + 'prefix': 'config get', + 'key': 'mon_allow_pool_delete', + 'who': 'mon.*', + 'format': 'json', + }) + if ret != 0: + return ret, out, err + mon_allow_pool_delete = json.loads(out) + if not mon_allow_pool_delete: + return -errno.EPERM, "", "pool deletion is disabled; you must first " \ + "set the mon_allow_pool_delete config option to true before volumes " \ + "can be deleted" + + metadata_pool, data_pools = get_pool_names(self.mgr, volname) + if not metadata_pool: + return -errno.ENOENT, "", "volume {0} doesn't exist".format(volname) + self.purge_queue.cancel_jobs(volname) + self.connection_pool.del_fs_handle(volname, wait=True) + return delete_volume(self.mgr, volname, metadata_pool, data_pools) + + def list_fs_volumes(self): + if self.stopping.is_set(): + return -errno.ESHUTDOWN, "", "shutdown in progress" + volumes = list_volumes(self.mgr) + return 0, json.dumps(volumes, indent=4, sort_keys=True), "" + + ### subvolume operations + + def _create_subvolume(self, fs_handle, volname, group, subvolname, **kwargs): + size = kwargs['size'] + pool = kwargs['pool_layout'] + uid = kwargs['uid'] + gid = kwargs['gid'] + mode = kwargs['mode'] + isolate_nspace = kwargs['namespace_isolated'] + + oct_mode = octal_str_to_decimal_int(mode) + try: + create_subvol( + self.mgr, fs_handle, self.volspec, group, subvolname, size, isolate_nspace, pool, oct_mode, uid, gid) + except VolumeException as ve: + # kick the purge threads for async removal -- note that this + # assumes that the subvolume is moved to trashcan for cleanup on error. + self.purge_queue.queue_job(volname) + raise ve + + def create_subvolume(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + size = kwargs['size'] + pool = kwargs['pool_layout'] + uid = kwargs['uid'] + gid = kwargs['gid'] + isolate_nspace = kwargs['namespace_isolated'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + try: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.CREATE) as subvolume: + # idempotent creation -- valid. Attributes set is supported. + attrs = { + 'uid': uid if uid else subvolume.uid, + 'gid': gid if gid else subvolume.gid, + 'data_pool': pool, + 'pool_namespace': subvolume.namespace if isolate_nspace else None, + 'quota': size + } + subvolume.set_attrs(subvolume.path, attrs) + except VolumeException as ve: + if ve.errno == -errno.ENOENT: + self._create_subvolume(fs_handle, volname, group, subvolname, **kwargs) + else: + raise + except VolumeException as ve: + # volume/group does not exist or subvolume creation failed + ret = self.volume_exception_to_retval(ve) + return ret + + def remove_subvolume(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + force = kwargs['force'] + retainsnaps = kwargs['retain_snapshots'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + remove_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, force, retainsnaps) + # kick the purge threads for async removal -- note that this + # assumes that the subvolume is moved to trash can. + # TODO: make purge queue as singleton so that trash can kicks + # the purge threads on dump. + self.purge_queue.queue_job(volname) + except VolumeException as ve: + if ve.errno == -errno.EAGAIN: + ve = VolumeException(ve.errno, ve.error_str + " (use --force to override)") + ret = self.volume_exception_to_retval(ve) + elif not (ve.errno == -errno.ENOENT and force): + ret = self.volume_exception_to_retval(ve) + return ret + + def authorize_subvolume(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + authid = kwargs['auth_id'] + groupname = kwargs['group_name'] + accesslevel = kwargs['access_level'] + tenant_id = kwargs['tenant_id'] + allow_existing_id = kwargs['allow_existing_id'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.ALLOW_ACCESS) as subvolume: + key = subvolume.authorize(authid, accesslevel, tenant_id, allow_existing_id) + ret = 0, key, "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def deauthorize_subvolume(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + authid = kwargs['auth_id'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.DENY_ACCESS) as subvolume: + subvolume.deauthorize(authid) + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def authorized_list(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.AUTH_LIST) as subvolume: + auths = subvolume.authorized_list() + ret = 0, json.dumps(auths, indent=4, sort_keys=True), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def evict(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + authid = kwargs['auth_id'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.EVICT) as subvolume: + key = subvolume.evict(volname, authid) + ret = 0, "", "" + except (VolumeException, ClusterTimeout, ClusterError, EvictionError) as e: + if isinstance(e, VolumeException): + ret = self.volume_exception_to_retval(e) + elif isinstance(e, ClusterTimeout): + ret = -errno.ETIMEDOUT , "", "Timedout trying to talk to ceph cluster" + elif isinstance(e, ClusterError): + ret = e._result_code , "", e._result_str + elif isinstance(e, EvictionError): + ret = -errno.EINVAL, "", str(e) + return ret + + def resize_subvolume(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + newsize = kwargs['new_size'] + noshrink = kwargs['no_shrink'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.RESIZE) as subvolume: + nsize, usedbytes = subvolume.resize(newsize, noshrink) + ret = 0, json.dumps( + [{'bytes_used': usedbytes},{'bytes_quota': nsize}, + {'bytes_pcent': "undefined" if nsize == 0 else '{0:.2f}'.format((float(usedbytes) / nsize) * 100.0)}], + indent=4, sort_keys=True), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def subvolume_getpath(self, **kwargs): + ret = None + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.GETPATH) as subvolume: + subvolpath = subvolume.path + ret = 0, subvolpath.decode("utf-8"), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def subvolume_info(self, **kwargs): + ret = None + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.INFO) as subvolume: + mon_addr_lst = [] + mon_map_mons = self.mgr.get('mon_map')['mons'] + for mon in mon_map_mons: + ip_port = mon['addr'].split("/")[0] + mon_addr_lst.append(ip_port) + + subvol_info_dict = subvolume.info() + subvol_info_dict["mon_addrs"] = mon_addr_lst + ret = 0, json.dumps(subvol_info_dict, indent=4, sort_keys=True), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def list_subvolumes(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + subvolumes = group.list_subvolumes() + ret = 0, name_to_json(subvolumes), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + ### subvolume snapshot + + def create_subvolume_snapshot(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + snapname = kwargs['snap_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.SNAP_CREATE) as subvolume: + subvolume.create_snapshot(snapname) + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def remove_subvolume_snapshot(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + snapname = kwargs['snap_name'] + groupname = kwargs['group_name'] + force = kwargs['force'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.SNAP_REMOVE) as subvolume: + subvolume.remove_snapshot(snapname) + except VolumeException as ve: + # ESTALE serves as an error to state that subvolume is currently stale due to internal removal and, + # we should tickle the purge jobs to purge the same + if ve.errno == -errno.ESTALE: + self.purge_queue.queue_job(volname) + elif not (ve.errno == -errno.ENOENT and force): + ret = self.volume_exception_to_retval(ve) + return ret + + def subvolume_snapshot_info(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + snapname = kwargs['snap_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.SNAP_INFO) as subvolume: + snap_info_dict = subvolume.snapshot_info(snapname) + ret = 0, json.dumps(snap_info_dict, indent=4, sort_keys=True), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def list_subvolume_snapshots(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.SNAP_LIST) as subvolume: + snapshots = subvolume.list_snapshots() + ret = 0, name_to_json(snapshots), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def protect_subvolume_snapshot(self, **kwargs): + ret = 0, "", "Deprecation warning: 'snapshot protect' call is deprecated and will be removed in a future release" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.SNAP_PROTECT) as subvolume: + log.warning("snapshot protect call is deprecated and will be removed in a future release") + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def unprotect_subvolume_snapshot(self, **kwargs): + ret = 0, "", "Deprecation warning: 'snapshot unprotect' call is deprecated and will be removed in a future release" + volname = kwargs['vol_name'] + subvolname = kwargs['sub_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname, SubvolumeOpType.SNAP_UNPROTECT) as subvolume: + log.warning("snapshot unprotect call is deprecated and will be removed in a future release") + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def _prepare_clone_subvolume(self, fs_handle, volname, s_subvolume, s_snapname, t_group, t_subvolname, **kwargs): + t_pool = kwargs['pool_layout'] + s_subvolname = kwargs['sub_name'] + s_groupname = kwargs['group_name'] + t_groupname = kwargs['target_group_name'] + + create_clone(self.mgr, fs_handle, self.volspec, t_group, t_subvolname, t_pool, volname, s_subvolume, s_snapname) + with open_subvol(self.mgr, fs_handle, self.volspec, t_group, t_subvolname, SubvolumeOpType.CLONE_INTERNAL) as t_subvolume: + try: + if t_groupname == s_groupname and t_subvolname == s_subvolname: + t_subvolume.attach_snapshot(s_snapname, t_subvolume) + else: + s_subvolume.attach_snapshot(s_snapname, t_subvolume) + self.cloner.queue_job(volname) + except VolumeException as ve: + try: + t_subvolume.remove() + self.purge_queue.queue_job(volname) + except Exception as e: + log.warning("failed to cleanup clone subvolume '{0}' ({1})".format(t_subvolname, e)) + raise ve + + def _clone_subvolume_snapshot(self, fs_handle, volname, s_group, s_subvolume, **kwargs): + s_snapname = kwargs['snap_name'] + target_subvolname = kwargs['target_sub_name'] + target_groupname = kwargs['target_group_name'] + s_groupname = kwargs['group_name'] + + if not s_snapname.encode('utf-8') in s_subvolume.list_snapshots(): + raise VolumeException(-errno.ENOENT, "snapshot '{0}' does not exist".format(s_snapname)) + + with open_group_unique(fs_handle, self.volspec, target_groupname, s_group, s_groupname) as target_group: + try: + with open_subvol(self.mgr, fs_handle, self.volspec, target_group, target_subvolname, SubvolumeOpType.CLONE_CREATE): + raise VolumeException(-errno.EEXIST, "subvolume '{0}' exists".format(target_subvolname)) + except VolumeException as ve: + if ve.errno == -errno.ENOENT: + self._prepare_clone_subvolume(fs_handle, volname, s_subvolume, s_snapname, + target_group, target_subvolname, **kwargs) + else: + raise + + def clone_subvolume_snapshot(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + s_subvolname = kwargs['sub_name'] + s_groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, s_groupname) as s_group: + with open_subvol(self.mgr, fs_handle, self.volspec, s_group, s_subvolname, SubvolumeOpType.CLONE_SOURCE) as s_subvolume: + self._clone_subvolume_snapshot(fs_handle, volname, s_group, s_subvolume, **kwargs) + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def clone_status(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + clonename = kwargs['clone_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + with open_subvol(self.mgr, fs_handle, self.volspec, group, clonename, SubvolumeOpType.CLONE_STATUS) as subvolume: + ret = 0, json.dumps({'status' : subvolume.status}, indent=2), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def clone_cancel(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + clonename = kwargs['clone_name'] + groupname = kwargs['group_name'] + + try: + self.cloner.cancel_job(volname, (clonename, groupname)) + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + ### group operations + + def create_subvolume_group(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + groupname = kwargs['group_name'] + pool = kwargs['pool_layout'] + uid = kwargs['uid'] + gid = kwargs['gid'] + mode = kwargs['mode'] + + try: + with open_volume(self, volname) as fs_handle: + try: + with open_group(fs_handle, self.volspec, groupname): + # idempotent creation -- valid. + pass + except VolumeException as ve: + if ve.errno == -errno.ENOENT: + oct_mode = octal_str_to_decimal_int(mode) + create_group(fs_handle, self.volspec, groupname, pool, oct_mode, uid, gid) + else: + raise + except VolumeException as ve: + # volume does not exist or subvolume group creation failed + ret = self.volume_exception_to_retval(ve) + return ret + + def remove_subvolume_group(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + groupname = kwargs['group_name'] + force = kwargs['force'] + + try: + with open_volume(self, volname) as fs_handle: + remove_group(fs_handle, self.volspec, groupname) + except VolumeException as ve: + if not (ve.errno == -errno.ENOENT and force): + ret = self.volume_exception_to_retval(ve) + return ret + + def getpath_subvolume_group(self, **kwargs): + volname = kwargs['vol_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + return 0, group.path.decode('utf-8'), "" + except VolumeException as ve: + return self.volume_exception_to_retval(ve) + + def list_subvolume_groups(self, **kwargs): + volname = kwargs['vol_name'] + ret = 0, '[]', "" + try: + with open_volume(self, volname) as fs_handle: + groups = listdir(fs_handle, self.volspec.base_dir) + ret = 0, name_to_json(groups), "" + except VolumeException as ve: + if not ve.errno == -errno.ENOENT: + ret = self.volume_exception_to_retval(ve) + return ret + + ### group snapshot + + def create_subvolume_group_snapshot(self, **kwargs): + ret = -errno.ENOSYS, "", "subvolume group snapshots are not supported" + volname = kwargs['vol_name'] + groupname = kwargs['group_name'] + # snapname = kwargs['snap_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + # as subvolumes are marked with the vxattr ceph.dir.subvolume deny snapshots + # at the subvolume group (see: https://tracker.ceph.com/issues/46074) + # group.create_snapshot(snapname) + pass + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret + + def remove_subvolume_group_snapshot(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + groupname = kwargs['group_name'] + snapname = kwargs['snap_name'] + force = kwargs['force'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + group.remove_snapshot(snapname) + except VolumeException as ve: + if not (ve.errno == -errno.ENOENT and force): + ret = self.volume_exception_to_retval(ve) + return ret + + def list_subvolume_group_snapshots(self, **kwargs): + ret = 0, "", "" + volname = kwargs['vol_name'] + groupname = kwargs['group_name'] + + try: + with open_volume(self, volname) as fs_handle: + with open_group(fs_handle, self.volspec, groupname) as group: + snapshots = group.list_snapshots() + ret = 0, name_to_json(snapshots), "" + except VolumeException as ve: + ret = self.volume_exception_to_retval(ve) + return ret diff --git a/src/pybind/mgr/volumes/module.py b/src/pybind/mgr/volumes/module.py new file mode 100644 index 00000000..3b9ed4a9 --- /dev/null +++ b/src/pybind/mgr/volumes/module.py @@ -0,0 +1,576 @@ +import errno +import json +import logging +import traceback +import threading + +from mgr_module import MgrModule +import orchestrator + +from .fs.volume import VolumeClient + +log = logging.getLogger(__name__) + +class VolumesInfoWrapper(): + def __init__(self, f, context): + self.f = f + self.context = context + def __enter__(self): + log.info("Starting {}".format(self.context)) + def __exit__(self, exc_type, exc_value, tb): + if exc_type is not None: + log.error("Failed {}:\n{}".format(self.context, "".join(traceback.format_exception(exc_type, exc_value, tb)))) + else: + log.info("Finishing {}".format(self.context)) + +def mgr_cmd_wrap(f): + def wrap(self, inbuf, cmd): + astr = [] + for k in cmd: + astr.append("{}:{}".format(k, cmd[k])) + context = "{}({}) < \"{}\"".format(f.__name__, ", ".join(astr), inbuf) + with VolumesInfoWrapper(f, context): + return f(self, inbuf, cmd) + return wrap + +class Module(orchestrator.OrchestratorClientMixin, MgrModule): + COMMANDS = [ + { + 'cmd': 'fs volume ls', + 'desc': "List volumes", + 'perm': 'r' + }, + { + 'cmd': 'fs volume create ' + 'name=name,type=CephString ', + 'desc': "Create a CephFS volume", + 'perm': 'rw' + }, + { + 'cmd': 'fs volume rm ' + 'name=vol_name,type=CephString ' + 'name=yes-i-really-mean-it,type=CephString,req=false ', + 'desc': "Delete a FS volume by passing --yes-i-really-mean-it flag", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolumegroup ls ' + 'name=vol_name,type=CephString ', + 'desc': "List subvolumegroups", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolumegroup create ' + 'name=vol_name,type=CephString ' + 'name=group_name,type=CephString ' + 'name=pool_layout,type=CephString,req=false ' + 'name=uid,type=CephInt,req=false ' + 'name=gid,type=CephInt,req=false ' + 'name=mode,type=CephString,req=false ', + 'desc': "Create a CephFS subvolume group in a volume, and optionally, " + "with a specific data pool layout, and a specific numeric mode", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolumegroup rm ' + 'name=vol_name,type=CephString ' + 'name=group_name,type=CephString ' + 'name=force,type=CephBool,req=false ', + 'desc': "Delete a CephFS subvolume group in a volume", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume ls ' + 'name=vol_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "List subvolumes", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolume create ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=size,type=CephInt,req=false ' + 'name=group_name,type=CephString,req=false ' + 'name=pool_layout,type=CephString,req=false ' + 'name=uid,type=CephInt,req=false ' + 'name=gid,type=CephInt,req=false ' + 'name=mode,type=CephString,req=false ' + 'name=namespace_isolated,type=CephBool,req=false ', + 'desc': "Create a CephFS subvolume in a volume, and optionally, " + "with a specific size (in bytes), a specific data pool layout, " + "a specific mode, in a specific subvolume group and in separate " + "RADOS namespace", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume rm ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=group_name,type=CephString,req=false ' + 'name=force,type=CephBool,req=false ' + 'name=retain_snapshots,type=CephBool,req=false ', + 'desc': "Delete a CephFS subvolume in a volume, and optionally, " + "in a specific subvolume group, force deleting a cancelled or failed " + "clone, and retaining existing subvolume snapshots", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume authorize ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=auth_id,type=CephString ' + 'name=group_name,type=CephString,req=false ' + 'name=access_level,type=CephString,req=false ' + 'name=tenant_id,type=CephString,req=false ' + 'name=allow_existing_id,type=CephBool,req=false ', + 'desc': "Allow a cephx auth ID access to a subvolume", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume deauthorize ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=auth_id,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Deny a cephx auth ID access to a subvolume", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume authorized_list ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "List auth IDs that have access to a subvolume", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolume evict ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=auth_id,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Evict clients based on auth IDs and subvolume mounted", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolumegroup getpath ' + 'name=vol_name,type=CephString ' + 'name=group_name,type=CephString ', + 'desc': "Get the mountpath of a CephFS subvolume group in a volume", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolume getpath ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Get the mountpath of a CephFS subvolume in a volume, " + "and optionally, in a specific subvolume group", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume info ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Get the metadata of a CephFS subvolume in a volume, " + "and optionally, in a specific subvolume group", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolumegroup snapshot ls ' + 'name=vol_name,type=CephString ' + 'name=group_name,type=CephString ', + 'desc': "List subvolumegroup snapshots", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolumegroup snapshot create ' + 'name=vol_name,type=CephString ' + 'name=group_name,type=CephString ' + 'name=snap_name,type=CephString ', + 'desc': "Create a snapshot of a CephFS subvolume group in a volume", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolumegroup snapshot rm ' + 'name=vol_name,type=CephString ' + 'name=group_name,type=CephString ' + 'name=snap_name,type=CephString ' + 'name=force,type=CephBool,req=false ', + 'desc': "Delete a snapshot of a CephFS subvolume group in a volume", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume snapshot ls ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "List subvolume snapshots", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolume snapshot create ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=snap_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Create a snapshot of a CephFS subvolume in a volume, " + "and optionally, in a specific subvolume group", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume snapshot info ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=snap_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Get the metadata of a CephFS subvolume snapshot " + "and optionally, in a specific subvolume group", + 'perm': 'r' + }, + { + 'cmd': 'fs subvolume snapshot rm ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=snap_name,type=CephString ' + 'name=group_name,type=CephString,req=false ' + 'name=force,type=CephBool,req=false ', + 'desc': "Delete a snapshot of a CephFS subvolume in a volume, " + "and optionally, in a specific subvolume group", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume resize ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=new_size,type=CephString,req=true ' + 'name=group_name,type=CephString,req=false ' + 'name=no_shrink,type=CephBool,req=false ', + 'desc': "Resize a CephFS subvolume", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume snapshot protect ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=snap_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "(deprecated) Protect snapshot of a CephFS subvolume in a volume, " + "and optionally, in a specific subvolume group", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume snapshot unprotect ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=snap_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "(deprecated) Unprotect a snapshot of a CephFS subvolume in a volume, " + "and optionally, in a specific subvolume group", + 'perm': 'rw' + }, + { + 'cmd': 'fs subvolume snapshot clone ' + 'name=vol_name,type=CephString ' + 'name=sub_name,type=CephString ' + 'name=snap_name,type=CephString ' + 'name=target_sub_name,type=CephString ' + 'name=pool_layout,type=CephString,req=false ' + 'name=group_name,type=CephString,req=false ' + 'name=target_group_name,type=CephString,req=false ', + 'desc': "Clone a snapshot to target subvolume", + 'perm': 'rw' + }, + { + 'cmd': 'fs clone status ' + 'name=vol_name,type=CephString ' + 'name=clone_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Get status on a cloned subvolume.", + 'perm': 'r' + }, + { + 'cmd': 'fs clone cancel ' + 'name=vol_name,type=CephString ' + 'name=clone_name,type=CephString ' + 'name=group_name,type=CephString,req=false ', + 'desc': "Cancel an pending or ongoing clone operation.", + 'perm': 'r' + }, + + # volume ls [recursive] + # subvolume ls + # volume authorize/deauthorize + # subvolume authorize/deauthorize + + # volume describe (free space, etc) + # volume auth list (vc.get_authorized_ids) + + # snapshots? + + # FIXME: we're doing CephFSVolumeClient.recover on every + # path where we instantiate and connect a client. Perhaps + # keep clients alive longer, or just pass a "don't recover" + # flag in if it's the >1st time we connected a particular + # volume in the lifetime of this module instance. + ] + + MODULE_OPTIONS = [ + { + 'name': 'max_concurrent_clones', + 'type': 'int', + 'default': 4, + 'desc': 'Number of asynchronous cloner threads', + } + ] + + def __init__(self, *args, **kwargs): + self.inited = False + # for mypy + self.max_concurrent_clones = None + self.lock = threading.Lock() + super(Module, self).__init__(*args, **kwargs) + # Initialize config option members + self.config_notify() + with self.lock: + self.vc = VolumeClient(self) + self.inited = True + + def __del__(self): + self.vc.shutdown() + + def shutdown(self): + self.vc.shutdown() + + def config_notify(self): + """ + This method is called whenever one of our config options is changed. + """ + with self.lock: + for opt in self.MODULE_OPTIONS: + setattr(self, + opt['name'], # type: ignore + self.get_module_option(opt['name'])) # type: ignore + self.log.debug(' mgr option %s = %s', + opt['name'], getattr(self, opt['name'])) # type: ignore + if self.inited: + if opt['name'] == "max_concurrent_clones": + self.vc.cloner.reconfigure_max_concurrent_clones(self.max_concurrent_clones) + + def handle_command(self, inbuf, cmd): + handler_name = "_cmd_" + cmd['prefix'].replace(" ", "_") + try: + handler = getattr(self, handler_name) + except AttributeError: + return -errno.EINVAL, "", "Unknown command" + + return handler(inbuf, cmd) + + @mgr_cmd_wrap + def _cmd_fs_volume_create(self, inbuf, cmd): + vol_id = cmd['name'] + return self.vc.create_fs_volume(vol_id) + + @mgr_cmd_wrap + def _cmd_fs_volume_rm(self, inbuf, cmd): + vol_name = cmd['vol_name'] + confirm = cmd.get('yes-i-really-mean-it', None) + return self.vc.delete_fs_volume(vol_name, confirm) + + @mgr_cmd_wrap + def _cmd_fs_volume_ls(self, inbuf, cmd): + return self.vc.list_fs_volumes() + + @mgr_cmd_wrap + def _cmd_fs_subvolumegroup_create(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), empty string(str), error message (str) + """ + return self.vc.create_subvolume_group( + vol_name=cmd['vol_name'], group_name=cmd['group_name'], + pool_layout=cmd.get('pool_layout', None), mode=cmd.get('mode', '755'), + uid=cmd.get('uid', None), gid=cmd.get('gid', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolumegroup_rm(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), empty string(str), error message (str) + """ + return self.vc.remove_subvolume_group(vol_name=cmd['vol_name'], + group_name=cmd['group_name'], + force=cmd.get('force', False)) + + @mgr_cmd_wrap + def _cmd_fs_subvolumegroup_ls(self, inbuf, cmd): + return self.vc.list_subvolume_groups(vol_name=cmd['vol_name']) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_create(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), empty string(str), error message (str) + """ + return self.vc.create_subvolume(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + group_name=cmd.get('group_name', None), + size=cmd.get('size', None), + pool_layout=cmd.get('pool_layout', None), + uid=cmd.get('uid', None), + gid=cmd.get('gid', None), + mode=cmd.get('mode', '755'), + namespace_isolated=cmd.get('namespace_isolated', False)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_rm(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), empty string(str), error message (str) + """ + return self.vc.remove_subvolume(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + group_name=cmd.get('group_name', None), + force=cmd.get('force', False), + retain_snapshots=cmd.get('retain_snapshots', False)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_authorize(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), secret key(str), error message (str) + """ + return self.vc.authorize_subvolume(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + auth_id=cmd['auth_id'], + group_name=cmd.get('group_name', None), + access_level=cmd.get('access_level', 'rw'), + tenant_id=cmd.get('tenant_id', None), + allow_existing_id=cmd.get('allow_existing_id', False)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_deauthorize(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), empty string(str), error message (str) + """ + return self.vc.deauthorize_subvolume(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + auth_id=cmd['auth_id'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_authorized_list(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), list of authids(json), error message (str) + """ + return self.vc.authorized_list(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_evict(self, inbuf, cmd): + """ + :return: a 3-tuple of return code(int), empyt string(str), error message (str) + """ + return self.vc.evict(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + auth_id=cmd['auth_id'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_ls(self, inbuf, cmd): + return self.vc.list_subvolumes(vol_name=cmd['vol_name'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolumegroup_getpath(self, inbuf, cmd): + return self.vc.getpath_subvolume_group( + vol_name=cmd['vol_name'], group_name=cmd['group_name']) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_getpath(self, inbuf, cmd): + return self.vc.subvolume_getpath(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_info(self, inbuf, cmd): + return self.vc.subvolume_info(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolumegroup_snapshot_create(self, inbuf, cmd): + return self.vc.create_subvolume_group_snapshot(vol_name=cmd['vol_name'], + group_name=cmd['group_name'], + snap_name=cmd['snap_name']) + + @mgr_cmd_wrap + def _cmd_fs_subvolumegroup_snapshot_rm(self, inbuf, cmd): + return self.vc.remove_subvolume_group_snapshot(vol_name=cmd['vol_name'], + group_name=cmd['group_name'], + snap_name=cmd['snap_name'], + force=cmd.get('force', False)) + + @mgr_cmd_wrap + def _cmd_fs_subvolumegroup_snapshot_ls(self, inbuf, cmd): + return self.vc.list_subvolume_group_snapshots(vol_name=cmd['vol_name'], + group_name=cmd['group_name']) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_snapshot_create(self, inbuf, cmd): + return self.vc.create_subvolume_snapshot(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + snap_name=cmd['snap_name'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_snapshot_rm(self, inbuf, cmd): + return self.vc.remove_subvolume_snapshot(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + snap_name=cmd['snap_name'], + group_name=cmd.get('group_name', None), + force=cmd.get('force', False)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_snapshot_info(self, inbuf, cmd): + return self.vc.subvolume_snapshot_info(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + snap_name=cmd['snap_name'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_snapshot_ls(self, inbuf, cmd): + return self.vc.list_subvolume_snapshots(vol_name=cmd['vol_name'], + sub_name=cmd['sub_name'], + group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_resize(self, inbuf, cmd): + return self.vc.resize_subvolume(vol_name=cmd['vol_name'], sub_name=cmd['sub_name'], + new_size=cmd['new_size'], group_name=cmd.get('group_name', None), + no_shrink=cmd.get('no_shrink', False)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_snapshot_protect(self, inbuf, cmd): + return self.vc.protect_subvolume_snapshot(vol_name=cmd['vol_name'], sub_name=cmd['sub_name'], + snap_name=cmd['snap_name'], group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_snapshot_unprotect(self, inbuf, cmd): + return self.vc.unprotect_subvolume_snapshot(vol_name=cmd['vol_name'], sub_name=cmd['sub_name'], + snap_name=cmd['snap_name'], group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_subvolume_snapshot_clone(self, inbuf, cmd): + return self.vc.clone_subvolume_snapshot( + vol_name=cmd['vol_name'], sub_name=cmd['sub_name'], snap_name=cmd['snap_name'], + group_name=cmd.get('group_name', None), pool_layout=cmd.get('pool_layout', None), + target_sub_name=cmd['target_sub_name'], target_group_name=cmd.get('target_group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_clone_status(self, inbuf, cmd): + return self.vc.clone_status( + vol_name=cmd['vol_name'], clone_name=cmd['clone_name'], group_name=cmd.get('group_name', None)) + + @mgr_cmd_wrap + def _cmd_fs_clone_cancel(self, inbuf, cmd): + return self.vc.clone_cancel( + vol_name=cmd['vol_name'], clone_name=cmd['clone_name'], group_name=cmd.get('group_name', None)) diff --git a/src/pybind/mgr/zabbix/__init__.py b/src/pybind/mgr/zabbix/__init__.py new file mode 100644 index 00000000..8f210ac9 --- /dev/null +++ b/src/pybind/mgr/zabbix/__init__.py @@ -0,0 +1 @@ +from .module import Module diff --git a/src/pybind/mgr/zabbix/module.py b/src/pybind/mgr/zabbix/module.py new file mode 100644 index 00000000..25d2f825 --- /dev/null +++ b/src/pybind/mgr/zabbix/module.py @@ -0,0 +1,380 @@ +""" +Zabbix module for ceph-mgr + +Collect statistics from Ceph cluster and every X seconds send data to a Zabbix +server using the zabbix_sender executable. +""" +import json +import errno +import re +from subprocess import Popen, PIPE +from threading import Event +from mgr_module import MgrModule + + +def avg(data): + if len(data): + return sum(data) / float(len(data)) + else: + return 0 + + +class ZabbixSender(object): + def __init__(self, sender, host, port, log): + self.sender = sender + self.host = host + self.port = port + self.log = log + + def send(self, hostname, data): + if len(data) == 0: + return + + cmd = [self.sender, '-z', self.host, '-p', str(self.port), '-s', + hostname, '-vv', '-i', '-'] + + self.log.debug('Executing: %s', cmd) + + proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) + + for key, value in data.items(): + proc.stdin.write('{0} ceph.{1} {2}\n'.format(hostname, key, value).encode('utf-8')) + + stdout, stderr = proc.communicate() + if proc.returncode != 0: + raise RuntimeError('%s exited non-zero: %s' % (self.sender, + stderr)) + + self.log.debug('Zabbix Sender: %s', stdout.rstrip()) + + +class Module(MgrModule): + run = False + config = dict() + ceph_health_mapping = {'HEALTH_OK': 0, 'HEALTH_WARN': 1, 'HEALTH_ERR': 2} + _zabbix_hosts = list() + + @property + def config_keys(self): + return dict((o['name'], o.get('default', None)) + for o in self.MODULE_OPTIONS) + + MODULE_OPTIONS = [ + { + 'name': 'zabbix_sender', + 'default': '/usr/bin/zabbix_sender' + }, + { + 'name': 'zabbix_host', + 'default': None + }, + { + 'name': 'zabbix_port', + 'type': 'int', + 'default': 10051 + }, + { + 'name': 'identifier', + 'default': "" + }, + { + 'name': 'interval', + 'type': 'secs', + 'default': 60 + } + ] + + COMMANDS = [ + { + "cmd": "zabbix config-set name=key,type=CephString " + "name=value,type=CephString", + "desc": "Set a configuration value", + "perm": "rw" + }, + { + "cmd": "zabbix config-show", + "desc": "Show current configuration", + "perm": "r" + }, + { + "cmd": "zabbix send", + "desc": "Force sending data to Zabbix", + "perm": "rw" + }, + ] + + def __init__(self, *args, **kwargs): + super(Module, self).__init__(*args, **kwargs) + self.event = Event() + + def init_module_config(self): + self.fsid = self.get('mon_map')['fsid'] + self.log.debug('Found Ceph fsid %s', self.fsid) + + for key, default in self.config_keys.items(): + self.set_config_option(key, self.get_module_option(key, default)) + + if self.config['zabbix_host']: + self._parse_zabbix_hosts() + + def set_config_option(self, option, value): + if option not in self.config_keys.keys(): + raise RuntimeError('{0} is a unknown configuration ' + 'option'.format(option)) + + if option in ['zabbix_port', 'interval']: + try: + value = int(value) + except (ValueError, TypeError): + raise RuntimeError('invalid {0} configured. Please specify ' + 'a valid integer'.format(option)) + + if option == 'interval' and value < 10: + raise RuntimeError('interval should be set to at least 10 seconds') + + self.log.debug('Setting in-memory config option %s to: %s', option, + value) + self.config[option] = value + return True + + def _parse_zabbix_hosts(self): + self._zabbix_hosts = list() + servers = self.config['zabbix_host'].split(",") + for server in servers: + uri = re.match("(?:(?:\[?)([a-z0-9-\.]+|[a-f0-9:\.]+)(?:\]?))(?:((?::))([0-9]{1,5}))?$", server) + if uri: + zabbix_host, sep, zabbix_port = uri.groups() + zabbix_port = zabbix_port if sep == ':' else self.config['zabbix_port'] + self._zabbix_hosts.append({'zabbix_host': zabbix_host, 'zabbix_port': zabbix_port}) + else: + self.log.error('Zabbix host "%s" is not valid', server) + + self.log.error('Parsed Zabbix hosts: %s', self._zabbix_hosts) + + def get_pg_stats(self): + stats = dict() + + pg_states = ['active', 'peering', 'clean', 'scrubbing', 'undersized', + 'backfilling', 'recovering', 'degraded', 'inconsistent', + 'remapped', 'backfill_toofull', 'backfill_wait', + 'recovery_wait'] + + for state in pg_states: + stats['num_pg_{0}'.format(state)] = 0 + + pg_status = self.get('pg_status') + + stats['num_pg'] = pg_status['num_pgs'] + + for state in pg_status['pgs_by_state']: + states = state['state_name'].split('+') + for s in pg_states: + key = 'num_pg_{0}'.format(s) + if s in states: + stats[key] += state['count'] + + return stats + + def get_data(self): + data = dict() + + health = json.loads(self.get('health')['json']) + # 'status' is luminous+, 'overall_status' is legacy mode. + data['overall_status'] = health.get('status', + health.get('overall_status')) + data['overall_status_int'] = \ + self.ceph_health_mapping.get(data['overall_status']) + + mon_status = json.loads(self.get('mon_status')['json']) + data['num_mon'] = len(mon_status['monmap']['mons']) + + df = self.get('df') + data['num_pools'] = len(df['pools']) + data['total_used_bytes'] = df['stats']['total_used_bytes'] + data['total_bytes'] = df['stats']['total_bytes'] + data['total_avail_bytes'] = df['stats']['total_avail_bytes'] + + wr_ops = 0 + rd_ops = 0 + wr_bytes = 0 + rd_bytes = 0 + + for pool in df['pools']: + wr_ops += pool['stats']['wr'] + rd_ops += pool['stats']['rd'] + wr_bytes += pool['stats']['wr_bytes'] + rd_bytes += pool['stats']['rd_bytes'] + + data['wr_ops'] = wr_ops + data['rd_ops'] = rd_ops + data['wr_bytes'] = wr_bytes + data['rd_bytes'] = rd_bytes + + osd_map = self.get('osd_map') + data['num_osd'] = len(osd_map['osds']) + data['osd_nearfull_ratio'] = osd_map['nearfull_ratio'] + data['osd_full_ratio'] = osd_map['full_ratio'] + data['osd_backfillfull_ratio'] = osd_map['backfillfull_ratio'] + + data['num_pg_temp'] = len(osd_map['pg_temp']) + + num_up = 0 + num_in = 0 + for osd in osd_map['osds']: + if osd['up'] == 1: + num_up += 1 + + if osd['in'] == 1: + num_in += 1 + + data['num_osd_up'] = num_up + data['num_osd_in'] = num_in + + osd_fill = list() + osd_pgs = list() + osd_apply_latency_ns = list() + osd_commit_latency_ns = list() + + osd_stats = self.get('osd_stats') + for osd in osd_stats['osd_stats']: + if osd['kb'] == 0: + continue + osd_fill.append((float(osd['kb_used']) / float(osd['kb'])) * 100) + osd_pgs.append(osd['num_pgs']) + osd_apply_latency_ns.append(osd['perf_stat']['apply_latency_ns']) + osd_commit_latency_ns.append(osd['perf_stat']['commit_latency_ns']) + + try: + data['osd_max_fill'] = max(osd_fill) + data['osd_min_fill'] = min(osd_fill) + data['osd_avg_fill'] = avg(osd_fill) + data['osd_max_pgs'] = max(osd_pgs) + data['osd_min_pgs'] = min(osd_pgs) + data['osd_avg_pgs'] = avg(osd_pgs) + except ValueError: + pass + + try: + data['osd_latency_apply_max'] = max(osd_apply_latency_ns) / 1000000.0 # ns -> ms + data['osd_latency_apply_min'] = min(osd_apply_latency_ns) / 1000000.0 # ns -> ms + data['osd_latency_apply_avg'] = avg(osd_apply_latency_ns) / 1000000.0 # ns -> ms + + data['osd_latency_commit_max'] = max(osd_commit_latency_ns) / 1000000.0 # ns -> ms + data['osd_latency_commit_min'] = min(osd_commit_latency_ns) / 1000000.0 # ns -> ms + data['osd_latency_commit_avg'] = avg(osd_commit_latency_ns) / 1000000.0 # ns -> ms + except ValueError: + pass + + data.update(self.get_pg_stats()) + + return data + + def send(self): + data = self.get_data() + + identifier = self.config['identifier'] + if identifier is None or len(identifier) == 0: + identifier = 'ceph-{0}'.format(self.fsid) + + if not self.config['zabbix_host'] or not self._zabbix_hosts: + self.log.error('Zabbix server not set, please configure using: ' + 'ceph zabbix config-set zabbix_host ') + self.set_health_checks({ + 'MGR_ZABBIX_NO_SERVER': { + 'severity': 'warning', + 'summary': 'No Zabbix server configured', + 'detail': ['Configuration value zabbix_host not configured'] + } + }) + return + + result = True + + for server in self._zabbix_hosts: + self.log.info( + 'Sending data to Zabbix server %s, port %s as host/identifier %s', + server['zabbix_host'], server['zabbix_port'], identifier) + self.log.debug(data) + + try: + zabbix = ZabbixSender(self.config['zabbix_sender'], + server['zabbix_host'], + server['zabbix_port'], self.log) + zabbix.send(identifier, data) + except Exception as exc: + self.log.exception('Failed to send.') + self.set_health_checks({ + 'MGR_ZABBIX_SEND_FAILED': { + 'severity': 'warning', + 'summary': 'Failed to send data to Zabbix', + 'detail': [str(exc)] + } + }) + result = False + + self.set_health_checks(dict()) + return result + + def handle_command(self, inbuf, command): + if command['prefix'] == 'zabbix config-show': + return 0, json.dumps(self.config), '' + elif command['prefix'] == 'zabbix config-set': + key = command['key'] + value = command['value'] + if not value: + return -errno.EINVAL, '', 'Value should not be empty or None' + + self.log.debug('Setting configuration option %s to %s', key, value) + if self.set_config_option(key, value): + self.set_module_option(key, value) + if key == 'zabbix_host' or key == 'zabbix_port': + self._parse_zabbix_hosts() + return 0, 'Configuration option {0} updated'.format(key), '' + + return 1,\ + 'Failed to update configuration option {0}'.format(key), '' + + elif command['prefix'] == 'zabbix send': + if self.send(): + return 0, 'Sending data to Zabbix', '' + + return 1, 'Failed to send data to Zabbix', '' + else: + return (-errno.EINVAL, '', + "Command not found '{0}'".format(command['prefix'])) + + def shutdown(self): + self.log.info('Stopping zabbix') + self.run = False + self.event.set() + + def serve(self): + self.log.info('Zabbix module starting up') + self.run = True + + self.init_module_config() + + while self.run: + self.log.debug('Waking up for new iteration') + + try: + self.send() + except Exception as exc: + # Shouldn't happen, but let's log it and retry next interval, + # rather than dying completely. + self.log.exception("Unexpected error during send():") + + interval = self.config['interval'] + self.log.debug('Sleeping for %d seconds', interval) + self.event.wait(interval) + + def self_test(self): + data = self.get_data() + + if data['overall_status'] not in self.ceph_health_mapping: + raise RuntimeError('No valid overall_status found in data') + + int(data['overall_status_int']) + + if data['num_mon'] < 1: + raise RuntimeError('num_mon is smaller than 1') diff --git a/src/pybind/mgr/zabbix/zabbix_template.xml b/src/pybind/mgr/zabbix/zabbix_template.xml new file mode 100644 index 00000000..d75d912e --- /dev/null +++ b/src/pybind/mgr/zabbix/zabbix_template.xml @@ -0,0 +1,2569 @@ + + + 3.0 + 2017-10-24T07:00:13Z + + + Templates + + + + + + + + {ceph-mgr Zabbix module:ceph.overall_status_int.last()}=2 + Ceph cluster in ERR state + + 0 + 5 + Ceph cluster is in ERR state + 0 + + + + {ceph-mgr Zabbix module:ceph.overall_status_int.avg(1h)}=1 + Ceph cluster in WARN state + + 0 + 4 + Issue a trigger if Ceph cluster is in WARN state for >1h + 0 + + + + {ceph-mgr Zabbix module:ceph.num_osd_in.change()}>0 + Number of IN OSDs decreased + + 0 + 2 + Amount of OSDs in IN state decreased + 0 + + + + {ceph-mgr Zabbix module:ceph.num_osd_up.change()}>0 + Number of UP OSDs decreased + + 0 + 2 + Amount of OSDs in UP state decreased + 0 + + + + + + Ceph bandwidth + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 1 + 1 + 0 + 0.0000 + 0.0000 + 0 + 0 + 0 + 0 + + + 0 + 0 + 1A7C11 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.rd_bytes + + + + 1 + 0 + F63100 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.wr_bytes + + + + + + Ceph free space + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 1 + 2 + 0 + + ceph-mgr Zabbix module + ceph.total_bytes + + + + 0 + 0 + 00AA00 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.total_avail_bytes + + + + 1 + 0 + DD0000 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.total_used_bytes + + + + + + Ceph health + 900 + 200 + 0.0000 + 2.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 1 + 1 + 0 + 0 + + + 0 + 0 + 1A7C11 + 0 + 7 + 0 + + ceph-mgr Zabbix module + ceph.overall_status_int + + + + + + Ceph I/O + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 1 + 1 + 0 + 0.0000 + 0.0000 + 1 + 0 + 0 + 0 + + + 0 + 0 + 1A7C11 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.rd_ops + + + + 1 + 0 + F63100 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.wr_ops + + + + + + Ceph OSD latency + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 0 + 0 + 0 + 0 + + + 0 + 0 + 1A7C11 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.osd_latency_apply_avg + + + + 1 + 0 + F63100 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.osd_latency_commit_avg + + + + 2 + 0 + 2774A4 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.osd_latency_apply_max + + + + 3 + 0 + A54F10 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.osd_latency_commit_max + + + + 4 + 0 + FC6EA3 + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.osd_latency_apply_min + + + + 5 + 0 + 6C59DC + 0 + 4 + 0 + + ceph-mgr Zabbix module + ceph.osd_latency_commit_min + + + + + + Ceph OSD utilization + 900 + 200 + 0.0000 + 100.0000 + 1 + 1 + 0 + 1 + 0 + 0.0000 + 0.0000 + 1 + 1 + 0 + 0 + + + 0 + 0 + 0000CC + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.osd_nearfull_ratio + + + + 1 + 0 + F63100 + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.osd_full_ratio + + + + 2 + 0 + CC00CC + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.osd_backfillfull_ratio + + + + 3 + 0 + A54F10 + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.osd_max_fill + + + + 4 + 0 + FC6EA3 + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.osd_avg_fill + + + + 5 + 0 + 6C59DC + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.osd_min_fill + + + + + + Ceph storage overview + 900 + 200 + 0.0000 + 0.0000 + 0 + 0 + 2 + 1 + 0 + 0.0000 + 0.0000 + 0 + 0 + 0 + 0 + + + 0 + 0 + F63100 + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.total_used_bytes + + + + 1 + 0 + 00CC00 + 0 + 2 + 0 + + ceph-mgr Zabbix module + ceph.total_avail_bytes + + + + + + -- cgit v1.2.3